Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
435d0fb
feat(agent): add boundary and isolation evaluation gates
DavidHLP Oct 1, 2026
adef778
test(agent): align evaluation fixtures with guarded model alias
DavidHLP Oct 1, 2026
f71c7a5
fix: harden account isolation evidence
DavidHLP Oct 1, 2026
0590e87
feat(app): preserve idempotent learning plan storage slice
DavidHLP Oct 2, 2026
f466d9c
fix(dev): pass container MySQL credentials via stdin
DavidHLP Oct 3, 2026
c470276
feat(agent): checkpoint explicit budget period lifecycle
DavidHLP Oct 3, 2026
6ef0028
feat(agent): checkpoint canonical period accounting seam
DavidHLP Oct 3, 2026
5a270e7
fix(agent): preserve SQLite locks in period accounting checkpoint
DavidHLP Oct 3, 2026
9e9d4b5
feat(agent): checkpoint explicit DAV58 period binding
DavidHLP Oct 3, 2026
5dd6e0c
docs: record DAV-58 boundary run failure
DavidHLP Oct 3, 2026
65c86a6
fix(agent): correct boundary predicates and guard live acceptance costs
DavidHLP Oct 3, 2026
dc342eb
fix(agent): validate observed tool traces and resume cumulative accep…
DavidHLP Oct 4, 2026
3a52bd1
fix(agent): require citation-free refusals for unavailable source req…
DavidHLP Oct 4, 2026
4fa42c7
fix(agent): recognize equivalent clarification and scoped failure den…
DavidHLP Oct 4, 2026
82554db
feat(agent): audit a single bounded DAV-58 budget continuation
DavidHLP Oct 4, 2026
e36f76c
fix(agent): audit the reviewed Btrfs budget binding migration
DavidHLP Oct 4, 2026
cf57fcd
test: reproduce inline references in source refusals
DavidHLP Oct 4, 2026
45e1c1a
test: cover www URLs and markdown images in refusals
DavidHLP Oct 4, 2026
bd6b0a9
test: cover edge cases in source refusal references
DavidHLP Oct 4, 2026
9b27ea9
test: isolate quoted reference refusal regression
DavidHLP Oct 4, 2026
e95fd74
fix: reject inline references in source refusals
DavidHLP Oct 4, 2026
4c96464
Merge remote-tracking branch 'origin/main' into agent/first-delivery
DavidHLP Oct 5, 2026
60c07cc
Merge remote-tracking branch 'origin/main' into agent/first-delivery
DavidHLP Oct 5, 2026
2218bc1
Merge remote-tracking branch 'origin/main' into agent/first-delivery
DavidHLP Oct 5, 2026
073e8c8
fix: enforce agent budget and offline contract safety gates
DavidHLP Oct 5, 2026
b9d5801
fix: scope Nacos metadata writes to workload identities
DavidHLP Oct 5, 2026
1733278
feat(agent): add gated durable learning workflows
DavidHLP Oct 6, 2026
3da2f11
fix: migrate backend to patched Spring Boot 4 baseline
DavidHLP Oct 6, 2026
17245bb
fix: pin patched Tomcat 11 and Jackson 3 dependencies
DavidHLP Oct 6, 2026
214c204
fix: exclude the incoherent Boot gRPC module at its source
DavidHLP Oct 7, 2026
a3c6061
fix: bind agent acceptance to executed source and citation-free refusals
DavidHLP Oct 7, 2026
35eab1d
fix: separate U04 SQL reservations from sequential guard envelope
DavidHLP Oct 7, 2026
a0c3f19
fix: preserve citations for source code concept explanations
DavidHLP Oct 7, 2026
b76b73c
fix: scope source concept qualifiers to the requested phrase
DavidHLP Oct 7, 2026
4000b48
test: cover uncited non-refusal source answers
DavidHLP Oct 7, 2026
a1cdf46
fix: require refusal for unavailable source requests
DavidHLP Oct 7, 2026
399f091
test: cover locked audit ledger recovery copies
DavidHLP Oct 7, 2026
450d54c
feat: rehearse locked accounting recovery without paid authorization
DavidHLP Oct 7, 2026
ff2e933
docs: explain audit-only accounting recovery rehearsal
DavidHLP Oct 7, 2026
0e3e5b1
test: cover autonomous confirmation without fabricated human evidence
DavidHLP Oct 7, 2026
31b079f
fix: make acceptance confirmation autonomous without human claims
DavidHLP Oct 7, 2026
0ec4f07
fix: require affirmative autonomous review before confirmation
DavidHLP Oct 7, 2026
1f1bf0c
docs: distinguish autonomous working decisions from user evidence
DavidHLP Oct 7, 2026
4fdf766
fix: accept documented skip-install startup option
DavidHLP Oct 8, 2026
060ca86
fix: address agent workflow review failures
DavidHLP Oct 8, 2026
dd1e156
fix: distinguish verified status facts from source diagnosis
DavidHLP Oct 8, 2026
3a35ff3
test: specify conservative acceptance recovery boundaries
DavidHLP Oct 8, 2026
24df095
test: require explicit inputs for offline recovery planning
DavidHLP Oct 8, 2026
f51f432
Merge remote-tracking branch 'origin/agent/first-delivery' into agent…
DavidHLP Oct 8, 2026
aad5491
feat: validate conditional offline acceptance recovery plans
DavidHLP Oct 8, 2026
f327bdc
docs: distinguish conditional recovery costs from authorization
DavidHLP Oct 8, 2026
d8a9696
fix: reject ambiguous recovery snapshots and unlocked guards
DavidHLP Oct 8, 2026
6410575
fix: bound Nacos young generation within heap
DavidHLP Oct 8, 2026
5f766fa
feat: bind revalidation to cumulative accounting
DavidHLP Oct 8, 2026
01d6c77
fix: interpret retrieved topic questions without over-refusal
DavidHLP Oct 8, 2026
81d6b0a
fix: declare the enforced answer length in evaluation prompts
DavidHLP Oct 8, 2026
f2f62f4
feat: preserve sealed accounting for acceptance budget extension
DavidHLP Oct 8, 2026
8e170ae
test: complete bound evaluation recording fixture
DavidHLP Oct 8, 2026
d33f7f8
fix: retry concurrent budget WAL initialization
DavidHLP Oct 8, 2026
a4a212d
feat: retain unknown liabilities in acceptance recovery
DavidHLP Oct 9, 2026
a6ede80
fix: distinguish boundary denials from observed failures
DavidHLP Oct 9, 2026
46fc5ef
fix: bound source refusals and equivalent boundary summaries
DavidHLP Oct 9, 2026
0223102
fix: use available Maven wrapper distribution
DavidHLP Oct 9, 2026
e376694
fix: complete authorized parts of mixed read-only requests
DavidHLP Oct 9, 2026
2d31a9f
feat: bind approved revalidation budget to sealed history
DavidHLP Oct 9, 2026
22e9a81
fix: recognize v4 allowance in development evaluation
DavidHLP Oct 9, 2026
f7994f1
fix: leave answer length headroom and retain failed revalidation
DavidHLP Oct 9, 2026
afc0e02
fix: clarify serialized answer evaluation envelope
DavidHLP Oct 9, 2026
9fc627e
test: align Core owner journey startup budgets
DavidHLP Oct 9, 2026
7d9fed9
fix: persist Agent event run ownership atomically
DavidHLP Oct 9, 2026
48ebf56
feat: stream bounded Agent workflow events
DavidHLP Oct 9, 2026
792a0d1
fix: drain durable events before stream terminal
DavidHLP Oct 9, 2026
36d3c94
test: exercise live Agent stream lifecycle
DavidHLP Oct 9, 2026
337ab82
fix: return canonical state after Agent run fencing
DavidHLP Oct 9, 2026
b3f70c9
fix: reconcile incomplete fenced Agent graph results
DavidHLP Oct 9, 2026
f13a8df
test: verify Agent stream pagination and timeout
DavidHLP Oct 9, 2026
384ca79
test: resume Agent checkpoint across process death
DavidHLP Oct 9, 2026
ce1554c
feat: correlate Agent model usage with workflow runs
DavidHLP Oct 9, 2026
1dd6274
test: preserve model observation failure semantics
DavidHLP Oct 9, 2026
4b1c3c7
test: account for fenced model observation events
DavidHLP Oct 9, 2026
4735ced
feat: bind licensed repository corpus to source manifests
DavidHLP Oct 9, 2026
2ac8d99
fix: bound repository operations excerpt to retrieval limit
DavidHLP Oct 9, 2026
f3464fe
feat: evaluate records against explicit retrieval corpora
DavidHLP Oct 9, 2026
f602bda
test: predeclare licensed corpus development cases
DavidHLP Oct 9, 2026
4b2b502
fix: filter vector evaluation by trusted access scope
DavidHLP Oct 9, 2026
8ef44a4
feat: bind owned vector evaluation to verified sessions
DavidHLP Oct 9, 2026
83656b3
test: declare licensed repository holdout cases
DavidHLP Oct 9, 2026
200bf88
test: verify Core read adapters against Auth owner
DavidHLP Oct 9, 2026
6821d9c
docs: align Core architecture with bounded owner proof
DavidHLP Oct 9, 2026
9163a8b
test: enforce Agent cookie identity before upstream access
DavidHLP Oct 9, 2026
bd8f2f3
fix: validate Agent response envelopes with Pydantic
DavidHLP Oct 9, 2026
c5d12c8
fix: refresh licensed corpus versions after documentation changes
DavidHLP Oct 9, 2026
b1f04b3
fix: preserve licensed reference excerpt boundaries
DavidHLP Oct 9, 2026
c6a6afd
feat: expose isolated core owner HTTP journeys
DavidHLP Oct 9, 2026
cb86f25
test: bind core HTTP journey storage fixtures
DavidHLP Oct 9, 2026
af7822b
docs: describe core HTTP validation boundary
DavidHLP Oct 9, 2026
099d8af
test: provide JWT inputs to core owner journey
DavidHLP Oct 9, 2026
bb04075
fix: allow absent app profile provider in admin enrichment
DavidHLP Oct 9, 2026
ed9155b
fix: preserve optional admin detail provider wiring
DavidHLP Oct 9, 2026
c06dc45
docs: close bounded Core owner journey acceptance
DavidHLP Oct 9, 2026
1a9a2ce
docs: align Core architecture with verified HTTP journey
DavidHLP Oct 9, 2026
1ed2d88
feat: bind approved test budget to retained acceptance history
DavidHLP Oct 10, 2026
da75af7
test: reject writable sealed history verification views
DavidHLP Oct 10, 2026
e1f5658
fix: verify sealed budget history once per traversal
DavidHLP Oct 10, 2026
ab68e43
test: require submission clarification in model protocol
DavidHLP Oct 10, 2026
f7891b5
fix: clarify submission identity before invoking tools
DavidHLP Oct 10, 2026
29ef36c
test: cover equivalent provide submission clarification
DavidHLP Oct 10, 2026
66d2223
fix: recognize equivalent submission ID clarification
DavidHLP Oct 10, 2026
b63f4ce
test: require executing requested authorized read-only actions
DavidHLP Oct 10, 2026
d53150a
fix: execute already requested authorized read-only actions
DavidHLP Oct 10, 2026
fc4eefe
fix: bind repository corpus to updated development guide
DavidHLP Oct 10, 2026
ab97f3e
test: retain sealed v6 liabilities in next acceptance binding
DavidHLP Oct 10, 2026
4f488c5
fix: bind next acceptance package to sealed v6 history
DavidHLP Oct 10, 2026
45ec05d
test: cover boundary corpus text digest semantics
DavidHLP Oct 10, 2026
8d70ff0
fix: validate boundary digest against loaded corpus text
DavidHLP Oct 10, 2026
ae6e0c9
test: require known settled boundary period receipts
DavidHLP Oct 10, 2026
b645a14
fix: emit verified settlement state in boundary receipts
DavidHLP Oct 10, 2026
2f9119d
test: bind judge evidence to serialized boundary receipts
DavidHLP Oct 10, 2026
2bf644b
fix: bind published judge evidence to settled receipts
DavidHLP Oct 10, 2026
112ab15
fix: reject invalid judge indices before offset
DavidHLP Oct 10, 2026
41378e3
test: pass published judge metering to receipt regression
DavidHLP Oct 10, 2026
9b42ba4
test: retain sealed v7 liabilities in v8 budget binding
DavidHLP Oct 10, 2026
aa4343b
fix: bind v8 allowance to sealed v7 budget history
DavidHLP Oct 10, 2026
3ff452a
test: require shared guarded transport in fresh boundary runner
DavidHLP Oct 10, 2026
cc3394f
fix: share bound guard across boundary loop and judge
DavidHLP Oct 10, 2026
9266e2f
test: include provider identity in guarded boundary response
DavidHLP Oct 10, 2026
5700d1c
test: assert fresh boundary accounting state
DavidHLP Oct 10, 2026
8b06b72
fix: bind boundary documentation corpus version
DavidHLP Oct 10, 2026
fd7db8e
fix: preserve guarded boundary entry transport ownership
DavidHLP Oct 10, 2026
06010a6
test: cover fresh guarded boundary entry and helper restoration
DavidHLP Oct 10, 2026
58a840e
test: preserve fresh guarded prompt envelope assertions
DavidHLP Oct 10, 2026
6888c31
test: retain sealed v8 liabilities in new acceptance binding
DavidHLP Oct 10, 2026
7b5e997
test: reject tampered and unsealed v8 rollover history
DavidHLP Oct 10, 2026
128e62e
fix: bind fresh acceptance to sealed v8 liabilities
DavidHLP Oct 10, 2026
e01ed2c
test: cover gate refusal and default boundary source pins
DavidHLP Oct 10, 2026
053d225
fix: align formal gate refusal checks and source provenance
DavidHLP Oct 10, 2026
44d345f
test: retain sealed V9 accounting in the next acceptance package
DavidHLP Oct 10, 2026
c4fe4e4
fix: bind fresh acceptance to permanently halted V9 history
DavidHLP Oct 10, 2026
425398a
test: pin evidence-based development judging contract
DavidHLP Oct 10, 2026
c5505d9
fix: define development judge evidence and behavior rubric
DavidHLP Oct 10, 2026
f6326d8
test: retain sealed v10 liabilities in acceptance rollover
DavidHLP Oct 10, 2026
e5b6011
feat: bind acceptance v11 to retained sealed history
DavidHLP Oct 10, 2026
1ecabda
test: require prior evidence to meet acceptance thresholds
DavidHLP Oct 10, 2026
91c9551
test: cover second development pass and typed thresholds
DavidHLP Oct 10, 2026
37baa6c
fix: enforce required prior evidence observations
DavidHLP Oct 10, 2026
69b9ac3
test: retain sealed v11 accounting in next acceptance period
DavidHLP Oct 10, 2026
e0afd12
fix: bind next acceptance period to sealed v11 accounting
DavidHLP Oct 10, 2026
dab478b
test: retain sanitized network failure diagnostics
DavidHLP Oct 10, 2026
eb2587a
fix: preserve safe network failure types in budget receipts
DavidHLP Oct 10, 2026
c654e92
test(agent): cover network diagnostic recovery compatibility
DavidHLP Oct 11, 2026
f047619
fix(agent): accept bounded network diagnostics during recovery
DavidHLP Oct 11, 2026
f5163a2
Merge pull request #258 from DavidHLP/codex/guard-network-diagnostics
DavidHLP Oct 11, 2026
0b511a3
fix(agent): propagate reviewed U02 judging and operator repairs
DavidHLP Oct 11, 2026
ef4c0a2
Merge pull request #269 from DavidHLP/codex/u02-reviewed-repairs
DavidHLP Oct 11, 2026
c6b8d6f
Merge pull request #257 from DavidHLP/codex/acceptance-v12-binding
DavidHLP Oct 11, 2026
1f6af8b
Merge pull request #256 from DavidHLP/codex/prior-five-required-obser…
DavidHLP Oct 11, 2026
9048657
Merge pull request #255 from DavidHLP/codex/acceptance-v11-binding
DavidHLP Oct 11, 2026
7efe2dc
Merge pull request #254 from DavidHLP/codex/development-judge-rubric
DavidHLP Oct 11, 2026
5a1cbf7
Merge pull request #253 from DavidHLP/codex/acceptance-v10-binding
DavidHLP Oct 11, 2026
316a17b
Merge pull request #252 from DavidHLP/codex/refusal-gate-alignment
DavidHLP Oct 11, 2026
b028533
Merge pull request #246 from DavidHLP/codex/acceptance-v9-binding
DavidHLP Oct 11, 2026
9ac1679
Merge pull request #245 from DavidHLP/codex/boundary-shared-guard
DavidHLP Oct 11, 2026
7e03bd4
Merge pull request #244 from DavidHLP/codex/acceptance-v8-binding
DavidHLP Oct 11, 2026
7e5f1db
Merge pull request #243 from DavidHLP/codex/boundary-budget-receipts
DavidHLP Oct 11, 2026
d6c1ad9
Merge pull request #242 from DavidHLP/codex/boundary-content-digest
DavidHLP Oct 11, 2026
bf1c25f
Merge pull request #241 from DavidHLP/codex/acceptance-v7-binding
DavidHLP Oct 11, 2026
44d28a2
Merge pull request #240 from DavidHLP/codex/mixed-read-only-execution
DavidHLP Oct 11, 2026
736c85f
Merge pull request #239 from DavidHLP/codex/sealed-history-verification
DavidHLP Oct 11, 2026
442cebb
merge: integrate current main into agent delivery
DavidHLP Oct 11, 2026
d1a77e4
merge: align agent delivery with release 1.0.2
DavidHLP Oct 11, 2026
9ff372e
fix: refresh corpus versions after main integration
DavidHLP Oct 11, 2026
b1e9dbd
test: retain unknown liabilities during authorized DeepSeek recovery
DavidHLP Oct 11, 2026
2da3568
fix: authorize sealed DeepSeek recovery with retained unknown usage
DavidHLP Oct 11, 2026
25f5b16
Merge pull request #273 from DavidHLP/codex/deepseek-authorized-recovery
DavidHLP Oct 11, 2026
b3bbc57
test: preserve safe isolation protocol failure diagnostics
DavidHLP Oct 11, 2026
5567dec
fix: retain safe isolation protocol failure details
DavidHLP Oct 11, 2026
0d3e97d
docs: describe isolated protocol failure evidence
DavidHLP Oct 11, 2026
0163753
Merge pull request #274 from DavidHLP/codex/isolation-protocol-diagno…
DavidHLP Oct 11, 2026
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
1 change: 1 addition & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ services:
MYSQL_SERVICE_DB_PARAM: "characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true"
JVM_XMS: 256m
JVM_XMX: 512m
JVM_XMN: 128m
NACOS_AUTH_ENABLE: "true"
NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN:?NACOS_AUTH_TOKEN is required}
NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY:?NACOS_AUTH_IDENTITY_KEY is required}
Expand Down
20 changes: 14 additions & 6 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ UltiCode 已形成五个 Data Owner 与两个不持有业务表的 Worker:
| Worker | `backend-judge` | 消费 Judge Streams,执行沙箱,回写 Submission verdict |
| Worker | `backend-search` | 消费 `SearchDocumentChanged`,维护 MeiliSearch 派生索引 |
| Profile | `backend-core` | opt-in parent process; assembles Owner child contexts and does not own business tables |
| Standalone | `services/agent` | opt-in Python Agent runtime; U01 read-only loop plus bounded synthetic retrieval/sourced analysis, executable keyword-evaluation tooling, and an evaluation-only vector comparison (one embedding model + single-node Qdrant, `e2e_vector_comparison.py`) that never replaces the keyword main path; licensed-corpus, real-model evaluation, and isolation evidence are tracked in the U02 Linear tasks |
| Standalone | `services/agent` | opt-in Python Agent service; one LangGraph read-only model/tool kernel, U03 workflow orchestration and private workflow state; no UltiCode business-table ownership |

