Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
jobs:
checks:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6
Expand All @@ -16,4 +17,7 @@ jobs:
enable-cache: true
- run: uv python install 3.13
- run: make install
- run: make db-up
- run: make check
- if: always()
run: make db-down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ docs/design/2026-07-18-context-engine-design.md
.env.*
*.local
credentials*.json
.context-engine/

# --- Python ---
__pycache__/
Expand Down
15 changes: 11 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,22 @@ make typecheck # strict mypy
make test # unit test suite
make catalog # static security catalog tests and validation
make smoke # API and worker process smoke suite
make check # all required repository checks
make db-up # start the real PostgreSQL 17 + pgvector harness
make db-down # stop the harness while preserving its disposable data volume
make db-reset # destroy and rebuild only the harness's disposable data volume
make integration # real PostgreSQL integration/security harness
make check # all checks; requires make db-up first
```

## Verification Contract

Before claiming an implementation done, run the verified commands recorded
above. Never fabricate output. A green process smoke proves only boot/readiness;
Runtime delivery, database and worker-job capabilities remain `NOT_ACTIVE` until
their owning issues implement and verify them.
above. Never fabricate output. `.context-engine/database.env` is the generated,
ignored, mode-0600 source for local database connection contracts; `compose.yaml`
owns the pinned test service topology. A green process smoke proves only
boot/readiness. The database harness proves PG17/pgvector, role, migration, and
pool-reset infrastructure only; tenant schema, RLS enforcement, Runtime delivery,
and worker-job behavior remain `NOT_ACTIVE` until their owning issues verify them.

## Safety-Rails / Do Not

Expand Down
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: install build lint typecheck test catalog smoke check
.PHONY: install build lint typecheck test catalog smoke db-up db-down db-reset integration check

install:
uv sync --frozen
Expand All @@ -22,4 +22,16 @@ catalog:
smoke:
uv run pytest -q tests/process

check: build lint typecheck test catalog smoke
db-up:
./scripts/database_harness.sh up

db-down:
./scripts/database_harness.sh down

db-reset:
./scripts/database_harness.sh reset

integration:
./scripts/database_harness.sh integration

check: build lint typecheck test catalog smoke integration
44 changes: 36 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
企业微信),下游把「经过授权、带证据、有预算」的 ContextPackage 交付给 agent
应用与 IM bot(飞书群聊问答优先)。

**当前状态**:M0 工程骨架已启动。API 和独立 Supply worker 可运行,但
Runtime delivery、数据库和 worker job 行为仍为 `NOT_ACTIVE`。整体计划见
**当前状态**:M0 工程骨架已启动。API 和独立 Supply worker 可运行,真实
PostgreSQL 17 + pgvector 测试底座可复现;Runtime delivery、tenant schema、
RLS enforcement 和 worker job 行为仍为 `NOT_ACTIVE`。整体计划见
[PLAN.md](./PLAN.md)。

## 开发命令
Expand All @@ -25,9 +26,35 @@ make typecheck # strict mypy
make test # 单元测试
make catalog # 安全目录静态测试与校验
make smoke # API / worker 进程 smoke
make check # build + lint + typecheck + test + catalog + smoke
make db-up # 启动真实 PostgreSQL 17 + pgvector 测试底座
make db-down # 停止测试底座并保留 disposable data volume
make db-reset # 删除并重建该测试底座的 disposable data volume
make integration # 真实 PostgreSQL integration/security harness
make check # 全部门禁;要求先执行 make db-up
```

数据库底座首次启动时会在被 Git 忽略的
`.context-engine/database.env` 生成随机凭据并将文件权限设为 `0600`;该文件是
本地 migration、API Runtime、worker、security test 连接配置和该 checkout
独有 Compose project 身份的唯一实时来源,避免多个 worktree 或 checkout 共享
容器、网络与数据卷。
镜像及服务拓扑的版本真相位于 [`compose.yaml`](./compose.yaml),PostgreSQL 只绑定
一个动态选择的 `127.0.0.1` host port。migration、runtime 与 worker 使用不同
角色;runtime/security test 不会回退到 migration 或 bootstrap 凭据。

从 clean checkout 运行与 CI 相同的数据库门禁:

```bash
make install
make db-up
make check
make db-down
```

`make db-reset` 只删除当前 checkout 的 generated Compose project 所属的
disposable PostgreSQL volume,然后从初始化脚本重建。它不会删除仓库内容,但会
清除该本地测试数据库中的全部数据。

本地启动 API:

```bash
Expand All @@ -44,8 +71,9 @@ uv run context-engine-worker --test-mode
```

健康响应中的 `runtime_delivery: NOT_ACTIVE` 和 worker 输出中的
`job_behavior: NOT_ACTIVE` 是能力边界,不表示数据库、授权或 ContextPackage
交付已经实现。
`job_behavior: NOT_ACTIVE` 是能力边界。当前数据库测试只证明 PG17/pgvector、
角色隔离、空 Alembic baseline 和连接池清理契约;它没有 tenant table,也不声明
RLS、授权或 ContextPackage 交付已经实现。

本次公开候选 bundle 包含实现权威、ADR、安全契约、PRD、Tech Spec
与四个公开参考仓的证据基线;经维护者批准并提交后,它们将与实现一同
Expand All @@ -70,9 +98,9 @@ ContextEngine 的安全协议依据自身需求与威胁模型独立设计,零
- [D0 Baseline Candidate](./DESIGN-BASELINE.md):当前候选状态与尚未关闭的
evidence gates。

当前只有固定 commit 的四仓静态证据与仓库内设计拆解;PostgreSQL RLS、
filtered ANN 和飞书 capability 的 disposable evidence spikes 尚未完成,
因此不声称已有动态可行性或产品能力验证
当前除固定 commit 的四仓静态证据与仓库内设计拆解外,已有真实 PostgreSQL 17 +
pgvector 的基础 harness 证据。tenant schema / RLS isolation、filtered ANN 和飞书
capability 的动态证据仍未完成,因此不声称这些产品能力已经验证

## 为什么做这个

Expand Down
38 changes: 38 additions & 0 deletions alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[alembic]
script_location = %(here)s/migrations
prepend_sys_path = .
path_separator = os

[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
30 changes: 30 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
services:
postgres:
image: pgvector/pgvector:0.8.5-pg17-bookworm@sha256:d2ef61f42ef767baa5a1475393303cc235bcd92febd9d7014eddb48b41f3bad0
environment:
POSTGRES_DB: ${POSTGRES_DB:?POSTGRES_DB is required}
POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER is required}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256
CONTEXT_ENGINE_MIGRATOR_ROLE: ${CONTEXT_ENGINE_MIGRATOR_ROLE:?CONTEXT_ENGINE_MIGRATOR_ROLE is required}
CONTEXT_ENGINE_MIGRATOR_PASSWORD: ${CONTEXT_ENGINE_MIGRATOR_PASSWORD:?CONTEXT_ENGINE_MIGRATOR_PASSWORD is required}
CONTEXT_ENGINE_RUNTIME_ROLE: ${CONTEXT_ENGINE_RUNTIME_ROLE:?CONTEXT_ENGINE_RUNTIME_ROLE is required}
CONTEXT_ENGINE_RUNTIME_PASSWORD: ${CONTEXT_ENGINE_RUNTIME_PASSWORD:?CONTEXT_ENGINE_RUNTIME_PASSWORD is required}
CONTEXT_ENGINE_WORKER_ROLE: ${CONTEXT_ENGINE_WORKER_ROLE:?CONTEXT_ENGINE_WORKER_ROLE is required}
CONTEXT_ENGINE_WORKER_PASSWORD: ${CONTEXT_ENGINE_WORKER_PASSWORD:?CONTEXT_ENGINE_WORKER_PASSWORD is required}
ports:
- "127.0.0.1:${CONTEXT_ENGINE_POSTGRES_PORT:?CONTEXT_ENGINE_POSTGRES_PORT is required}:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
- ./infra/postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test:
- CMD-SHELL
- pg_isready --username "$${POSTGRES_USER}" --dbname "$${POSTGRES_DB}"
interval: 1s
timeout: 5s
retries: 30
start_period: 5s

volumes:
postgres-data:
23 changes: 23 additions & 0 deletions engine/persistence/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""PostgreSQL connectivity owned by the engine."""

from engine.persistence.configuration import (
DatabaseConfiguration,
DatabaseConfigurationError,
DatabasePurpose,
HarnessDatabaseConfigurations,
load_database_configuration,
load_harness_database_configurations,
)
from engine.persistence.database import create_database_engine
from engine.persistence.role_guard import assert_runtime_role

__all__ = [
"DatabaseConfiguration",
"DatabaseConfigurationError",
"DatabasePurpose",
"HarnessDatabaseConfigurations",
"assert_runtime_role",
"create_database_engine",
"load_database_configuration",
"load_harness_database_configurations",
]
Loading
Loading