`services/agent` is an independent Python service module, not a Maven reactor module or an Owner/Worker. It calls existing Auth/App HTTP contracts, keeps identity server-side, and must project tool results before they reach a model. Its current retrieval slice is limited to checked-in agent-authored synthetic Markdown; it does not ingest public user solutions. It is not started by the default `dev-lite`/`dev-full` scopes until its runtime, readiness, and secret wiring are explicitly added.
`services/agent` is independent of Maven and the Owner/Worker topology. It calls existing Auth/App and LearningPlan HTTP contracts; it never connects to business databases or reads Owner Entities/Mappers. The checked-in retrieval corpus is agent-authored synthetic material, not user source or licensed corpus. The Agent is not started by default `dev-lite`/`dev-full` scopes.

`judge-runtime` 是共享执行依赖,不是进程。Contract modules 在 `services/api/`;共享平台能力在 `services/platform/`。跨 Owner 通过 provider-owned contract 或 consumer-owned port 协作,不共享 Entity、Mapper 或业务 Service。
`services/agent` 的依赖规则是 `Agent -> existing Auth/App HTTP contracts`;它不得连接业务数据库、读取 Owner Entity/Mapper、共享 Java 业务实现或绕过服务端身份/授权。当前仓库只包含 agent-authored synthetic fixtures;未来真实 corpus 必须来自自有或明确授权资料,公开题解不自动获得 corpus/模型外发许可。
Expand All @@ -42,10 +42,13 @@ Judge0 默认关闭且没有外部实例验证;async receipt 当前仅进程
默认七进程 topology 仍保持为 distributed profile 与回滚路径;另有 opt-in
`core` profile(Core 9108 + 独立 Judge)用于同进程 owner assembly 验证。
Core 已通过显式扫描、多数据源/事务、readiness 和 judge-runtime classpath
静态段测试;但 enabled Owner child assembly 的 exec-jar smoke 当前因同一
classpath 的跨 Owner package leakage 在 bean wiring 阶段失败。完整 local
Adapter parity、同进程业务路由、远端 Judge TLS 和生产性能/HA 仍未证明,
不得切换默认或推断生产可用性。
静态段测试。显式 opt-in 的 disposable Auth/Admin 门禁已验证真实 child
装配、本地 identity/account 只读委派与合法 permission grant;历史 exec-jar
装配失败保留为风险记录,不能代替当前门禁结果。真实 HTTP 登录、授权持久化
和重新登录权限读取已通过;测试使用 HS256,不证明 RSA/JWKS、App 四步
journey、全量 Admin bean graph 或 distributed RPC transport/filter parity。
远端 Judge TLS 和生产性能/HA 仍未证明,不得切换默认。具体证据边界见
[`SERVICES_ISSUES.md` 的 SVC-025](../services/docs/SERVICES_ISSUES.md)。

Core 的 enabled Owner child 启动使用单一尝试协议:每个模块的内部对象
`CoreOwnerContextManager.OwnerStartup` 从线程提交前就注册并持有资源身份,
Expand Down Expand Up @@ -145,6 +148,11 @@ Notification 是 notifications、preferences、delivery ledger 和 email 的唯
#### Judge / Search

Judge 通过 Redis Streams 异步接收 Submission outbox,使用 Problem facts 和沙箱控制执行,失败留在 PEL 或进入 DLQ。Search 只消费 allowlisted、版本化事件并更新 MeiliSearch;删除是 tombstone,业务写路径不得直写索引。
#### Agent

The Agent is a standalone consumer of existing Auth/App/LearningPlan HTTP contracts; it never connects to business databases or adds model-controlled write tools. The only bounded model/tool loop is `agent_service.graph`; `agent_loop.run_tool_loop` delegates to it. The checkpointed workflow graph dispatches server-validated actions and reuses that read-only loop for analysis. Offline scripted-model injection and guarded live-provider analysis use the same workflow and kernel. Live analysis is fail-closed unless the evidence-bound U02 gate, expected budget period, shared guard, and authorized `u03_analysis` purpose are valid; its citation judge uses the separate `u03_citation_judge` purpose.

Drafts and events live in canonical private Agent SQLite state; LangGraph checkpoints are resumable control state. Confirming a draft is not a Java write; only explicit save can persist a LearningPlan through Java. Uncertain writes remain `unknown` and reconcile through the original idempotency key. `/auth/me` is the identity source; unsafe Agent requests require the access/CSRF pair and matching header. Confirm/save/recover routes are registered only with valid evidence-bound U02 gate material; model calls additionally require the current gate and budget authorization. Nonempty citations are checked against same-run retrieval, document integrity, and support/derivability; answer text also passes bounded source-fact and tool-trace checks. These are fail-closed safeguards, not a claim of perfect semantic verification. The candidate and evidence-bound U02/U03/U04 release sequence is documented in [Development and testing](DEVELOPMENT.md#u02-u03-u04-immutable-acceptance-chain); it does not itself authorize production deployment.

### 依赖规则

Expand Down
595 changes: 579 additions & 16 deletions docs/DEVELOPMENT.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/OPERATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

`docker/docker-compose.yml` 是基础配置;`docker/docker-compose.dev.yml` 只在 loopback 暴露开发端口;`docker/docker-compose.prod.yml` 不发布 MySQL、Redis、Nacos 或 backend 端口,前端仅作 HTTPS edge。不要直接用 PM2/Maven 启动 owner runtime,以免绕过 manifest、migration、readiness 和 rollback gate。

Nacos 的 512 MB 堆显式使用 128 MB 年轻代,避免镜像默认的 `JVM_XMN=512m` 占满堆空间;调整堆上限时应同时检查年轻代和容器内存限额。

### 生产发布前

Docker Verify builds each service locally (`load: true`, no push) and runs pinned Trivy v0.74.0 against that local image. Docker Publish pushes digest-only candidates: it does not assign normal `sha-*` or `v*` release tags while individual service gates are running.
Expand Down
111 changes: 110 additions & 1 deletion docs/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,120 @@
| --- | --- | --- |
| Auth | `http://localhost:9101` / `/auth/**` | `backend-auth` |
| Admin | `http://localhost:9102` / `/admin/**`、`/moderation/**` | `backend-admin` |
| App | `http://localhost:9103` / `/users`、`/problems`、`/contests`、`/solutions`、`/forum`、`/search`、`/ws/**` | `backend-app` |
| App | `http://localhost:9103` / `/users`、`/problems`、`/contests`、`/solutions`、`/forum`、`/learning-plans/**`、`/search`、`/ws/**` | `backend-app` |
| Notification | `http://localhost:9105` / `/notifications/**` | `backend-notification` |
| Submission | internal `9106` / Dubbo `20886` | `backend-submission` |
| Judge | internal Dubbo `20884` | `backend-judge` |

`POST /learning-plans` 为当前已认证、有效且未封禁的用户保存已确认的学习计划。请求必须携带规范 UUID 格式的 `Idempotency-Key`,且来源提交必须属于当前用户。相同 key 和请求内容重试时返回原记录;同一 key 携带不同内容时返回 HTTP 409(业务码 `40900`)。`GET /learning-plans/{id}` 和 `GET /learning-plans/by-key/{key}` 仅返回当前用户拥有的记录。

### Agent workflow API

The opt-in Python Agent service is separate from Java `/learning-plans`: it owns local workflow
drafts, while App Java owns confirmed LearningPlan records. Factory: `agent_service.app.create_app(...)`.
Thread IDs are server-generated. Every operation checks the authenticated owner; a body field
cannot select a user, model, graph node, or checkpoint.

| Operation | Request body | Purpose |
| --- | --- | --- |
| `POST /agent/threads` | `{"sourceSubmissionId": "...", "question": "..."}` | Verify caller-owned source, create thread and offline draft |
| `GET /agent/threads/{thread_id}` | — | Read caller's canonical workflow and draft |
| `GET /agent/threads/{thread_id}/events?after=N` | — | Read bounded event page; does not resume workflow |
| `POST /agent/threads/{thread_id}/analyze` | `{}` | Explicit analysis request through the shared graph; requires injected offline model factory or live model authorization |
| `PUT /agent/threads/{thread_id}/draft` | `{"draftVersion": N, "title": "...", "content": "..."}` | Compare version, update draft, invalidate confirmation |
| `POST /agent/threads/{thread_id}/confirm` | `{"draftVersion": N, "paramsDigest": "...", "confirm": true}` | Persist expiring confirmation for exact owner/version/payload; no Java write |
| `POST /agent/threads/{thread_id}/save` | `{"confirmationId": "..."}` | Explicitly dispatch the confirmed payload to Java |
| `POST /agent/threads/{thread_id}/recover` | `{"retry": false}` or `{"retry": true}` | Reconcile by original Java idempotency key; retry only when explicitly requested and all guards pass |
| `POST /agent/threads/{thread_id}/cancel` | `{}` | Fence later work; cannot roll back a dispatched Java write |

Workflow states include `draft`, `analyzing`, `awaiting_confirmation`, `confirmed`, `saving`,
`saved`, `unknown`, `failed`, and `cancelled`. Agent SQLite is canonical for drafts, workflow state,
and events; LangGraph checkpoints are resumable control state only. `saved` requires an accepted
Java record response. A timeout, lost response, or uncertain process restart remains `unknown`;
reconcile by the same idempotency key before any retry. A by-key lookup is treated as not found only
for HTTP 404 with business code `40400`; transport/server errors remain unresolved. Retry is never
automatic: `retry:true` is an explicit action and still requires an eligible unexpired confirmation,
matching payload, no cancellation, and the exact not-found result. Never mint a replacement key.

GET thread responses expose `threadId`, `runId`, `status`, `sourceSubmissionId`, `question`, a
versioned `draft` (`title`, `content`, `facts`, `hypotheses`, `citations`, `citationChecks`,
`sampleScope`), `paramsDigest`, `analysis`, a redacted `confirmation` summary, and `receipt`
(`planId`, `cancelRequested`, `failureReason`). They do not expose owner IDs or the business key.
Draft facts are derived from the validated metadata projection; source code and test data are not
included. `sampleScope` marks the checked-in synthetic corpus. Initial offline-draft citations only
establish source traceability; model-answer citations, when present, are added only after same-run
retrieval, document-integrity, support, and derivability checks.
The Agent keeps the business idempotency key private. Its recovery action uses that original key
for owner-scoped by-key reconciliation; a user-facing saved-record readback uses
`GET /learning-plans/{planId}` with the returned `planId`.
Use the GET `paramsDigest` and current `draftVersion` in the confirmation request. The returned
confirmation summary contains its id, action, bound version/digest, and expiry; it never contains
the idempotency key.
Events return `{events, next}` with a bounded page. New events persist the authoritative
run identifier in `detail.runId` in the same transaction as their state transition;
older events without it retain their original payload and must not be assigned the current run.
`GET /agent/threads/{thread_id}/events/stream?after=...` authenticates the owner and
returns SSE for the run current at subscription time. `workflow` events retain their
durable sequence and include tool start/completion metadata without arguments or results.
Model start/completion events associate a server-generated call ID and node with the run;
completion records elapsed milliseconds, a bounded provider model label, budget attempt ID
when available, and nonnegative token counts. Missing usage is `null` with `usageStatus=unavailable`,
never inferred as zero. Errors use fixed reasons, without prompts, answers, credentials or
provider error bodies. The observer delegates to the existing authorized model and budget.
`text` contains only validated, persisted answer text; `terminal` reports canonical status,
failure reason and cancellation intent. SSE IDs bind run, sequence and event kind for replay
deduplication. Run replacement or the 30-second subscription limit emits `stream_closed`;
this is a transport outcome, not business completion. Disconnect ends the subscription,
while explicit cancellation uses the existing cancel endpoint and does not undo Java writes.
`after` must be between 0 and
`2^63 - 1`. Invalid or foreign submission sources return `404 source_not_owned`
during creation and analysis. Authorization failures during Java save leave the outcome
`unknown` and permit explicit recovery after session and ownership checks; payload and
idempotency rejections remain terminal. Learning-plan routes are also registered in the
opt-in Core App context.

Agent responses use `{code,message,data,traceId}` with a server-generated `traceId`; the envelope
is validated by a strict Pydantic response schema before serialization, including JSON-only data
and rejection of non-finite numbers. Upstream response bodies are not exposed. Request bodies require `application/json`, are strict and bounded
to 128 KiB, use canonical UUIDs and exact integer versions, reject extra/duplicate JSON keys and
non-finite numbers, and enforce question length 2–200 plus Java-compatible nonblank title/content
limits of 200/16,000 Unicode code points. Event reads are bounded and read-only.

#### Identity, CSRF, and gate

`/auth/me` is the sole principal source; accept only nonempty `data.user.id` with `is_active=true`
and `is_banned=false`. Each request gets an isolated client with access cookie held only in memory.
Reads require one access cookie. Malformed access/CSRF cookie values return 401/403 before
client construction. Unsafe calls require exactly one access cookie, one CSRF cookie,
and a constant-time match with `X-CSRF-Token`; ambiguous duplicate Cookie/header input fails before
upstream HTTP. If an unsafe request includes `Origin`, it must match the configured trusted origin.
Request bodies reject identity fields. The service does not refresh sessions, set login cookies, or
configure cross-origin access.

The evidence-bound `ulticode-u02-gate-v1` loader checks candidate head/base and referenced DAV-58,
DAV-53, budget-audit, and prior-five evidence against their SHA-256 digests. Confirm, save, and
recovery routes are registered only when that gate validates. Live model requests additionally
require the expected budget period, shared budget guard, and policy-authorized purpose:
`u03_analysis` for the analysis model and `u03_citation_judge` for citation judgments. The
authorized model and guarded transport use the existing period/lane limits; missing or invalid
authorization fails closed with `503 model_budget_blocked` before a provider request. This is not
evidence that a real acceptance run has passed.

The workflow runs analysis through the shared checkpointed action graph and read-only model/tool
kernel. Answer text must pass bounded source-fact, negation-aware boundary, source-reference, and
tool-trace checks; those safeguards do not guarantee perfect semantic correctness. Nonempty
citations must exactly match evidence retrieved during that run, pass document-integrity checks,
then receive positive support and derivability judgments. A citation that was not retrieved in-run,
fails integrity/judging, or has unknown judge usage rejects analysis. Empty citations are allowed
only when the answer itself satisfies the boundary checks. Offline scripted-model/MockTransport
tests are not live acceptance evidence.

Without a valid U02 gate, confirm/save/recover routes are not mounted; requests to those paths use
the normal not-found response envelope. A valid gate alone does not authorize model calls.

For the opt-in U02/U03/U04 candidate-freeze, gate, and acceptance-bundle commands, see the
[immutable acceptance workflow](DEVELOPMENT.md#u02-u03-u04-immutable-acceptance-chain).

浏览器通常通过前端 Nginx/gateway 访问 `/api`;不要把内部 Dubbo、数据库、Redis、Nacos 或 worker 端口发布到公网。

浏览器侧统一经 `packages/http-client` 发起调用,成功结果只暴露业务 payload:`Result.code` 为 0 返回 `data`,非 0 以 `ApiError` 拒绝,非 `Result` envelope 返回 payload 本身(含 Blob),不提供原始 transport response。`apiDownload` 返回 `Promise<void>`,以 object URL 与临时 `<a download>` 元素触发浏览器保存;URL 创建后无论 DOM 步骤成功与否都会移除元素并 revoke URL,清理失败不覆盖原始错误。
Expand Down
2 changes: 1 addition & 1 deletion init-db/baseline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This runs the full incremental migration set (`baselineOnMigrate=false`).

Adoption requires per-schema `flyway baseline` at the auto-detected max
versions (shared `20260822120000`, `auth` `20260821100000`,
`admin` `20260822120001`, `app` `20260811180000`,
`admin` `20260822120001`, `app` `20261001120000`,
`notification` `20260815100200`, `submission` `20260817000000`):

```bash
Expand Down
Loading
Loading