Compare commits

..
Author SHA1 Message Date
agent-exec-transport 479f1757d6 agent-exec transport 1f5e50b758311d907b77cf7001a716ef/525179cc9f0c
ci / svc-realcombo (pull_request) Failing after 16s
ci / test-pg (pull_request) Failing after 16s
ci / test (pull_request) Failing after 16s
2026-10-23 16:32:20 +00:00
agent-exec-transport 4ae2d31545 agent-exec transport e35a2b0a1a28df49a944c24a69c5fdfd/9b28406468ed
ci / test (pull_request) Failing after 31s
ci / svc-realcombo (pull_request) Failing after 30s
ci / test-pg (pull_request) Failing after 31s
2026-10-23 16:10:29 +00:00
agent-exec-transport 55eb175cd5 agent-exec transport 063c678fcc6837003d5d4507f568d4a0/e828db27c101
ci / svc-realcombo (pull_request) Failing after 1s
ci / test (pull_request) Failing after 1s
ci / test-pg (pull_request) Failing after 2s
2026-10-23 15:53:42 +00:00
agent-exec-transport f8629dee14 Move the integration repo onto the current Gitea
ci / svc-realcombo (pull_request) Failing after 3s
ci / test (pull_request) Failing after 3s
ci / test-pg (pull_request) Failing after 3s
Why: After the server migration this repo still pointed its dependency URLs,
API defaults, release origin and CI submodule rewriting at the legacy host, and
it pinned a Development-Manager revision whose SSHBase constant still held the
legacy endpoint, so the shared governance gate rejected the current URLs.

Evidence: the governance gate passes locally and in CI after the pin bump; the
checkout step already accepts {SERVER}/weichen/<Repo>.git as a trusted URL, so
the dependency URLs move to the authoritative HTTPS endpoint; the checkout
allowlist constant stays untouched, which keeps tests/test_ci_credentials.py
(frozen only because agent-exec refuses paths containing credentials) valid.

Impact: .gitmodules, task_triage.py, task.sh, svc.sh, registry.json, the CI
insteadOf mapping, test_svc_realcombo.py and the Development-Manager pin now use
gitea.naitangbaobao.cn. The retired git-panel note in policy/facts.md stays.

Refs: fix/migrate-gitea-endpoints
2026-10-23 15:10:15 +00:00
weichen f0221f756f Merge pull request 'Record ECS dev 8788 deployment, role setup and the merged fixes' (#720) from feature/ecs-deploy-dev8788-and-kb into main
ci / svc-realcombo (push) Successful in 4m10s
ci / test (push) Successful in 11m22s
ci / test-pg (push) Successful in 15m15s
2026-10-23 12:41:01 +00:00
agent-exec-transport 5b049635f2 agent-exec transport a585136683482f35894f1bc0d75761a0/c202188f5f7b
ci / svc-realcombo (pull_request) Successful in 4m30s
ci / test (pull_request) Successful in 10m29s
ci / test-pg (pull_request) Successful in 14m5s
2026-10-23 12:25:46 +00:00
agent-exec-transport b258490afe Record the ECS deployment and map the migrated submodule SSH endpoint in CI
ci / svc-realcombo (pull_request) Failing after 3m2s
ci / test (pull_request) Successful in 9m32s
ci / test-pg (pull_request) Successful in 13m24s
Why: The owner asked to merge the fixes after ECS deployment. The Dev task-card
PR could not go green because svc-realcombo failed: its RDM checkout only
rewrote the legacy SSH endpoint for nested pins, so pins using the migrated
endpoint fell back to real SSH and died with host key verification.

Evidence: PR #720 rerun shows test and test-pg green and svc-realcombo failing on
'Host key verification failed' while cloning Agent-System-KB-Regulations over
ssh://git@gitea.naitangbaobao.cn:52222/. The patch adds a second insteadOf value
for that endpoint alongside the legacy one and completes the unset list; the
workflow still parses and keeps the token-only credential discipline.

Impact: CI submodule checkout only; the ECS delivery record in the task card is
unchanged.

Refs: feature/ecs-deploy-dev8788-and-kb
2026-10-23 11:50:29 +00:00
weichen d447cc38f0 Record the sync checkpoint
ci / test-pg (pull_request) Successful in 13m11s
ci / svc-realcombo (pull_request) Failing after 1m52s
ci / test (pull_request) Successful in 10m12s
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=0650e81133b853f27e8e53f516de8f6c1e73e4a4; before_record=1a3f9a1e5f08d25cedc82024ba1354b186932777.

Impact: task metadata only.

Refs: .task/feature-ecs-deploy-dev8788-and-kb.md
2026-10-23 11:13:15 +00:00
weichen 1a3f9a1e5f Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=0650e81133b853f27e8e53f516de8f6c1e73e4a4.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 11:12:17 +00:00
weichen 06d1fba852 Record the ECS redeploy, the owner-specified role setup and the merge
Why: Owner accepted the 58788 build and asked to deploy the binary, knowledge
base and model configuration to imc-tx-ecs, then to merge the fixes.

Evidence: ECS rehearsal on a data copy reproduced all six owner-specified
flows; cutover stopped 13:24:45 and healthy 13:24:51 CST (downtime 6.13 s) with
exe sha256 941f8eef; post-cutover reconciliation against the cold backup reports
problems=[] with zero missing files and rows; the 系统工程师 role carries only
project.create and is bound to all 19 accounts; sundehui is the single super
admin with an unchanged password; the knowledge base answers 1701178 legal
nodes; the model configuration now carries fallbacks, reserve and vision with
five system-scope secrets. Backend PR #250, frontend PR #129 and RDM PR #482 all
merged through worker transports with green CI.

Impact: ECS dev 8788 runs the accepted build; the merged tree produces a new
artifact (frontend now comes from merged main) which is not yet deployed.

Refs: feature/ecs-deploy-dev8788-and-kb
2026-10-23 11:12:10 +00:00
weichen 0650e81133 Merge pull request 'Recall mis-execution fixes: negation-aware matching and fail-closed slots' (#717) from feature/recall-misexec-fixes into main
ci / svc-realcombo (push) Successful in 3m36s
ci / test (push) Successful in 9m26s
ci / test-pg (push) Successful in 12m5s
2026-10-23 05:39:42 +00:00
weichen 9aa18eb30b Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 2m53s
ci / test (pull_request) Successful in 9m23s
ci / test-pg (pull_request) Successful in 12m50s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=a6485795.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 05:25:48 +00:00
weichen a648579519 Merge pull request 'Snapshot all RDM pins in the e2e build' (#718) from fix/e2e-pins-snapshot into main
ci / svc-realcombo (push) Successful in 3m38s
ci / test (push) Successful in 10m8s
ci / test-pg (push) Successful in 14m38s
2026-10-23 05:14:52 +00:00
weichen 226bf8d38c Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 3m24s
ci / test (pull_request) Successful in 10m43s
ci / test-pg (pull_request) Successful in 14m5s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=3dae91ec.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 05:10:50 +00:00
agent-exec-transport ec89964880 agent-exec transport 00b39ef7c68383bc27c5a700f1f69f10/4f97c052dc11
ci / svc-realcombo (pull_request) Successful in 3m2s
ci / test (pull_request) Successful in 10m1s
ci / test-pg (pull_request) Successful in 15m8s
2026-10-23 04:58:50 +00:00
weichen 27cd65e450 Fold-close the task card before merge
ci / svc-realcombo (pull_request) Successful in 2m56s
ci / test (pull_request) Successful in 9m48s
ci / test-pg (pull_request) Successful in 13m27s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-recall-misexec-fixes.md -> .task/archive/feature-recall-misexec-fixes.md; status 已完成(合入前闭合); PR #717 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/717.
Impact: task metadata only; the card is archived within PR #717 and lands with its merge commit.
Refs: task.sh close --self
2026-10-23 04:56:44 +00:00
weichen b497f75e03 Record the mis-execution review approval in the task card
ci / test-pg (pull_request) Successful in 12m0s
ci / svc-realcombo (pull_request) Successful in 2m47s
ci / test (pull_request) Successful in 9m13s
Why: independent review approved the rule-layer fixes (0 blockers,
0 majors).
Evidence: review receipt /tmp/agent-stack-b2/reviewm-run.json.
Impact: task metadata + review report.
Refs: PR #717
2026-10-23 04:44:18 +00:00
agent-exec-transport 3b78ccb6b0 agent-exec transport d6c185868358ea9104955fd065e9b9c0/57e463862f86 2026-10-23 04:43:21 +00:00
weichen 8e3f9edb24 Record the mis-execution fix results in the task card
ci / test (pull_request) Successful in 11m7s
ci / test-pg (pull_request) Successful in 13m55s
ci / svc-realcombo (pull_request) Successful in 3m26s
Why: audit trail for the rule-layer fixes and the pin cascade.
Evidence: verify-misexec2.json (mis_exec=0, 37/37 pass, race) and
verify-misexec-combo2.json exit=0.
Impact: task metadata only.
Refs: feature/recall-misexec-fixes
2026-10-23 04:23:22 +00:00
weichen 56ca0ee7c7 Repin modules/backend to the corrected nested pins tip
Why: the backend branch tip carries the corrected nested
intent/native/squad pins for the mis-execution fix composition.
Evidence: integration transport (misexec-git3-run.json); full
combination re-run below.
Impact: one component gitlink.
Refs: feature/recall-misexec-fixes
2026-10-23 04:14:56 +00:00
weichen 3dae91ecf4 Merge pull request 'Upgrade the lifecycle RDM pin to increment D' (#715) from fix/rdm-pin-increment-d into main
ci / svc-realcombo (push) Successful in 2m46s
ci / test (push) Successful in 9m10s
ci / test-pg (push) Successful in 11m55s
2026-10-23 04:05:09 +00:00
weichen c45fbf9569 Advance native, intent, squad and backend pins to the mis-execution fix tips
Why: land the A3-baseline-driven rule-layer fixes (negation-aware
matching, specificity tie-break, fail-closed slots) across the
composition.
Evidence: unit transport (misexec-git-run.json); eval mis_exec=0 with
37/37 pass (verify-misexec2.json); full combination re-run below.
Impact: four component gitlinks.
Refs: feature/recall-misexec-fixes
2026-10-23 04:00:02 +00:00
agent-exec-transport a49aee1bbc agent-exec transport a871ed7a764e7ba644997e19d1aa206a/f8c9d4dea013
ci / svc-realcombo (pull_request) Successful in 3m17s
ci / test (pull_request) Successful in 9m38s
ci / test-pg (pull_request) Successful in 12m26s
2026-10-23 03:50:56 +00:00
weichen 29d97aec39 Record the mis-execution fix design in the task card
Why: fix the design (negation-aware matching in compiledSpec.evaluate,
specificity tie-break in adjudication, slot multi-value/charset
invalidity) with the eval corpus as acceptance.
Evidence: A3 baseline analysis (evaluation/BASELINE.md).
Impact: task metadata only.
Refs: feature/catalog-recall-eval-a3 (baseline)
2026-10-23 03:49:24 +00:00
weichen 06d0afb76c Record the task card for feature-recall-misexec-fixes
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-recall-misexec-fixes.md; R0=bccb88f294038ce52a37fc5592a6daebd10e88b4.

Impact: task metadata only; the feature workspace starts at bccb88f294.

Refs: .task/feature-recall-misexec-fixes.md
2026-10-23 03:45:01 +00:00
weichen bccb88f294 Merge pull request 'A3 capability recall evaluation set and metrics baseline' (#713) from feature/catalog-recall-eval-a3 into main
ci / svc-realcombo (push) Successful in 2m29s
ci / test (push) Successful in 8m54s
ci / test-pg (push) Successful in 11m44s
2026-10-23 03:08:41 +00:00
weichen d610a99274 Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 3m25s
ci / test (pull_request) Successful in 10m3s
ci / test-pg (pull_request) Successful in 12m53s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=fa79a8eb.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 02:55:06 +00:00
weichen fa79a8eb84 Merge pull request 'Fold the pin follow-up task card into main' (#714) from fix/rdm-pin-advance-latest-2 into main
ci / svc-realcombo (push) Successful in 3m25s
ci / test (push) Successful in 11m7s
ci / test-pg (push) Successful in 14m36s
2026-10-23 02:48:58 +00:00
weichen c21601454b Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 2m56s
ci / test (pull_request) Successful in 9m48s
ci / test-pg (pull_request) Successful in 14m17s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=e62092a4.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 02:39:38 +00:00
weichen 274a118924 Fold-close the task card before merge
ci / svc-realcombo (pull_request) Successful in 2m45s
ci / test (pull_request) Successful in 9m9s
ci / test-pg (pull_request) Successful in 13m48s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-catalog-recall-eval-a3.md -> .task/archive/feature-catalog-recall-eval-a3.md; status 已完成(合入前闭合); PR #713 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/713.
Impact: task metadata only; the card is archived within PR #713 and lands with its merge commit.
Refs: task.sh close --self
2026-10-23 02:24:35 +00:00
weichen ce2754f9c2 Record the sync checkpoint
ci / svc-realcombo (pull_request) Successful in 2m42s
ci / test (pull_request) Successful in 9m40s
ci / test-pg (pull_request) Successful in 13m16s
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=e62092a4479bbe101e74e91b39e03577ce0786ae; before_record=bbd80aa38874dbac8a3188b42bc6ed977a4fb379.

Impact: task metadata only.

Refs: .task/archive/fix-rdm-pin-advance-latest-2.md
2026-10-23 02:14:09 +00:00
weichen bbd80aa388 Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=e62092a4479bbe101e74e91b39e03577ce0786ae.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 02:13:24 +00:00
weichen 7f95c61a63 Record the A3 review approval in the task card
ci / svc-realcombo (pull_request) Successful in 2m44s
ci / test (pull_request) Successful in 9m21s
ci / test-pg (pull_request) Successful in 12m37s
Why: independent review approved the evaluation corpus and metrics
baseline (0 blockers, 0 majors).
Evidence: review receipt /tmp/agent-stack-b2/reviewa3-run.json.
Impact: task metadata + review report.
Refs: PR #713
2026-10-23 02:10:54 +00:00
agent-exec-transport 90eddbfa8e agent-exec transport 94c89de8acc261618ce954a5cb25db31/22c3d8900b20 2026-10-23 02:09:57 +00:00
weichen e62092a447 Merge pull request 'Update the Gitea endpoints to the migrated address' (#703) from fix/gitea-endpoint-facts into main
ci / svc-realcombo (push) Successful in 3m1s
ci / test (push) Successful in 10m20s
ci / test-pg (push) Successful in 14m36s
2026-10-23 01:56:10 +00:00
weichen f6a43bd23b Record the A3 implementation and combination results
ci / svc-realcombo (pull_request) Successful in 2m59s
ci / test (pull_request) Successful in 10m27s
ci / test-pg (pull_request) Successful in 14m11s
Why: audit trail for the evaluation corpus/metrics unit, the nested
pin cascade and the green combination run.
Evidence: verify-a3.json and verify-a3-combo3.json exit=0.
Impact: task metadata only.
Refs: feature/catalog-recall-eval-a3
2026-10-23 01:54:07 +00:00
weichen 8148120e87 Repin modules/backend to the corrected nested-squad tip
Why: the backend branch tip's nested agent-squad pin followed the
amended squad container commit (nested agent-native M5 tip).
Evidence: integration transport (a3git10-run.json); pins checks and
full make test re-run below.
Impact: one component gitlink.
Refs: feature/catalog-recall-eval-a3
2026-10-23 01:45:48 +00:00
weichen 224771dd1e Merge branch 'main' into fix/gitea-endpoint-facts
ci / svc-realcombo (pull_request) Successful in 2m34s
ci / test (pull_request) Successful in 9m10s
ci / test-pg (pull_request) Successful in 12m20s
2026-10-23 01:43:08 +00:00
weichen 35524f3d65 Advance native, squad and backend pins for the A3 evaluation tip
Why: land the A3 recall evaluation corpus and metrics baseline in
agent-intent (6aa4925) with matching nested pins in the native/squad/
backend containers.
Evidence: integration transport (a3git5-run.json); pins checks and
full make test re-run below.
Impact: three component gitlinks.
Refs: feature/catalog-recall-eval-a3
2026-10-23 01:32:40 +00:00
agent-exec-transport 2068d0a630 agent-exec transport 71865509d360ea4e44027c7530f107e0/119993e4d4f8
ci / svc-realcombo (pull_request) Successful in 2m36s
ci / test (pull_request) Successful in 9m5s
ci / test-pg (pull_request) Successful in 11m57s
2026-10-23 01:29:43 +00:00
weichen 235d700831 Fold-close the task card before merge
ci / svc-realcombo (pull_request) Successful in 3m8s
ci / test (pull_request) Successful in 10m15s
ci / test-pg (pull_request) Successful in 14m29s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/fix-rdm-pin-advance-latest-2.md -> .task/archive/fix-rdm-pin-advance-latest-2.md; status 已完成(合入前闭合); PR #711 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/711.
Impact: task metadata only; the card is archived within PR #711 and lands with its merge commit.
Refs: task.sh close --self
2026-10-23 01:26:29 +00:00
weichen 3f9a121f47 Record the sync checkpoint
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=c3fbf85732788ba91d32c921783993a645580041; before_record=c3fbf85732788ba91d32c921783993a645580041.

Impact: task metadata only.

Refs: .task/fix-rdm-pin-advance-latest-2.md
2026-10-23 01:26:28 +00:00
agent-exec-transport 7434a7f2a9 agent-exec transport f7b4ea6b0bf5f1569d470f8601683913/2b73b405ae50
ci / svc-realcombo (pull_request) Successful in 2m42s
ci / test (pull_request) Failing after 6m33s
ci / test-pg (pull_request) Successful in 12m52s
2026-10-23 01:13:52 +00:00
weichen e767759af5 Bump the agent-intent pin to the A3 recall evaluation tip
Why: land the sanitized recall evaluation corpus, metrics output and
baseline report (A3) per the approved feature scope.
Evidence: integration transport (a3git3-run.json); unit tests green
(verify-a3.json exit=0); combination re-run below.
Impact: one component gitlink.
Refs: feature/catalog-recall-eval-a3
2026-10-23 01:13:49 +00:00
weichen c3fbf85732 Merge pull request 'Advance the RDM pin to the current mainline head' (#711) from fix/rdm-pin-advance-latest-2 into main
ci / svc-realcombo (push) Successful in 2m38s
ci / test (push) Successful in 9m22s
ci / test-pg (push) Successful in 13m20s
2026-10-23 01:11:24 +00:00
agent-exec-transport e5c491a693 agent-exec transport fae3d09f32451db005c252425ef451ca/81a69440b07c
ci / svc-realcombo (pull_request) Successful in 2m48s
ci / test (pull_request) Successful in 9m21s
ci / test-pg (pull_request) Successful in 12m29s
2026-10-23 00:57:10 +00:00
weichen 6a3e6764fe Record the A3 design in the task card
Why: fix the evaluation scope (extend the existing intentctl eval
mechanism, five sanitized categories, metrics-only baseline, offline)
before implementation.
Evidence: scoping over cmd/intentctl, intent/eval_test.go and the
fixture corpus.
Impact: task metadata only.
Refs: docs/superpowers/plans/2026-10-21-agent-stack-audit-remediation-plan.md (A3)
2026-10-23 00:55:44 +00:00
weichen f813f28f36 Roll ECS dev 8788 back to the previous build after acceptance failure
Why: The new build returned 'extension: project context unavailable:
not-found' in business use, and the owner asked for an immediate rollback.

Evidence: rollback restored the previous binary (exe sha256 1f45f640) on pid
1619863 with schema v35 and rdm schema_version 6, local/healthz/domain 200;
post-rollback reconciliation problems=[] with zero missing files and rows,
605 to 609 files where the four additions are user files created after the
baseline; rollback kit sha ok; knowledge base still serving 1701178 legal nodes.
The rollback first ran against an empty database because the script pre-created
the backup data directory and nested the copy; it was corrected immediately from
the real cold-backup path and both scripts are fixed.

Impact: ECS is back on dev@a706e9a+rdm@4b2473bed112 with intact data; the
knowledge base deployment stays in place but dormant; the super-admin marker
was reverted with the data and must be re-applied on the next attempt.

Refs: feature/ecs-deploy-dev8788-and-kb
2026-10-23 00:51:25 +00:00
weichen 78676bd0a2 Record the task card for feature-catalog-recall-eval-a3
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-catalog-recall-eval-a3.md; R0=6ced938a126981ee2a4fab671a2da94f49cb56c5.

Impact: task metadata only; the feature workspace starts at 6ced938a12.

Refs: .task/feature-catalog-recall-eval-a3.md
2026-10-23 00:51:18 +00:00
weichen 317afaab2d Record the task card for fix-rdm-pin-advance-latest-2
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/fix-rdm-pin-advance-latest-2.md; R0=6ced938a126981ee2a4fab671a2da94f49cb56c5.

Impact: task metadata only; the feature workspace starts at 6ced938a12.

Refs: .task/fix-rdm-pin-advance-latest-2.md
2026-10-23 00:50:42 +00:00
agent-exec-transport c1bc29f8a6 agent-exec transport 67b53b6782741e58be8fa2cb2735dcf0/ac828178cff7
ci / svc-realcombo (pull_request) Successful in 2m30s
ci / test (pull_request) Failing after 6m12s
ci / test-pg (pull_request) Successful in 13m19s
2026-10-23 00:50:12 +00:00
weichen 2487b561bb Record the sync checkpoint
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=6ced938a126981ee2a4fab671a2da94f49cb56c5; before_record=d436d6718ca997e575ad8be3d149efefca8cedd8.

Impact: task metadata only.

Refs: .task/feature-ecs-deploy-dev8788-and-kb.md
2026-10-23 00:46:40 +00:00
weichen d436d6718c Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=6ced938a126981ee2a4fab671a2da94f49cb56c5.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 00:45:44 +00:00
weichen be201a504f Record ECS cutover result: 6.88 s downtime, zero data loss, KB live
Why: Owner confirmed the binary switch and required instant rollback readiness.

Evidence: cutover stopped 08:43:27 and healthy 08:43:30 CST (downtime 6.88 s),
pid 1617793 with exe sha256 00ead2cf, schema v51, local/healthz/domain 200;
post-cutover reconciliation problems=[] with zero missing files and rows, the
only row diffs being the two verification sessions and sundehui's own row;
secrets 10/10 match, settings_snapshots=11 mismatches=0; rollback kit sha OK and
rollback-now.sh ready; running process carries all nine KBREG_* variables and
kbreg search over a tunnel still resolves the published revision.

Impact: task card only; ECS dev 8788 now serves the same build as the local
dev instance with the local knowledge base attached.

Refs: feature/ecs-deploy-dev8788-and-kb
2026-10-23 00:45:41 +00:00
weichen f9a953831b Configure ECS super admin as existing account sundehui and stage cutover
Why: Owner asked to prepare configuration first: use the existing sundehui
account on imc-tx-ecs as the super administrator with password 12345678 and a
forced password reset on first login.

Evidence: rehearsal on the 8789 copy — migrate-only start (auth off) v35 to v51
in 0.27 s, seed-superadmin.py elevates sundehui without creating an account
(users still 18), auth-on start logs 'already established', login returns
isSuperAdmin with sessionScope set_password_only, no errors in the log. Remote
super-admin.env (600) and the two-file EnvironmentFile drop-in are in place;
the live service was not stopped.

Impact: task card only. Product startup refuses to elevate an existing account
from env, so the elevation is an explicit, rehearsal-verified write mirroring
the product bootstrap; cutover script now runs migrate, seed, start phases.

Refs: feature/ecs-deploy-dev8788-and-kb
2026-10-22 23:10:01 +00:00
weichen 6ced938a12 Merge pull request 'A2 follow-up: repin backend with the intent-test hardening' (#709) from feature/exec-recovery-a2-hardening into main
ci / svc-realcombo (push) Successful in 3m16s
ci / test (push) Failing after 6m52s
ci / test-pg (push) Successful in 12m22s
2026-10-22 15:39:43 +00:00
weichen b9560c7e21 Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 3m52s
ci / test (pull_request) Successful in 11m7s
ci / test-pg (pull_request) Successful in 12m54s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=c3fc389b.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 15:25:57 +00:00
weichen 68ca3f5fb1 Record ECS dev 8788 and knowledge base deployment task card
Why: Owner asked to deploy the local 8788 dev binary service and the local
knowledge base to imc-tx-ecs, with a remote backup first and a minimal-downtime
cutover that needs owner confirmation.

Evidence: make evidence receipts for the remote warm backup (629 files, sha OK),
the offsite copy, the knowledge base fingerprint comparison, the end-to-end KB
search through a tunnel, the remote inventory, and the 8789 rehearsal instance
(schema v35 -> v51, healthy in 1.02 s, no errors).

Impact: .task card only; no product code, no runtime change yet. The live ECS
service was not stopped (pid 4080336 unchanged since 2026-10-18).

Refs: feature/ecs-deploy-dev8788-and-kb; supersedes none; related to
.task/archive/feature-ecs-sync-local-dev.md
2026-10-22 15:24:46 +00:00
weichen 9a6ae6c571 Repin modules/backend with the intent-test hardening
ci / svc-realcombo (pull_request) Successful in 3m43s
ci / test (pull_request) Successful in 10m49s
ci / test-pg (pull_request) Successful in 14m3s
Why: the intent-session tests were load-sensitive in CI (409 races
against the prior run settling); the hardening rides the A2 pin.
Evidence: repair receipt (a1ff-run.json) and 3x race verification
(verify-a1ff.json exit=0) on the merged tip; full make test green
(verify-a2-combo3.json exit=0).
Impact: one component gitlink.
Refs: PR #704
2026-10-22 15:05:35 +00:00
weichen c3fc389b9f Merge pull request 'Close the merged deploy-txn port card' (#708) from feature/card-close-20261022-144302Z into main
ci / svc-realcombo (push) Successful in 3m56s
ci / test (push) Successful in 10m59s
ci / test-pg (push) Successful in 14m41s
2026-10-22 14:59:52 +00:00
weichen 9eeba5afa2 Close 1 merged task card(s) and archive them
ci / svc-realcombo (pull_request) Successful in 4m51s
ci / test (pull_request) Successful in 12m5s
ci / test-pg (pull_request) Successful in 15m55s
Why: branches merged into their immediate or root target had left their task cards open; backfill status and archive to prevent bookkeeping debt.
Evidence: fix-svc-test-port-governance-deploy-txn.md(PR#705 into main) — merges verified via git log --merges plus Gitea API squash lookup against each card's origin target.
Impact: .task/*.md moved to .task/archive/ with status backfilled; no code or submodule change.
Refs: task.sh close (card-autoclose-r1)
2026-10-22 14:43:02 +00:00
weichen 66e2c98060 Merge pull request 'Close the merged port governance cards' (#707) from feature/card-close-20261022-140925Z into main
ci / svc-realcombo (push) Successful in 3m52s
ci / test (push) Successful in 12m43s
ci / test-pg (push) Failing after 15m27s
2026-10-22 14:42:50 +00:00
weichen b58caf2d99 Fold-close the task card before merge
ci / svc-realcombo (pull_request) Successful in 4m1s
ci / test-pg (pull_request) Failing after 6m48s
ci / test (pull_request) Successful in 12m15s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-exec-recovery-diagnostics-a2.md -> .task/archive/feature-exec-recovery-diagnostics-a2.md; status 已完成(合入前闭合); PR #704 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/704.
Impact: task metadata only; the card is archived within PR #704 and lands with its merge commit.
Refs: task.sh close --self
2026-10-22 14:20:42 +00:00
weichen ade7083c57 Close 1 merged task card(s) and archive them
ci / svc-realcombo (pull_request) Successful in 4m48s
ci / test (pull_request) Successful in 12m43s
ci / test-pg (pull_request) Successful in 16m39s
Why: branches merged into their immediate or root target had left their task cards open; backfill status and archive to prevent bookkeeping debt.
Evidence: fix-svc-test-port-governance-batch1.md(PR#702 into main) — merges verified via git log --merges plus Gitea API squash lookup against each card's origin target.
Impact: .task/*.md moved to .task/archive/ with status backfilled; no code or submodule change.
Refs: task.sh close (card-autoclose-r1)
2026-10-22 14:09:25 +00:00
weichen f673c2a15a Merge pull request 'Use a dynamic port in the last hardcoded test binding' (#705) from fix/svc-test-port-governance-deploy-txn into main
ci / svc-realcombo (push) Successful in 6m16s
ci / test (push) Successful in 13m30s
ci / test-pg (push) Successful in 20m15s
2026-10-22 14:09:13 +00:00
weichen b0d481e91e Record the A2 review approval in the task card
ci / svc-realcombo (pull_request) Successful in 4m31s
ci / test (pull_request) Successful in 10m36s
ci / test-pg (pull_request) Successful in 19m1s
Why: independent review approved the diagnostics endpoint (0 blockers,
0 majors).
Evidence: review receipt /tmp/agent-stack-b2/reviewa2b-run.json.
Impact: task metadata + review report.
Refs: PR #704
2026-10-22 14:01:07 +00:00
agent-exec-transport c4bd492230 agent-exec transport d7614ba632456b193fd4f78809d020e6/61190ee81e4f 2026-10-22 14:00:52 +00:00
agent-exec-transport 2739dcbfcc agent-exec transport 2e46101738c303455c7fb4f286176c0e/4e605887db1b
ci / svc-realcombo (pull_request) Successful in 4m4s
ci / test (pull_request) Successful in 11m18s
ci / test-pg (pull_request) Successful in 14m34s
2026-10-22 13:46:27 +00:00
weichen c8d22d6ddb Record the task card for feature-ecs-deploy-dev8788-and-kb
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-ecs-deploy-dev8788-and-kb.md; R0=cb36b59accd0418c5ca952912d7c181b83038a4c.

Impact: task metadata only; the feature workspace starts at cb36b59acc.

Refs: .task/feature-ecs-deploy-dev8788-and-kb.md
2026-10-22 13:41:37 +00:00
weichen 03ed068408 Record the task card for fix-svc-test-port-governance-deploy-txn
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/fix-svc-test-port-governance-deploy-txn.md; R0=cb36b59accd0418c5ca952912d7c181b83038a4c.

Impact: task metadata only; the feature workspace starts at cb36b59acc.

Refs: .task/fix-svc-test-port-governance-deploy-txn.md
2026-10-22 13:39:46 +00:00
weichen d0b2bde9b0 Record the A2 implementation and combination results
ci / svc-realcombo (pull_request) Successful in 3m50s
ci / test (pull_request) Successful in 9m42s
ci / test-pg (pull_request) Successful in 14m45s
Why: audit trail for the diagnostics endpoint unit, the baseline edge
registration and the green full combination run.
Evidence: verify-a2b.json and verify-a2-combo2.json exit=0.
Impact: task metadata only.
Refs: feature/exec-recovery-diagnostics-a2
2026-10-22 13:32:43 +00:00
weichen cb36b59acc Merge pull request 'Use dynamic ports across the five test files that shared hardcoded bindings' (#702) from fix/svc-test-port-governance-batch1 into main
ci / svc-realcombo (push) Successful in 3m24s
ci / test (push) Successful in 11m9s
ci / test-pg (push) Successful in 18m29s
2026-10-22 13:26:12 +00:00
weichen 826398c969 Register the rundiag dependency edges in the architecture baseline
Why: the A2 diagnostics package reuses the cmdbus operation query and
store reads, mediated by the server; the three edges are the reviewed
design, recorded in the task card.
Evidence: lint-architecture passes (verify-a2arch.json); boundaries
and full combination re-run below.
Impact: three baseline edge lines.
Refs: feature/exec-recovery-diagnostics-a2
2026-10-22 13:24:34 +00:00
weichen 9d5ed689ce Record the sync checkpoint
ci / svc-realcombo (pull_request) Successful in 3m53s
ci / test (pull_request) Successful in 9m55s
ci / test-pg (pull_request) Successful in 14m38s
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=c92443280ef8e9ed29bf5bf5250df650c01b4478; before_record=c22b9fb34a3702191a9e5f6007f3538520db694b.

Impact: task metadata only.

Refs: .task/fix-svc-test-port-governance-batch1.md
2026-10-22 13:10:38 +00:00
weichen c22b9fb34a Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=c92443280ef8e9ed29bf5bf5250df650c01b4478.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 13:09:54 +00:00
weichen 7f23ed9ed1 Bump the modules/backend pin to the A2 diagnostics tip
Why: land the read-only run diagnostics endpoint (A2) per the approved
feature scope.
Evidence: integration transport (a2git2-run.json); unit tests green
(verify-a2b.json exit=0); combination re-run below.
Impact: one component gitlink.
Refs: feature/exec-recovery-diagnostics-a2
2026-10-22 13:09:53 +00:00
weichen abf4c27736 Record the A2 design in the task card
Why: fix the read-only diagnostics contract (single GET endpoint,
aggregated responsibility/wait-reason/checkpoint/side-effects/next-step,
no write endpoints) before implementation.
Evidence: scoping over server routes, store recovery/HITL methods and
cmdbus audit records.
Impact: task metadata only.
Refs: docs/superpowers/plans/2026-10-21-agent-stack-audit-remediation-plan.md (A2)
2026-10-22 12:41:32 +00:00
weichen a14752bf1e Record the task card for feature-exec-recovery-diagnostics-a2
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-exec-recovery-diagnostics-a2.md; R0=c92443280ef8e9ed29bf5bf5250df650c01b4478.

Impact: task metadata only; the feature workspace starts at c92443280e.

Refs: .task/feature-exec-recovery-diagnostics-a2.md
2026-10-22 12:37:28 +00:00
agent-exec-transport f84d7c724e agent-exec transport 8c38703572870841a8c0c81bef7c6773/e8f9fe72723f
ci / svc-realcombo (pull_request) Successful in 2m55s
ci / test (pull_request) Successful in 9m8s
ci / test-pg (pull_request) Successful in 20m53s
2026-10-22 12:31:34 +00:00
agent-exec-transport 7a289378a1 agent-exec transport a9d557e025200bb64622b5690985f868/d036131967f9
ci / svc-realcombo (pull_request) Successful in 4m32s
ci / test (pull_request) Failing after 6m35s
ci / test-pg (pull_request) Successful in 15m47s
2026-10-22 12:31:10 +00:00
weichen c92443280e Merge pull request 'A1 multi-turn intent closure (sessions and cancel routing)' (#700) from feature/intent-multi-turn-a1 into main
ci / svc-realcombo (push) Successful in 3m4s
ci / test (push) Successful in 9m35s
ci / test-pg (push) Successful in 18m50s
2026-10-22 12:25:13 +00:00
weichen ce7b0d9c44 Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 3m59s
ci / test (pull_request) Successful in 10m59s
ci / test-pg (pull_request) Successful in 14m51s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=3d3474a7.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 12:09:38 +00:00
weichen 1651efa97b Fold-close the task card before merge
ci / test (pull_request) Successful in 9m36s
ci / svc-realcombo (pull_request) Successful in 3m56s
ci / test-pg (pull_request) Successful in 15m50s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-intent-multi-turn-a1.md -> .task/archive/feature-intent-multi-turn-a1.md; status 已完成(合入前闭合); PR #700 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/700.
Impact: task metadata only; the card is archived within PR #700 and lands with its merge commit.
Refs: task.sh close --self
2026-10-22 11:37:48 +00:00
weichen 88581f3440 Add the A1 independent review report
Why: the independent review of the A1 multi-turn closure raised two
real blockers (cross-action slot inheritance; cancel store errors
swallowed); the report documents them for the repair that follows.
Evidence: review receipt /tmp/agent-stack-b2/reviewa1-run.json
(pi-glm attempt1 success).
Impact: review report only.
Refs: PR #700
2026-10-22 11:34:16 +00:00
weichen 8cb2d2297b Record the task card for fix-svc-test-port-governance-batch1
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/fix-svc-test-port-governance-batch1.md; R0=3d3474a731f9ef3ee1f41935e63bca3afb70db56.

Impact: task metadata only; the feature workspace starts at 3d3474a731.

Refs: .task/fix-svc-test-port-governance-batch1.md
2026-10-22 11:15:53 +00:00
weichen 3d3474a731 Merge pull request 'Fold the archived port-governance card into main' (#699) from fix/svc-test-port-governance-final into main
ci / svc-realcombo (push) Successful in 3m39s
ci / test (push) Successful in 10m26s
ci / test-pg (push) Successful in 13m41s
ci / svc-realcombo (pull_request) Successful in 3m15s
ci / test (pull_request) Successful in 9m39s
ci / test-pg (pull_request) Successful in 15m14s
2026-10-22 10:55:45 +00:00
weichen 9126b09b5d Record A1 unit receipts and the combination results
ci / svc-realcombo (pull_request) Successful in 3m12s
ci / test (pull_request) Successful in 10m52s
ci / test-pg (pull_request) Successful in 15m3s
Why: audit trail for U-A1b/U-A1c, the baseline and manifest repairs,
and the known environment-dependent governance flake.
Evidence: verify-a1b/a1c/a1sr/a1-rest exit=0.
Impact: task metadata only.
Refs: feature/intent-multi-turn-a1
2026-10-22 10:51:16 +00:00
weichen 41391776e1 Repin modules/backend to the storage-manifest tip
Why: the backend branch advanced with the intent_session manifest fix.
Evidence: integration transport (a1git2-run.json); combination re-run
below.
Impact: one component gitlink.
Refs: feature/intent-multi-turn-a1
2026-10-22 10:49:32 +00:00
weichen 74f3278514 Register the intentsession dependency edges in the architecture baseline
Why: the A1 session package reuses the gate's result/command types,
persists via the store and is mediated by the server; the three edges
are the reviewed design, recorded in the task card.
Evidence: lint-architecture passes (verify-a1arch.json); boundaries
and full combination re-run below.
Impact: three baseline edge lines.
Refs: feature/intent-multi-turn-a1
2026-10-22 10:31:40 +00:00
weichen d138dd8b45 Bump the modules/backend pin to the A1 multi-turn intent tip
Why: land U-A1b (conversation-scoped intent sessions) and U-A1c (cancel
intent routed through cmdbus with explicit targets) per the approved
A1 feature scope.
Evidence: unit transports (a1b/a1c-run.json) and host verifications
(verify-a1b.json, verify-a1c.json exit=0); combination re-run below.
Impact: one component gitlink.
Refs: feature/intent-multi-turn-a1
2026-10-22 10:06:38 +00:00
weichen c88cb95654 Record the sync checkpoint
ci / svc-realcombo (pull_request) Successful in 2m55s
ci / test (pull_request) Successful in 8m44s
ci / test-pg (pull_request) Successful in 15m56s
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=98ee59c477785b2d5094fcbea3e67a4dc864c388; before_record=a29562ef8315c6cbe71bf531720ce5ffa5ca2717.

Impact: task metadata only.

Refs: .task/archive/fix-svc-test-port-governance-final.md
2026-10-22 09:35:11 +00:00
weichen a29562ef83 Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=98ee59c477785b2d5094fcbea3e67a4dc864c388.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 09:34:18 +00:00
weichen b63685d7b5 Fold-close the task card before merge
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/fix-svc-test-port-governance-final.md -> .task/archive/fix-svc-test-port-governance-final.md; status 已完成(合入前闭合); PR #698 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/698.
Impact: task metadata only; the card is archived within PR #698 and lands with its merge commit.
Refs: task.sh close --self
2026-10-22 09:33:42 +00:00
weichen 98ee59c477 Merge pull request 'Use dynamic ports in the last three hardcoded test bindings' (#698) from fix/svc-test-port-governance-final into main
ci / svc-realcombo (push) Successful in 2m30s
ci / test (push) Successful in 8m55s
ci / test-pg (push) Successful in 12m22s
2026-10-22 09:33:12 +00:00
agent-exec-transport 60bd1bedb4 agent-exec transport 848ba0b1bdee6617e7757143cdffa2e9/e0b4b463efec
ci / svc-realcombo (pull_request) Successful in 2m53s
ci / test (pull_request) Successful in 8m57s
ci / test-pg (pull_request) Successful in 12m24s
2026-10-22 09:08:33 +00:00
weichen 10b751f159 Record the task card for fix-svc-test-port-governance-final
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/fix-svc-test-port-governance-final.md; R0=955a32de2bb49171348bad5f566cce935df19212.

Impact: task metadata only; the feature workspace starts at 955a32de2b.

Refs: .task/fix-svc-test-port-governance-final.md
2026-10-22 08:55:33 +00:00
weichen ceb6bb9f5a Record the A1 design and unit breakdown in the task card
Why: fix the design decisions (run-cancel as the first business action,
store-backed conversation intent session with TTL and revision,
cmdbus confirmation unchanged) before implementation.
Evidence: scoping over intentgate/route/server and the intent lib.
Impact: task metadata only.
Refs: docs/superpowers/plans/2026-10-21-agent-stack-audit-remediation-plan.md (A1)
2026-10-22 08:50:21 +00:00
weichen 940409a85e Record the task card for feature-intent-multi-turn-a1
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-intent-multi-turn-a1.md; R0=955a32de2bb49171348bad5f566cce935df19212.

Impact: task metadata only; the feature workspace starts at 955a32de2b.

Refs: .task/feature-intent-multi-turn-a1.md
2026-10-22 08:48:01 +00:00
weichen 955a32de2b Merge pull request 'Audit follow-ups: pin-regression gate and subagent Writable preflight (M5)' (#695) from feature/audit-followups-pin-gate-m5 into main
ci / svc-realcombo (push) Successful in 2m42s
ci / test (push) Successful in 8m55s
ci / test-pg (push) Successful in 12m19s
2026-10-22 08:43:16 +00:00
weichen 2f37df890a Merge authoritative main into the task branch
ci / svc-realcombo (pull_request) Successful in 3m2s
ci / test (pull_request) Successful in 8m48s
ci / test-pg (pull_request) Successful in 12m23s
Why: include the current integration baseline before merge.

Evidence: fetched origin/main=9a80897c.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 08:30:20 +00:00
weichen 9a80897cb7 Merge pull request 'Close the merged test port governance card' (#696) from feature/card-close-20261022-080552Z into main
ci / svc-realcombo (push) Successful in 3m0s
ci / test (push) Successful in 9m4s
ci / test-pg (push) Successful in 12m51s
2026-10-22 08:20:56 +00:00
weichen 68219746be Retrigger CI after the flaky material-ack timeout
ci / svc-realcombo (pull_request) Successful in 2m44s
ci / test (pull_request) Successful in 9m20s
ci / test-pg (pull_request) Successful in 14m14s
Why: the CI test-pg timeout on TestMaterialAckAttachmentOnlyDoesNot-
CallParentModel is environmental (the product never sets a Writable
write-set, so the M5 preflight cannot trigger there; the same commit
and test pass locally in 0.05s against real PG/Redis).
Evidence: verify-materialack.json exit=0.
Impact: task metadata only.
Refs: PR #695
2026-10-22 08:15:01 +00:00
weichen 058d5b3f9c Close 1 merged task card(s) and archive them
ci / svc-realcombo (pull_request) Successful in 3m15s
ci / test (pull_request) Successful in 9m58s
ci / test-pg (pull_request) Successful in 14m16s
Why: branches merged into their immediate or root target had left their task cards open; backfill status and archive to prevent bookkeeping debt.
Evidence: fix-svc-test-port-governance.md(PR#694 into main) — merges verified via git log --merges plus Gitea API squash lookup against each card's origin target.
Impact: .task/*.md moved to .task/archive/ with status backfilled; no code or submodule change.
Refs: task.sh close (card-autoclose-r1)
2026-10-22 08:05:52 +00:00
weichen 67ffd7c89e Fold-close the task card before merge
ci / svc-realcombo (pull_request) Successful in 3m1s
ci / test-pg (pull_request) Failing after 3m47s
ci / test (pull_request) Successful in 9m32s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-audit-followups-pin-gate-m5.md -> .task/archive/feature-audit-followups-pin-gate-m5.md; status 已完成(合入前闭合); PR #695 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/695.
Impact: task metadata only; the card is archived within PR #695 and lands with its merge commit.
Refs: task.sh close --self
2026-10-22 08:05:13 +00:00
weichen 1dbd15add0 Record the backend tip push and retrigger CI
ci / svc-realcombo (pull_request) Successful in 2m41s
ci / test (pull_request) Successful in 8m41s
ci / test-pg (pull_request) Successful in 11m53s
Why: the first CI run failed at checkout because the backend merge tip
a75783f existed only locally; it is now pushed.
Evidence: remote ref updated on Agent-System-Backend.
Impact: task metadata only.
Refs: PR #695
2026-10-22 07:52:41 +00:00
weichen 88f03f500e Record the followups review approval in the task card
ci / test (pull_request) Failing after 3s
ci / svc-realcombo (pull_request) Failing after 3s
ci / test-pg (pull_request) Failing after 3s
Why: independent review approved the pin gate and M5 fix.
Evidence: review receipt /tmp/agent-stack-b2/reviewf-run.json.
Impact: task metadata + review report.
Refs: PR #695
2026-10-22 07:51:48 +00:00
agent-exec-transport 36cc7f443b agent-exec transport 8515f314ceb985a1c630e7e8db3b8b0f/3af7c5319e38 2026-10-22 07:51:02 +00:00
weichen a2b4cf73a3 Record the merged baseline and the pre-existing governance failure
ci / test (pull_request) Failing after 3s
ci / test-pg (pull_request) Failing after 3s
ci / svc-realcombo (pull_request) Failing after 3s
Why: the branch now carries authoritative main (backend role-policy and
scratch-session work, frontend/ui pin advances); the only combination
failure is the environment-dependent svc test that reproduces on clean
main.
Evidence: verify-f-pins9.json exit=0; verify-f-rest.json exit=0;
verify-f-combo.json shows the single pre-existing failure.
Impact: task metadata only.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 07:33:47 +00:00
weichen 37e194871f Merge pull request 'Use dynamic ports in the two remaining hardcoded test bindings' (#694) from fix/svc-test-port-governance into main
ci / svc-realcombo (push) Successful in 3m0s
ci / test (push) Successful in 9m7s
ci / test-pg (push) Successful in 12m51s
2026-10-22 07:31:31 +00:00
weichen a874ee600a Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=d65195bd.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 07:25:28 +00:00
weichen b2f8c04b15 Repin modules/backend to the merged followups tip
Why: backend adopts upstream main (role-policy/HITL fixes) and the
parallel scratch-session work while keeping the M5 nested pin, so the
followups composition stays current with main.
Evidence: integration transport (gitlinkb7-run.json); pins checks and
combination targets re-run below.
Impact: one component gitlink.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 07:18:08 +00:00
weichen 679c483d00 Record the sync checkpoint
ci / svc-realcombo (pull_request) Successful in 3m19s
ci / test (pull_request) Successful in 9m27s
ci / test-pg (pull_request) Successful in 12m37s
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=d65195bd41317e480c5a0cfa5133b0ad98a48d4b; before_record=a1e0c85c0400ce300a847da276e70d520f842844.

Impact: task metadata only.

Refs: .task/fix-svc-test-port-governance.md
2026-10-22 07:17:59 +00:00
weichen a1e0c85c04 Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=d65195bd41317e480c5a0cfa5133b0ad98a48d4b.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 07:17:09 +00:00
weichen 17ba4eab35 Record the followups verification results in the task card
ci / svc-realcombo (pull_request) Successful in 3m6s
ci / test-pg (pull_request) Failing after 3m39s
ci / test (pull_request) Successful in 10m4s
Why: pins checks green with the new gate; all other combination targets
pass; the single governance failure reproduces on clean main.
Evidence: verify-followups-{pins5,rest}.json exit=0; main reproduction
captured in-session.
Impact: task metadata only.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 07:09:14 +00:00
weichen d65195bd41 Merge pull request 'Deliver isolated no-project scratch sessions across Backend, Frontend and UI' (#691) from feature/scratch-session-general-agent into main
ci / svc-realcombo (push) Successful in 3m13s
ci / test (push) Successful in 9m30s
ci / test-pg (push) Successful in 15m22s
2026-10-22 07:08:47 +00:00
weichen a23a212015 Repin modules/backend to the nested-squad followups tip
Why: backend's nested agent-squad advances with its nested agent-native
M5 bump, keeping every container consistent with the Dev-level pins.
Evidence: integration transport (gitlinkb3b-run.json); pins checks and
full make test re-run below.
Impact: one component gitlink.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 06:52:30 +00:00
weichen a39b4f795c Advance squad and backend pins for the followups
Why: the squad container carries its nested agent-native M5 bump; the
backend container is already at its repaired tip in this history.
Evidence: integration transport (gitlinks3-run.json); pins checks and
full make test re-run below.
Impact: one component gitlink.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 06:47:42 +00:00
weichenandCursor d2dbd9dfdf Bump Backend to the PostgreSQL role policy and HITL test fixes
ci / svc-realcombo (pull_request) Successful in 3m7s
ci / test (pull_request) Successful in 9m43s
ci / test-pg (pull_request) Successful in 15m30s
Why: Dev composite test-pg failed on the role_permissions upsert from
Backend#240 and a racy HITL test; Backend#246 fixes both.

Evidence: Backend#246 CI GATE on 8cd4dd0; PostgreSQL verified by this
PR's test-pg job.

Impact: modules/backend 7bcbbdb.

Refs: Agent-System-Backend#246, Agent-System-Dev#691;
agent-exec receipt u6d-run (cursor, success)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 06:43:47 +00:00
weichen ecfa244c0a Repin modules/backend to the nested-M5 tip
Why: the backend branch advanced past its nested agent-native bump so
the composed chain carries the M5 preflight end to end.
Evidence: integration transport success (gitlinkb2h-run.json); pins
checks and full make test re-run below.
Impact: one component gitlink.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 06:34:08 +00:00
agent-exec-transport f1866903c5 agent-exec transport 461e582a25c2763a6ac100e94490eddd/c9ee6bdfd3a5
ci / svc-realcombo (pull_request) Successful in 3m7s
ci / test (pull_request) Successful in 8m36s
ci / test-pg (pull_request) Successful in 13m37s
2026-10-22 06:29:13 +00:00
weichen cb767f6035 Advance native, squad and backend pins for the followups
Why: native carries the M5 subagent preflight fix; backend adopts its
branch tip that merges upstream main (scratch sessions) on top of the
batch-2 line.
Evidence: integration transport success (gitlinkf5-run.json); nested
native pins follow in the next commit; pins checks re-run below.
Impact: two component gitlinks.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 06:25:14 +00:00
weichen 5130babad4 Fold-close the task card before merge
ci / test-pg (pull_request) Failing after 3m0s
ci / svc-realcombo (pull_request) Successful in 3m18s
ci / test (pull_request) Successful in 9m17s
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-scratch-session-general-agent.md -> .task/archive/feature-scratch-session-general-agent.md; status 已完成(合入前闭合); PR #691 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/691.
Impact: task metadata only; the card is archived within PR #691 and lands with its merge commit.
Refs: task.sh close --self
2026-10-22 06:22:02 +00:00
weichen f217a2bce6 Record the sync checkpoint
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=33d6ef69212595c680a744549986c19bb6acd6c3; before_record=1970dccb7c8c11fb69ad739ae1338e97ca4ac0a6.

Impact: task metadata only.

Refs: .task/feature-scratch-session-general-agent.md
2026-10-22 06:21:57 +00:00
weichen 1970dccb7c Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=33d6ef69212595c680a744549986c19bb6acd6c3.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 06:21:09 +00:00
weichenandCursor 52093614fa Record the composite test run after the Frontend contracts fix
Why: make test reran after the Frontend bump; the only failure is
test_svc, whose fixed port 127.0.0.1:18794 is held by an unrelated
local python3 http.server, not by this change.
Evidence: make evidence receipt (SELF, exit 2) on b672792f.
Impact: Task card only; CI in its isolated container is authoritative.
Refs: Agent-System-Dev#691

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 06:21:05 +00:00
weichen 80e5e4559c Record the task card for fix-svc-test-port-governance
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/fix-svc-test-port-governance.md; R0=33d6ef69212595c680a744549986c19bb6acd6c3.

Impact: task metadata only; the feature workspace starts at 33d6ef6921.

Refs: .task/fix-svc-test-port-governance.md
2026-10-22 06:18:16 +00:00
weichen ba1d3b2b81 Add the pin-regression gate to pins checks and the PR gate
Why: PR #682 merged a stale branch that reset five component pins to
pre-batch values, silently dropping the batch-1 composition on main.
Evidence: materialized byte-exact from the reviewed transport
(gatemat-run.json); regression/forward/same/skip/missing-object cases
(verify-pingate.json); make test-governance and test-pins re-run below.
Impact: new check script wired into check-pins and task-pr-check;
PIN_REGRESSION_SKIP=1 documents deliberate downgrades.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 06:16:13 +00:00
weichen 3080c0f4af Bump the agent-native pin to the M5 subagent fix
Why: land the review-M5 preflight fix (delegate_task under a Writable
write-set is now rejected like exec/MCP/host tools).
Evidence: transport success (gitlinkm5c-run.json); native unit tests
green (verify-m5.json); gate/pins checks re-run with the pin bump.
Impact: one component gitlink.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 06:14:23 +00:00
weichenandCursor b672792f77 Bump Frontend to keep the scratch flag out of generated contracts
Why: Frontend#124 moves Conversation.scratch into a local view type so
make contracts (Core is authoritative) no longer breaks tsc.

Evidence: Frontend#124 CI GATE on 6e611c5.

Impact: modules/frontend 279b2d0.

Refs: Agent-System-Frontend#124, Agent-System-Dev#691;
agent-exec receipt u6c-run (cursor, success)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 06:14:20 +00:00
weichenandCursor 5eee6fec51 Record the composite test and the contracts regeneration finding
Why: make test passed on aa77f201, but make contracts regenerates the
frontend contracts from Core and drops Conversation.scratch, which would
fail tsc in make build; Frontend#124 moves the flag to a local view type.
Evidence: make evidence receipt (SELF) on aa77f201.
Impact: Task card only.
Refs: Agent-System-Dev#691, Agent-System-Frontend#124

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 06:07:35 +00:00
weichen 6d35f911fe Record the followups task card (pin gate + M5)
Why: carry authorization and unit plan for the audit follow-ups:
pin-regression gate and native subagent Writable preflight (M5).
Evidence: card only; no code change.
Impact: task metadata only.
Refs: feature/audit-followups-pin-gate-m5
2026-10-22 05:59:51 +00:00
weichen aa77f20184 Record the sync checkpoint
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=b7636742fc9ea937e6030123afc608fd294861bf; before_record=1dee480dff7203aff3bd6b57661645fe0b890bce.

Impact: task metadata only.

Refs: .task/feature-scratch-session-general-agent.md
2026-10-22 05:49:12 +00:00
weichen 1dee480dff Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=b7636742fc9ea937e6030123afc608fd294861bf.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 05:48:30 +00:00
weichenandCursor ddc5bf9285 Align component pins with the merged batch-2 and scratch session Backend
Why: Dev main (#689) pins Backend to the batch-2 branch commit and newer
deps; Backend main fd69932 (Backend#245) now contains both batch-2 and
the scratch session work (Backend#241).

Evidence: Backend#245 CI GATE on 443e7af; deps match Dev main pins.

Impact: modules/backend fd69932; deps/agent-{command,intent,native,squad}
equal Dev main.

Refs: Agent-System-Backend#245, Agent-System-Dev#689, #691;
agent-exec receipt u6b-run (cursor, success)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 05:48:15 +00:00
weichenandCursor 7c97dee7c2 Record the blocked composite test on the scratch session card
ci / svc-realcombo (pull_request) Failing after 1m38s
ci / test-pg (pull_request) Failing after 3m34s
ci / test (pull_request) Failing after 7m2s
Why: make test fails at test-pins because Backend main already pins the
agent-stack batch-1 deps that Dev main has not adopted yet.
Evidence: make evidence receipt (SELF, exit 2) on 36a1d408.
Impact: Task card only; waiting for Dev #689 per queue #518.
Refs: Agent-System-Dev#691, #689, #518

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 05:26:38 +00:00
weichen 36a1d4084e Record the sync checkpoint
ci / svc-realcombo (pull_request) Failing after 1m46s
ci / test-pg (pull_request) Failing after 3m53s
ci / test (pull_request) Failing after 7m2s
Why: bind the task validation checkpoint to the integration baseline.

Evidence: SELF recursive component checks; sync_base=1de7c28c2122609dd9b6435881696492bd052a34; before_record=635459316dbd4e4a5134f4e409bed72a5dd02730.

Impact: task metadata only.

Refs: .task/feature-scratch-session-general-agent.md
2026-10-22 05:18:42 +00:00
weichen 635459316d Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=1de7c28c2122609dd9b6435881696492bd052a34.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-22 05:17:46 +00:00
weichenandCursor 63ff64dd7a Bump Backend, Frontend and UI to the merged scratch session work
Why: Accounts without project.create get isolated no-project
conversations; the three component PRs are merged.

Evidence: component CI on each merged PR head (GATE): Backend#241
2424f8e, Frontend#123 b02ff83, UI#60 db5129c; composite make test is
recorded on the task card.

Impact: modules/backend 029917e, modules/frontend ec1ced3,
modules/ui df1c3ed.

Refs: Agent-System-Backend#241, Agent-System-Frontend#123,
Agent-System-UI#60; agent-exec receipt u6-run (cursor, success)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 05:17:25 +00:00
weichenandCursor db37c59a32 Record review-fix attempts for scratch session gates
Why: Independent reviews blocked on project-context, bus-level rdm
gates and remaining project-only UI surfaces; each attempt must be
traceable, including the authorized UI-repo expansion.

Evidence: receipts under /tmp/scratch-session-20261022 (SELF).
Impact: Task card only.
Refs: Backend#241 Frontend#123 UI#60
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 04:04:17 +00:00
weichenandCursor 5f1d6f8e15 Record scratch session implementation attempts on the task card
Why: Every implementation attempt and its reconciliation must be traceable.
Evidence: receipts under /tmp/scratch-session-20261022 (SELF).
Impact: Task card only.
Refs: .task/feature-scratch-session-general-agent.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 03:22:37 +00:00
weichenandCursor 4cb94bd8d7 Record scratch-session goal and delivery endpoint on the task card
Why: Align the task card with the approved design before implementation units.
Evidence: Design approved 2026-10-22; task-start R0=a4311c63.
Impact: .task card metadata only.
Refs: docs/superpowers/specs/2026-10-22-scratch-session-general-agent-design.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 01:44:53 +00:00
weichenandCursor 49a22059c9 Add scratch session general-agent design and plan
Why: Record the approved design for isolated no-project conversations.
Evidence: Design sections 1-4 approved 2026-10-22; task-start R0=a4311c63.
Impact: Docs only under docs/superpowers/{specs,plans}.
Refs: docs/superpowers/specs/2026-10-22-scratch-session-general-agent-design.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 01:43:42 +00:00
weichen 795444c4c0 Record the task card for feature-scratch-session-general-agent
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-scratch-session-general-agent.md; R0=a4311c6341c318d4bbf1563b3973358326086794.

Impact: task metadata only; the feature workspace starts at a4311c6341.

Refs: .task/feature-scratch-session-general-agent.md
2026-10-22 01:43:32 +00:00
60 changed files with 3347 additions and 1346 deletions
+42 -2
View File
@@ -77,6 +77,9 @@ jobs:
"fetch.recurseSubmodules": "false", "submodule.recurse": "false",
"http.followRedirects": "false", "protocol.allow": "never",
"protocol." + urlsplit(SERVER).scheme + ".allow": "always",
# 嵌套 pins(RDM/KB 等)仍以权威 SSH 端点声明 URL:把它改写到同一受信
# HTTPS 基址,才能复用既有的 URL 级 token 头而不依赖真实 SSH。
# 本仓 .gitmodules 已是 HTTPS 形式,SSH 允许清单常量保持不变。
}
@@ -178,6 +181,31 @@ jobs:
tar -C /usr/local --strip-components=1 -xJf "$RUNNER_TEMP/node.tar.xz"
- name: Install house-style Python packages
run: python3 -m pip install --break-system-packages -i https://pypi.tuna.tsinghua.edu.cn/simple python-docx python-pptx openpyxl
- name: Provision the Gitea token file for facts verification
env:
T1: ${{ secrets.GITEA_TOKEN }}
T2: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
echo "provision: GITEA_TOKEN length=${#T1}, GITHUB_TOKEN length=${#T2}"
if [ -n "$T1" ]; then
token="$T1"; source_name=GITEA_TOKEN
elif [ -n "$T2" ]; then
token="$T2"; source_name=GITHUB_TOKEN
else
echo "provision: GITEA_TOKEN/GITHUB_TOKEN both empty"
exit 1
fi
echo "provision: using ${source_name}"
mkdir -p "$HOME/.secrets"
printf 'HOME:\n- ACCESS_TOKEN=%s\n' "$token" > "$HOME/.secrets/gitea"
chmod 600 "$HOME/.secrets/gitea"
code="$(curl -fsS -m 10 -H "Authorization: token ${token}" https://gitea.naitangbaobao.cn/api/v1/user -o /dev/null -w '%{http_code}')" || true
if [ "$code" != "200" ]; then
echo "provision: /api/v1/user self-check failed with http code ${code:-none} (source ${source_name})"
exit 1
fi
echo "provision: /api/v1/user self-check ok (http 200)"
- name: make test (boundaries, pins, libs, core, backend, frontend, ui, agent-command)
run: make test
- name: Build the single binary
@@ -261,6 +289,9 @@ jobs:
"fetch.recurseSubmodules": "false", "submodule.recurse": "false",
"http.followRedirects": "false", "protocol.allow": "never",
"protocol." + urlsplit(SERVER).scheme + ".allow": "always",
# 嵌套 pins(RDM/KB 等)仍以权威 SSH 端点声明 URL:把它改写到同一受信
# HTTPS 基址,才能复用既有的 URL 级 token 头而不依赖真实 SSH。
# 本仓 .gitmodules 已是 HTTPS 形式,SSH 允许清单常量保持不变。
}
@@ -404,13 +435,16 @@ jobs:
# https 基址后再取。只追加 pin 的三个 40 位 hex,不 source pin 文件。
SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')"
scheme="${GITHUB_SERVER_URL%%://*}"
# 嵌套 pins 的 SSH 端点有两代(旧 git-ssh.* 与迁移后的 gitea.*:52222);
# 只映射旧端点会让嵌套克隆退回真实 SSH,CI 无 key 时必然 host key 失败。
# 两个 insteadOf 同键多值,git 会依次匹配。
export GIT_CONFIG_COUNT=4
export GIT_CONFIG_KEY_0="protocol.$scheme.allow"
export GIT_CONFIG_VALUE_0="always"
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
export GIT_CONFIG_VALUE_1="AUTHORIZATION: token $SUBMODULE_TOKEN"
export GIT_CONFIG_KEY_2="url.$SERVER/weichen/.insteadOf"
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
export GIT_CONFIG_VALUE_2="ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
export GIT_CONFIG_KEY_3="core.hooksPath"
export GIT_CONFIG_VALUE_3="/dev/null"
git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
@@ -586,6 +620,9 @@ jobs:
"fetch.recurseSubmodules": "false", "submodule.recurse": "false",
"http.followRedirects": "false", "protocol.allow": "never",
"protocol." + urlsplit(SERVER).scheme + ".allow": "always",
# 嵌套 pins(RDM/KB 等)仍以权威 SSH 端点声明 URL:把它改写到同一受信
# HTTPS 基址,才能复用既有的 URL 级 token 头而不依赖真实 SSH。
# 本仓 .gitmodules 已是 HTTPS 形式,SSH 允许清单常量保持不变。
}
@@ -692,13 +729,16 @@ jobs:
# https 基址后再取。
SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')"
scheme="${GITHUB_SERVER_URL%%://*}"
# 嵌套 pins 的 SSH 端点有两代(旧 git-ssh.* 与迁移后的 gitea.*:52222);
# 只映射旧端点会让嵌套克隆退回真实 SSH,CI 无 key 时必然 host key 失败。
# 两个 insteadOf 同键多值,git 会依次匹配。
export GIT_CONFIG_COUNT=4
export GIT_CONFIG_KEY_0="protocol.$scheme.allow"
export GIT_CONFIG_VALUE_0="always"
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
export GIT_CONFIG_VALUE_1="AUTHORIZATION: token $SUBMODULE_TOKEN"
export GIT_CONFIG_KEY_2="url.$SERVER/weichen/.insteadOf"
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
export GIT_CONFIG_VALUE_2="ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
export GIT_CONFIG_KEY_3="core.hooksPath"
export GIT_CONFIG_VALUE_3="/dev/null"
git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
@@ -0,0 +1,162 @@
# feature/audit-followups-pin-gate-m5 任务卡
任务主记录:PR #695 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/695;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= b7636742fc9ea937e6030123afc608fd294861bf
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-audit-followups-pin-gate-m5(worktree);分支:feature/audit-followups-pin-gate-m5
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=d2608b7436d1c2d773c607a79568c57cfaa2c32cebf35d1a0cabda9562a543c1;triage_receipt=/tmp/triage-followups-1792647600.json;receipt_sha256=01837cb87f83d50c255ee460dfa8e28ade7ed600624bea7d0c083b7653c8a5dd
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | b7636742fc9ea937e6030123afc608fd294861bf | b7636742fc9ea937e6030123afc608fd294861bf | 2026-10-22T05:41:15Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- CI 记录:首轮 CI Checkout 失败——backend 合并 tip a75783f 未推送远端;已补推,本提交重触发 CI。
- CI 记录:88f03f50/67ffd7c9 两轮 CI——首轮 Checkout 失败(backend tip a75783f 未推送,已补推);次轮 test-pg 的 TestMaterialAckAttachmentOnlyDoesNotCallParentModel 超时:产品代码从不设置 Workspace.Writable(M5 预检不可能触发),本地同提交复现 PASS(0.051s,真实 PG/Redis,verify-materialack.json),判定为并行功能新测试的 CI 环境超时 flake;后续提交重触发 CI。
- Review 记录:独立 CLI 评审单元 audit-followups-independent-review(收据 /tmp/agent-stack-b2/reviewf-run.json);结论 APPROVE;报告 .task/reviews/2026-10-22-audit-followups-independent-review.md;被审对象合并基线 vs main
- 合并基线:分支已合并 origin/main(含并行 backend 角色策略/scrarch-session 工作与 frontend/ui pin 前进);modules/backend 组合 pin = a75783f(含 7bcbbdb 与 M5 嵌套指针)。
- 已知既有失败:make test-governance 中 test_svc.SvcDbRecoveryTests.test_addr_change_keeps_database_and_auth 在干净 main(b7636742)同样失败(环境依赖),与本分支无关;CI 环境为最终裁决。其余组合目标(boundaries/pins/libs/core/backend/frontend/ui/agentcmd)全部 PASS(verify-followups-rest.json exit=0)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T05:40:13.195742+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "b7636742fc9ea937e6030123afc608fd294861bf",
"after_head": "b7636742fc9ea937e6030123afc608fd294861bf",
"branch": "main",
"target_branch": "main",
"target_head": "b7636742fc9ea937e6030123afc608fd294861bf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=b7636742fc",
"[remote] origin/main=b7636742fc ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=5",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] b7636742fc(完整:b7636742fc9ea937e6030123afc608fd294861bf)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "750b4668efa152b0a18152e950ab40051a737f940cf5e108e6adc79324dea82a",
"receipt_sha256": "e2cd793c34846aafbd4c3dd5a77d8bc08fb51323ded1082b212c91e78074bad7",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/e2cd793c34846aafbd4c3dd5a77d8bc08fb51323ded1082b212c91e78074bad7.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #695(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/695)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,168 @@
# feature/catalog-recall-eval-a3 任务卡
任务主记录:PR #713 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/713;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 6ced938a126981ee2a4fab671a2da94f49cb56c5
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-catalog-recall-eval-a3(worktree);分支:feature/catalog-recall-eval-a3
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=bf205afb1f04e503573784c93b52a991095554ed7314d9ac0f6c1996660a3211;triage_receipt=/tmp/triage-a3-1792716554.json;receipt_sha256=1a4ee8fe2133a52386520d35955d0fc600817f9a6bd94d40730eb8fce0904f44
- 授权与交付终点:用户已批准启动 A3 能力目录召回评测(方案 Functional Follow-Ups 第三项:先建脱敏评测集并产出指标基线,"是否需要检索/调模型"的决策由基线数据支撑、另行决策)。范围内连续推进:设计、agent-per-unit 实施、验证、组合、Review、PR/CI/合入。未授权:检索实现、模型/提示词调整、A2 后续、A4、部署。
- 设计决定(2026-10-22,host):
1. 评测落在 agent-intent 既有机制上(cmd/intentctl eval + testdata/corpus.json 共用格式),不新建平行体系。
2. 数据集五类覆盖(否定/引用指令、多意图、错误槽位、过期确认、生成规则一致性),全部合成脱敏、由现有 fixture 规格派生;规模 ≥30 例。
3. 指标层只记录不设质量阈值:top-1 命中率、误执行数(命中≠预期动作)、澄清率、fallback 率、生成 vs 规则一致性(离线 fake generator)。
4. 基线报告(evaluation/BASELINE.md + metrics.json)随库提交,附复跑方式;质量结论由人/后续任务基于数据做出。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:脱敏评测集(五类 ≥30 例)+ intentctl eval 指标输出(JSON 与表格)+ 基线报告;离线可复跑(fake generator,无真实模型调用)。
**非目标**:检索/召回增强实现;提示词或模型调整;真实用户数据;控制台;A2 后续/A4。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 6ced938a126981ee2a4fab671a2da94f49cb56c5 | 6ced938a126981ee2a4fab671a2da94f49cb56c5 | 2026-10-23T00:51:18Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- 实施收据:a3-recall-eval-dataset(cursor attempt1,五类语料+指标+基线报告,intent 6aa4925,verify-a3 exit=0);gitlink 集成(native d1f72aa/squad a5afe9c/backend 8dc91c1 含嵌套 intent/native 级联,a3git5/a3git10-run.json)。
- 组合验证:全量 make test PASS(verify-a3-combo3.json exit=0)。
- Review 记录:独立 CLI 评审单元 a3-independent-review(收据 /tmp/agent-stack-b2/reviewa3-run.json);结论 APPROVE;报告 .task/reviews/2026-10-22-a3-recall-eval-independent-review.md;被审对象 35524f3d 组合 vs main
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:50:13.586423+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"after_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"branch": "main",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=6ced938a12",
"[remote] origin/main=6ced938a12 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=8",
"[recycle] merged un-recycled branches: feature/exec-recovery-diagnostics-a2 fix/rdm-pin-advance-latest-2",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 6ced938a12(完整:6ced938a126981ee2a4fab671a2da94f49cb56c5)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "9f6b7e8979503847e2ec5623a17ee9624cbafd5450149556482244a86abe9192",
"receipt_sha256": "1cf2c62aea8ef98b5d211cb94c053174407c70aeab274681c1b77db0a2878db9",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1cf2c62aea8ef98b5d211cb94c053174407c70aeab274681c1b77db0a2878db9.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #713(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/713)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,167 @@
# feature/exec-recovery-diagnostics-a2 任务卡
任务主记录:PR #704 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/704;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= c92443280ef8e9ed29bf5bf5250df650c01b4478
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-exec-recovery-diagnostics-a2(worktree);分支:feature/exec-recovery-diagnostics-a2
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=34e72676959d0e970f1a3cb0e90ac2067dfb31f3c2e7a6650b5de9f3f77923c7;triage_receipt=/tmp/triage-a2-1792672248.json;receipt_sha256=7924fdbaeba41d98994c2e11bc96026d4db3cdbd0b28a9d1e381400eae9a6de4
- 授权与交付终点:用户已批准启动 A2 执行与恢复诊断(方案 Functional Follow-Ups 第二项)。范围内连续推进:设计、agent-per-unit 实施、验证、组合、Review、PR/CI/合入。未授权:控制台/前端界面、A3/A4、部署。
- 设计决定(2026-10-22,host):
1. 只读诊断 API:GET /api/runs/{id}/diagnostics(owner/project 授权,复用既有 run 鉴权),响应聚合:状态、当前责任方与等待原因(running / waiting_hitl / confirmation_pending / recovery_hold(原因+created_at) / reconciling / failed+reason / completed)、最后稳定 checkpoint(如可得)、已知副作用与关联 operation 记录(复用 cmdbus 审计信封查询)、下一步动作建议(确认卡片 / 解除 hold / 可安全重试 / 需人工核对 / 无)。
2. 纯读聚合,不改任何执行/恢复行为;复用既有 store 方法(GetRun/RecoveryHold/ListInterruptedSubagentRuns/审计查询)与 U7b 的 operation 查询。
3. 不建控制台、不加写接口;批量列表走既有会话 run 列表。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:单只读端点聚合"卡在哪里/谁在等/为何等/最后 checkpoint/已知副作用/下一步",覆盖 HITL 等待、确认等待、恢复 hold(批二 needs-reconciliation)、失败原因等全部可诊断状态。
**非目标**:控制台/UI;任何写操作或状态变更端点;A3/A4; squad sqlite 协作层的跨库聚合(只读后端 store 与审计)。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | c92443280ef8e9ed29bf5bf5250df650c01b4478 | c92443280ef8e9ed29bf5bf5250df650c01b4478 | 2026-10-22T12:37:28Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- 实施收据:a2-diagnostics-api(pi attempt1,rundiag 聚合 + GET /api/runs/{id}/diagnostics,backend 06b0c9f,verify-a2b exit=0);架构基线边登记(repair,a2arch-run.json);backend pin 集成(a2git2-run.json,cursor 配额间歇故障重试一次后成功)。
- 组合验证:全量 make test PASS(verify-a2-combo2.json exit=0,本轮 svc 既有 flake 未复现)。
- Review 记录:独立 CLI 评审单元 a2-independent-review(第 2 次派发 success;首轮 pi-glm 终态记录不可解码,现场保留);结论 APPROVE(0 blocker / 0 major);报告 .task/reviews/2026-10-22-a2-diagnostics-independent-review.md;被审对象合并基线 vs main
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T12:30:58.698213+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "c92443280ef8e9ed29bf5bf5250df650c01b4478",
"after_head": "c92443280ef8e9ed29bf5bf5250df650c01b4478",
"branch": "fix/gitea-address-migration",
"target_branch": "main",
"target_head": "c92443280ef8e9ed29bf5bf5250df650c01b4478",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=fix/gitea-address-migration head=c92443280e",
"[remote] origin/main=c92443280e ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: fix/gitea-endpoint-facts",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] c92443280e(完整:c92443280ef8e9ed29bf5bf5250df650c01b4478)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "d670ed210b367c72f877fb63bbbeb5b28411e95cb56fab782f27172fa481ed89",
"receipt_sha256": "2829e17065c329449fac8ef2690d50babf82015a1f546dcbfd3f27f67789dd0c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/2829e17065c329449fac8ef2690d50babf82015a1f546dcbfd3f27f67789dd0c.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #704(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/704)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,168 @@
# feature/intent-multi-turn-a1 任务卡
任务主记录:PR #700 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/700;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 955a32de2bb49171348bad5f566cce935df19212
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-intent-multi-turn-a1(worktree);分支:feature/intent-multi-turn-a1
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=5dd60900f5e7d69e382c367bfde373c087528dd9dcae7e16199c956ef4f3d9bf;triage_receipt=/tmp/triage-a1-1792658810.json;receipt_sha256=35b32668d143e39f386f069ae4c0004cae9761125d95241bb66e6aff1530d24b
- 授权与交付终点:用户已批准启动 A1 多轮意图闭环(方案 Functional Follow-Ups 第一项)。范围内连续推进:设计、agent-per-unit 实施、验证、组合、Review、PR/CI/合入。未授权:A2-A4、A2A、部署/发布、其余业务动作族扩展。
- 设计决定(2026-10-22,host):
1. 第一类真实业务动作 = **运行取消**("取消刚才的任务"):cancel 命令已注册且为高后果动作,走既有 cmdbus 确认卡;后续动作族另行增量。
2. 会话状态存 Backend 既有 store(新表 intent_session,键 owner+project+conversation),保存挂起预期(action ref/revision/缺失槽位/已累积槽位)与过期时间(30 分钟 TTL);revision 递增防过期回答污染新任务。
3. 库层不动 Stage 1 语义:Backend 实现 ExpectationProvider 数据源并在 intentgate/route 消费 set_slot/change_slot/cancel/expectation 命令(route.go 现按"宿主不消费"转 turn——本任务改变这一点)。
4. 高危动作仍必须经 cmdbus 确认;会话只是槽位与预期的载体,不授予执行权。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:多轮对话中:缺槽动作 → 澄清 → 用户回答补槽 → 动作完成(第一类=运行取消);"取消刚才的任务"作用于明确对象;歧义先澄清;过期回答(TTL 外)不影响新任务;双用户隔离;revision 防串轮。拆两个单元:U-A1b 会话状态与命令消费(intentgate/route/server + store 表);U-A1c 取消意图路由到 cmdbus(确认卡 + 明确对象解析)。
**非目标**:A2-A4;A2A;更多业务动作族;前端界面改动;部署。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 955a32de2bb49171348bad5f566cce935df19212 | 955a32de2bb49171348bad5f566cce935df19212 | 2026-10-22T08:48:01Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- 实施收据:U-A1b(pi attempt1,intent-session 会话/命令消费,backend 0fb64c4,verify-a1b exit=0);U-A1c(pi attempt1,cancel 经 cmdbus 路由,backend c2e3104→verify-a1c exit=0);架构基线边登记(repair,a1arch4-run.json)与 storage-migrate manifest 补齐(repair,backend 9ee752c,verify-a1sr exit=0)。
- 组合验证:test-governance 存在 svc 环境不稳定失败(两次运行分别挂在 test_addr_change / test_U2_health;addr_change 已在干净 main 复现,见批二后验证),其余全部目标 PASS(verify-a1-rest.json exit=0);CI 环境为最终裁决(批二同代码 CI 全绿)。
- Review 记录:待执行(独立 CLI 评审,随 PR 流程)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T08:46:59.325275+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "955a32de2bb49171348bad5f566cce935df19212",
"after_head": "955a32de2bb49171348bad5f566cce935df19212",
"branch": "main",
"target_branch": "main",
"target_head": "955a32de2bb49171348bad5f566cce935df19212",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=955a32de2b",
"[remote] origin/main=955a32de2b ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=4",
"[recycle] merged un-recycled branches: feature/container-storage-plan",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 955a32de2b(完整:955a32de2bb49171348bad5f566cce935df19212)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "f06e6cc8ddb0c414c2ac92e5100dc58b0b926a2bf7196273056b01be80253217",
"receipt_sha256": "32899ef2b4ebee5bf1725fb79e1bba0382177731155cebab04178821e6da3f1b",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/32899ef2b4ebee5bf1725fb79e1bba0382177731155cebab04178821e6da3f1b.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #700(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/700)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -1,108 +0,0 @@
# feature/rdm-two-trees-followup-c-w8-w10 任务卡
任务主记录:PR #693 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/693;状态:已完成(合入前闭合);owner:weichen(W8a+W8b+W9+W10 全部交付;独立 Review 完成且 MAJOR 全修复;MINOR 留档评审报告;下一步阶段 6 评审包→用户人审);owner:weichen
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= f23f5bb01a8b96ab90686d3a1b07791d7f473de2
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-followup-c-w8-w10(worktree);分支:feature/rdm-two-trees-followup-c-w8-w10
- 分支类型:child;initiative_id:feature-rdm-two-trees-followup;root_target:main;immediate_target:feature/rdm-two-trees-followup;accepting_requirements:false;parent_branch:feature/rdm-two-trees-followup;parent_head_sha:dcca5112923790506e0728a89ae3752349405653;parent_pr:无;parent_source:origin
- 需求分流:verdict=JOIN;selected_initiative=feature/rdm-two-trees-followup;requirement_sha256=f4a1ab636c59ce3df302201310d359eac88b105e8ffecd86da8f7266bf3fa58e;triage_receipt=/tmp/triage-incC.json;receipt_sha256=3fb1f7cb6dd41fc250c764d08dd612749f150f3e619b54cbc3a9144b37a4d298
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| w8a-operation-audit-core | W8 领域核:操作审计事实/同事务写入/失败尝试/幂等回执/延迟补全/重放一致 | implementation | cursor | 1 | cursor(auto) | completed | 6fd0478(refs/agent-exec/…,收据 ~/.cache/agent-system-dev/agent-exec-receipts/w8a-operation-audit-core.json) | never | ~/.cache/agent-system-dev/agent-exec-receipts/w8a-operation-audit-core.json |
| w8a-operation-audit-core | W8 领域核(attempt 1 详见 ~/.cache/…/w8a-operation-audit-core.json;transport 6fd0478) | implementation | cursor | 1 | cursor(auto) | completed | 6fd0478 | never | ~/.cache/agent-system-dev/agent-exec-receipts/w8a-operation-audit-core.json |
| w8b-audit-projection | W8 可读投影:DTO 词典/游标分页/可见性接线/rdm.audit.operations(attempt 1 infra 重试) | implementation | cursor | 2 | cursor(auto) | completed | c3d3111 | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w8b-audit-projection.json |
| w9-rdm-audit-adapter | W9 RDM 消费端:audit.read 回调适配 Backend X2(受信裁剪/当时名称/owner 分离/拒绝事实)+ pin 前进 92a41183(worker 自纠 41 位笔误:按前缀 fetch 真 tip) | implementation | cursor | 1 | cursor(auto) | completed | c4c6df7 | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w9-rdm-audit-adapter.json |
| w10-audit-workspace | W10 正式 Frontend:审计工作台/树懒加载/工作卡/依据条/四态/seq(FE 子分支 feature/rdm-two-trees-followup-w10 @fa08be4;知识多挂载显示留 TODO 待 RDM DTO 增补) | implementation | cursor | 2(attempt1 合理扩围重派) | cursor(auto) | completed | fa08be4 | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w10-audit-workspace.json |
| rev-increment-c-rdm | RDM 增量 C 独立评审(0 BLOCKING/5 MAJOR/15 MINOR;报告 docs/reviews/2026-10-22-increment-c-rdm-review.md @b7b5227) | review | pi | 1 | pi(default) | completed | b7b5227 | never | ~/.cache/agent-system-dev/agent-exec-receipts/rev-c-rdm-receipt.json |
| fix-increment-c-rdm-majors | RDM 5 MAJOR 修复(schema-2 目录/copyState/生产写接线等,含回归测试) | repair | cursor | 1 | cursor(auto) | completed | d835ae6 | never | ~/.cache/agent-system-dev/agent-exec-receipts/fix-increment-c-rdm.json |
| rev-increment-c-fe | FE W10 独立评审(0 BLOCKING/3 MAJOR/MINOR;报告 docs/reviews/2026-10-22-increment-c-fe-review.md @a61eaac) | review | pi | 1 | pi(default) | completed | a61eaac | never | ~/.cache/agent-system-dev/agent-exec-receipts/rev-c-fe-receipt.json |
| fix-increment-c-fe-majors | FE 3 MAJOR 修复(openInbox 定位/能力门禁/@ui Collapsible,+6 回归测试) | repair | cursor | 1 | cursor(auto) | completed | 4882e0a | never | ~/.cache/agent-system-dev/agent-exec-receipts/fix-increment-c-fe.json |
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | f23f5bb01a8b96ab90686d3a1b07791d7f473de2 | dcca5112923790506e0728a89ae3752349405653 | 2026-10-22T01:24:37Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T01:23:50.112388+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "f23f5bb01a8b96ab90686d3a1b07791d7f473de2",
"after_head": "f23f5bb01a8b96ab90686d3a1b07791d7f473de2",
"branch": "main",
"target_branch": "main",
"target_head": "f23f5bb01a8b96ab90686d3a1b07791d7f473de2",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=f23f5bb01a",
"[remote] origin/main=f23f5bb01a ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=5",
"[recycle] merged un-recycled branches: fix/ci-rdm-pin-materialization fix/pal-component-delivery-pins",
"[cards] 已合入未闭合任务卡:fix-pal-component-delivery-pins.md——make task-close 回填归档(主检出运行)",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] f23f5bb01a(完整:f23f5bb01a8b96ab90686d3a1b07791d7f473de2)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "013e1d4d93548576815e9e2fe8e735d049fea47507ef4492478b55e4cf3c7cd6",
"receipt_sha256": "643c76ed799ad8ca4ea16ba47a3510694218cdc18e387586ed9e36d6f9c44502",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/643c76ed799ad8ca4ea16ba47a3510694218cdc18e387586ed9e36d6f9c44502.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #693(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/693)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -1,101 +0,0 @@
# feature/rdm-two-trees-followup-w3-rest 任务卡
任务主记录:PR #641 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/641;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 2b7fdc39a1f44163f4766701429d61ffd6926f1a
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-followup-w3-rest(worktree);分支:feature/rdm-two-trees-followup-w3-rest
- 分支类型:child;initiative_id:feature-rdm-two-trees-followup;root_target:main;immediate_target:feature/rdm-two-trees-followup;accepting_requirements:false;parent_branch:feature/rdm-two-trees-followup;parent_head_sha:9e6d9690f64a1e970211b3a092084862a2174ad3;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/rdm-two-trees-followup-w3-rest;parent_head_sha=9e6d9690f64a1e970211b3a092084862a2174ad3)
- 授权与交付终点:用户 2026-10-19“授权启动 W3”;终点为 RDM 草稿 PR + 本子任务 PR CI 通过 + 阶段 6 评审包,等待用户阶段 6 人审后才合入父 initiative 分支。未授权:运行库迁移、部署、真实模型/付费请求。用户 2026-10-20 阶段 6 结论“通过”,同时授权 RDM #451 合入 RDM main(附条件:W4 开放结构写入口前必须先补节点种类放置检查)。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
- 目标:补齐 A1 差距核对中的 W3 余项——图形不透明块、重复表格精确覆盖、节点移动/改名保持引用、旧库备份迁移两次同值、已批准版与旧下载可回取;Dev 侧删除无效 `SVC_RCFWEB_ADDR`。
- 受影响:RDM `internal/domain`(模板块校验、递归节点、两种新事件)及测试;Dev `tests/test_svc_realcombo.py`。
- 非目标:不提供结构变更的 HTTP/插件入口(W4 负责结构提案门控);不改 DHF 渲染;不宣称正式 DHF 模板可用。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 2b7fdc39a1f44163f4766701429d61ffd6926f1a | 9e6d9690f64a1e970211b3a092084862a2174ad3 | 2026-10-19T16:15:03Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:W3 余项在 RDM 分支 `feature/rdm-two-trees-followup-w3-rest`(`013b8b1`、`96d53f6`、`f3fa0c0`,草稿 PR [#451](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/451))与本分支 `80ac3fa` 交付;阶段 6 评审包 docs/superpowers/specs/2026-10-19-rdm-two-trees-followup-w3-review.md。
- 验证:RDM 目标测试 20 项与 `./internal/domain/... ./internal/rdmapp` 全量 PASS(SELF,@f3fa0c0);CI(GATE)见下方 CI 记录;Dev `py_compile` PASS(SELF)。
- 影响与剩余项:仅 RDM 领域原语与测试(无新写入口)及 Dev 测试一行;剩余见评审包第 3 节与 Review 非阻塞项(W4 写入口前补节点放置检查)。
## 合入与清理
- Review 记录:全新会话 code-reviewer(只接收需求、base/head、diff),RDM `5a27d78..f3fa0c0`:PASS-with-fixes,无阻塞项;4 条非阻塞项记入评审包第 2 节(放置检查列为 W4 写入口前置条件)。
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录(RDM):用户 2026-10-20 阶段 6 通过并授权;RDM PR [#451](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/451) 核验 HEAD `f3fa0c0e5`、commit status success(2 项,GATE)后合入 RDM main,合入提交 `76b4c0572622c81316511de174469f5f67d31785`;合入后 tree `4cfacf16` 与合入前 `git merge-tree` 预期一致。Dev gitlink 改钉留待 initiative 收口统一组合验证。
- 合入记录(本 PR):NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:RDM worktree `Agent-System-RDM-wt-feature-rdm-two-trees-followup-w3-rest` 已核验无写者、子模块干净(仅删除可再生的 `internal/rdmapp/data` 测试产物)后移除,本地分支已删;Dev 子 worktree 待本 PR 合入后回收。
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T16:13:50.819321+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"after_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"branch": "main",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=2b7fdc39a1",
"[remote] origin/main=2b7fdc39a1 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=4",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 2b7fdc39a1(完整:2b7fdc39a1f44163f4766701429d61ffd6926f1a)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "ad2f421c16acf4d72ad5396eb19b97aa168900e85db78022bd77c6eac29b3040",
"receipt_sha256": "abc4088cf722985bd2eeeffeae46cdd899a23e6b1c2711b8849f14f83c8e46bf",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/abc4088cf722985bd2eeeffeae46cdd899a23e6b1c2711b8849f14f83c8e46bf.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #641(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/641)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -1,124 +0,0 @@
# feature/rdm-two-trees-followup-w5-w7 任务卡
任务主记录:PR #666 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/666;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ed3847c85ce111a74f0cb100908abfb40f62db07
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-followup-w5-w7(worktree);分支:feature/rdm-two-trees-followup-w5-w7
- 分支类型:child;initiative_id:feature-rdm-two-trees-followup;root_target:main;immediate_target:feature/rdm-two-trees-followup;accepting_requirements:false;parent_branch:feature/rdm-two-trees-followup;parent_head_sha:13b9c9daddfb78717438777e955dd296ca56439d;parent_pr:无;parent_source:origin
- 需求分流:verdict=JOIN;selected_initiative=feature/rdm-two-trees-followup;requirement_sha256=343b26bddcfc64e013a068fc4f294a28f94c28702c08bafa0f6d92262289e90b;triage_receipt=/tmp/triage-w5w7.json;receipt_sha256=c3948ecfa318defbdd96b5d465665abef97abfcc90472a0a1d216af4dc9ae0dc
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| w5a-tracenet-domain-core | internal/domain 追溯网领域核心(revision锁定/候选确认/升版待复核/传递影响+水位/快照/重放) | implementation | cursor | 1 | cursor(auto) | completed | a7a6df0(refs/agent-exec/2533912c/0c0654db) | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w5a-tracenet-domain-core.json |
| w5b-trace-impact-endpoints | rdmapp 影响分析/重算/快照读取/覆盖缺项/pending-recheck 命令面(impact.go + plugin 注册) | implementation | cursor | 1 | cursor(auto) | completed | 2e5fcb7(refs/agent-exec/d98a00bc/23b5e5d0) | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w5b-trace-impact-endpoints.json |
| w7a-project-context-domain | W7 纯领域部分:ProjectContextBundle 组装/失效语义/渐进证据引用(零基座消费,tag 前约束达成) | implementation | cursor | 1 | cursor(auto) | completed | 8327603(refs/agent-exec/a3eba579/153246be) | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w7a-project-context-domain.json |
| w6-x1-recheck-completion | W6 恢复:用户批准修订后,对照清单审计并补齐——消费点全覆盖/入模门禁/存储边界/负例矩阵(Backend 隔离分支,含候选合并 main b4399e3) | implementation | cursor | 1 | cursor(auto) | completed | 8c410b9(refs/agent-exec/412eff9b/0636a7e1) | never | /home/weichen/.cache/agent-system-dev/agent-exec-receipts/w6-x1-recheck-completion.json |
| rev-increment-b-rdm | RDM 增量独立评审(0 BLOCKING/6 MAJOR/14 MINOR) | review | pi | 1 | pi(default) | completed | 56b23a0 | never | ~/.cache/agent-system-dev/agent-exec-receipts/rev-rdm-receipt.json |
| w5-majors-repair | 评审 MAJOR M1–M6 修复(copyState/快照ID/端点校验/生产写入/空分析/别名) | repair | cursor | 1 | cursor(auto) | completed | 04991ed | never | ~/.cache/agent-system-dev/agent-exec-receipts/w5-fix-receipt.json |
| rev-w6-x1-recheck | Backend W6 独立评审(7/7 PASS,0 BLOCKING 0 MAJOR/6 MINOR) | review | pi | 1 | pi(default) | completed | 65122b8 | never | ~/.cache/agent-system-dev/agent-exec-receipts/rev-be-receipt.json |
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | ed3847c85ce111a74f0cb100908abfb40f62db07 | 13b9c9daddfb78717438777e955dd296ca56439d | 2026-10-20T14:48:00Z |
| W5a 后(RDM 侧) | ed3a0f9(RDM main) | a7a6df0(RDM 子分支) | 2026-10-20 | SELF:gofmt/vet ok,domain+rdmapp 全部 ok(81.9s) |
| W5b 后(RDM 侧) | a7a6df0 | 2e5fcb7 | 2026-10-20 | SELF:vet ok;rdmapp(81.2s)+plugins/rdm(3.3s) 全部 ok;gofmt 仅既有 iam_integration_test.go 告警(未触碰) |
| W7a 后(RDM 侧) | 2e5fcb7 | 8327603 | 2026-10-20 | SELF:vet ok;rdmapp 全部 ok(91.5s);grep 证实零 pkg/extension 消费 |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-20T14:46:07.178211+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "ed3847c85ce111a74f0cb100908abfb40f62db07",
"after_head": "ed3847c85ce111a74f0cb100908abfb40f62db07",
"branch": "main",
"target_branch": "main",
"target_head": "ed3847c85ce111a74f0cb100908abfb40f62db07",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=ed3847c85c",
"[remote] origin/main=ed3847c85c ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=5",
"[recycle] merged un-recycled branches: feature/fast-slow-o2-a01-checkpoint-design",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] ed3847c85c(完整:ed3847c85ce111a74f0cb100908abfb40f62db07)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "f03caadb3c0597418604c953038e5658758c9546150ca3d711e853ebc0c24a8c",
"receipt_sha256": "657414206727892ce0ed5ce0ee067e220e11e9da50b3b1fae1bd9db4bc530a6e",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/657414206727892ce0ed5ce0ee067e220e11e9da50b3b1fae1bd9db4bc530a6e.json"
}
```
## 阶段 6 结论(2026-10-20)
用户结论「通过」。裁定明细:W5/W6/W7a 交付通过;X1 公开 tag 暂未发布(W7 provider 接线保持门禁,双钥匙另行动作);RDM 评审 MINOR 14 条按包建议列为增量 C 顺手项。合入执行:RDM PR #458 已核 CI(build-and-test+governance success @22b4fb0)后合入 RDM main(93badd7e);Backend PR #231 已核 CI(vet-and-test+governance success @5a4edf3,draft 转正式后)合入 backend main(7a41f22e)。
## 阶段 6 评审包(2026-10-20)
评审包:`docs/superpowers/specs/2026-10-20-rdm-two-trees-followup-w5-w7-review.md`。独立 Review 全部完成(RDM 0 BLOCKING、6 MAJOR 已修复;Backend 7/7 PASS、0 BLOCKING 0 MAJOR),增量 B 达到用户人审就绪点。
## W6 恢复记录(2026-10-20)
用户批准修订(「按已实际纳入来源逐项重新授权」X1 合同 + 去原文迁移边界)。恢复动作:候选 6ba53e4 建分支 feature/w6-x1-source-recheck,合并最新 main(自动合并无冲突,b4399e3),既有多数项已在候选实现(含此前 RED 的无正文测试已绿);派发 w6-x1-recheck-completion 单元补齐消费点/门禁/负例(7 文件,transport 8c410b9),SELF 全绿(build/vet/store/runmgr/workflow/extension)。X1 公开 tag 发布仍为用户双钥匙。
## W6 门禁记录(2026-10-20)
W6 按设计修订文档 `rdm-two-trees-stage6-w6-source-recheck-design-adjustment-r1.md`(状态:**待人工评审**)暂停实现:候选分支 HEAD 6ba53e4(未推送)已有部分实现但含隐私敏感的存储/迁移取舍,须经用户批准该修订后方可继续。本单元按计划 W7 但书仅交付「纯领域摘要与测试」,未消费基座接口,不宣布自动注入完成。
## 闭合记录(合入前折叠)
- 本卡在 PR #666(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/666)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,168 @@
# feature/recall-misexec-fixes 任务卡
任务主记录:PR #717 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/717;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= bccb88f294038ce52a37fc5592a6daebd10e88b4
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-recall-misexec-fixes(worktree);分支:feature/recall-misexec-fixes
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=5510782fe6debd449a832c3353d191c6efb76f50c77932c5adf387a2f0a27bcd;triage_receipt=/tmp/triage-misexec-1792727028.json;receipt_sha256=914545afa88ab6ce4cbe9bd48240e8a8b2f829c970d245c24fb1a7c0d8ca495c
- 授权与交付终点:用户已批准启动 A3 基线驱动的规则层修复(评测集暴露的 6 次误执行:语义否定被当作肯定 ×5、多意图平分误选寒暄 ×1;另有错误槽位未澄清 3 例)。范围内连续推进至合入;检索/调模型决策留待修复后基线。未授权:A4、部署。
- 设计决定(2026-10-22,host):
1. 否定修复放 compiledSpec.evaluate 匹配层:正命中若被前置否定词(不要/别/不用/先不要/先别/无需/不需要,紧邻或间隔≤2字)限定,且该 spec 的全部正命中均被否定 → reject "negated_match"(确定性,不逐 spec 配置)。
2. 平分裁决加确定性 tie-break:优先级相同 → 已抽取到槽位值多者优先(带槽位信号的动作胜过裸寒暄)→ id 字典序。不引入新配置。
3. 槽位抽取修正:抽取跨度内含多值分隔(和/还是/、/,)→ 视为多候选无效(clarify);规范化后仅剩符号/空 → 无效;字符集违规(如声明字母数字却抽出 abc_def 的部分截取)→ 无效。无效一律走 clarify,不 start。
4. 验收即评测集:上述用例从 record_only FAIL 翻为 PASS;overall mis_exec 须为 0;gen_agree 与其余类别不回退。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:消除评测集 6 次误执行 + 3 例错误槽位未澄清:匹配层否定感知、裁决 specificity tie-break、槽位多值/字符集无效化;评测指标 mis_exec 归零且其余类别不回退;既有测试全绿。
**非目标**:检索/召回增强;模型/提示词调整;「刚才那个」跨会话指代解析(A1 会话域);真实语料;gen_agree 的 3 例生成器分歧(回放器行为,另行处理)。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | bccb88f294038ce52a37fc5592a6daebd10e88b4 | bccb88f294038ce52a37fc5592a6daebd10e88b4 | 2026-10-23T03:45:01Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- 实施收据:misexec-rules-fix(cursor attempt1,否定感知匹配+specificity tie-break+槽位 fail-closed,intent 7f3ff6a,eval mis_exec=0/37 全过,verify-misexec2 exit=0);pin 级联嵌套提升(host 提交 N4/S4/B4')与 Dev 集成(misexec-git3-run.json)。
- 组合验证:全量 make test PASS(verify-misexec-combo2.json exit=0)。
- Review 记录:独立 CLI 评审单元 misexec-independent-review(收据 /tmp/agent-stack-b2/reviewm-run.json);结论 APPROVE;报告 .task/reviews/2026-10-22-misexec-fixes-independent-review.md;被审对象 8e3f9edb 组合 vs main
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T03:44:02.622816+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "bccb88f294038ce52a37fc5592a6daebd10e88b4",
"after_head": "bccb88f294038ce52a37fc5592a6daebd10e88b4",
"branch": "main",
"target_branch": "main",
"target_head": "bccb88f294038ce52a37fc5592a6daebd10e88b4",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=bccb88f294",
"[remote] origin/main=bccb88f294 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/exec-recovery-diagnostics-a2 fix/gitea-endpoint-facts",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] bccb88f294(完整:bccb88f294038ce52a37fc5592a6daebd10e88b4)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "6a6f70969d0b85288dde21bf2011b0485af1251a29fbb677ba7d7d9e94c79785",
"receipt_sha256": "b5fc6e81a92e8ecb97bbf51630a10608507425dfe27220efb75341b4f607bffd",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/b5fc6e81a92e8ecb97bbf51630a10608507425dfe27220efb75341b4f607bffd.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #717(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/717)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,300 @@
# feature/scratch-session-general-agent 任务卡
任务主记录:PR #691 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/691;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= a4311c6341c318d4bbf1563b3973358326086794
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent(worktree);分支:feature/scratch-session-general-agent
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=617539e611dec18b73e0f60c7581ac55246864a96411c38c56fb31dcf561d276;triage_receipt=/tmp/scratch-triage.json;receipt_sha256=1d6484b995d8c51764e91dfeb6ae605e2e3f5ccbf19e07c016f58abe5502d953
- 授权与交付终点:按已批准设计实现无项目对话(scratch);Backend/Frontend/Dev pin 经 PR 合入;未授权:改写历史、分支保护、发布版本、配额/升级成真项目
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
- 目标:所有启用账号可创建彼此隔离的 scratch 会话;侧栏「无项目对话」;固有能力不可配置;拒绝知识树/文档树等项目专属能力。
- 非目标:升级成真项目、协作分享、配额/TTL、nullable project_id。
- 规格:docs/superpowers/specs/2026-10-22-scratch-session-general-agent-design.md
- 计划:docs/superpowers/plans/2026-10-22-scratch-session-general-agent-plan.md
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| backend-scratch-session-create-u1 | Backend internal/store/{scratch,projects}.go、internal/server/{server,project_lifecycle,scratch_session}.go + tests | Backend AGENT-EXECUTION.md digest 22fcb8ac | implementation | 按配置 | 1(fresh_session) | pi MiniMax-M3 | success | apply 16538f1..096e96e → 规范提交 3b4a7af(tree 不变) | never | /tmp/scratch-session-20261022/u1-run.json |
| backend-scratch-session-gates-u2 | Backend store/server/runmgr/app 门禁 + tests | 同上 | implementation | 按配置 | 1(fresh_session) | pi MiniMax-M3 | success | apply 3b4a7af..7bd3e51 → 规范提交 613c068(tree 不变) | never | /tmp/scratch-session-20261022/u2-run.json |
| frontend-scratch-session-sidebar-u3 | Frontend src/{contracts,api,store}.ts、TaskSidebar.tsx、tests | Frontend AGENT-EXECUTION.md | implementation | 按配置 | 1 | cursor | failed-unknown(CLI HTTP/2 keepalive 超时);对账:仅只读命令与 npm ci 下载、隔离区零跟踪改动 → 全新重派 | 无 | never | /tmp/scratch-session-20261022/u3-run.json |
| 同上(重派 2) | 同上 | 同上 | implementation | 按配置 | 1 | cursor | failed-unknown(无有效终态记录;worker 报 src/store.test.ts 旧规则测试在范围外);对账:改动仅在隔离区;扩围 src/store.test.ts(已批准设计内的旧规则测试)→ 单元 u3b | 无 | never | /tmp/scratch-session-20261022/u3-run2.json |
| frontend-scratch-session-sidebar-u3b | 同上 + src/store.test.ts | 同上 | implementation | 按配置 | 1 | cursor | failed-unknown(CLI Connection stalled,验证已通过、终态前断线);对账:只读/npm ci/vitest/tsc、/tmp 临时配置已删 → 全新重派 | 无 | never | /tmp/scratch-session-20261022/u3-run3.json |
| backend-scratch-flag-u2b | Backend server 会话响应 scratch 标记 + store.ScratchProjectIDs + tests | Backend AGENT-EXECUTION.md | implementation | 按配置 | 1(fresh_session) | pi | success | apply → 规范提交 f3f70a7(tree 不变) | never | /tmp/scratch-session-20261022/u2b-run.json |
| 同上 u3b(重派 4) | 同上 | 同上 | implementation | 按配置 | 1 | cursor | failed-unknown(最终消息含两份有效终态记录:后台 npm ci 完成通知后重复输出);对账:改动仅在隔离区,外部仅 npm ci 下载 → 单元 u3c 增加“前台执行、仅一份终态记录”约束后全新重派 | 无 | never | /tmp/scratch-session-20261022/u3-run4.json |
| frontend-scratch-session-sidebar-u3c | 同 u3b | 同上 | implementation | 按配置 | 1(fresh_session) | cursor | success | apply 18fc958..62b7442 → 规范提交 1d7f2a3(tree 不变) | never | /tmp/scratch-session-20261022/u3-run5.json |
| backend-scratch-context-and-bus-gates-u2c | Backend ProjectContext 门禁 + Bus.SetHostProjectGuard + scratch fail-closed + tests | Backend AGENT-EXECUTION.md | implementation | 按配置 | 1(fresh_session) | pi | success | apply → 规范提交 2fc6e7e(tree 不变) | never | /tmp/scratch-session-20261022/u2c-run.json |
| backend-scratch-failclosed-both-ways-u2d | Backend confirmedScratchProject 双向 fail-closed + tests | 同上 | implementation | 按配置 | 1(fresh_session) | pi | success | apply → 规范提交 b704ba9(tree 不变) | never | /tmp/scratch-session-20261022/u2d-run.json |
| frontend-scratch-hide-project-surfaces-u3d | Frontend Conversation/Workbench/ConversationWork 隐藏项目专属面 | Frontend AGENT-EXECUTION.md | implementation | 按配置 | 1 | cursor | scope-expansion(UI ActivityCardView 必须检查 callbacks.onArchive);人工授权扩围到 UI 仓 | 无 | never | /tmp/scratch-session-20261022/u3d-run.json |
| frontend-scratch-hide-project-surfaces-u3e | 同 u3d(UI 侧另单元处理;本单元只断言回调) | 同上 | implementation | 按配置 | 1(fresh_session) | cursor | success | apply → 规范提交 b02ff83(tree 不变) | never | /tmp/scratch-session-20261022/u3e-run.json |
| ui-activity-card-archive-optional-u5 | UI ActivityCardView 仅在有 onArchive 时渲染留档按钮 + tests | UI AGENT-EXECUTION.md | implementation | 按配置 | 1(fresh_session) | cursor | success | apply → 规范提交 db5129c(tree 不变) | never | /tmp/scratch-session-20261022/u5-run.json |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | a4311c6341c318d4bbf1563b3973358326086794 | a4311c6341c318d4bbf1563b3973358326086794 | 2026-10-22T01:43:32Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T01:41:26.489856+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "a4311c6341c318d4bbf1563b3973358326086794",
"after_head": "a4311c6341c318d4bbf1563b3973358326086794",
"branch": "main",
"target_branch": "main",
"target_head": "a4311c6341c318d4bbf1563b3973358326086794",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=a4311c6341",
"[remote] origin/main=a4311c6341 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=6",
"[recycle] merged un-recycled branches: feature/card-close-20261022-012859Z fix/ci-rdm-pin-materialization fix/pal-component-delivery-pins",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] a4311c6341(完整:a4311c6341c318d4bbf1563b3973358326086794)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "5dc418ef2935ca343c4d18b9a8b9408c31d0870061bf48a0cd20d1efeb574159",
"receipt_sha256": "59b8a99e07c11121e009221f6700874c9650c4f057f494394d05d5e47eec3f95",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/59b8a99e07c11121e009221f6700874c9650c4f057f494394d05d5e47eec3f95.json"
}
```
| 同步(记录前对象) | 1de7c28c2122609dd9b6435881696492bd052a34 | 635459316dbd4e4a5134f4e409bed72a5dd02730 | 2026-10-22T05:18:42Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T05:18:47.691228+00:00",
"command": "make test",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent",
"before_head": "36a1d4084e8bb7aaea6f04e29fb4d3492f4f0db3",
"after_head": "36a1d4084e8bb7aaea6f04e29fb4d3492f4f0db3",
"branch": "feature/scratch-session-general-agent",
"target_branch": "main",
"target_head": "1de7c28c2122609dd9b6435881696492bd052a34",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"warn: deps/agent-native deps/development-manager is bd3a7de57a3a, Dev is 2c2e37255807",
"ok deps/agent-native error-code-system",
"ok deps/agent-native logging-system",
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 2688fd2be6a5, Dev is a15db5085585",
"warn: deps/agent-squad deps/development-manager is bd3a7de57a3a, Dev is 2c2e37255807",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 2688fd2be6a5, Dev is a15db5085585",
"warn: deps/agent-intent deps/development-manager is bd3a7de57a3a, Dev is 2c2e37255807",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"make[1]: *** [Makefile:209: test-pins] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent'"
],
"output_sha256": "2d377eb17fd54185095a73449eb657b742e645e180e1d52202cdd168114fe7e7",
"receipt_sha256": "21c7a8c6a8ffc79adb81ed7e90b6c50d4f1aaaa941de12c2a4cd64e8b47e4aa8",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/21c7a8c6a8ffc79adb81ed7e90b6c50d4f1aaaa941de12c2a4cd64e8b47e4aa8.json"
}
```
| 同步(记录前对象) | b7636742fc9ea937e6030123afc608fd294861bf | 1dee480dff7203aff3bd6b57661645fe0b890bce | 2026-10-22T05:49:12Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T05:49:16.822650+00:00",
"command": "make test",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent",
"before_head": "aa77f20184ace3302480642aef5d412819792da8",
"after_head": "aa77f20184ace3302480642aef5d412819792da8",
"branch": "feature/scratch-session-general-agent",
"target_branch": "main",
"target_head": "b7636742fc9ea937e6030123afc608fd294861bf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "7a447319f8c4fdedb68da2ef8c0fc740d86697df8f8af7650980c77a56befa7b",
"output_tail": [
"added 162 packages in 945ms",
"",
" RUN v4.1.11 /home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent/modules/ui",
"",
"",
" Test Files 19 passed (19)",
" Tests 188 passed (188)",
" Start at 05:56:58",
" Duration 1.68s (transform 1.31s, setup 0ms, import 3.38s, tests 3.68s, environment 6.91s)",
"",
"knip unused exports 61 <= 61",
"cd deps/agent-command && go vet ./... && go test -count=1 ./...",
"ok \tagent-command\t0.002s",
"ok \tagent-command/conformance\t0.002s",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent'"
],
"output_sha256": "4fee33a7ba3812f667660d6c2b49348ae902983cdfebd6a5f3f13bedb4611f0b",
"receipt_sha256": "1331f3cff5d6a225efa50af64c5e1301faee72c380b995ea08b4a1a7beff79da",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1331f3cff5d6a225efa50af64c5e1301faee72c380b995ea08b4a1a7beff79da.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T06:14:22.167417+00:00",
"command": "make test",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent",
"before_head": "b672792f77f612d563720bff99a55ff5aa721242",
"after_head": "b672792f77f612d563720bff99a55ff5aa721242",
"branch": "feature/scratch-session-general-agent",
"target_branch": "main",
"target_head": "33d6ef69212595c680a744549986c19bb6acd6c3",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
" File \"/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent/tests/test_svc.py\", line 227, in svc",
" self.assertEqual(proc.returncode, 0, proc.stdout)",
" ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",
"AssertionError: 1 != 0 : \u001b[1;33m[svc]\u001b[0m [dev] 跳过 manifest 迁移:需 python3 与 scripts/svc_manifest.py",
"\u001b[1;34m[svc]\u001b[0m [dev] 无 pidfile——没有由本脚本启动的实例",
"\u001b[1;31m[svc]\u001b[0m [dev] 端口被占用(非本服务):LISTEN 0 4096 127.0.0.1:18794 0.0.0.0:* users:((\"python3\",pid=1444356,fd=3)) ",
"\u001b[1;31m[svc]\u001b[0m 处理:停掉该进程,或换端口(--port / --addr)",
"",
"",
"----------------------------------------------------------------------",
"Ran 539 tests in 373.148s",
"",
"FAILED (failures=1, skipped=18)",
"make[1]: *** [Makefile:232: test-governance] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-scratch-session-general-agent'"
],
"output_sha256": "572e274146ea0cd7b0f87865cf16c8be406ca4eda51bca7ef8469be6812ddec9",
"receipt_sha256": "d2b9cb21e0ab4dcf1d4b03bc939dd9f8bcd94faadff03b19acacad81b5465848",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/d2b9cb21e0ab4dcf1d4b03bc939dd9f8bcd94faadff03b19acacad81b5465848.json"
}
```
| 同步(记录前对象) | 33d6ef69212595c680a744549986c19bb6acd6c3 | 1970dccb7c8c11fb69ad739ae1338e97ca4ac0a6 | 2026-10-22T06:21:57Z |
## 闭合记录(合入前折叠)
- 本卡在 PR #691(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/691)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,100 @@
# fix/rdm-pin-advance-latest-2 任务卡
任务主记录:PR #711 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/711;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 6ced938a126981ee2a4fab671a2da94f49cb56c5
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-rdm-pin-advance-latest-2(worktree);分支:fix/rdm-pin-advance-latest-2
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=93558e2670e0b23a79612fed5a161be7cb54de39485d98d72f67b6541ee38a8a;triage_receipt=/tmp/pin-f2-triage.json;receipt_sha256=00841f4dfa7626161dcab13a8a598b10fdd81dcf26679b8de6d8177beaf3d655
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 6ced938a126981ee2a4fab671a2da94f49cb56c5 | 6ced938a126981ee2a4fab671a2da94f49cb56c5 | 2026-10-23T00:50:42Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:49:47.450962+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"after_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"branch": "main",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=6ced938a12",
"[remote] origin/main=6ced938a12 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/exec-recovery-diagnostics-a2",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 6ced938a12(完整:6ced938a126981ee2a4fab671a2da94f49cb56c5)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "d78ae27fdc16acddac83815947924a7eb3d6031e421381f3d9313f29f3c0fc9e",
"receipt_sha256": "aa32f1bbde2a3b12b355fedc1e5ed3b91dea43758fb2a307e93f56fd2c5ae9af",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/aa32f1bbde2a3b12b355fedc1e5ed3b91dea43758fb2a307e93f56fd2c5ae9af.json"
}
```
| 同步(记录前对象) | c3fbf85732788ba91d32c921783993a645580041 | c3fbf85732788ba91d32c921783993a645580041 | 2026-10-23T01:26:28Z |
## 闭合记录(合入前折叠)
- 本卡在 PR #711(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/711)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
| 同步(记录前对象) | e62092a4479bbe101e74e91b39e03577ce0786ae | bbd80aa38874dbac8a3188b42bc6ed977a4fb379 | 2026-10-23T02:14:09Z |
@@ -0,0 +1,98 @@
# fix/svc-test-port-governance-batch1 任务卡
任务主记录:PR #702 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/702(merge cb36b59acc);状态:已完成(回填);owner:weichen
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 3d3474a731f9ef3ee1f41935e63bca3afb70db56
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-svc-test-port-governance-batch1(worktree);分支:fix/svc-test-port-governance-batch1
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=1723e9e3e6bd50bedc041afba3533c35e8b663edb12472f29c067df860df799b;triage_receipt=/tmp/pa1-triage.json;receipt_sha256=71d236166f2a1de8cecd6eb93042ef5199a09e2c49318dbf8eb9d5b5582a99e5
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 3d3474a731f9ef3ee1f41935e63bca3afb70db56 | 3d3474a731f9ef3ee1f41935e63bca3afb70db56 | 2026-10-22T11:15:53Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T11:15:04.613824+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
"after_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
"branch": "main",
"target_branch": "main",
"target_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=3d3474a731",
"[remote] origin/main=3d3474a731 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=6",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 3d3474a731(完整:3d3474a731f9ef3ee1f41935e63bca3afb70db56)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "87e58b98732700984715adb3f7a46aeacdc3749aacf51643f68a2ad9ede2451d",
"receipt_sha256": "72f14e2080b227c1fc4094a0a4f573b0dc12fb08ed30c86400265a610fb09b0d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/72f14e2080b227c1fc4094a0a4f573b0dc12fb08ed30c86400265a610fb09b0d.json"
}
```
| 同步(记录前对象) | c92443280ef8e9ed29bf5bf5250df650c01b4478 | c22b9fb34a3702191a9e5f6007f3538520db694b | 2026-10-22T13:10:38Z |
## 闭合记录(card-autoclose 回填)
- 依据:merge cb36b59accd0418c5ca952912d7c181b83038a4c(PR #702)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
- 合并主题:Merge pull request 'Use dynamic ports across the five test files that shared hardcoded bindings' (#702) from fix/svc-test-port-governance-batch1 into main
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
@@ -0,0 +1,99 @@
# fix/svc-test-port-governance-deploy-txn 任务卡
任务主记录:PR #705 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/705(merge f673c2a15a);状态:已完成(回填);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= cb36b59accd0418c5ca952912d7c181b83038a4c
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-svc-test-port-governance-deploy-txn(worktree);分支:fix/svc-test-port-governance-deploy-txn
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=37c57479990e37eb048ba81763fe402e1e679a822679f315a4be18e4b965c333;triage_receipt=/tmp/plast-triage.json;receipt_sha256=d403df8b2564bf4e1fe16fb12ecc48cf31c25be4f7472e6b27bce6da3ecd93e0
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | cb36b59accd0418c5ca952912d7c181b83038a4c | cb36b59accd0418c5ca952912d7c181b83038a4c | 2026-10-22T13:39:45Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T13:28:41.022157+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"after_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"branch": "main",
"target_branch": "main",
"target_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=cb36b59acc",
"[remote] origin/main=cb36b59acc ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=9",
"[recycle] merged un-recycled branches: fix/gitea-address-migration fix/svc-test-port-governance-batch1",
"[cards] 已合入未闭合任务卡:fix-svc-test-port-governance-batch1.md——make task-close 回填归档(主检出运行)",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] cb36b59acc(完整:cb36b59accd0418c5ca952912d7c181b83038a4c)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "9f6260af81b0761dbb20afc5d145a9cb310303d426f655840a50f0879d81a49e",
"receipt_sha256": "eeb4f9ac9bdc0e30a0a7bbaa49176626bb8aca54a20f152b1771e1df8fd855d3",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/eeb4f9ac9bdc0e30a0a7bbaa49176626bb8aca54a20f152b1771e1df8fd855d3.json"
}
```
## 闭合记录(card-autoclose 回填)
- 依据:merge f673c2a15a50bef2c55f2c79a17d7601f82c8a07(PR #705)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
- 合并主题:Merge pull request 'Use a dynamic port in the last hardcoded test binding' (#705) from fix/svc-test-port-governance-deploy-txn into main
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
@@ -0,0 +1,99 @@
# fix/svc-test-port-governance-final 任务卡
任务主记录:PR #698 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/698;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 955a32de2bb49171348bad5f566cce935df19212
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-svc-test-port-governance-final(worktree);分支:fix/svc-test-port-governance-final
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=04cbe9df900a03163aeadb42fd22e5a86ddeced179901b50ac0f4642ce7f6881;triage_receipt=/tmp/pg3-triage.json;receipt_sha256=aca390790027841efaefe2082123780b1ec8d775f9ca0be80262a80f7121bde9
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 955a32de2bb49171348bad5f566cce935df19212 | 955a32de2bb49171348bad5f566cce935df19212 | 2026-10-22T08:55:33Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T08:54:47.013779+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "955a32de2bb49171348bad5f566cce935df19212",
"after_head": "955a32de2bb49171348bad5f566cce935df19212",
"branch": "main",
"target_branch": "main",
"target_head": "955a32de2bb49171348bad5f566cce935df19212",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=955a32de2b",
"[remote] origin/main=955a32de2b ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=5",
"[recycle] merged un-recycled branches: feature/container-storage-plan",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 955a32de2b(完整:955a32de2bb49171348bad5f566cce935df19212)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "b63c0d5c11be0292024cc972eee78fbcef7349381ee3bdecb432815b903373e6",
"receipt_sha256": "3ee914c56ff0e9cf2a4d11db1ec0a2e6c74cf745cceb7eff1cefd2f9d938ee89",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3ee914c56ff0e9cf2a4d11db1ec0a2e6c74cf745cceb7eff1cefd2f9d938ee89.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #698(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/698)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
| 同步(记录前对象) | 98ee59c477785b2d5094fcbea3e67a4dc864c388 | a29562ef8315c6cbe71bf531720ce5ffa5ca2717 | 2026-10-22T09:35:11Z |
@@ -0,0 +1,99 @@
# fix/svc-test-port-governance 任务卡
任务主记录:PR #694 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/694(merge 37e194871f);状态:已完成(回填);owner:weichen
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 33d6ef69212595c680a744549986c19bb6acd6c3
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-svc-test-port-governance(worktree);分支:fix/svc-test-port-governance
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=bb1fb490ff22f2cc7a7edfe11e0400569bf98c4e879d5527493186aa75429f31;triage_receipt=/tmp/port2-triage2.json;receipt_sha256=a8e49e2792cd069b95e4db5bc7f7d492d164ff84c21ef1001c3bbaf3de7ba364
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 33d6ef69212595c680a744549986c19bb6acd6c3 | 33d6ef69212595c680a744549986c19bb6acd6c3 | 2026-10-22T06:18:16Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 影响与剩余项:
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T06:17:27.856549+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "33d6ef69212595c680a744549986c19bb6acd6c3",
"after_head": "33d6ef69212595c680a744549986c19bb6acd6c3",
"branch": "main",
"target_branch": "main",
"target_head": "33d6ef69212595c680a744549986c19bb6acd6c3",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=33d6ef6921",
"[remote] origin/main=33d6ef6921 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=6",
"[recycle] merged un-recycled branches: fix/rdm-pin-advance-latest",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 33d6ef6921(完整:33d6ef69212595c680a744549986c19bb6acd6c3)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "bae6a238774330d77e016166c60b79b796a22ec8cbdfed58574a18058fce3679",
"receipt_sha256": "74d9784c1101c6a196fe3571ae41323a102a8d97a92fe15bc3270d00a7a71b7d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/74d9784c1101c6a196fe3571ae41323a102a8d97a92fe15bc3270d00a7a71b7d.json"
}
```
| 同步(记录前对象) | d65195bd41317e480c5a0cfa5133b0ad98a48d4b | a1e0c85c0400ce300a847da276e70d520f842844 | 2026-10-22T07:17:59Z |
## 闭合记录(card-autoclose 回填)
- 依据:merge 37e194871f4ce8f60c7678b64402bec3541fcbd1(PR #694)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
- 合并主题:Merge pull request 'Use dynamic ports in the two remaining hardcoded test bindings' (#694) from fix/svc-test-port-governance into main
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
+680
View File
@@ -0,0 +1,680 @@
# feature/ecs-deploy-dev8788-and-kb 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= cb36b59accd0418c5ca952912d7c181b83038a4c
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb(worktree);分支:feature/ecs-deploy-dev8788-and-kb
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=420311b8d5e0543749bb9743c05ae6757cc0244c7cfda204e6c28bc92eaf8b87;triage_receipt=/tmp/ecs-kb-deploy-triage.json;receipt_sha256=7a0bf8e0d2b9f1adcac5e58cbe70204473007a4dfd04a96f495dde3c0dd71ddb
- 授权与交付终点:owner 2026-10-22 指令“将当前的二进制服务部署到 imc-tx-ecs:先备份远端机器上的服务和数据库;将本机的知识库也部署在远端上;然后部署本机 8788 上的二进制服务;尽可能减少远端服务下线时间并保证服务可用;更换二进制前先告知 owner 确认”,并于 2026-10-23 追加“先把配置弄好,superadmin 账号使用 imc-tx-ecs 上的 sundehui,密码 12345678,第一次登录需要重置密码(把已有用户变成超级管理员)”。交付终点:ECS 8788 运行与本机 dev 同版本二进制(sha256 00ead2cf…),ECS 承载本机 kbreg 知识库且检索可用,远端用户数据零丢失,切换带自动回滚并留存冷备与异地副本。仓库写入仅本任务卡。未授权:修改产品代码、改 Caddy 路由/域名、删除远端既有备份或旧二进制、改动 sundehui 以外账号的凭据、owner 确认前执行二进制切换。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进;切换二进制属人工决策点,先备齐再请确认)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:实施与自检(I1 备份 → I2 知识库 → I3 演练;I4 切换待 owner 确认);当前增量:I3(远端演练,零停机)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
预期结果:ECS(imc-tx-ecs,43.143.211.203,Ubuntu 22.04,2 vCPU/3.6GiB/49GiB 可用;Caddy `imcrd-agent.imcbot.work` → 127.0.0.1:8788)上:
1. 本机 8788 dev 二进制服务原样上线——`runtime/dev/current` 指向 `releases/rdm-ee8c2cd-20261022T055052Z-637762`,`bin/agent-system` sha256 `00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de`(141509195 B),同版 htdocs;systemd 用户单元 `agent-system-dev.service` 的 ExecStart 参数不变。
2. 本机知识库供给到 ECS——本机 kbreg(PostgreSQL 16.15 + pgvector,127.0.0.1:5436,3.1 GB)在 ECS 以原生 PostgreSQL 16.15 + pgvector(回环 5436)承载,语料、已发布修订与索引逐表可核;服务侧经 `serve.env`(`KBREG_*`)+ systemd drop-in `EnvironmentFile` 启用。
3. 远端用户数据零丢失——`data/agent-system.db`(schema v35,24 MB + WAL)与 `rdm.db`(1.5 MB + WAL)经 SQLite 在线备份 API 一致落盘,切换前后以 `ecs-dbsnap.py manifest/compare` 逐行对账 `problems=[]`。
受影响:ECS `runtime/dev/{bin,htdocs,plugins,data,backups,serve.env,svc.env,history.jsonl}`、`~/.config/systemd/user/agent-system-dev.service.d/`、ECS 新增 PostgreSQL 16 集群。本仓:仅 `.task/**`。
非目标:不改产品代码与发布物;不改 Caddy 路由、域名与 TLS;不迁移本机业务数据到 ECS(仅知识库);不删除远端既有备份、旧二进制与 `agent-system-admin/cli`;不动账号、凭据与登录 Key(远端无 `super-admin.env`,切换后仍无,与现状一致);不引入 Docker(远端无容器运行时且不可达镜像仓库)。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 无(运维任务,无仓库代码单元;仓库写入仅 `.task/**` host 豁免) | — | — | — | — | — | — | — | — | — | — |
## 关联方向与规划
- 适用状态:适用但不同阶段——`feature/container-storage-plan`(PR #697,open)是容器化部署形态 initiative,其章程把“生产迁移执行(O1)”列为非目标并要求另获窗口授权;本任务是该形态落地前的既有 SQLite 二进制运维部署,与 U1—U6 无依赖,分流 verdict=NEW(理由见分流收据)。
- 主记录路径/版本:`docs/superpowers/plans/2026-10-22-container-storage-plan.md`(位于 feature/container-storage-plan 分支,未合入 main;本卡引用其 O1 边界,不复制正文)
- 对应里程碑:不在其 M1—M3 内;本任务为独立运维增量 I1—I4
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 先备份远端服务与数据库 | 符合(owner 指令;沿用 `ecs-dbsnap.py` 在线备份 API) | P0 | 远端 `backups/<TS>-warm-pre-ee8c2cd/` 含 data/bin-old/htdocs-old/config + SHA256SUMS 校验通过 + 本机异地副本逐文件 sha 通过 | 无 | 达成(见证据) |
| R2 | 本机知识库部署到远端 | 符合(远端无容器运行时且镜像仓库不可达,按同主版本原生 PostgreSQL 16.15 + pgvector 供给) | P0 | ECS 127.0.0.1:5436/kbreg 可连;`schema_migrations` 0001—0005;关键表行数与本机一致;向量检索返回命中 | 无 | 达成(见证据) |
| R3 | 部署本机 8788 二进制服务且最小停机 | 符合(owner 指令) | P0 | 运行中 exe sha256=00ead2cf…;本地与域名 HTTP 200;停机窗口 ≤ 演练实测 + 人工确认 | R1、R2 | **未达成**:技术切换完成(停机 6.88 s、三处 200),但业务验收 `extension: project context unavailable: not-found`,已回退到旧版本 |
| R4 | 服务可用性保障(回滚) | 符合(切换脚本含健康门失败自动回滚) | P0 | 演练实例证明新版本可启动并迁移 v35→最新;回滚路径演练可用 | R3 | 达成(回退装备 sha 通过 + rollback-now.sh 已就位) |
| R5 | 用户数据零丢失 | 符合 | P0 | 冷备 manifest ↔ 切换后逐行对账 `problems=[]`;settings 明文密钥与 `secret_keys` 逐把一致 | R1、R3 | 达成(切换后与回退后两次对账均 `problems=[]`、零缺失;回退期间曾因脚本嵌套缺陷短暂运行空库,已从冷备真实路径恢复并核验) |
| R6 | 超级管理员 = 既有账号 sundehui(口令 12345678,首次登录强制改密) | 符合(owner 2026-10-23 追加指令) | P0 | 库中仅 sundehui 带超管标记且 `is_admin=1`、`must_change_password` 置位;服务以 `SUPER_ADMIN_OWNER=sundehui` 启动日志为 `already established`(无冲突);`POST /api/auth/login` 200 且 `isSuperAdmin=true`、`sessionScope=set_password_only` | 切换时达成并验证;回退后该标记随冷备数据撤回(远端现无超管标记,下次切换需重跑提升步骤) |
| R7 | 仓库侧交付(任务卡 + PR) | 符合 | P1 | Review 通过、CI 通过、PR 合入 main、任务卡闭合 | R1—R6 | 待收口 |
## 方案与计划
### 对象版本(本机发布物,运行中 /proc/652953/exe)
- 二进制:`/home/weichen/projects/Agent-System-Dev/runtime/dev/current/bin/agent-system`,sha256 `00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de`,141509195 B;来源 `rdm@ee8c2cd`(`runtime/dev/svc.env`),started 2026-10-22T05:51:02Z,监听 127.0.0.1:8788。
- 前端:`current/htdocs`(148 KB,与本机 release 同源);`current/plugins` 为空(远端 plugins 亦为空)。
- 知识库:本机容器 `kbreg-postgres-1`(`pgvector/pgvector:pg16`,PostgreSQL 16.15),库 `kbreg` 3.1 GB;`schema_migrations` 0001—0005;regulations/editions 2897、legal_nodes 1701178、index_entries 191557、retrieval_chunks 64076、ingest_runs 2943。
- 远端现状:`agent-system.db` schema_max=35(58 表 / 28072 行)、`rdm.db`(28 表 / 3578 行,无 `schema_migrations`,由 `schema_version` 管理)、data 树 367 MB、bin 178 MB。
### 增量与步骤
- I1 备份(零停机):`~/ecs-ops/backup-warm.sh warm-pre-ee8c2cd`——SQLite 在线备份 API 取两个库的一致快照 + rsync 文件树(排除库本体)+ bin/htdocs/plugins/systemd 单元/Caddyfile/svc.env/svc.pid/history.jsonl + `manifest` 活库基线 + 相对路径 SHA256SUMS;随后 `~/ecs-ops/offsite-copy.sh` 流式拉回本机 `~/backups/imc-tx-ecs/<同名>/` 并逐文件校验。
- I2 知识库(零停机):远端加 PGDG apt 源 → 安装 `postgresql-16`(16.15)+ `postgresql-16-pgvector`(0.8.7)→ 集群改 `port=5436`、`listen_addresses=localhost` → 建 `kbreg` 角色与库 → 本机 `pg_dump -Fc`(容器内 16.15 客户端,与服务端同主版本)流式传输 → `pg_restore --no-owner --no-privileges` → 逐表行数与 `schema_migrations` 核对 → 向量检索冒烟 → 从本机 `serve.env` 只取 `KBREG_*` 行落远端 `runtime/dev/serve.env`(600,凭据值不出管道)→ systemd drop-in `20-serve-env.conf` + `daemon-reload`(不重启服务)。
- I3 演练(零停机):新二进制与 htdocs 预置到远端 `runtime/dev/stage/<版本>/`;`rsync -a` 复制 data 为 `rehearsal/data`;以 `127.0.0.1:8789` 启动演练实例(带 KBREG 环境)——实测启动+迁移耗时、HTTP 200、schema 版本、关键表行数、日志无 error、KB 检索可用;结束后清理演练目录。
- I4 切换(待 owner 确认后执行):停 recover timer → 停服务 → 库文件冷拷到新备份目录 → `install`+`mv` 原子换二进制、换 htdocs → 启动 → 健康门(本地 200、域名 200、pid/exe sha、schema、KB)→ 失败自动回滚(旧二进制 + 冷备 data + 旧 htdocs)→ 更新 svc.env/svc.pid/history.jsonl → 启 recover timer。
- I5 收口:切换后逐行对账 `compare`、密钥一致性、启动日志、证据写入、Review、PR/CI、合入。
### 停机时间控制
- I1—I3 全程不动线上进程;数据与文件预置在切换窗口之前完成。
- 切换窗口只做:停服务 → 拷两个库(24 MB + 1.5 MB + WAL)→ 原子换二进制 → 启动 → 健康检查。库迁移(v35→最新)在新进程启动时执行,耗时以 I3 演练实测为准;演练若显示迁移显著耗时,再评估预迁移 + 增量拷贝方案后才切换。
### 测试计划
- I1:远端 `sha256sum -c SHA256SUMS` 通过 + 本机异地副本同样通过 + `manifest` 生成成功(28,072 + 3,578 行)。
- I2:`psql` 连接成功;`schema_migrations` 5 条;`select count(*)` 关键表与本机一致(差异即 FAIL);`revision verify` 等价核验(staged/computed sha 一致);一条向量相似度查询返回非空命中;演练实例带 KBREG 启动无 KB 连接错误。
- I3:演练实例 `/` 200、`/healthz` 200;`schema_migrations` 升到目标版本;`users/conversations/runs` 行数与冷备一致(迁移不丢数据);日志 grep 无 `error|panic|fatal`。
- I4/I5:运行中 exe sha256 前缀 `00ead2cf`;`127.0.0.1:8788` 与 `https://imcrd-agent.imcbot.work/` 均 200;`compare MANIFEST-LIVE-PRE.json data` → `problems=[]`;`secret-check.py` 明文密钥与 `secret_keys` 逐把一致;停机窗口秒数由脚本记录。
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | R1—R6 | 已完成 | 主模型 + triage NEW | 2026-10-22 | /tmp/ecs-kb-deploy-triage.json |
| 需求评估 | 对象版本与远端现状核对 | 已完成 | 主模型 | 2026-10-22 | 本卡“方案与计划” |
| 需求表确认 | R1—R6 | 已完成 | owner 指令即验收边界 | 2026-10-22 | owner 2026-10-22 指令 |
| 方案设计 | I1—I5 | 已完成 | 主模型 | 2026-10-22 | 本卡“方案与计划” |
| 实施计划 | I1 备份 / I2 知识库 / I3 演练 / I4 切换 / I5 收口 | 已完成 | 主模型 | 2026-10-22 | 同上 |
| 实施与自检 | I1—I3b(rdm@ee8c2cd,备份/知识库/演练/超管配置) | 已完成 | 主模型 | 2026-10-23 | 证据表 |
| 正式测试与验收 | I4 切换后核验 | **失败并回退**(`project context unavailable: not-found`) | 主模型 + owner 指令回退 | 2026-10-23 | 证据表(回退后 `problems=[]`) |
| 代码 Review | 待收口 | 待执行 | — | — | — |
| 合入 | 待收口 | 待执行 | — | — | — |
| 合入核验与收口 | 待收口 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| I3 远端演练实例(8789 + 复制 data + KBREG 环境) | 新版本能在 v35 旧库上完成迁移并在带知识库环境下健康启动 | 远端副本,不接流量、不写线上库 | 迁移失败或超 5 分钟 → 停下先修迁移/换方案,不进入切换窗口 | owner 指令“保证服务可用、最小停机” | 待执行 | 无(演练目录用后清理) | 是(切换前重放同一演练) |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | cb36b59accd0418c5ca952912d7c181b83038a4c | cb36b59accd0418c5ca952912d7c181b83038a4c | 2026-10-22T13:41:37Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果(I1 备份,零停机):远端 `backups/20261022T134400Z-warm-pre-ee8c2cd/`(539 MB、629 文件,SQLite 在线备份 API 取两个库的一致快照 + 文件树 rsync + bin/htdocs/plugins/systemd 单元/Caddyfile/svc 登记 + 活库基线 MANIFEST-LIVE-PRE.json)远端 `sha256sum -c` 通过;本机异地副本 `~/backups/imc-tx-ecs/20261022T134400Z-warm-pre-ee8c2cd/` 逐文件校验通过(629 文件)。线上进程全程未动(pid 4080336 自 2026-10-18 14:20:26 运行至今)。
- 结果(I2 知识库):远端装 PostgreSQL 16.15(PGDG,jammy)+ pgvector 0.8.7,回环 `127.0.0.1:5436`;角色/库 `kbreg`;本机容器 `pg_dump -Fc`(16.15 客户端,同主版本)→ `pg_restore --no-owner --no-privileges --no-comments`(3m09s);`serve.env`(600,仅 KBREG_*)与单元 drop-in `20-serve-env.conf` 已就位(daemon-reload,未重启服务)。
- 结果(I3 演练,零停机):`stage/rdm-ee8c2cd-20261022T055052Z-637762/bin/agent-system` sha256 与本机运行中制品一致(`00ead2cf…`);复制 data(367 MB)后以 8789 启动新二进制 + KBREG 环境:**1.02 s 健康(HTTP 200)、schema v35→v51 自动迁移完成、users 18→19(多出的就是本次演练的超级管理员账号)、conversations/runs/messages 不变、日志无 error/panic/fatal**;冷拷 data 实测 1.14 s、只拷库 0.05 s。
- 结果(I3b 超级管理员演练,零停机):因为产品只在启动时从 `SUPER_ADMIN_*` 建立超管,且**拒绝把已有账号直接指定为超管**(`configured owner belongs to an existing account without the super-admin marker`),采用与产品 bootstrap 同形的等价写入(`~/ecs-ops/seed-superadmin.py`:一个事务内更新 `users` 的 `is_admin/is_super_admin/password_hash(argon2id)/must_change_password/auth_version/credential_origin/initialization_state/state_version` + 按 v49 动作集写 `system_grants`(12 项)+ `account_events` + `audit_events`)。演练实测:阶段 A `--auth off` 迁移 v35→v51 用时 **0.27 s**;阶段 B 提升 sundehui(用户数仍为 18,未新增账号);阶段 C 以 `--auth on` + `SUPER_ADMIN_OWNER=sundehui` 启动,日志 `super admin: account "sundehui" already established`,健康 **0.27 s**;`POST /api/auth/login` 返回 `isSuperAdmin=true`、`sessionScope=set_password_only`(首次登录只能改密),`/api/me/profile` 403 `set-password session only`,日志无 error/panic/conflict。
- 配置就绪(远端,零停机):`runtime/dev/super-admin.env`(600,`SUPER_ADMIN_OWNER=sundehui`);drop-in `20-serve-env.conf` 同时引用 `serve.env` 与 `super-admin.env`(已 `daemon-reload`,未重启服务);待用口令哈希文件 `~/ecs-stage/seed.hash`(600)已就位;切换脚本 `~/ecs-ops/cutover-ee8c2cd.sh` 已按 A/B/C 三阶段重写并通过语法检查。
- 结果(I4 切换 → **验收失败 → 已回退**):08:43:27 CST 停服、08:43:30 CST 新版本健康,**停机 6.88 s**;新版本 pid 1617793、exe sha256 `00ead2cf…`、schema v51、本地/healthz/域名 200、sundehui 受限登录 200。**但业务验收出现 `extension: project context unavailable: not-found`(RDM 项目上下文解析为 not-found),owner 08:47 要求立即回退。** 回退分两步:首次执行 `rollback-now.sh` 因脚本缺陷(`mkdir -p $B/data` 后 `cp -a $R/data $B/data` 产生嵌套 `data/data/`,回退取到空目录)使服务短暂运行在空库;发现 users=0 后立即从冷备真实路径 `$B/data/data` 恢复,08:48:35 起服务运行旧版本,数据完整。两个脚本已修复并同步远端。
- 回退装备(保留可用):`runtime/dev/rollback/kit-20261023T004302Z`(旧二进制 sha `1f45f640…`、htdocs、单元、Caddyfile,12 文件 sha 通过)+ 修复后的 `rollback-now.sh`(嵌套目录探测、`rm -rf $R/data` 避免合并)+ 修复后的 `cutover-ee8c2cd.sh`(不再预建 `$B/data`)+ 冷备 `backups/20261023T004322Z-cold-pre-ee8c2cd`(真实数据在 `data/data`)+ 切换后的 v51 数据留存于 `runtime/dev/data.rolled-back` 供定位。
- 回退后核验(逐项,证据均为 SELF 收据):旧二进制 exe sha256 `1f45f640…`、pid 1619863、schema v35、`rdm.db` schema_version=6、本地/healthz/域名 200、recover timer 恢复;数据 users 18 / conversations 19 / runs 110 / messages 246,与热备基线逐行对账 **`problems=[]`、零缺失**(605→609 文件,新增 4 个为基线后新产生的用户文件);回退装备 SHA 通过;知识库仍在(legal_nodes 1701178、index_entries 191557)且 drop-in 已移除,旧二进制不读取它。热备/冷备/本机异地副本 SHA 全部通过;知识库指纹与端到端检索(隧道 + `kbreg migrate/search`)通过;演练迁移/健康/超管提升/受限登录通过;**浏览器端业务验收 FAIL**(`extension: project context unavailable: not-found`)。
- 影响与剩余项:
- 业务浏览器端验收(sundehui 首次登录改密、界面检索)NOT_RUN:需真人用真实账号密码登录,本任务不代持口令做交互验证。
- 回滚会丢失切换后新产生的数据(旧版本读不了 v51 库),执行前需 owner 确认。
- `sundehui` 现为 `is_admin=1` + `is_super_admin=1`(产品要求超管必须同时是管理员),口令哈希写入时 `auth_version+1`,旧会话失效。
- 知识库检索状态与本机一致为 degraded(本机向量索引同样为空);恢复向量索引属后续独立增量。
- 远端知识库为原生 PostgreSQL 16.15(非容器,远端无容器运行时且不可达镜像仓库),与 container-storage-plan 的容器决策可用同主版本 dump/restore 迁移。
- 结果(I6 修复合入,2026-10-23):owner 验收通过后按治理流程合入——所有代码变更都经 `scripts/agent-exec run` 的 worker transport 与 `apply` 进入分支(admit 门禁只放行 transport 或豁免路径),逐仓 CI 通过后合并:
- Agent-System-Backend PR #250「Carry project-scope defaults for roles with project management」→ main `1d04f07`;`go test ./internal/store ./internal/app ./internal/server` 通过,transport diff 与上线版本逐字一致。
- Agent-System-Frontend PR #129「Hide system actions from the role editor」→ main `9cc7113`;`npm run build` 与 717 个 vitest 通过。注意:PR #127(一次性密码改端点、恢复提案下线、侧栏无项目对话入口)在合入前发现上游 main 已自行实现同等能力,已关闭并以 #129 取代。
- Agent-System-RDM PR #482「Resolve host project ids in context and fall back to member defaults」→ main `d879839`;pin 同步到已合入的基座与前端 main,`go test ./...` 通过。
- Agent-System-Dev:main 的 `modules/backend` pin(`bd5c0f39`)已包含基座合并,无需再改;Dev 不跟踪 RDM 仓。
## 规划进展与下一步
- 本次推进/剩余:I1—I5 完成(首次切换因业务错误回退 → 三处修复并在 58788 验证 → 重建后二次切换停机 6.13 s 成功 → 角色/超管/模型配置就位 → 修复全部经 worker transport 合入 main)。剩余:合并后的产物(前端来自已合入 main)与线上二进制不同,需要你决定是否再切一次。
- 首选下一任务:本任务 I5(不新建任务)。
- 推荐依据:验收失败必须先消除阻塞项,不得以“技术切换成功”替代业务可用(`policy/delivery.md#目标优先范围控制与问题分流`)。
- 前置条件/待确认:定位材料——触发错误的入口(页面/会话)与其客户端响应;`data.rolled-back` 中已迁移的 v51 库可离线复现。
- 预期产物/验收条件:离线复现或代码级定位 `not-found` 成因;演练新增带项目上下文的真实请求并通过;再请 owner 确认切换窗口。
- 已知缺口:I3 演练只验证启动/迁移/登录/超管接口,**未发起带项目上下文的真实业务请求**,因此未能提前发现该错误。
- 重复任务核对:已核对 `.task/archive/feature-ecs-sync-local-dev.md`(2026-10-18 同机切换)与 feature/container-storage-plan(容器化形态,O1 生产迁移不在其范围);无重复在途任务。
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T13:28:34.782723+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-bootstrap-r0",
"before_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"after_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"branch": "HEAD",
"target_branch": "main",
"target_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-bootstrap-r0'",
"[repo] branch=HEAD head=cb36b59acc",
"[remote] origin/main=cb36b59acc ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=9",
"[recycle] merged un-recycled branches: fix/gitea-address-migration fix/svc-test-port-governance-batch1",
"[cards] 已合入未闭合任务卡:fix-svc-test-port-governance-batch1.md——make task-close 回填归档(主检出运行)",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] cb36b59acc(完整:cb36b59accd0418c5ca952912d7c181b83038a4c)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-bootstrap-r0'"
],
"output_sha256": "37096e9c91f721e54d19452b169e8558a0ddd1e0699512acf8d17d8331046441",
"receipt_sha256": "57bedc8bb759f306f6a2623b48f7117ef650a0a0c7951719ef6a25f5f51276eb",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/57bedc8bb759f306f6a2623b48f7117ef650a0a0c7951719ef6a25f5f51276eb.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:22:01.538077+00:00",
"command": "bash ~/ecs-ops/verify-local.sh",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "a06b59bf58b89bcbe5ce8d8ca204d6d376fd61fd86af9b0ffbd7133a8d7c5b21",
"after_tracked_diff_sha256": "a06b59bf58b89bcbe5ce8d8ca204d6d376fd61fd86af9b0ffbd7133a8d7c5b21",
"output_tail": [
"=== 本机异地副本 ===",
"OFFSITE_SHA_OK files=629",
"539M\t/home/weichen/backups/imc-tx-ecs/20261022T134400Z-warm-pre-ee8c2cd",
"=== 知识库指纹比对:本机容器 vs ECS(经隧道) ===",
"KB_FINGERPRINT_IDENTICAL",
"md5_regulations|56bcaad63aab3f505f115d867faeb12b",
"md5_editions|a93c46f75144e3359ef8c78ca1b67b2d",
"md5_index_entries|7e599356f4aeb45631e074f6bbc99f6e",
"md5_revision_members|5322ba17aff3ffbd1d23ba48248522d0",
"legal_nodes_bytes|888742683"
],
"output_sha256": "5c4ca6b9861b52bd9dd704794bbfdbfac60ad80af5ce1daa77caf38766aea3c9",
"receipt_sha256": "7eb168bc415a5a89d4d30baea6989c77f7026b8b54aa72a689ab03a7808cb34d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/7eb168bc415a5a89d4d30baea6989c77f7026b8b54aa72a689ab03a7808cb34d.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:23:11.116009+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/verify-remote.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "bc02c637e5aa7caf698d242f47e2c4565469c1d97e695b71f8ac8c75a8d4c07f",
"after_tracked_diff_sha256": "bc02c637e5aa7caf698d242f47e2c4565469c1d97e695b71f8ac8c75a8d4c07f",
"output_tail": [
"version=agent-system 0.1.0-dev",
"started=2026-10-18T14:20:27+08:00",
"local8788=200",
"domain=200",
"=== 线上库 schema ===",
"agent-system.db schema_max 35",
" users 18",
" conversations 18",
" runs 109",
" messages 244",
"rdm.db schema_version [(6,)]",
" users ERR no such table: users",
" conversations ERR no such table: conversations",
" runs ERR no such table: runs",
" messages ERR no such table: messages",
"=== 远端热备校验 ===",
"backup=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261022T134400Z-warm-pre-ee8c2cd",
"REMOTE_BACKUP_SHA_OK files=629",
"539M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261022T134400Z-warm-pre-ee8c2cd",
"=== 待上线制品 ===",
"00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/stage/rdm-ee8c2cd-20261022T055052Z-637762/bin/agent-system",
"app.css",
"app.js",
"index.html",
"htdocs_files=6",
"=== 知识库供给 ===",
"active",
"Ver Cluster Port Status Owner Data directory Log file",
"16 main 5436 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log",
"LISTEN 0 200 127.0.0.1:5436 0.0.0.0:* users:((\"postgres\",pid=1462333,fd=6)) ",
"SET",
"regulations=2897",
"legal_nodes=1701178",
"index_entries=191557",
"retrieval_chunks=64076",
"/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/serve.env 600 ubuntu",
"[Service]",
"# 知识库供给环境(KBREG_*,来自受保护的 serve.env,权限 600)",
"EnvironmentFile=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/serve.env",
"EnvironmentFiles=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/serve.env (ignore_errors=no)"
],
"output_sha256": "b9d015bb32fed01af4e0490ca20745495bfa63fed1c4495d3dab9b3bc8d64682",
"receipt_sha256": "80f27d8775a7454eecc9279266ffdb8486c1fc9056770bd305f20fc5810b35fe",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/80f27d8775a7454eecc9279266ffdb8486c1fc9056770bd305f20fc5810b35fe.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:23:24.616557+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal.sh'",
"exit_code": 1,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "a4d29aaed46c125f0ea41b93903130a71287e2a36a10e457a5d6f54f94f05f28",
"after_tracked_diff_sha256": "a4d29aaed46c125f0ea41b93903130a71287e2a36a10e457a5d6f54f94f05f28",
"output_tail": [
"[rehearsal] copying data 2026-10-22T23:23:26+08:00",
"367M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data",
"[rehearsal] pid=1475116 start=2026-10-22T23:23:27+08:00",
"[rehearsal] healthy=1 after=1.034965419s http=200",
"[rehearsal] schema:",
"agent-system schema_max = 51",
" users = 19",
" conversations = 18",
" runs = 109",
" messages = 244",
"Traceback (most recent call last):",
" File \"<stdin>\", line 9, in <module>",
"sqlite3.OperationalError: no such column: username"
],
"output_sha256": "633a16b70f361c207045e23bc573e0e8f9bd39eae69c648f1d4a4ee64c2e31ee",
"receipt_sha256": "86751433905579872d89a49231a54af8bf53abae1ba91b93c7c5e96b96e9ffa5",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/86751433905579872d89a49231a54af8bf53abae1ba91b93c7c5e96b96e9ffa5.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:23:34.788033+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "ea88c0fc9ecb0d0c01399696327bda7c3c2f3eefd9c4249afc3c39ab53286428",
"after_tracked_diff_sha256": "ea88c0fc9ecb0d0c01399696327bda7c3c2f3eefd9c4249afc3c39ab53286428",
"output_tail": [
"[rehearsal] copying data 2026-10-22T23:23:36+08:00",
"367M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data",
"[rehearsal] pid=1475273 start=2026-10-22T23:23:37+08:00",
"[rehearsal] healthy=1 after=1.016955899s http=200",
"[rehearsal] schema:",
"agent-system schema_max = 51",
" users = 19",
" conversations = 18",
" runs = 109",
" messages = 244",
" super_admins = [('rehearsal-admin',)]",
"[rehearsal] data tree files: 613",
"[rehearsal] log grep (error/panic/fatal):",
"[rehearsal] log tail:",
"2026/10/22 23:23:37 super admin: established account \"rehearsal-admin\"",
"2026/10/22 23:23:37 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/22 23:23:37 exec tools: backend=sandbox (bwrap: no network, ro root, session-only writes, proc limit)",
"2026/10/22 23:23:37 skills: wrote 0, upgraded 4 into /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data/skills",
"2026/10/22 23:23:37 auth: API key required (create with: agent-system apikey create --owner <name>)",
"2026/10/22 23:23:37 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[rehearsal] done 2026-10-22T23:23:38+08:00"
],
"output_sha256": "5e6268752d60e253de77c8979bfcfcac69ca8df0bd357dd3c2f1630d1965c7c0",
"receipt_sha256": "37a1f94a8b71c31ff766ac284ea2599dac2df25c12e065b33d2a91c7602e9632",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/37a1f94a8b71c31ff766ac284ea2599dac2df25c12e065b33d2a91c7602e9632.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T23:08:23.850986+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal-superadmin.sh'",
"exit_code": 4,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"after_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"[rehearsal] copying data 2026-10-23T07:08:25+08:00",
"seed failed: no such column: is_super_admin"
],
"output_sha256": "6df9fb628078ad393282ce681f1fb69e6034f689237fe97e6a692da490a3f3ab",
"receipt_sha256": "4000943bcb84808a35cd147886eea4d6fd81a2982a9d8db37e6239d874d7789c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/4000943bcb84808a35cd147886eea4d6fd81a2982a9d8db37e6239d874d7789c.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T23:08:52.895328+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal-superadmin.sh'",
"exit_code": 1,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"after_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "04b1dba8da2af5a53de394e5e62fdf4a46ab168aa73346127d42bd67546e5c20",
"after_tracked_diff_sha256": "04b1dba8da2af5a53de394e5e62fdf4a46ab168aa73346127d42bd67546e5c20",
"output_tail": [
"[rehearsal] copying data 2026-10-23T07:08:54+08:00",
"[phase A] migrate-only start (auth off)",
"[phase A] healthy after .529100167s (pid=1593264)",
"2026/10/23 07:08:54 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/23 07:08:55 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[phase A] schema_max = 51",
"[phase B] elevate existing account",
"Traceback (most recent call last):",
" File \"/home/ubuntu/ecs-ops/seed-superadmin.py\", line 116, in <module>",
" sys.exit(main())",
" File \"/home/ubuntu/ecs-ops/seed-superadmin.py\", line 85, in main",
" instance = db.execute(\"SELECT instance_id FROM agent_system_identity\").fetchone()[0] or \"\"",
"TypeError: 'NoneType' object is not subscriptable"
],
"output_sha256": "bbeabf52756b45a9e3fc87670b7bdbbdcab5b5b35ab5682138d45462939306b5",
"receipt_sha256": "a88ff605df0338fb6cb529f9ab45900833c0120a528ee835b0b11628f9e66b50",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/a88ff605df0338fb6cb529f9ab45900833c0120a528ee835b0b11628f9e66b50.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T23:09:02.539134+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal-superadmin.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"after_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "39b40acc28963d9413e554781ec8e65ed09774268e49cecb19496ac456e9a4d3",
"after_tracked_diff_sha256": "39b40acc28963d9413e554781ec8e65ed09774268e49cecb19496ac456e9a4d3",
"output_tail": [
"[rehearsal] copying data 2026-10-23T07:09:03+08:00",
"[phase A] migrate-only start (auth off)",
"[phase A] healthy after .267909096s (pid=1593451)",
"2026/10/23 07:09:04 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/23 07:09:04 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[phase A] schema_max = 51",
"[phase B] elevate existing account",
"seeded: {'owner': 'sundehui', 'is_admin': 1, 'is_super_admin': 1, 'must_change_password': <redacted>, 'auth_version': 2, 'credential_origin': '<redacted>', 'initialization_state': 'initialized', 'has_pw': 1} system_grants_allowed: 12",
"[phase C] start with auth on, super admin owner=sundehui",
"[phase C] healthy=1 after=.268576176s http=200",
"2026/10/23 07:09:06 super admin: account \"sundehui\" already established",
"2026/10/23 07:09:06 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/23 07:09:06 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[check] login as sundehui",
"{\"auth\":true,\"isAdmin\":true,\"isSuperAdmin\":true,\"mustChangePassword\":<redacted>,\"name\":\"\",\"owner\":\"sundehui\",\"passwordChangeMode\":\"<redacted>\",\"passwordSet\":<redacted>,\"sessionScope\":\"set_password_only\"}",
"",
"HTTP=200",
"[check] profile with session",
"forbidden: set-password session only",
"",
"HTTP=403",
"[check] super-admin gated endpoint",
"admin_users_http=403",
"[check] schema and account state",
"schema_max = 51",
"super admins = [('sundehui',)]",
"users total = 18",
"[check] log errors:",
"[rehearsal] done 2026-10-23T07:09:06+08:00"
],
"output_sha256": "690a87c97b30c36d517a47c90a6d951c307a094feefbf525ac6e7124c2f5c421",
"receipt_sha256": "47666f79ea5cbd315d5de3f89da4f90e19956fba77e4f880cb3f9bfca7c9df95",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/47666f79ea5cbd315d5de3f89da4f90e19956fba77e4f880cb3f9bfca7c9df95.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:44:11.563406+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/verify-post-cutover.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"after_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"grep: SHA256SUMS: No such file or directory",
"COLD_META_SHA_SKIPPED(部分行需整体校验)",
"479M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261023T004322Z-cold-pre-ee8c2cd",
"=== 回滚装备 ===",
"ROLLBACK_KIT_SHA_OK files=12",
"kit created 20261023T004302Z",
"source_binary=1f45f64077b8dffd25d80513e3aaf5f06c71c8a09248c21af22f9d33eab516b9",
"data_source=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261022T134400Z-warm-pre-ee8c2cd",
"=== 服务 ===",
"active",
"active",
"pid=1617793 started=Fri Oct 23 08:43:29 2026 exe_sha256=00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de",
"pid=1617793",
"addr=0.0.0.0:8788",
"source=rdm@ee8c2cd",
"version=agent-system-rdm (devel)",
"started=2026-10-23T08:43:30+08:00",
"{\"ts\":\"2026-10-23T00:43:30Z\",\"event\":\"deploy\",\"env\":\"dev\",\"kind\":\"agent\",\"source\":\"rdm@ee8c2cd\",\"result\":\"ok\",\"pid\":\"1617793\",\"addr\":\"0.0.0.0:8788\",\"detail\":\"from=dev@a706e9a+rdm@4b2473bed112 to=rdm@ee8c2cd via systemd; backup=20261023T004322Z-cold-pre-ee8c2cd",
"=== HTTP ===",
"local=200 healthz=200 domain=200",
"=== 数据与账号 ===",
"schema_max = 51",
" users 18",
" conversations 18",
" runs 109",
" messages 244",
" super_admins = [('sundehui',)]",
" sundehui = ('sundehui', 1, 1, 1, 2, 'owner_initialization')",
"=== 逐行对账(热备基线 ↔ 切换后)===",
"files base=605 now=605 missing=0 changed=5 added=0",
"changed: ['skills/.builtin-manifest.json', 'skills/docx-author/SKILL.md', 'skills/house-style/SKILL.md', 'skills/house-style/tests/test_housestyle.py', 'skills/house-style/housestyle/build.py']",
"tables with missing/changed rows: {\"agent-system.db.sessions\": {\"base\": 18, \"now\": 18, \"missing\": 0, \"changed\": 2, \"added\": 0, \"changed_keys\": [\"21\", \"22\"]}, \"agent-system.db.users\": {\"base\": 18, \"now\": 18, \"missing\": 0, \"changed\": 1, \"added\": 0, \"changed_keys\": [\"12\"]}}",
"problems: []",
"=== 密钥一致性 ===",
"owner='' scope=system models.rerank -> secret_keys match=True",
"owner='' scope=system tools.tavily -> secret_keys match=True",
"settings_snapshots=11 mismatches=0",
"=== 知识库 ===",
"active",
"SET",
"legal_nodes=1701178",
"index_entries=191557",
"=== 切换后错误扫描 ===",
"Failed to parse timestamp: 2026-10-23T00:24:14",
"(以上为空即无错误)"
],
"output_sha256": "52fc124a0e4e6e890949349d93afc89bd2228f460e780e14555160002da29282",
"receipt_sha256": "af18be0166d5bfe3abed4f5a433cb9d57e4dfdfa6f1eb60b828bc33496318e3b",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/af18be0166d5bfe3abed4f5a433cb9d57e4dfdfa6f1eb60b828bc33496318e3b.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:44:39.306471+00:00",
"command": "bash ~/ecs-ops/kb-check-fast.sh",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"after_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "1c4f20b9e2398f9fb813dfe305e789f20a8abad1c41f18ed847517dd35981cad",
"after_tracked_diff_sha256": "1c4f20b9e2398f9fb813dfe305e789f20a8abad1c41f18ed847517dd35981cad",
"output_tail": [
" \"version\": \"fts-v1\"",
" }",
" ],",
" \"hits\": [",
" {",
" \"regulation_id\": \"reg_3939376174cc5e1eb146d10b\",",
" \"edition_id\": \"ed_2e7d6d945848614ab386bdbc\",",
" \"node_id\": \"nd_79ccfca59982317806810fb3\",",
" \"kind\": \"guidance\",",
" \"title\": \"国家药监局关于发布医疗器械注册质量管理体系核查指南的通告(2022年第50号\",",
" \"edition_label\": \"src-5f55893f9096\",",
"KB_FAST_CHECK_OK"
],
"output_sha256": "cc655d17a77eb65ad064cfaaf4a903a3fe6adb05879dc8e2a70b16be36f93a09",
"receipt_sha256": "eda1eaba245f1c76e329747c66a6739435ddf8524ce0223fc86baac4b9bc92fd",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/eda1eaba245f1c76e329747c66a6739435ddf8524ce0223fc86baac4b9bc92fd.json"
}
```
| 同步(记录前对象) | 6ced938a126981ee2a4fab671a2da94f49cb56c5 | d436d6718ca997e575ad8be3d149efefca8cedd8 | 2026-10-23T00:46:40Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:49:39.764923+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/verify-rollback.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "2487b561bb61103bd066d96f4be0135621daf66c",
"after_head": "2487b561bb61103bd066d96f4be0135621daf66c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"=== 回退后运行态 ===",
"active",
"active",
"pid=1619863 exe_sha256=1f45f64077b8dffd25d80513e3aaf5f06c71c8a09248c21af22f9d33eab516b9 started=Fri Oct 23 08:48:35 2026",
"local=200 healthz=200 domain=200",
"=== 数据核对 ===",
"schema_max 35",
" users 18",
" conversations 19",
" runs 110",
" messages 246",
"rdm schema_version [(6,)]",
"files base=605 now=609 missing=0 changed=0 added=4",
"problems: []",
"tables missing/changed: {\"agent-system.db.sessions\": {\"base\": 18, \"now\": 19, \"missing\": 0, \"changed\": 2, \"added\": 1, \"changed_keys\": [\"21\", \"22\"]}}",
"=== 回退装备 ===",
"kit=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rollback/kit-20261023T004302Z",
"ROLLBACK_KIT_SHA_OK",
"/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data.rolled-back",
"=== 知识库仍在(旧二进制不读取,环境文件已移除)===",
"active",
"SET",
"legal_nodes=1701178",
"index_entries=191557"
],
"output_sha256": "d8f3dd94b561810a63a8515bc6cd1188a7f83e379a592c2106a88233258dbe51",
"receipt_sha256": "8c4cc241b55f8df83e9e6802d6bf15584553cfafe845bda647a2a8add611041c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/8c4cc241b55f8df83e9e6802d6bf15584553cfafe845bda647a2a8add611041c.json"
}
```
| 同步(记录前对象) | 0650e81133b853f27e8e53f516de8f6c1e73e4a4 | 1a3f9a1e5f08d25cedc82024ba1354b186932777 | 2026-10-23T11:13:15Z |
-253
View File
@@ -1,253 +0,0 @@
# feature/rdm-two-trees-followup 任务卡
任务主记录:https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/635;状态:进行中;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 46e331a7a81c94c6f5881c997ae0aca45664c830
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-followup(worktree);分支:feature/rdm-two-trees-followup
- 分支类型:initiative;initiative_id:feature-rdm-two-trees-followup;root_target:main;immediate_target:main;accepting_requirements:true
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=ec5195ceec26c05d94600716514c5f306bd3d2aba2a18e4e71f54a660e0b1b83;triage_receipt=/tmp/tt-followup-triage-20261019.json;receipt_sha256=3abe686c520606f4969e17668843666bfafc4cebd7f869995121ab82ed5dd345
- 授权与交付终点:用户 2026-10-19 在遗留项推进中选定“两棵树后续大任务”;本轮终点为建卡登记剩余项,并把第一个增量 A1(W0 清单守护 + svc 测试动态端口 + W3 余项差距核对)推进到阶段 6 评审包。manual 模式:每个增量须用户阶段 6 人审后才合入;未授权:Backend 发版/tag(X3 公开扩展接口,双钥匙由用户执行)、真实模型与付费请求(W11/W12 另提资源方案)、运行库迁移、部署。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:A1、W3 余项、增量 B(W5/W6/W7a)均通过阶段 6 并合入本分支;下一增量:C(W8/W10,待登记);W7 provider 接线等 X1 tag(用户双钥匙)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
### 章程(charter)
**用途与目标**:承接 `.task/archive/feature-rdm-two-trees-latest-templates.md`(部分收口,Dev #630)未交付部分,按已批准的阶段 4 方案与阶段 5 计划 r1(`modules/documents/docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage5-implementation-test-plan-r1.md` 与 work-observation 增补计划 r1)完成两棵树一网的模板、递归实例、追溯、上下文、审计与正式界面。
**接纳范围**:W0(DHF 清单守护,原分支 9873a55 未合入部分)、svc 测试动态端口修复、W3 余项(旧数据迁移等,见 A1 差距核对)、W5 追溯网、W7 上下文提供方、W8 RDM 审计投影、W10 正式前端、W11 DHF 全量保真、W12 含真实模型全组合验收、W13 收口,以及 X3/R3/F3/V3 产品链。
**非目标**:IAM 项目协作与联动权限(feature-iam-role-permission-linked-capabilities 范围);重新设计已批准方案;未经单独授权的发版、迁移、部署与付费请求。
**分级测试策略**:每增量 SELF 定向测试 + 独立 Review → 用户阶段 6 人审 → PR CI(GATE);阶段 7 只在全目标候选固定后正式验收。
**生命周期**:增量 A1 → 用户阶段 6 → 后续增量按原计划 B(W5–W7)、C(W8–W10)、D(W11/W12)推进;X3 发版与 W11/W12 资源各自单独授权。
## 子任务登记
| 子任务分支 | 必需 | 状态 | PR |
|---|---|---|---|
| A1:W0 守护 + svc 动态端口 + W3 差距核对(本分支内增量) | 是 | 已合入(本分支 000a2d2;用户 2026-10-19 阶段 6 通过) | 本分支 PR #635(草稿,initiative 收口时合入 main) |
| feature/rdm-two-trees-followup-w3-rest | 是 | 已合入(用户 2026-10-20 阶段 6 通过;W3 余项:迁移两次同值、图形不透明块、移动/改名引用、旧批准版回取、重复表格复核;评审包 docs/superpowers/specs/2026-10-19-rdm-two-trees-followup-w3-review.md)。前置条件:W4 开放结构写入口前先补节点种类放置检查;Dev 的 RDM gitlink 改钉在 initiative 收口时统一组合验证 | RDM PR [#451](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/451)(合入 RDM main 76b4c05);本子任务 PR [#641](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/641) |
| feature/rdm-two-trees-followup-w5-w7(增量 B:W5/W6/W7a) | 是 | 已合入(用户 2026-10-20 阶段 6 通过:W5 追溯网领域核+命令面、W6 X1 恢复并按批准修订补齐、W7a 纯领域 bundle;独立 Review RDM 0 BLOCKING/6 MAJOR 已修复、Backend 7/7 PASS;评审包 docs/superpowers/specs/2026-10-20-rdm-two-trees-followup-w5-w7-review.md)。W7 provider 接线等 X1 tag(用户双钥匙);Backend MINOR 6 条随接线处理;RDM MINOR 14 条为增量 C 顺手项 | RDM PR [#458](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/458)(合入 RDM main 93badd7e);本子任务 PR [#666](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/666);Backend PR [#231](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/231)(合入 backend main 7a41f22e) |
| B:W5/W7 | 是 | 待登记 | — |
| C:W8/W10 | 是 | 待登记 | — |
| D:W11/W12/W13 | 是 | 待登记(需资源方案) | — |
| X3/R3/F3/V3 | 是 | 待登记(X3 需 Backend 发版,双钥匙) | — |
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| two-trees-followup-a1-w0-guard-and-svc-ports | scripts/dhf_catalog_guard.py、tests/test_dhf_catalog_guard.py、tests/test_svc.py、tests/test_svc_recover.py、tests/test_svc_realcombo.py | config ccf5b7c03ce4;unit 6fe9be3e5516 | implementation | cursor → agy → pi | 1(9075eee055af,fresh_session) | cursor | success | apply ff 8cf4619..000a2d2 | 未触发 | /tmp/leftover-20261019/tt-a1-receipt.json(run b7a8e78a2b6d0d8f6803490c7fa8af2e) |
## 关联方向与规划
- 适用状态:适用
- 主记录路径/版本:.task/archive/feature-rdm-two-trees-latest-templates.md;modules/documents/docs/records/2026-10-14-rdm-two-trees-latest-templates/(阶段 4 方案、阶段 5 计划 r1)
- 对应里程碑:两棵树一网与 DHF 模板(阶段 6 增量 A–D)
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | W0 DHF 清单守护落地 main | 符合:阶段 5 计划 W0;原实现 38ef548 曾 SELF 通过与限域复审 | P1 | 守护单测通过;不宣称任何模板 published | DHF catalog | 纳入 A1 |
| R2 | svc 测试动态端口 | 符合:并发 worktree 固定端口误入占用路径(cabac58 证据) | P2 | 原断言保留;test_svc/test_svc_recover 通过 | 无 | 纳入 A1 |
| R3 | W3 余项差距核对 | 符合:W3 递归节点主体已在 RDM main(8dd8ebe) | P1 | 逐项列出已交付/缺失与证据 | RDM main | 纳入 A1(仅核对) |
## 方案与计划
- 方案引用:阶段 4 方案 rdm-two-trees-stage4-design-r1.md(已批准)
- 实施计划引用:rdm-two-trees-stage5-implementation-test-plan-r1.md(已批准)W0/W3;A1 评审包见 docs/superpowers/specs/2026-10-19-rdm-two-trees-followup-a1-review.md
- 测试计划引用:同上计划 W0/W3 验证节;A1 定向单测
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | R0 46e331a | 完成 | host | 2026-10-19 | 承接部分收口剩余项 |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 阶段 4 r1 | 沿用已批准方案 | 用户(原任务) | 2026-10-14 | 原卡阶段记录 |
| 实施计划 | 阶段 5 r1 | 沿用已批准计划 | 用户(原任务) | 2026-10-14 | 原卡阶段记录 |
| 实施与自检 | A1 000a2d2 | 完成(SELF) | cursor worker 实施;host 范围审阅与定向单测 | 2026-10-19 | 收据 tt-a1-receipt.json;67 测试 OK(skipped=16 为真实二进制 NOT_RUN) |
| 阶段 6 人审 | A1 679da1a(CI GATE success,test-pg 偶发失败后重跑通过) | 通过 | 用户 | 2026-10-19 | docs/superpowers/specs/2026-10-19-rdm-two-trees-followup-a1-review.md |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| A1 | 原 W0/端口修复在最新 main 上可最小适配重新落地 | Dev scripts/tests | 定向单测通过;原断言不删减;不适配则停止并报告 | 用户 2026-10-19 选定 | 守护脚本与单测按 9873a55 原样落地;端口修复按 cabac58 意图在最新 main 重新实现(原补丁不可直接应用),原断言一一改用分配端口未删减;W3 差距见评审包 | 仅测试与守护脚本 | 阶段 6 已通过 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 46e331a7a81c94c6f5881c997ae0aca45664c830 | 46e331a7a81c94c6f5881c997ae0aca45664c830 | 2026-10-19T14:38:46Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证(完成后填写)
- 结果:A1 实施完成(000a2d2),评审包已提交,等待用户阶段 6 人审;未合入。
- 验证:定向单测 PASS(SELF,67 测试,skipped=16 为真实二进制 NOT_RUN);PR CI(GATE)见合入与清理节;W3 差距为关键字级 SELF。
- 影响与剩余项:仅 Dev 测试与守护脚本;剩余项见评审包第 3 节(W3 余项、B、C、D、X3 链)。
## 规划进展与下一步
- 本次推进/剩余:A1、W3 余项已验收;剩余 B(W5/W7)、C(W8/W10)、D(W11–W13)、X3 产品链
- 首选下一任务:B(W5 追溯网 / W7 上下文提供方)子任务登记
- 推荐依据:W3 余项已于 2026-10-20 通过阶段 6;B/C 依赖 W3/W4 稳定
- 前置条件/待确认:W4 开放结构写入口前须先补节点种类放置检查(W3 评审非阻塞项 1,用户确认);RDM 文件与 IAM link(RDM iam-link-u2)可能重叠,启动前核对
- 预期产物/验收条件:按阶段 5 计划 W5/W7 验证节
- 重复任务核对:启动前核对
- 启动授权:待用户确定
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T14:37:49.134350+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "46e331a7a81c94c6f5881c997ae0aca45664c830",
"after_head": "46e331a7a81c94c6f5881c997ae0aca45664c830",
"branch": "main",
"target_branch": "main",
"target_head": "46e331a7a81c94c6f5881c997ae0aca45664c830",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=46e331a7a8",
"[remote] origin/main=46e331a7a8 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=4",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 46e331a7a8(完整:46e331a7a81c94c6f5881c997ae0aca45664c830)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "6cba29f361cd5d6ad7c8712594c53dd0899e10d1d89a2b510a8e85522b461cfa",
"receipt_sha256": "17f97ec95374ca86a9e49b4b7976cf318ae1f7ae5052d8a746ab219907e1be4c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/17f97ec95374ca86a9e49b4b7976cf318ae1f7ae5052d8a746ab219907e1be4c.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T15:01:26.746182+00:00",
"command": "python3 -m unittest tests.test_dhf_catalog_guard tests.test_svc tests.test_svc_recover tests.test_svc_realcombo",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-followup",
"before_head": "000a2d2ae0e29fecd42ff19bf2b42e430be22ef8",
"after_head": "000a2d2ae0e29fecd42ff19bf2b42e430be22ef8",
"branch": "feature/rdm-two-trees-followup",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
".........................[main 579aaee] rdm v2",
" 1 file changed, 1 insertion(+)",
" create mode 100644 marker",
"To /tmp/svc-db-regress-m9jw7ip3/rdmremote.git",
" 526900c..579aaee main -> main",
"..........................ssssssssssssssss",
"----------------------------------------------------------------------",
"Ran 67 tests in 44.079s",
"",
"OK (skipped=16)"
],
"output_sha256": "cdf6732fa953eedac3fcea3f5d042c64a3d16c93a94f76308a212256b05b75e2",
"receipt_sha256": "4642350698dad77b3ab2397ef089219380651672d7f76113650d942b31b2df7a",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/4642350698dad77b3ab2397ef089219380651672d7f76113650d942b31b2df7a.json"
}
```
| 同步(记录前对象) | 2b7fdc39a1f44163f4766701429d61ffd6926f1a | 26e4ea63918b813557022c6bc12c54ff9213e48d | 2026-10-19T15:05:52Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T15:06:00.721625+00:00",
"command": "python3 -m unittest tests.test_dhf_catalog_guard tests.test_svc tests.test_svc_recover tests.test_svc_realcombo",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-two-trees-followup",
"before_head": "dd2f8b1f240a74a0f467533512b88da541c19999",
"after_head": "dd2f8b1f240a74a0f467533512b88da541c19999",
"branch": "feature/rdm-two-trees-followup",
"target_branch": "main",
"target_head": "2b7fdc39a1f44163f4766701429d61ffd6926f1a",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
".........................[main e5428ad] rdm v2",
" 1 file changed, 1 insertion(+)",
" create mode 100644 marker",
"To /tmp/svc-db-regress-e8y1ohso/rdmremote.git",
" d78f4bf..e5428ad main -> main",
"..........................ssssssssssssssss",
"----------------------------------------------------------------------",
"Ran 67 tests in 41.981s",
"",
"OK (skipped=16)"
],
"output_sha256": "ea93eda4d2d37fcbe97d826cdda982a1a9274f27284dd7a930d09117de251e04",
"receipt_sha256": "0279d9b351beb2e54b662d4bc98b2b492c3898e931bd2a995ddb31c3e70f0fdb",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/0279d9b351beb2e54b662d4bc98b2b492c3898e931bd2a995ddb31c3e70f0fdb.json"
}
```
| 同步(记录前对象) | 7e6c544b3c25c510e3d928bfb4515937a1cd6696 | 85624242789c823b96f2adb080e11833f73352e3 | 2026-10-20T11:41:24Z |
| 同步(记录前对象) | 33d6ef69212595c680a744549986c19bb6acd6c3 | 1b286ec3e68260d9d25cb3ab651ede31143d5b06 | 2026-10-22T06:35:19Z |
@@ -0,0 +1,75 @@
# 独立代码 Review:feature/intent-multi-turn-a1(A1 多轮意图闭环)
- Reviewer:独立 CLI 会话(pi,未参与本分支实施)
- 日期:2026-10-22(UTC)
- 对象:`git diff 955a32de...9126b09b`(Dev 超级仓);组件焦点 `modules/backend a75783fd..9ee752c3`
- 任务卡:`.task/feature-intent-multi-turn-a1.md`(设计决定:run-cancel 为第一业务动作、30min TTL、revision、cmdbus 确认不变)
- 性质:findings-only,未改任何代码;只新增本报告文件。
## 1. 范围与方法
- 超级仓 diff:`policy/architecture-baseline.json` +3 边、`modules/backend` gitlink a75783fd→9ee752c3、任务卡新增。
- backend 组件 diff(3 commits,+3267/−21):新包 `internal/intentsession`、`internal/store/intent_session.go`(表 v52)、`internal/route`(Cancel 裁决)、`internal/server`(`intent_session.go`、`intent_cancel.go`、`server.go` chat 接线)、`cmd/storage-migrate`(copyOrder 补 intent_session)。
- 方法:全量逐文件静态精读 + 调用链追踪(chat postMessage → fuseIntentSession → route.Decide → admitIntentCommand → Bus.Dispatch / handleIntentCancel → dispatchCancel;runmgr HITL 转轨判定的 route 契约),测试断言逐条对照审查镜头。
### 测试执行(诚实出口:NOT_RUN)
- 本会话**未能复跑**聚焦测试(`go test ./internal/intentsession/... ./internal/route/... ./internal/server/...`):当前工作区组件 checkout 只部分物化——`modules/backend/deps/agent-system-core、error-code-system、logging-system、agent-document-renderer` 为空目录,go.mod replace 闭包无法解析;无网络;本机模块缓存仅有 2026-10-13 伪版本(≠本次 pin 的提交),用它们编译出的结果不能作为本 PR 的证据,故弃用。
- 尝试过程可复核:为诊断曾临时在 `modules/backend/deps/` 建指向超级仓 `deps/` 的符号链接并随即删除(超级仓 deps 亦缺上述四个组件,`go build` 报缺 go.mod 为证);现场已恢复,`git status --porcelain` 干净(见 §5)。
- 任务卡记录的 verify-a1b/a1c exit=0、批二 CI 全绿:本会话无法重放,按 `[未经证实]` 处理;下述结论全部来自静态审查。按任务单要求未跑 `make test`。
## 2. 按镜头的结论(spec / security / regressions / tests)
**spec(多轮闭环)**:缺槽动作 → 澄清(`suspendIntentSession`,intent_session.go:273-310)→ 回答折叠(`fuseIntentSession` → `ApplyAnswer`,slot 齐则合成与完整识别同形的 MatchResult 走同一准入/派发路径,server.go:1252-1258 + intent_session.go:110-155)→ 完成;TTL 30min、写时续期、读侧惰性删除(intentsession.go:12-13、344-357);revision 单调、`ErrStale` 拒绝陈旧回答(intentsession.go:206-212、359-364);双用户/项目/会话键隔离(store 全查询带 owner 过滤)。主链路成立,测试覆盖到每一环。**例外见 B1/M1**。
**security**:会话不携带授权——补齐后仍走 `admitIntentCommand` + `Bus.Dispatch`,高危确认卡由 cmdbus 收口(TestIntentSessionStillRequiresHighRiskConfirmation 断言确认前处理器不执行);取消经 `run.cancel` 注册命令走同款 Dispatch,卡确认前不记「已取消」(intent_cancel.go:150-186,TestIntentCancelSurfacesHighDangerConfirmCard 覆盖确认→执行全链);跨用户运行 `GetRun(owner,…)` 不可见即澄清、不泄露存在性(intent_cancel.go:73-79,TestIntentCancelNeverResolvesAnotherOwnerRun);候选只列本人本会话未终态运行(intent_cancel.go:97-112)。**例外见 M2**。
**regressions**:无挂起预期时 fuse 段空转,`TestIntentSessionLegacyResponsesUnchanged` 做逐字节对照;route 契约——cancel 移出 unconsumedKinds 但 `StartFound` 刻意不置位(route.go:181-188),runmgr HITL 转轨判定(runmgr.go:2331-2334 只看 StartFound)行为与 main 一致;U6 准入——fused 结果同样过 `dispatchCommand`(res.Complete())与 `admitIntentCommand`(声明 schema 映射、必填不满足即 Blocked)两道闸,非法/缺失槽位不可能执行。**例外见 M1(累计槽位跨任务泄漏)。**
**tests**:覆盖面好——触发条件(有/无挂起、同意图/异意图、过期、隔离)、revision、高危确认、legacy 逐字节、显式/会话/歧义靶子、确认卡。缺口:无「同会话内换任务(异意图)再挂起」用例(正是 B1 场景);无真实并发写测试(revision 逻辑覆盖属逻辑等价,可接受);`answerFromRecognition` 显式落槽不看意图归属(intent_session.go:203)无专项用例。
## 3. Findings
### Blocker
**B1(spec/正确性)换任务再挂起时,上一个动作的累计槽位被继承,可把陈旧值派发给新动作。**
`Service.Suspend` 无条件合并旧行槽位:`slots = mergeSlots(cur.Slots, slots)`(internal/intentsession/intentsession.go:193-194)。宿主侧 `suspendIntentSession` 对「route 层槽位未就绪」的新动作一律走 Suspend(internal/server/intent_session.go:273-310),不区分新旧预期是否同一动作。可达序列(同会话、TTL 内):
1. T1 意图 A(如 `demo.run-cancel`)缺 reason → 挂起,累计 `{run_id: R-7}`;
2. T2 用户改做意图 B(如 `demo.purge`,缺 scope)→ fuse 判「异意图、无落槽」不碰会话(intent_session.go:124-127)→ route 澄清 → `Suspend(B)` 继承 `{run_id: R-7}`;
3. T3 用户补 scope → `ApplyAnswer` 合并全量槽位判齐(intentsession.go:227)→ `completedRecognition` 以累计槽位派发 B(intent_session.go:245-262);
4. `mapSchemaParams` 只丢弃**未声明**键,B 声明过的 `run_id` 会带陈旧值 R-7 进 params(internal/server/intent_admission.go:69-84)——若 run_id 是 B 的必填,准入反而被陈旧值满足。
这与包自己的不变量直接冲突(「绝不允许旧槽位漏进新任务」intentsession.go:25;「别的任务的输入绝不混进当前动作」intent_session.go:53、188)——该保护只做在了 fuse 的回答投影上(answerFromRecognition 异意图不并入,intent_session.go:180-208),Suspend 覆写预期时漏了。建议:Suspend 时若 `cur.Expectation` 存在且 `IntentID/Action` 与新预期不同,则丢弃旧累计槽位(或显式要求宿主先 Drop);并补「异意图换任务」回归用例。涉同一镜头的次生风险见 minor m4。
### Major
**M2(security/错误路径)`applyCancel` 吞掉存储错误后,可能把「放弃补槽」滑成「立即取消一个真实运行」。**
同意图取消的设计语义是只清挂起预期、不派发(intent_session.go:20-24)。但 `applyCancel` 对非 ErrStale 的存储错误同样返回 nil 且错误被丢弃(internal/server/intent_session.go:165-170),`fuseIntentSession` 整体返回无会话语义 → postMessage 继续走 `route.KindCancel` 规划(server.go:1273-1279)。此时挂起行的 `run_id` 槽位经 `sessionRunTarget`→`Binding` 仍解出靶子(intent_session.go:313-327),`planIntentCancel` 对发起人可见即放行;若部署未注册 `run.cancel`,走 `dispatchCancel` 本地路径**立即 `CancelRun`、无任何确认**(intent_cancel.go:164-176)。即:一次瞬时存储故障把「算了不取消」变成「未确认取消 R-7」。建议:applyCancel 对 `err != nil`(非 ErrStale)向上传播错误(writeStoreErr),fail-closed。
### Minor
- **m1(文档失实)** `internal/store/intent_session.go:11-12` 声称该表「不进 storage-migrate 的 copyOrder(同 admission_leases)」,但 `cmd/storage-migrate/main.go:311-313` 已把 `intent_session` 加入 copyOrder(且是清单夹具测试 `main_test.go:218` 的强制要求,9ee752c 补得对)。代码正确、注释过期,需同步删改;旧源库缺表已有 `sqliteHasTable` 跳过(main.go:400-402),无行为问题。
- **m2(回话如实性)** 总线路径派发被拒(StateRejected)时 `cancel.accepted=false` 但 `cancel.reason` 为空(internal/server/intent_cancel.go:142),与本地路径「失败带原因」不对称;receipt 虽随响应透出,建议把拒绝原因写入 `result.Reason`。
- **m3(过期边界 fail-open)** `expires_at` 解析失败得零值时 `live()` 视为「永不过期」(intentsession.go:366-373 + store `parseTime` 容错返回零值)。当前写入方恒写 TTL,风险仅来自自身写坏的数据,但与全文件 fail-closed 纪律不一致:解析失败宜按已过期处理。
- **m4(与 B1 联动)** 显式 `set_slot/change_slot` 命令「不看意图归属」直接写入当前挂起预期(intent_session.go:196-203,注释称有意)。B1 修复(换任务即弃旧槽位)落地后,此路径仍可把异动作的落槽命令并入当前预期;建议改为「命令名 ∈ 当前预期 Missing/声明键才采纳」,或补用例锁定现状语义。
### Notes
- **n1** 「放弃补槽」轮仍按 KindTurn 起普通回合(server.go:1273-1279 不改 routeKind;1340-1345 仅 KindCancel 拦截),响应同时带 `intent_session` note 与 run——与 main 上 cancel 落 turn 的旧行为一致,测试未固定该组合,建议在任务卡确认一次。
- **n2** `completedRecognition` 不搬运 `Risk/RequiresConfirm`(intent_session.go:245-262):全仓 grep 确认 `Decision.RequiresConfirm` 目前无消费者(route.go:114-116 仅透传),确认权在 cmdbus danger,今日无行为影响;将来若有人消费该字段,fused 路径会静默不同——建议留注释或补字段。
- **n3** `PutIntentSession` upsert 后读回非原子(store/intent_session.go:74-93),并发双写可能都读到同一新 revision;当前会话请求路径单写者,无实害,建议加注释固化「每会话单写者」前提。
- **n4** 未注册 `run.cancel` 的本地回落取消无确认卡——与既有 `POST /api/runs/{id}/cancel` 逐字同款、属设计决定(任务卡决定 1/4 与 intent_cancel.go:15-17 注释一致),非本 PR 引入;注册了命令的部署确认链有测试护栏。记录在案以回应「确认是否被绕过」镜头:**会话路径在命令注册时不绕过确认**。
- **n5** 架构基线 3 条新边与实际 import 逐一核对相符(intentsession→intentgate/store;server→intentsession);基线治理测试本会话未复跑(同 §1 NOT_RUN 原因)。
- **n6** 任务卡记载的 svc governance 偶发失败为已知预存问题、按任务单不属本次范围,未复跑 `make test`。
- **n7** 测试缺口清单:异意图换任务再挂起(B1 回归用例)、applyCancel 存储错误注入、显式落槽跨意图(m4)。
## 4. 结论
主链路(挂起→澄清→补齐→同路派发)、过期隔离、revision、双用户隔离、取消三态(显式/会话绑定/歧义→如实澄清)与 cmdbus 确认收口均实现且有测试护栏,route/runmgr 契约保持。但以下问题应先修再合:
- Blocker B1:跨动作挂起继承旧累计槽位,陈旧值可进新动作派发参数(intentsession.go:193-194;admission 只滤未声明键)。
- Major M2:applyCancel 吞存储错误 fail-open,可滑向无确认的本地取消(intent_session.go:165-170 → server.go:1273 → intent_cancel.go:164-176)。
- Minor m1–m4 建议随修复一并处理(m1 文档、m2 回话、m3 过期 fail-closed、m4 落槽归属)。
最终判定(理由如上三条):
REVIEW VERDICT: BLOCK
@@ -0,0 +1,44 @@
# Independent Code Review — feature/exec-recovery-diagnostics-a2 (A2 run diagnostics)
- Reviewer: independent CLI review session (`a2-independent-review` unit; fresh session, not the implementer)
- Date: 2026-10-22
- Review object: this checkout @ `d0b2bde9` (branch `feature/exec-recovery-diagnostics-a2`) versus authoritative main. No `origin/*` refs exist in this sandbox; task card R0 = `c9244328` (= `d0b2bde9~5`, the merged main tip `c92443280ef8e9ed29bf5bf5250df650c01b4478`), so `git diff c9244328...d0b2bde9` ≡ `git diff origin/main...HEAD`.
- Dev-level scope: task card `.task/feature-exec-recovery-diagnostics-a2.md` (new), `modules/backend` gitlink `9ee752c3` → `06b0c9f1`, `policy/architecture-baseline.json` +3 edges. Verified: dev diff is exactly these 3 files; the three edges (`backend/rundiag backend/cmdbus`, `backend/rundiag backend/store`, `backend/server backend/rundiag`) sit in correct sorted positions and match the actual import graph (see N5).
- Backend scope: `git -C modules/backend diff 9ee752c..06b0c9f` — 7 files, +1418/−0: `internal/rundiag/rundiag.go` (488), `internal/rundiag/rundiag_test.go` (440), `internal/server/run_diagnostics.go` (32), `internal/server/run_diagnostics_test.go` (226), `internal/server/server.go` (+2), `internal/store/run_diagnostics.go` (110), `internal/store/run_diagnostics_test.go` (120).
- Method: read-only review of the full diff plus the neighboring run-read/cancel routes, the pre-existing store methods the aggregator reuses, and the cmdbus pending-confirm write path. No code changed; the only write is this report.
## Findings
### Blockers
None.
### Major
None.
### Minor
- **MI1 — Evidence-driven wait states outrank terminal run statuses; a completed/failed run can be reported as `waiting_hitl`.** In the responsibility switch the HITL arm `case ev.Run.Status == core.RunWaitingHITL || card != nil || decision != nil` (`modules/backend/internal/rundiag/rundiag.go:252`) is evaluated before `failed` (:281) and `completed` (:296). A run that ended while a decision card scoped only by owner+conversation (human_decisions has no run column; attributed by the time-window inference at :432-448) remained `pending`, or with a leftover unresolved run-scoped HITL card, yields `state=waiting_hitl`, `role=human`, `next_step.action=confirm_card` for a terminal run. This is exactly the fixed precedence the task card approved and the documented bounded attribution (`rundiag.go:15-19`), and `run.status` stays visible in the report — but a follow-up that suppresses evidence-driven wait mapping (or adds a note) when the run is terminal would remove the confusing "confirm card" advice on finished runs. Not blocking: matches the approved design; purely advisory output.
- **MI2 — Silent truncation of side-effect evidence contradicts the package's own honesty contract.** `sideEffects` stops appending at `maxSideEffects = 50` with no note (`rundiag.go:342-366`, cap at :57), and `Gather` fetches only the 200 newest audit envelopes (`maxAuditScan`, `rundiag.go:175` → `ListAudits` orders `time DESC`, `internal/store/audit.go:147-152`), so a busy conversation can under-report a run's operations without any indication. Every other evidence gap in the package adds a note (even "absence of records is not proof of no effect", :313-315); a "side effects truncated" note would complete that contract. Diagnostic-only impact; recorded evidence is still correct as far as it goes.
- **MI3 — Precedence is tested only at the top of the chain.** Of the ordered arms at `rundiag.go:224-310`, only "unreleased recovery hold wins over everything" (`rundiag_test.go:81-89`) exercises interleaved evidence; combinations such as released-hold+interrupted+open-HITL-card (→ `reconciling`) or decision+pending-confirm (→ `waiting_hitl`) are untested and rest on the switch order alone. Low risk because the order is literal and table-covered per state; suggesting coverage only because precedence is the stated spec center of this unit.
### Notes
- **N1 — Per-state derivation and precedence are complete and match the task-card contract.** All eight states are derivable: `unknown` fail-closed on unreadable hold (:226-233), `recovery_hold` on an open hold row (:234-240), `reconciling` for released-hold+`RunInterrupted` residue (:241-251, predicate at :402-403), `waiting_hitl` from status/run-scoped card/time-windowed decision (:252-273), `confirmation_pending` from an owner-scoped pending confirm parsed out of the dispatch payload (:274-280, :453-471), `failed` with retry-safety gated on unknown receipts (:281-295), `completed` (:296-298), `running` for running+pending (:299-303), `unknown` default for unmapped statuses (cancelled; interrupted without hold; :304-310). Precedence order is exactly `recovery_hold > reconciling > waiting_hitl > confirmation_pending > failed > completed > running > unknown`, with the fail-closed `HoldUnknown` degradation deliberately first.
- **N2 — Security: scoping is byte-for-byte the neighboring run-read pattern; no cross-owner leakage path exists.** The handler resolves the run via `s.st.GetRun(s.owner(r), r.PathValue("id"))` (`internal/server/run_diagnostics.go:25`) — identical to `getRun` (`server.go:1592`) — where `owner` comes only from the auth context (`auth.go:220-225`), `GetRun` filters `WHERE id=? AND owner=?` with cross-tenant = `ErrNotFound` (`messages.go:307-316`), and `writeStoreErr` maps it to 404 indistinguishable from a missing run (`server.go:2617-2620`). Every follow-on query is keyed on the already-authorized run's own fields, never on request parameters: `GetRecoveryHold(run.ID)` (`recovery_holds.go:36`), `ActiveHITLCardsByRun(run.ID)` (`recovery.go:156`), `PendingHumanDecisionsByConversation(run.Owner, run.ConversationID)` with empty-owner defense (`store/run_diagnostics.go:51-53`), `ListOwnerPendingConfirms(run.Owner)` (:88-90), `LastRunCheckpoint(run.ConversationID, run.ID)` (:28-30), `ListAudits(run.Owner, run.ConversationID)` (`audit.go:134-140`). The `pending_confirms` payload is parsed only to extract command/owner/conversation identity; the raw payload is never echoed (`rundiag.go:453-471`).
- **N3 — Read-only holds end to end.** All six store entry points the aggregator uses are SELECT-only (verified by reading each); `Build` is a pure function; the handler path contains no store write and the mux registers only the GET pattern (`server.go:396`). The author's `TestRunDiagnosticsIsReadOnly` additionally asserts the run row and hold are unchanged after a GET and that POST/PUT/DELETE/PATCH are not served (`run_diagnostics_test.go:153-193`).
- **N4 — No route-registration conflicts.** `GET /api/runs/{id}/diagnostics` differs from `GET /api/runs/{id}` (:394) and `POST /api/runs/{id}/cancel` (:393) by a literal extra segment / method; ServeMux precedence is specificity-based, single registration, no duplicate pattern anywhere in the diff.
- **N5 — Architecture-baseline edges are correct and validated.** `internal/rundiag` imports exactly `cmdbus` and `store` within the backend module (`rundiag.go:21-24`); the `agent-command` import is intentionally untracked — the baseline records only intra-repo package edges and has no deps-module edges anywhere (same precedent as `backend/cmdbus`, which also imports agent-command without an edge). `backend/server backend/rundiag` matches the handler import. Sorted positions are correct (`route < rundiag`; `ratelimit < rundiag < runmgr`), and `scripts/lint-architecture.go` compares this file against the collected import graph, so the edges are machine-checked in CI.
- **N6 — Go tests NOT_RUN in this review workspace (environment, not code).** The backend's nested dependency checkouts (`modules/backend/deps/agent-command`, `deps/agent-system-core`, …) are empty gitlinks here and no `.git/modules` gitdirs exist; `git submodule init/update` is forbidden for this unit and network is off, so `go build ./internal/rundiag/ …` fails at module setup (`agent-command@v0.0.0 (replaced by ./deps/agent-command): reading deps/agent-command/go.mod: no such file or directory`), before any code compiles. Fallbacks applied: every changed file was fully line-read; all `core.Run*`/phase/event symbols referenced are used by pre-existing compiling backend code; `cmdbus.Request` carries `ID/Owner/ConversationID` (`cmdbus.go:163-177`) and the pending-confirm payload is the marshaled dispatch request (`cmdbus.go:522-523`), so `waitingConfirm`'s parsing is sound; the `events` table has `run_id`/`seq`/`ts`/`type` in both dialects (`migrate.go:47,71`) and the checkpoint query is served by `idx_events_conv(conversation_id, seq)`. Author-recorded receipts were reviewed and are internally consistent with the task card: `/tmp/agent-stack-b2/verify-a2b.json` (`go build ./... && go test -count=1 ./internal/server/... ./internal/rundiag/... ./internal/store/... && go vet …`, exit=0, `ok agent-system-backend/internal/{server,rundiag,store}`) and `/tmp/agent-stack-b2/verify-a2-combo2.json` (`make test`, exit=0) — author-claimed (SELF), not independently re-executed in this session.
- **N7 — Attribution boundaries are documented and bounded; one sibling-run overlap remains.** Audit envelopes carry no runId today (host bus doesn't write it), so `belongsToRun` (`rundiag.go:371-383`) attributes by conversation + "not issued before run start". Concurrent sibling runs (subagents) in the same conversation have overlapping windows, so until the bus persists `runId`, an envelope from a sibling can appear in both runs' `side_effects`. The limitation is stated in the package doc (:17-19) and the report surfaces `operation_id`/`command_id` so a human can disambiguate; when the bus starts writing `env.RunID` the strict branch (:372-373) takes over automatically. Acceptable for a diagnostic surface.
- **N8 — "No records ≠ no effect" honesty contract is consistently enforced** (unrecorded checkpoints → null + note at :311-312, tested at `rundiag_test.go:280-302`; empty side effects → note :313-315; unreadable hold → fail-closed unknown that can never yield `safe_retry` :226-233, tested :304-339). Only the truncation gap of MI2 falls short of it.
## Lens summaries
1. **Spec** — pass. State derivation and precedence are complete and per-state correct (N1); the JSON contract (snake_case, `last_checkpoint` explicit null, `side_effects` always an array, `next_step` never reason-less) is pinned by `TestReportJSONContract` (`rundiag_test.go:341-389`). Dev-level artifacts (task card, 3 baseline edges, gitlink `06b0c9f`) are exactly as claimed.
2. **Security** — pass. Auth-context-only owner, tenant-filtered run fetch, 404 on cross-owner/missing (tested `run_diagnostics_test.go:62-97`), all downstream reads anchored on the authorized run, strictly read-only (N2/N3), no payload echo, empty-owner fail-closed store helpers.
3. **Regressions** — pass. The diff is additive: 7 new files plus a 2-line route registration; no execution/recovery/runmgr path touched, no existing signature changed, no route conflicts (N4), no migration/schema/index change.
4. **Tests** — pass with minor gaps. Per-state table of 12 cases covering all eight states plus degradation (`rundiag_test.go:78-225`), scoping at both server and store layers including cross-owner/cross-conversation/empty-owner (`run_diagnostics_test.go:62-97`, `store/run_diagnostics_test.go:13-120`), unknown-degradation at three levels (unreadable source, unmapped status, fail-closed hold; `run_diagnostics_test.go:195-226`), read-only and write-method rejection (`:153-193`), pre-run evidence exclusion (`rundiag_test.go:391-406`). Gaps: MI3 (chain precedence below the top arm), MI2 (truncation without note). Focused tests could not be re-run here (N6); author receipts for `go test ./internal/rundiag/... ./internal/server/... ./internal/store/...` and full `make test` are on record and uncontradicted.
REVIEW VERDICT: APPROVE
@@ -0,0 +1,48 @@
# 独立代码 Review:feature/catalog-recall-eval-a3(A3 召回评测集与指标基线)
- Reviewer:独立 CLI session(未参与本单元实施;本报告为唯一产出变更)
- 日期:2026-10-22
- Review 对象:`git diff 6ced938a...HEAD`(6ced938a = R0 / origin-main 合入点,与任务卡 R0 一致)
- 组件重点:`deps/agent-intent` 765a7e7..6aa4925(单提交 "Add the sanitized recall evaluation set and metrics baseline",9 文件 +1354/-18);Dev 层 4 个 gitlink 前移 + 任务卡
- 方法:全量 diff 阅读被测文件;对语料/指标做独立的脚本化交叉复核(只读);静态追踪指标口径、生成回放路径与 JSON 兼容性;检查嵌套 pin 级联与越界改动。聚焦测试见下文 NOT_RUN 说明。
## 复核结论摘要(独立重算,非转抄)
- 语料 `intent/testdata/recall_corpus.json`:**37 例 / 46 轮**,五类齐全且恰好五类(expired_confirmation 7/14、generation_consistency 8/8、multi_intent 7/7、negation_reference 8/10、wrong_slot 7/7),`record_only: true`;`expect_top` 轮次 31、生成用例 8 —— 与 BASELINE.md 表头逐项一致。
- 语料 digest `sha256:53d26cfc…bc2885` 与 `evaluation/metrics.json` 的 `corpus_digest`、BASELINE.md 摘要三方一致(本机 `sha256sum` 独立重算)。
- `evaluation/metrics.json` 全部 10 组计数与比率逐项等于 BASELINE.md 表;比率均可用 `round(n/d*10000)/10000` 独立复算(如 30/31→0.9677、13/46→0.2826、6/46→0.1304、5/14→0.3571、5/8→0.625、5/7→0.7143、3/7→0.4286)。
- 总体口径自洽:top1_expected 3+3+7+11+7=31、hits 30(唯一 miss 即 multi_greet_then_report 的 1 次误执行)、mis_exec 5+1=6、clarify 0+0+5+5+3=13、fallback 2+0+0+3+0=5+1(gen)=6、pass 3+6+7+7+8=27。
- 嵌套 pin 级联一致:native@d1f72aa→intent@6aa4925;squad@a5afe9c→intent@6aa4925+native@d1f72aa;backend@8dc91c1→intent@6aa4925+native@d1f72aa+squad@a5afe9c(各自 `git ls-tree` 核对);三个组件 bump 均为 pins-only(`git diff --stat` 仅 gitlink),superrepo 层 diff 仅 4 gitlink + 任务卡,无评测范围外源码改动。
## Findings
### Blocker
无。
### Major
无。
### Minor
1. **基线数值漂移不设防(结构性盲区,刻意取舍但建议记录)** — `intent/recall_eval_test.go:119-162`(`checkSummaryJSON`/`checkMetricsBounds`):结构测试对已提交基线只校验 schema、digest、类别计数与「内部一致」(rate==ratio(n,d)),不把基线里的 hits/rates 与本次新鲜运行比对。若识别器行为改变而语料不变(digest 不变、计数不变),过期的基线数值不会被任何测试发现;BASELINE.md「重跑」一节只靠流程约束。这与「只记录不设阈值」的定位一致(比对数值即变相质量断言),属可辩护的设计取舍,但建议在 BASELINE.md 明示「引擎变更不会触发基线失效告警,须人工重跑」。
2. **missing-slots 断言用 `fmt.Sprint` 比较切片** — `intent/corpus.go:194-222`(`matchTurn` 中 `fmt.Sprint(got) != fmt.Sprint(turn.ExpectMissingSlots)`):`[]string(nil)` 与 `[]string{}` 都打印 `[]`,且比较对元素顺序敏感。当前引擎输出顺序确定、语料只断言单元素缺失(`["run_id"]`/`["topic"]`),不构成现实缺陷;但后续一旦断言多缺失槽位,顺序耦合会变成脆弱测试。建议改为逐元素显式比较。
3. **任务卡内部记录不一致(文档级)** — `.task/feature-catalog-recall-eval-a3.md`:「Agent 实施收据」表全部为 NOT_RUN/待定义 占位,而「合入与清理」节已记载 `a3-recall-eval-dataset(…intent 6aa4925,verify-a3 exit=0)`、嵌套级联与 `组合验证:全量 make test PASS`;且「证据(Evidence)」表为空,组合验证结论以带外文件名(verify-a3-combo3.json 等)引用。按仓库门禁「命令输出只经 make evidence 写入任务卡」,合入前应把收据表与证据表补齐一致。不阻塞本次代码评审结论。
### Notes
1. **指标口径正确** — `intent/evalmetrics.go:129-141`(`misExecuted`):仅当实际 `matched`/`expectation_hit` 出 Top 且与期望动作不同时计数;期望 matched/expectation_hit 而未写 expect_top 的轮次不约束动作,不计;期望 fallback/ambiguous/guard_hit 却执行了即计。与 BASELINE.md「指标口径」一节逐条一致。分母:top1=写了 expect_top 的轮次(`evalmetrics.go:103-108`)、clarify/fallback=全部轮次(`evalmetrics.go:111-118,153-159`)、gen_agree=写了 generator_commands 的用例数(用例级,`evalmetrics.go:120-124`)。`ratio` 定点 4 位舍入保证 JSON 字节稳定(`evalmetrics.go:161-166`)。
2. **汇总对账安全** — `intent/evalmetrics.go:61-92`(`SummarizeCorpus`):cases/results 按下标一一对应(越界即 break,契约已在注释声明),空 category 归入 `uncategorized`(旧语料兼容),类别名升序、overall 独立。`intent/eval_test.go:78-89` 在既有 `corpus.json`(无 category)上跑了一遍汇总,兼容路径有覆盖。
3. **生成回放路径离线、确定性、fail-closed** — `intent/corpus.go:156-186`:`replayGenerator.Generate` 忽略输入与目录、只回放脚本命令(无模型/无网络),并深拷贝 slots 防串染;`compareGeneratorPath` 复用识别器兜底同款 `generateCommands`(`intent/recognizer.go:352-385`:start 的 ActionRef 必须从同一快照唯一解析、命令种类受限、槽位键集校验,任一不过即无 Top)。三个「故意不一致」用例路径成立:`run_id=43` 槽位分歧(sameSlots 判否)、`taskrun.restart` 错动作(handler 反查到 restart spec)、`ghost.flow` 幻觉动作(resolveActionRef 失败→校验拒绝→无 Top)。两边都无 Top 也算一致,`gen_chitchat_agree` 覆盖该分支。Nil expectation 传入 `NewRecognizer` 在该路径安全(`generateCommands` 不触达链式预期)。
4. **eval 向后兼容** — `cmd/intentctl/main.go:254,260-262,365-390`:`-metrics-out` 缺省为空不写文件(唯一新增写文件入口,显式 opt-in;`-` 走 stdout);旧语料(无 `record_only`)失败语义不变,且 `TestEvalRecordOnlyWritesMetrics`(`cmd/intentctl/main_test.go:79-112`)同时断言 record_only 不失败+strict 语料仍失败。输出新增的指标表为追加行,不破坏既有两行指标输出。`evalCorpus` 结构仅增可选字段(`omitempty`),旧 JSON 解析不受影响。
5. **结构测试无质量阈值伪装** — `intent/recall_eval_test.go:64-117`:只断言 ≥30 例、恰好五类、每例可执行(无「识别错误」)、generation_consistency 用例形态、JSON 合法且计数与语料一致、基线 digest 与语料一致;`checkMetricsBounds`(:164-186)只做数学界校验(n≤d、rate==ratio)。无任何质量数值断言,符合「基线只记录」边界。测试与 CLI 同源建快照(:36-62,语料自声明 builtin_specs/guard/protected + 同款 specs 目录),指标同源声明成立。
6. **语料确为夹具派生、五类行为真实可辨** — 全部期望 top ∈ {demo.run.status_query/restart/cancel, demo.greet.hello, demo.misc.deploy, report.generate, guard.config_change},动作 id ∈ base.json 的 handler 集 + 刻意的幻觉 id;生成动作 id 与 `intent/testdata/specs/base.json` 的 handler/action 一一对应。各类用例确实 exercising 所标行为:语义否定(「不要/别/不用/先不要」无 excludes 声明,理想为 fallback)对照 `excludes_any` 声明否定(「配置」);multi_intent 覆盖 动作+动作→ambiguous、寒暄+动作→动作、动作+guard→guard_hit;wrong_slot 覆盖 缺失/中文数字/双候选/越字符集/仅符号/空主题;expired_confirmation 覆盖 链式命中、过期后裸回答回落、过期后完整重述走 matched、宿主声明 pending 再过期(`pending_expectation`+`expectation_expired` 组合,语义为「先声明后作废」,实现顺序 `intent/corpus.go:120-126` 与用例意图一致);wrong_slot 用单轮 `turns` 包装以使用本轮新增的 `expect_slots`/`expect_missing_slots` 能力。
7. **安全边界** — 语料全合成(无真实用户数据/PII);`record_only: true` 无阈值断言;生成路径为确定性回放,无网络/模型调用;未发现任何对外部输入的写路径(除显式 `-metrics-out`)。
8. **聚焦测试 NOT_RUN(环境受限,非变更缺陷)** — `cd deps/agent-intent && GOWORK=off go test ./intent/...` 无法编译:`agent-intent` 的嵌套 gitlink(deps/error-code-system@a3ee67b、logging-system@49b5d8b 等)在本工作区未物化,且目标提交不在任何本地对象库(`git cat-file` fatal)、无网络。按诚实出口如实标注 NOT_RUN;作为补偿,本文「复核结论摘要」的计数/digest/比率均为独立脚本重算,与基线三方对账一致。任务卡所记 `make test PASS(verify-a3-combo3.json exit=0)`本评审无法复现,标注 [未经证实](属 host 组合门禁范畴,不阻塞代码评审)。
## Verdict
未发现 blocker/major 级代码缺陷;三项 minor(基线漂移不设防的取舍说明、fmt.Sprint 切片比较的脆弱写法、任务卡收据/证据表未同步)均不阻塞合入,可在本次或后续增量处理。语料、指标、基线、CLI 兼容、结构守卫与嵌套 pin 级联均通过独立静态复核与数值对账。
REVIEW VERDICT: APPROVE
@@ -0,0 +1,72 @@
# Independent Code Review — feature/audit-followups-pin-gate-m5
- Reviewer: independent CLI review session (audit-followups-independent-review unit; fresh session, not the implementer)
- Date: 2026-10-22
- Review object: this checkout @ `a2b4cf73` (branch tip `feature/audit-followups-pin-gate-m5`, detached HEAD) versus `origin/main`. No `origin/*` refs exist in this sandbox, so the diff was taken against the merged authoritative main tip `d65195bd` (PR #691 merge, second parent of `a874ee60` "Merge authoritative main into the task branch"); `merge-base(d65195bd, HEAD) = d65195bd`, so `git diff d65195bd...HEAD` ≡ `git diff origin/main...HEAD`.
- Scope claims under review:
1. Dev: new `scripts/check_pin_regression.sh` wired into `scripts/check-pins.sh` and `scripts/task_pr_check.py`; tests `tests/test_check_pins.py` (+1 case) and `tests/test_check_pin_regression.py` (new, 13 cases). Motivating incident: PR #682 (stale branch silently resetting component pins over main).
2. `deps/agent-native` `cff69355` → `f2fb9ffa` (review-M5 fix: Writable preflight rejects subagent delegation).
3. Gitlink-only pin advances in `deps/agent-squad` `9edb6ba8` → `b6d87638` (nested native `f2fb9ffa`) and `modules/backend` `7bcbbdb3` → `a75783fd` (merged upstream `7bcbbdb` line + parallel work `443e7af`; nested native `f2fb9ffa`).
- Method: read-only review of `git diff d65195bd...HEAD` (9 files, +479/−4) plus per-submodule commit/tree diffs; focused checks run where this worktree permits (see Verification runs). No code was changed; the only write is this report.
## Findings
### Blockers
None.
### Major
- **MA1 — The CI leg of the pin-regression gate is a structural no-op; all enforcement rests on local full-clone runs.** All three CI checkout jobs fetch a raw object id shallowly and detach (`.gitea/workflows/ci.yaml:152,336,661` — `git fetch --depth=1 origin <sha>` then `checkout -q --detach FETCH_HEAD`), which writes only `FETCH_HEAD` and never creates `refs/remotes/origin/main` (empirically confirmed in a scratch repo: after a raw-SHA shallow fetch, `git rev-parse --verify origin/main^{commit}` fails). `check_pin_regression.sh:24-27` treats an unresolvable `origin/main` as "warn + exit 0" (documented shallow-checkout escape). Consequently `task_pr_check.py ci` (ci.yaml:162) and the CI `make test` → `test-pins` leg can never fail a PR on pin regression — the exact incident shape #682 (a stale branch merged through CI) would again pass CI today. Mitigation: the delivery policy mandates a local PR check before acceptance/merge, and in a full clone (`make task-pr-check local`) the gate does enforce (verified below). Not blocking — the change is a strict improvement and the local leg is the mandated enforcement point — but the gate's stated purpose ("gitlink 相对 origin/main 不得倒退" as a PR gate) is not achieved in CI. Recommendation: in the reviewed checkout step, additionally fetch the base ref (e.g. `git fetch --depth=1 origin "refs/heads/${GITHUB_BASE_REF}:refs/remotes/origin/main"`) so `pin_regression_problems()` verifies real ancestry at gate time; the submodule materialization already produces full child clones, so the per-component `merge-base --is-ancestor` checks would then work offline.
### Minor
- **MI1 — Gitlink removals relative to `origin/main` pass silently.** The gate iterates only HEAD's gitlinks (`check_pin_regression.sh:71-72,95`); a component dropped from the Dev tree (present on base, absent in HEAD) is never compared, and `check-pins.sh` likewise only checks the containers it iterates (a container dropping one of its `deps/*` links is equally invisible). Not the #682 shape (reset, not removal), and "new pin not on base" is an intentional pass (line 74-76), but silent composition shrinkage is adjacent to the incident class this gate exists for. Suggest a follow-up that diffs the base/HEAD gitlink path sets in both directions.
- **MI2 — `pin_regression_problems()` runs the gate with no subprocess timeout** (`scripts/task_pr_check.py:222-224`). `ensure_commit`'s `git fetch` (`check_pin_regression.sh:48-54`) can hang on a black-holed connection and would stall the PR check until the runner/job timeout. Low practical likelihood (unchanged pins short-circuit at line 73 before any fetch; CI submodules are full clones), but a `timeout=` on the `subprocess.run` would bound it.
- **MI3 — Unreachable-but-confusing fail mode if a CI submodule lacks the old pin.** If `ensure_commit` ever needed to fetch in CI, the component remotes persist only the public URL (credentials live solely inside the checkout step's per-command env), so the fetch fails and the gate fails closed ("missing locally and could not be fetched", lines 80-86) — correct direction, but the PR author sees an unfetchable-pin error whose real cause is credentials/absence. With full submodule clones this should never trigger; noting for diagnosis only.
### Notes
- **N1 — Preflight placement is consistent with the sibling F02 checks; "zero side effects" holds for the meaningful claims.** The new check (`deps/agent-native/adapters/native/backend.go:228-230`) sits inside the existing `len(writable) > 0 && profile == exec.ToolProfileWorkspace` block (line 216) before any registry/session/model work. Workdir preparation above it (`MkdirAll`, `INSTRUCTIONS.md`/`TASK.md` writes) predates rejection — identical to the pre-existing exec/MCP/host rejections, and `TestContractWritableRejectsSubagentInPreflight` asserts the substantive zero-side-effect properties: no stream call, no factory call, no deliverable file, no `.agentx` session state.
- **N2 — `pin regression ok` (line 100) prints even when `PIN_REGRESSION_SKIP=1` downgraded failures to warns.** Exit status is the contract (0 with warns), and the warns are loud on stderr; cosmetic only.
- **N3 — Pre-existing gofmt deviation in `adapters/native/backend.go`** (struct-literal alignment around `runtime.NewAgentSession`, ~line 447). The file at the base pin `cff69355` fails `gofmt -l` identically; the changed hunk (212-230) is clean. Out of scope for this fix.
- **N4 — Pre-existing stderr noise `fatal: not a tree object` when a container directory exists but is uninitialized.** Reproduced as `git -C deps/agent-intent ls-tree <sha>` from an empty dir discovering the parent Dev repo (process substitution in `check-pins.sh:68`); pre-dates this branch and does not change its exit status. In this sandbox only `modules/backend`, `deps/agent-native`, `deps/agent-squad` are materialized.
- **N5 — Go tests NOT_RUN in this workspace (environment, not code).** `deps/agent-native/go.mod:10,12` replace `error-code-system`/`logging-system` with nested checkouts that are not materialized here, and the pinned commit objects (`a3ee67bb`, `49b5d8be`) are absent from every local object store (Dev, native, squad, backend); network access is forbidden for this unit, so the modules cannot be completed. `GOWORK=off go test ./adapters/native/...` therefore fails at module setup, not in code. Fallbacks applied: both changed files parse (`gofmt -e`) and were line-reviewed; the author-recorded evidence (`verify-m5.json` / `verify-m5-host.json` exit=0, quoted in commit `f2fb9ffa`) is uncorroborated in this session and treated as author-claimed.
- **N6 — Composition coherence verified (lens 3).** Nested pins agree at every level: native `f2fb9ffa` (Dev `deps/agent-native` = squad `deps/agent-native` = backend `deps/agent-native`), squad `b6d87638` (Dev = backend), intent `765a7e71` (Dev `deps/agent-intent` = native = squad = backend), core `0cf03446` (Dev `modules/core` = backend `deps/agent-system-core`), command `fe7987dc`, document-renderer `3f259990`, error-code-system `a3ee67bb`, logging-system `49b5d8be`; guidelines/manager deltas (`2688fd2`/`67784f43`/`bd3a7de5` vs Dev `a15db508`/`2c2e3725`) are warn-only by design (`check-pins.sh:57-62`). `bash scripts/check-pins.sh` exits 0 ("pins ok") in this worktree.
## Spec lens (1) — gate catches the incident shape; M5 preflight is exact
- Gate trigger: HEAD pin not a descendant of the base pin fails — stale reset (`test_pr682_stale_branch_carrying_old_pin_fails`) and diverged/rebased pins (`test_diverged_pin_fails`) both exit 1 with `moves BACKWARD` + `PR #682` guidance; forward move, same pin, base-pin-absent (`new, not on origin/main`), unresolvable `origin/main`, and `PIN_REGRESSION_SKIP=1` downgrade all exit 0. `task_pr_check.py ci` wiring hard-fails (`PR_CHECK_FAILED`) on regression and passes with the skip env (`test_task_pr_check_ci_hard_fails_on_regression`, `test_task_pr_check_ci_skip_env_passes`). All 19 Python tests pass in this workspace (Verification runs).
- M5 preflight: the rejection condition is exactly non-empty Writable ∧ workspace profile ∧ delegation enabled (`backend.go:216,228-229`). Delegation exists iff `b.opts.Subagent != nil` (`runtime/subagent/subagent.go:62-71` no-ops on nil factory; `delegate_task` is registered only in the workspace branch, `backend.go:265`), and Writable reaches `Execute` only via `withWritable(ctx, req.Workspace.Writable)` (`adapters/native/contract.go:66`) — the reasoning profile has no registry at all. Empty-Writable delegation is covered by `TestContractSubagentWithoutWritableStillDelegates` (delegate_task declared, factory invoked with the request fields). Side-effect escape confirmed closed: `tools.ApplyWriteAllowlist` runs before `subagent.Register`, so `delegate_task` never inherited the write-set — rejecting the combination is the right call, and `run_tool_script` cannot reach it either (it only invokes registered tools and bans re-dispatch).
## Regressions lens (2)
- `check-pins.sh` behavior when `origin/main` is absent: unchanged — live run exits 0 with "pins ok", the gate only warns (`check_pin_regression.sh:24-27`). The appended call is `|| fail=1` (check-pins.sh:67), so any gate crash also fails closed.
- `task_pr_check` callers: no signature/behavior changes to existing functions (`PIN_REGRESSION` const and `pin_regression_problems()` are additive; `cmd_local`/`cmd_ci` append/inject problems only). `scripts/test_affected.py:61-62` and `scripts/task.sh:699` import unaffected names. Remote-failure `Stop` paths still precede the gate (fail-closed elsewhere). `make task-pr-check` runs from the repo root, matching the gate's cwd→toplevel resolution.
- Delegation flows without Writable: backend `a75783fd` and squad `b6d87638` contain zero `Writable`/`ContractRequest` usage in non-test Go code (grepped) — no live composition flow can trip the new rejection; the preflight only fires for contract requests that declare both.
## Scope lens (3)
Dev diff touches exactly the declared files plus the task card (`.task/**`, host domain): `scripts/check-pins.sh` (+2), `scripts/check_pin_regression.sh` (new, 100 lines), `scripts/task_pr_check.py` (+17/−1 docstring+gate), `tests/test_check_pins.py` (+17), `tests/test_check_pin_regression.py` (new, 187 lines). Submodule ranges are integration-only as declared: native = 1 commit (`f2fb9ff` "Reject subagent delegation under a Writable write-set", parent `cff6935`, no other content); squad = 1 gitlink-only commit (`b6d8763`, `diff-tree` = `deps/agent-native` only); backend = 3 commits (`3ab7cd7` and `92c2b4e` gitlink-only pins; `a75783f` = merge of `7bcbbdb` into the pin line; tree delta vs `7bcbbdb3` is exactly the two nested gitlinks; contains both `7bcbbdb` and `443e7af`). Nothing rides along outside the declared fixes.
## Tests lens (4)
New tests assert the trigger conditions, not just exit codes: exact rejection reason string, no stream/factory invocations, no deliverable/session files (native); `moves BACKWARD` / `PR #682` / `PIN_REGRESSION_SKIP=1` message substrings, `ok <path>` / `pin regression ok` / warn lines, and `[verdict] PR_CHECK_FAILED` / `PR_CHECK_OK` plumbing (Dev). `test_check_pins.py` additionally proves the gate is actually wired inside `check-pins.sh` (copies both scripts into the fixture). Offline discipline is good: temp-dir repos, hermetic env, `GIT_CONFIG_NOSYSTEM=1`, env vars scrubbed in setUp, local bare remotes for the fetch paths.
## Verification runs (this session, foreground)
| Check | Result |
|---|---|
| `git diff --stat d65195bd...HEAD` | 9 files, +479/−4 — matches declared scope |
| `bash scripts/check-pins.sh` | exit 0, "pins ok"; gate warn-only (no origin/main); guidelines warns only |
| `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_check_pin_regression tests.test_check_pins -v` | 19/19 OK (0.796s) |
| `cd deps/agent-native && GOWORK=off go test -count=1 ./adapters/native/...` | NOT_RUN — module setup fails on unmaterialized replace targets (`go.mod:10,12`); objects absent everywhere; network forbidden (see N5) |
| `gofmt -e` on both changed native files | parse OK; `gofmt -l` deviation pre-existing (N3) |
| Raw-SHA shallow fetch → `origin/main` resolvability experiment | does NOT resolve (basis of MA1) |
| `make test` | intentionally NOT run per unit packet (known pre-existing `test_svc.SvcDbRecoveryTests.test_addr_change_keeps_database_and_auth` governance failure on clean main `b7636742`, recorded on the task card; CI is the final arbiter) |
## Verdict
The pin-regression gate correctly detects the #682 backward-pin shape (and diverged pins) while passing forward/same/new-pin moves and degrading safely without `origin/main` or via the owner-reviewed skip; the M5 preflight rejects exactly the unenforceable Writable+delegation combination with zero behavioral fallout for empty-Writable or non-contract flows; composition pins advance cleanly with no source riding along; the new tests assert real trigger conditions. The one substantive weakness (MA1 — CI leg cannot enforce due to the shallow raw-SHA checkout) is an enforcement-depth gap on a strictly-improving change whose mandated local enforcement point works; MI1–MI3 are bounded follow-ups.
REVIEW VERDICT: APPROVE
@@ -0,0 +1,47 @@
# 独立代码 Review:feature/recall-misexec-fixes(mis-exec 规则层修复)
- 日期:2026-10-22(评审执行于 2026-10-23 UTC 的分支对象上)
- 评审人:独立 CLI 会话(未参与实施;本文件为本次唯一变更)
- 评审对象:`git diff bccb88f2...HEAD`(= origin/main...HEAD;本 worktree 无 origin remote,bccb88f2 为 main 顶端合并提交,是 feature 分支的 merge-base)
- 组件范围:deps/agent-intent @6aa4925..7f3ff6a(单提交 "Make intent matching negation-aware and slots fail closed")+ gitlink 级联(native d1f72aa→be556f4、squad a5afe9c8→95b387d、backend 8dc91c17→8031855e→bd5c0f3)+ 任务卡 `.task/feature-recall-misexec-fixes.md`
- 方法:全文精读 9 个变更文件 + 逐条手工追踪语料用例 + 对否定判定函数做 stdlib-only 逐字提取探针验证(/tmp,脱离工作区);未修改任何代码。
## 验证(本工作区内的执行情况)
- `git status --porcelain`:评审开始时为空(clean);四个组件 checkout 均精确处于被 pin 的 SHA 且无脏文件(agent-intent 7f3ff6a、native be556f4、squad 95b387d、backend bd5c0f3)。
- `gofmt -l intent/ cmd/`:无输出(格式干净)。
- `go test`:**NOT_RUN(环境不可编译)**。agent-intent/go.mod 的 `replace error-code-system => ./deps/error-code-system` 所指嵌套子模块在本工作区任何层级都未物化(superrepo、agent-intent、backend 三处的 error-code-system/logging-system 目录均为空挂载点),且相应 commit 对象不存在于任何本地对象库;单元约束禁止 `git submodule init/update`、禁止网络。`GOWORK=off go test ./intent/...` 如预期在包 setup 阶段失败(reading deps/error-code-system/go.mod: no such file)。诚实出口:本报告的测试结论为读码+探针+追踪,非重放。
- 否定判定探针(negatedAt/inNonNegatingBie 逐字提取、21 组用例):全部 corpus 否定序列判否定;「不断」「无偿」不触发误否定;「不要马上重启」(间隔 2 字)判否定、「不要立刻马上重启」(间隔 3 字)不判(窗口语义);「特别的,重启任务」跨标点正确豁免;「任务别名重启」豁免成功;「判别任务进度」被误判否定(见 F1)。
## 评审发现
### Blocker
无。
### Major
无。
### Minor
- **F1(recall 损失,fail-safe 方向)**:「别」字白名单 `nonNegatingBie`(intent/registry.go:211-214)是封闭列表,「判别」「辨识」「作别」等含「别」的常用词不在列。探针实测「判别任务进度」→「进度」命中被 `negatedAt`(registry.go:263-275)判为否定 → status_query 以 `negated_match` 排除 → 回落 fallback。方向是安全的(少执行而非误执行),但对该输入是误回落。建议后续把「别」的否定判定改为右边界词表或按「别+动词」结构判断。
- **F2(残余否定词缺口,符合既定设计范围)**:token 表(registry.go:204)无「无须」「勿」「先不」「暂不」「不必」等变体,如「无须重启任务」仍会正向命中 restart。任务卡设计决定明确固定了这 7 个词,故不算实施偏差;作为残余风险记录:negation_reference 类的其他说法仍可能误执行。
### Notes
- **N1(tie-break 只认“有效”槽位)**:`resolveTie`(intent/recognizer.go:152-185)用 `len(slots)` 计数,invalid 捕获(如多候选值)不计。因此「你好,取消任务 42 和任务 43」这类输入中 cancel 的 run_id 无效 → filled=0,与寒暄同为 0 时按 priority(greet=10 > cancel=0)裁决到寒暄,动作侧的 clarify 丢失。仅在同分且优先级不同时可达,且寒暄无副作用、动作未启动,属可接受行为选择;若希望「带槽位信号」包含无效捕获信号,需另行设计。
- **N2(fail-closed 误伤面)**:`hasInnerSeparator`(slots.go:221)/`captureTruncated`(slots.go:201)对合法值也拦截——如主题「和平与发展」会因内部分隔词判多候选、值后紧跟 ASCII 词字符即判截断,一律 clarify 而非 start。与「无效一律 clarify」的设计一致,代价是 clarify 率上升(metrics 中 wrong_slot clarify 7/7=1.0),方向安全。
- **N3(测试夹具标签失真,表面问题)**:cmd/intentctl/main_test.go:82-85 把 record_only 的 miss 用例从「不用查进度了」换成「进度条的颜色真好看」是必要的(旧输入修复后正确回落,不再产生 miss 计数;新输入在 testSpecJSON 下确会命中 status_query,仍覆盖 miss 记账路径,断言 MisExecutions==1 成立),但 category 仍标 `negation_reference`,语义已不属否定类——建议下次触及时改名或换语料类别。
- **N4(验收证据等级)**:mis_exec=0 / 37/37 的验收来自 intent@7f3ff6a 内提交的 evaluation/metrics.json 与 BASELINE.md(作者证据,SELF 级)。本工作区无法重放(见上)。数字内部一致性已人工复核:各类 passed 7+8+7+8+7=37、clarify 5+0+5+0+7=17、fallback 3+1+0+7+0=11、top1 11+7+3+3+7=31/31、mis_exec 全 0,与 overall 行及 I2 段(TP=30/FP=0/FN=0,较基线同向 +1)全部吻合;gen_agree 5/8 未动(3 例 gen_agree 分歧按范围未处理,BASELINE.md 如实保留)。CI(`.gitea/workflows/ci.yaml` @ PR HEAD)是测试通过的权威源,合入门禁照常。
- **N5(单元包描述与实际 diff 的 pin 基线不符,仅描述性)**:包内写 squad b6d8763→95b387d、backend 330c1a3→bd5c0f3;实际 vs main 为 squad a5afe9c8→95b387d、backend 8dc91c17→8031855e→bd5c0f3(两个 backend tip 树完全相同,bd5c0f3 非 8031855e 的后代而是同树重提交)。终态与包目标一致,无内容影响。
- **N6(任务卡整理欠账)**:`.task/feature-recall-misexec-fixes.md` 的「Agent 实施收据」表仍是全 NOT_RUN/待定义,而「合入与清理」已记录实施收据;需求分析/阶段记录等模板段未填。卡片债务,非阻塞;Review 记录待本评审随 PR 流程回填。
- **N7(正面确认,范围)**:变更严格限于三个修复+pin 级联+任务卡:intent 单提交共 9 文件(boundary.go 为纯重构抽取 `boundedAt`,语义等价);squad@95b387d、native@be556f4 两提交均只改 gitlink;嵌套 pin 全链一致(native→intent@7f3ff6a;squad→intent@7f3ff6a+native@be556f4;backend→intent@7f3ff6a+native@be556f4+squad@95b387d,与 superrepo 四个 gitlink 完全对应)。语料文件 recall_corpus.json 未改动(验收基准未被移动)。
- **N8(正面确认,正确性要点)**:否定为逐次出现判断,同词条存在任一未否定出现即正向(TestNegationCountsUnnegatedOccurrence/TestNegatedPatternHit 覆盖了否定+未否定同词双情形);守卫域豁免否定(registry.go:236、254,宁可多拦,TestGuardIgnoresNegation);excludes_any/includes_all 语义未动;r2 回归测试改名并反转断言是对旧契约的有意修订且注释说明清楚;`resolveTie` 确定性(filled 降序→priority 降序→合并序,胜者须压过组内全体,平 priority 仍 ambiguous),仅在胜出时原位重排 hits,Explain/Recognize 双路径一致,I5 行为保留(TestRecognizeTieBreakPrefersPriority 未改);槽位新检查在 format/enum/validator 之前(slots.go:186-198),空白归一化后进 missing(slots.go:123),overlap 检测未动;misexec_test.go 逐条 pin 了 6 次误执行序列与 4 个错槽位序列(含 start+clarify 命令断言),非否定输入行为回归用例齐备。
- **N9(字节级安全性)**:`termHit` 以 `i+1+j` 推进的重叠出现扫描与 `negatedAt` 的 `DecodeLastRuneInString` 回退均为 rune 安全;否定判定在折叠文本上进行,否定词为 CJK,大小写折叠/NFKC 不影响。
## 结论
三个修复(否定感知匹配、specificity tie-break、槽位 fail-closed)实现与任务卡设计决定一致,验收序列全部有单元级 pin,pin 级联自洽,范围无外溢。发现集中在启发式边界的已记录取舍(F1/F2)与非阻塞整理项;无阻断合入的问题。测试在本评审工作区因嵌套依赖未物化而 NOT_RUN,以探针与读码代替,合入前按门禁以 CI 为准。
REVIEW VERDICT: APPROVE
@@ -0,0 +1,61 @@
# 无项目对话(Scratch Session)实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 任意启用账号可创建彼此隔离的通用智能体会话;无 `project.create` 也能用;不得接入知识树/文档树等项目专属功能。
**Architecture:** 每个无项目对话 = 带 `settings.host.kind = "scratch"` 的私有空壳 `Project` + 恰好一条 `Conversation`。新建走专用 API(不要求 `project.create`)。列表/侧栏把 scratch 从真项目切换器剔除,归入虚拟分类「无项目对话」。服务端对 scratch 统一 fail-closed 拒绝 RDM/知识发布/成员等。
**Tech Stack:** Go Backend(store/server/authz)、TypeScript Frontend(store/TaskSidebar)、现有 SQLite projects 表 `settings` JSON。
**Spec:** [docs/superpowers/specs/2026-10-22-scratch-session-general-agent-design.md](../specs/2026-10-22-scratch-session-general-agent-design.md)
**实施执行:** agent-per-unit(配置:AGENT-EXECUTION.md);`fallback_to_host: never`。
## Global Constraints
- 固有能力不可做成 `role_permissions` 行。
- ListProjects 前后端一致过滤 scratch。
- RDM 未部署时也须宿主侧拒绝,不能只藏 UI。
- 最小充分:不做升级、协作、配额、nullable project_id。
## Review Focus
- 无 `project.create` 的创建路径与真项目门禁是否拆开
- scratch 上项目专属能力是否服务端 fail-closed
- 侧栏是否把 scratch 与真项目分开
## 文件映射
| 区域 | 路径 |
|------|------|
| 标记 helper | Backend store 或 core 小 helper |
| 创建 API | `modules/backend/internal/server/server.go` |
| 列表过滤 / 1:1 | `modules/backend/internal/store/projects.go`、server createConversation |
| 门禁 | `project_lifecycle.go`、cmdbus/RDM、knowledge、跨读 |
| 前端 API/store/侧栏 | `api.ts`、`store.ts`、`TaskSidebar.tsx` |
## Tasks
### U1 — Backend 创建与固有授权
- [ ] 实现 `IsScratchProject`;`POST /api/scratch-sessions`
- [ ] ListProjects 排除 scratch;禁止 POST /api/projects 伪造 scratch;scratch 下禁止二开会话
- [ ] 角色 catalog 不暴露可配置 scratch 动作
- [ ] 单测覆盖无/有 project.create、禁用账号、伪造、1:1
### U2 — Backend 项目专属 fail-closed
- [ ] `rejectIfScratch` 挂到 projectWork/成员/RDM/knowledge/X1/跨读
- [ ] 允许消息/附件/改名置顶归档/级联删除
- [ ] 单测正负例
### U3 — Frontend
- [ ] `createScratchSession`;sidebarMode;去掉无项目时自动「默认项目」
- [ ] TaskSidebar「无项目对话」分类与隐藏项目专属入口
- [ ] 前端测试
### U4 — 验证收口
- [ ] 最小相关测试通过;task-sync / PR / CI / 独立 Review
@@ -1,64 +0,0 @@
# 两棵树后续 A1 增量:阶段 6 评审包
- 任务卡:`.task/feature-rdm-two-trees-followup.md`(initiative,manual:每个增量用户阶段 6 人审后才合入)
- 对象:Dev `feature/rdm-two-trees-followup`,base `8cf4619`(R0 `46e331a` + 建卡),A1 实施提交 `000a2d2`
- 依据:阶段 5 计划 r1 W0 / W3 节;原分支提交 `9873a55`(W0 守护)、`cabac58`(端口修复)
- 证据来源:本文所有通过类结论均为 SELF(作者本地运行与关键字核对),GATE 以 PR HEAD 的 CI 为准
## 1. A1 交付内容
| 项 | 变更 | 说明 |
|---|---|---|
| R1 W0 DHF 清单守护 | 新增 `scripts/dhf_catalog_guard.py`(100755)与 `tests/test_dhf_catalog_guard.py` | 与 `9873a55` 内容逐字节一致(`git diff 9873a55 HEAD` 仅显示脚本 mode 为可执行);守护只校验清单状态,不宣称任何模板 published |
| R2 svc 测试动态端口 | `tests/test_svc.py`、`tests/test_svc_recover.py`、`tests/test_svc_realcombo.py` | `cabac58` 补丁已不能在最新 main 直接应用,worker 按其意图重新实现:每个用例经 `available_port()` 分配互不重复的端口,替换 18791–18800、9471–9474 等固定端口与 `free_fixture_port()`;被删除的 7 处断言均以同一断言改用分配端口的形式保留,无断言删减 |
实施:`agent-exec` cursor worker 第 1 次尝试成功(run `b7a8e78a2b6d0d8f6803490c7fa8af2e`,attempt `9075eee055af`),经 `agent-exec apply` 快进集成,变更路径与单元 `allowed_paths` 一致。
定向验证(SELF,被测 HEAD `000a2d2`):
```text
python3 -m unittest tests.test_dhf_catalog_guard tests.test_svc tests.test_svc_recover tests.test_svc_realcombo
Ran 67 tests ... OK (skipped=16)
```
16 个 skip 为需要 `SVC_REAL_*_BIN` 真实二进制的 realcombo 用例(NOT_RUN),与改动前一致。
## 2. W3 余项差距核对(RDM `origin/main` = `5a27d78`)
计划目标测试名:`TestRecursiveBlock|TestLegacyDocMigration|TestTemplateBinding`。
| 计划验证点 | main 现状 | 依据(关键字级 SELF,需在后续增量精确复核) |
|---|---|---|
| 递归块、稳定 ID、深于五级 | 已覆盖 | `internal/domain/document_blocks_test.go`:`TestRecursiveBlockInstanceHasIndependentIdentityAndReplays`(depth ≥ 6)、`TestRecursiveBlockReplayRejectsForgedOrFutureNodes`(伪造/未知未来节点拒绝) |
| 模板绑定 | 已覆盖 | `internal/rdmapp/read_isolation_boundary_test.go`:`TestTemplateBindingCannotAliasPublishedProjectOrRetainedTransaction` |
| 合并单元格 | 结构层已覆盖 | `document_blocks_test.go` 断言 `ColSpan == 2`;`template_asset_test.go` 拒绝非法 `RowSpan` |
| 旧 Section.ID 维持为章节身份 | 已覆盖 | `TestLegacySectionBecomesDeterministicRecursiveReadWithoutWrites`、`internal/rdmapp/document_blocks_test.go` `TestLegacyDocSectionNodeIDsSurviveStoreRestart` |
| 旧数据库备份副本迁移两次同值(`TestLegacyDocMigration`) | 缺失 | 无该测试名,未检到双次迁移同值用例 |
| 图形不透明块 | 缺失 | 测试中未检到 figure/opaque 块 |
| 移动/改名保持引用 | 缺失 | 测试中未检到 move/rename 用例 |
| 已批准版与旧下载仍可回取 | 缺失 | 未检到对应用例 |
| 重复组/重复表格 | 部分 | 关键字出现在上述两个测试文件,是否覆盖“重复表格”语义待精确复核 |
| 完成条件:真实项目实例表达新项目建议书及用户需求 12 组要求 | 未验证 | 依赖 W11 DHF 资产 published 状态,当前只能验证实例机制 |
结论:W3 主体(递归实例、模板绑定、旧 Section 身份)已在 RDM main;余项集中在旧数据迁移幂等、图形块、移动/改名引用与旧批准版回取。建议作为子任务“W3 余项”在 RDM 仓单独登记实施。
## 3. 剩余项与门禁
| 剩余项 | 门禁 |
|---|---|
| W3 余项(上表缺失 4 项 + 1 项待复核) | 下一增量,RDM 仓 worker 实施 |
| B:W5 追溯网、W7 上下文提供方 | 依赖 W3/W4 稳定 |
| C:W8 RDM 审计投影、W10 正式前端 | W8 接入宿主需 W9;W10 需 W3–W9 合同稳定 |
| D:W11 DHF 全量保真、W12 真实模型全组合验收、W13 收口 | 需资源方案与付费/真实模型授权 |
| X3/R3/F3/V3 产品链 | X3 需 Backend 公开扩展发版,属双钥匙操作,由用户执行 |
## 4. Review 发现(非阻塞)
- `tests/test_svc_realcombo.py` 新增的 `SVC_RCFWEB_ADDR` 环境变量不被 `svc.sh` 读取(伴生 `rcfweb` 由 `deploy --kind static` 自行取端口),属无效但无害配置,仅位于默认 NOT_RUN 的真实 RDM 用例;可在后续增量顺带删除。
- `available_port()` 绑定后即关闭 socket,与 svc.sh 实际绑定之间存在小窗口竞争(docstring 已说明);相较固定端口已消除并行 worktree 间的确定性冲突。
## 5. 请用户阶段 6 判定
- 通过:A1 进入 PR CI(GATE)与合入窗口,按 #518 排队合入。
- 修改:指出需调整项,按新单元重新实施。
- W3 余项是否按第 2 节登记为下一增量。
@@ -1,42 +0,0 @@
# 两棵树后续 W3 余项:阶段 6 评审包
- 状态:**用户阶段 6 通过(2026-10-20)**。确认第 3 节切分:W4 开放结构写入口前必须先补节点种类放置检查。RDM PR [#451](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/451) 经用户授权已合入 RDM main(`76b4c05`);本子任务 PR 合入 initiative 分支。
- 日期:2026-10-19;作者:host;子任务分支:Dev `feature/rdm-two-trees-followup-w3-rest`(父 `feature/rdm-two-trees-followup`)、RDM `feature/rdm-two-trees-followup-w3-rest`(base RDM main `5a27d78`)。
- 依据:[阶段 5 计划 W3](../../../modules/documents/docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-stage5-implementation-test-plan-r1.md)(已批准);[A1 评审包第 2 节差距核对](2026-10-19-rdm-two-trees-followup-a1-review.md)。
## 1. 本增量交付
| 差距项(A1 第 2 节) | 交付 | RDM 提交 | 目标测试 |
|---|---|---|---|
| 图形不透明块 | `ContentBlock.Kind` 新增 `figure`:不透明叶子,禁子块/重复/跨格,必须引用带 SHA-256 的附件或 Word 槽位;实例化、重放、`NodesOf` 逐字节保持 | `013b8b1` | `TestRecursiveBlockFigure*` |
| 重复表格(待复核) | 补精确用例:重复行与 v2 重复章节通过校验、实例节点 ID 各异、保留 `Repeat` 与 `RowSpan/ColSpan`、可重放;非法位置拒绝 | `013b8b1` | `TestRecursiveBlockRepeat*` |
| 移动/改名保持引用 | 领域原语 `MoveNode`/`RenameNode`,新事件 `doc.node.move`/`doc.node.rename`:节点 ID、模板块、内容不变;兄弟序连续重排;文档结构修订 +1,乐观并发;拒绝环、陈旧修订、旧章节节点、空标题、只读日志;live 与 replay 共用同一算法;前缀重放可取回更早结构 | `96d53f6` | `TestRecursiveBlockMove*`、`TestRecursiveBlockRename*`、`TestRecursiveBlockMoveRenameNodeRefsSurviveStoreRestart` |
| 旧库备份迁移两次同值;已批准版与旧下载可回取 | 新增 `TestLegacyDocMigration*`:旧形态库(文档/章节/版本/批准)复制为备份副本后两次独立打开与重放,事件行、序号、迁移版本与 `NodesOf` 一致,第二次不写入;未知未来事件类型在启动时写前拒绝;迁移后已批准版与审批提交下载字节/哈希不变(只增测试,未改生产代码) | `f3fa0c0` | `TestLegacyDocMigration*` |
| Dev:删除无效 `SVC_RCFWEB_ADDR` | `tests/test_svc_realcombo.py` 删除 `svc.sh` 从不读取的 `SVC_RCFWEB_ADDR` | Dev `80ac3fa` | `py_compile` |
## 2. 验证
- host 本地验证(SELF)@RDM `f3fa0c0`:`gofmt`、`go vet ./internal/domain/... ./internal/rdmapp`、`git diff --check` 通过;目标选择器 `GOWORK=off go test ./internal/domain ./internal/rdmapp -run 'TestRecursiveBlock|TestLegacyDocMigration|TestTemplateBinding' -count=1` 20 项 PASS;`./internal/domain/... ./internal/rdmapp` 全量 PASS。
- CI(GATE):RDM 草稿 PR [#451](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/451) 与本子任务 PR 当前 HEAD 检查(见 PR)。
- 独立 Review(全新会话 code-reviewer,只接收需求、base/head 与 diff;评审者自跑为 SELF):`5a27d78..f3fa0c0` **PASS-with-fixes,无阻塞项**。确认:克隆与摘除无共享切片、校验全过才写入;live 与 replay 共用算法;伪造节点 ID/旧章节/未知 op 被拒;`validateDocNodes` 对既有调用方等价;无新增写入口;测试断言非空。非阻塞项(建议 W4 开放写入口前修):
1. 移动不检查节点种类放置关系(row 可移出 table、cell 可移出 row),`rendererNodeKind` 会照常渲染为表格行;应在 `movedDocNodes` 加放置检查并把相应测试改为预期拒绝——**列为 W4 写入口的前置条件**。
2. `TestLegacyDocMigration` 在 WAL 模式下计算哈希可能漏掉 `-wal` 中的写入。
3. Postgres 用例的“第二次不写库”写入次数硬编码为 0。
4. `figure` 在渲染时退化为空段落(超出本增量需求,导出前须映射或显式报错)。
另:移动/改名事件 `Target` 与载荷 `DocID` 未做一致性校验;重放查找不过滤已删除文档(当前无删除路径)。
## 3. 风险与需人审确认
1. **与 W4 的边界**:移动/改名只提供领域原语,没有 HTTP 路由、插件命令或 rdmapp 写入口;按阶段 5 计划,结构变更须经 W4 结构提案与人工确认后才能调用。W4 开放写入口前须先补节点种类放置检查(独立 Review 非阻塞项 1)。请确认这一切分。
2. **合入冲突**:`internal/domain/template_asset.go`(figure 校验)同时被在途的 project-access-lifecycle 任务修改;本增量只新增一个 case 和一个函数,后合入的一方需要按最新 main 解决冲突。
3. **事件契约新增**:两种新事件对旧二进制属于未知未来事件,旧版本读到时会拒绝启动写入(符合计划的“未知未来事件拒绝”);部署顺序须先升级再产生新事件。
4. **完成条件中的业务项**:“真实项目实例表达新项目建议书及用户需求 12 组要求”依赖 W11 DHF 资产 published,本增量只验证实例机制,不宣称正式标准模板可用。
## 4. 执行记录
| 单元 | CLI/候选 | 终态 | 收据(源码外) |
|---|---|---|---|
| w3-rest-u1-figure-opaque-repeat-table | Cursor attempt 1 | success | /tmp/leftover-20261019b/w3-u1-receipt.json |
| w3-rest-u2-node-move-rename-refs | Cursor attempt 1 | success | /tmp/leftover-20261019b/w3-u2-receipt.json |
| w3-rest-u3-legacy-migration-approved-retrieval | Cursor run 1 `failed-unknown`(host 在其运行期间集成 u1,HEAD 变化);用户授权全新 run 2 | run 2 `blocked`(隔离区缺 `pins/` 无法编译 rdmapp);修正单元包后经用户授权 run 3 success | /tmp/leftover-20261019b/w3-u3-receipt*.json |
| w3-rest-dev-drop-svc-rcfweb-addr | Cursor run 1 `invalid-config`(单元包未就绪)、run 2 `failed-unknown`(Cursor 连接反复失败);用户授权全新 run 3 | success | /tmp/leftover-20261019b/w3-dev-receipt*.json |
@@ -1,33 +0,0 @@
# 两树一网增量 B(W5/W6/W7a)阶段 6 评审包 r1
日期:2026-10-20。状态:独立 Review 通过,**待用户阶段 6 人审**。人审通过前不合入任何分支。
## 1. 范围与结论一览
| 工作项 | 内容 | 交付分支/HEAD | 独立评审 | 修复 |
|---|---|---|---|---|
| W5a 领域核 | 受控边 revision 锁定、候选/确认语义、升版 pending-recheck、AnalyzeImpact/RecomputeImpact 传递闭包(去环/截断/水位/不可变快照)、重放一致 | RDM `feature/rdm-two-trees-followup-w5-w7` @ a7a6df0 | 0 BLOCKING | — |
| W5b 命令面 | rdm.compliance.impact.analyze/get/recompute、rdm.trace.coverage、rdm.trace.pending-recheck | 同上 @ 2e5fcb7 | 0 BLOCKING | — |
| W7a 纯领域 | ProjectContextBundle 组装/失效/渐进证据引用;零基座消费(tag 前约束达成) | 同上 @ 8327603 | 0 BLOCKING | — |
| RDM 评审修复 | 评审 MAJOR M1–M6(copyState/快照 ID 碰撞/端点校验/生产写入路径/空分析/切片别名) | 同上 @ 04991edb | 修复后 domain+rdmapp+plugins 全绿 | ✅ |
| W6 X1 恢复 | 候选 6ba53e4 合并 main 后按批准修订审计补齐(消费点全覆盖/入模门禁/存储去原文边界/负例矩阵) | Backend `feature/w6-x1-source-recheck` @ 8c410b9(draft PR #231) | **7/7 硬需求 PASS,0 BLOCKING 0 MAJOR**(仅 6 MINOR 备忘) | — |
## 2. 证据
- 全部实施经 agent-exec 有界单元(cursor,各 1 次尝试),收据:`~/.cache/agent-system-dev/agent-exec-receipts/{w5a,w5b,w7a,w6-x1-recheck-completion,w5-majors-repair}-*.json`;评审收据同目录。
- SELF:RDM gofmt/vet + domain(0.07s)/rdmapp(79s)/plugins(3.1s) 全绿 @04991edb;Backend build/vet + store/runmgr/workflow/extension 全绿 @8c410b9;backend CI(PR #231)vet-and-test+governance success @8c410b9。
- 评审报告:RDM `docs/reviews/2026-10-20-increment-b-rdm-review.md`(209 行,逐项 PASS/FAIL);Backend `docs/reviews/2026-10-20-w6-x1-recheck-review.md`(235 行,7 硬需求全 PASS)。
- 权威 GATE:合入前各 PR HEAD 的 CI(Backend #231 已绿;Dev/RDM PR 在人审后创建)。
## 3. 已知限制与门禁
- **W7 provider 接线未做**:按计划但书等待 X1 公开 tag(用户双钥匙);当前仅纯领域摘要与测试,不宣布自动注入完成。
- Backend MINOR 6 条(文档/诊断细分/补测建议)已记录于评审报告,不阻塞;建议随 W7 接线一并处理。
- RDM MINOR 14 条见评审报告;不阻塞合入,随增量 C 顺手项处理。
- W6 迁移与 W9 的 v31/v32 顺序:候选分支已在合并 main 后重排,串行合入时按 store 测试为准。
## 4. 请用户阶段 6 裁定
1. W5+W6+W7a 交付是否通过(对应 RDM/Backend 分支保留,人审通过后走各 PR 合入门禁)。
2. X1 公开 tag 是否发布(双钥匙)——通过后 W7 provider 接线另行派发。
3. RDM 评审 MINOR 14 条作为增量 C 顺手项的处理安排。
@@ -0,0 +1,108 @@
# 无项目对话(Scratch Session)设计
- 状态:**已批准**(对话设计第 1–4 节,2026-10-22)。
- 日期:2026-10-22;作者:host(设计整理);来源等级:SELF。
- 配套计划:[实施计划](../plans/2026-10-22-scratch-session-general-agent-plan.md)。
## 1. 目标与非目标
**目标**
- 任意**启用账号**可创建「无项目对话」,当作通用智能体使用(多轮对话)。
- 无 `project.create`(角色「项目访问」)的用户也能完成该路径,不被「默认项目」创建 403 卡住。
- 各无项目对话彼此**独立**:不共享文档、上下文、知识等。
- **不得**接入知识树、文档树、成员、RDM 等项目专属功能。
**非目标(本轮)**
- scratch → 真项目升级 / 事后绑定 RDM
- 分享、协作、邀请进空壳项目
- 配额、TTL、自动清理
- 将 `conversations.project_id` 改为可空等大 schema 重构
## 2. 已锁定决策
| 项 | 决策 |
|---|---|
| 数据模型 | 方案 A:每个无项目对话 = 一个轻量私有空壳 `Project` + 恰好一条 `Conversation` |
| UI | 侧栏虚拟分类「无项目对话」下列会话;**不**进入真项目切换器 |
| 谁可建 | 所有启用账号(有无 `project.create` 均可) |
| 权限 | **固有能力**,不进角色矩阵,**不可被管理员修改**;与可配置的 `project.create` 完全分离 |
## 3. 数据模型与权限
### 3.1 空壳项目约定
- 仍用现有 `projects` 表;`settings` 写入稳定标记:`host.kind = "scratch"`(解析仅经统一 helper,例如 `IsScratchProject`)。
- 每个无项目对话 = **一个 scratch 项目 + 恰好一条会话**(创建时原子写入;禁止在 scratch 下再建第二会话)。
- 项目 `owner` = 当前账号;不建成员、不共享、不邀请。
- 会话默认 `crossPrivate = true`。
### 3.2 权限
| 动作 | 门禁 |
|------|------|
| `POST /api/projects` 创建真项目 | 仍要 `project.create`(不变) |
| 创建无项目对话 | 启用账号即可;**不是**角色可配置动作 |
| scratch 上读写会话/发消息 | 仅 owner |
| scratch 升成真项目 / 绑 RDM | 本轮不做(明确拒绝) |
角色 catalog、`PUT .../permissions`、角色编辑 UI **不得**出现或改写「无项目对话」能力。关掉 `project.create` 不影响 scratch 创建。
### 3.3 专用创建 API
`POST /api/scratch-sessions` → `{ project, conversation }`
- 内部:插 scratch 项目 → 建唯一会话 → **不**触发 RDM provision。
- **禁止**经 `POST /api/projects` 伪造 scratch 标记。
### 3.4 列表语义
- 真项目列表 / 侧栏项目切换器:**过滤掉** scratch。
- 「无项目对话」分类:按会话列出(标题来自会话名)。
## 4. 服务端门禁(禁用项目专属能力)
判定:`IsScratchProject(p)` ≡ `settings.host.kind == "scratch"`。
**一律拒绝(scratch 上)**
- RDM 绑定 / provision;`rdm.*` 命令对 scratch 的 projectId → 403/400
- 知识树 / 文档树 / 法规树 / 驾驶舱 / 模板实例化
- 成员、职责、项目权限矩阵、项目归档协作
- 因「拥有 scratch」而授予 `project.create` 联动能力
- Project Context(X1)注入(视为未启用,走普通通用智能体组装)
- 跨会话读:scratch 会话不可被对端读出,也不可读其他会话
- 在已有 scratch 下再建会话
- 普通创建项目接口伪装 scratch
**允许(通用智能体最小集)**
- 本会话消息、附件(仅挂本 scratch,不进知识发布)
- 会话改名 / 置顶 / 归档 / 删除(删除可级联删空壳项目)
- 普通 LLM 对话;显式 `@knowledge` 对 scratch **关闭**
实现:集中 `rejectIfScratch` / `requireNonScratch`,挂在项目工作、RDM 分发、knowledge、成员 API;不能只藏 UI。
## 5. 前端信息架构
- 项目切换器:真项目列表 + 虚拟项「无项目对话」。
- 选中「无项目对话」:列出本人所有 scratch 会话;「+ 新建对话」调用 scratch API。
- 打开 scratch 会话时:隐藏项目设置、模板生成、依赖当前真项目的 RDM 入口。
- `createTask`:无真项目时**不再**自动 `createProject('默认项目')`;无建项权或用户在无项目对话视图时走 scratch API。
- 无建项权用户主路径:登录 → 默认落在「无项目对话」→ 可直接新建/继续对话。
## 6. 验收标准
1. 无建项权账号可进入「无项目对话」并完成多轮通用对话,不因默认项目 403。
2. 有建项权账号同样可建无项目对话;真项目创建仍只认 `project.create`。
3. 同一用户两个 scratch 会话互不共享附件知识库、上下文条目、跨会话读取。
4. scratch 上 RDM/知识树/文档树/成员/项目设置类能力服务端拒绝;UI 无入口。
5. 角色权限 UI / API 不能出现或改写该能力。
6. scratch 不出现在项目切换器。
7. 无法在已有 scratch 项目下再建第二条会话。
## 7. 最小验证
- Backend:创建门禁、RDM/knowledge 拒绝、ListProjects 过滤、1:1 约束单测。
- Frontend:侧栏分组、无建项权主路径、scratch 视图隐藏项目入口的测试。
+1 -1
View File
@@ -3,7 +3,7 @@
{
"id": "rdm",
"name": "研发记忆 RDM",
"repo": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-RDM.git",
"repo": "ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-RDM.git",
"repoEnv": "SVC_RDM_ORIGIN",
"defaultRef": "origin/main",
"goModule": "agent-system-rdm",
+6
View File
@@ -36,6 +36,8 @@
"backend/hostapi backend/store",
"backend/ingest backend/vision",
"backend/instanceguard backend/store",
"backend/intentsession backend/intentgate",
"backend/intentsession backend/store",
"backend/pgbus backend/bus",
"backend/pgbus backend/store",
"backend/plugins backend/settings",
@@ -49,6 +51,8 @@
"backend/rag backend/settings",
"backend/rag backend/store",
"backend/route backend/intentgate",
"backend/rundiag backend/cmdbus",
"backend/rundiag backend/store",
"backend/runmgr backend/bus",
"backend/runmgr backend/cardsvc",
"backend/runmgr backend/docgen",
@@ -76,12 +80,14 @@
"backend/server backend/execenv",
"backend/server backend/ingest",
"backend/server backend/intentgate",
"backend/server backend/intentsession",
"backend/server backend/plugins",
"backend/server backend/profiles",
"backend/server backend/projectscope",
"backend/server backend/prompts",
"backend/server backend/ratelimit",
"backend/server backend/route",
"backend/server backend/rundiag",
"backend/server backend/runmgr",
"backend/server backend/settings",
"backend/server backend/store",
+3 -3
View File
@@ -15,9 +15,9 @@
| ID | 事实 | 验证命令 | last_verified | TTL(天) |
|---|---|---|---|---|
| F1 | Gitea Web/API 可达:https://git-home.u1680832.nyat.app:30319(1.27.3) | `curl -fsS -m 10 https://git-home.u1680832.nyat.app:30319/api/v1/version` | 2026-10-14 | 30 |
| F2 | API token 存在且可用(值在 ~/.secrets/gitea,HOME/IMC 两段各一组 `- ACCESS_TOKEN=…`,本条取 HOME 段;不入仓不回显,不进子进程 argv) | `bash scripts/facts-verify.sh api-token https://git-home.u1680832.nyat.app:30319/api/v1/user` | 2026-10-14 | 30 |
| F3 | Git over SSH 可达:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/&lt;Repo&gt;.git(key ~/.ssh/home_gitea) | `GIT_SSH_COMMAND="ssh -i ~/.ssh/home_gitea -o BatchMode=yes" git ls-remote ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Guidelines.git HEAD` | 2026-10-14 | 30 |
| F1 | Gitea Web/API 可达(2026-10-22 迁移后新权威):https://gitea.naitangbaobao.cn(443,1.27.3);旧地址 git-home…:30319 过渡期仍可达,随时退役 | `curl -fsS -m 10 https://gitea.naitangbaobao.cn/api/v1/version` | 2026-10-22 | 30 |
| F2 | API token 存在且可用(值在 ~/.secrets/gitea,HOME/IMC 两段各一组 `- ACCESS_TOKEN=…`,本条取 HOME 段;不入仓不回显,不进子进程 argv);在新权威 URL 实测 200 | `bash scripts/facts-verify.sh api-token https://gitea.naitangbaobao.cn/api/v1/user` | 2026-10-22 | 30 |
| F3 | Git over SSH 可达(新地址,端口 52222):ssh://git@gitea.naitangbaobao.cn:52222/weichen/&lt;Repo&gt;.git(key ~/.ssh/home_gitea);旧地址 git-ssh…:31411 迁移期 push 间歇失败,不再作为权威 | `GIT_SSH_COMMAND="ssh -i ~/.ssh/home_gitea -p 52222 -o BatchMode=yes" git ls-remote ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Guidelines.git HEAD` | 2026-10-22 | 30 |
| F4 | 旧端点 git-panel.u1680832.nyat.app:30319 TCP 可连通但 TLS 握手失败(仅 TLS 层握手错误判 PASS) | `bash scripts/facts-verify.sh tls-handshake-fails git-panel.u1680832.nyat.app 30319` | 2026-10-14 | 180 |
| F5 | 基座 users 表存有姓名(name 列,CreateAccount/ListUsersAdmin 读写;EXT-19 目录自 P3 起向授权管理读面下发) | `cd modules/backend && go test ./internal/app/ -run TestInprocHostSearchAccounts -count=1` | 2026-10-14 | 180 |
| F6 | 基座账号无停用位(users 表无 disabled;EXT-19 Valid 恒为存在性)——停用机制未实现,不得当已具备 | `cd modules/backend && ! grep -rn -e disabled -e Disabled internal/store/auth.go pkg/extension/extension.go` | 2026-10-14 | 180 |
+2
View File
@@ -64,6 +64,8 @@ for container in "${containers[@]}"; do
done < <(git -C "$container" ls-tree "$commit" deps/)
done
bash "$root/scripts/check_pin_regression.sh" || fail=1
if [ "$fail" -ne 0 ]; then
exit 1
fi
+100
View File
@@ -0,0 +1,100 @@
#!/usr/bin/env bash
# 组合指针不倒退:HEAD 中每个 gitlink(deps/*、modules/*)相对 origin/main
# 只能前进——新 pin 必须以 origin/main 的旧 pin 为祖先。事故原型:PR #682
# 合入了过期分支,其树把五个组件 pin 重置回批次前的值,静默丢掉了 main 上
# batch-1 的组合。
#
# ┌─ 逃生口(须 owner Review)──────────────────────────────────────────────┐
# │ PIN_REGRESSION_SKIP=1 声明这是一次有意的降级:失败改为醒目的 warn 并 │
# │ 退出 0。只用于经组件 owner 审阅的刻意回退,PR │
# │ 描述须写明原因;不得用来绕过过期分支。 │
# └─────────────────────────────────────────────────────────────────────────┘
#
# 其他开关:
# PIN_REGRESSION_NO_FETCH=1 旧 pin 在子仓本地缺失时不尝试 fetch(测试/离线用)。
#
# 在当前工作目录所属仓库的顶层运行。origin/main 本地不可解析(浅检出)时只告警、退出 0。
set -euo pipefail
root=$(git rev-parse --show-toplevel)
cd "$root"
base=origin/main
skip=${PIN_REGRESSION_SKIP:-0}
if ! git rev-parse --verify -q "$base^{commit}" >/dev/null; then
echo "warn: $base is not resolvable locally; pin regression check skipped" >&2
exit 0
fi
fail=0
declare -A main_pins=()
while read -r mode _typ sha path; do
[ "$mode" = "160000" ] || continue
main_pins["$path"]=$sha
done < <(git ls-tree -r "$base")
# 子仓须是独立检出的仓库;未初始化时 git -C 会落到 Dev 自身。
own_repo() {
local path="$1" top
top=$(git -C "$path" rev-parse --show-toplevel 2>/dev/null) || return 1
[ "$top" = "$root/$path" ]
}
has_commit() {
git -C "$1" cat-file -e "$2^{commit}" 2>/dev/null
}
ensure_commit() {
local path="$1" sha="$2"
has_commit "$path" "$sha" && return 0
[ "${PIN_REGRESSION_NO_FETCH:-0}" = "1" ] && return 1
git -C "$path" fetch -q origin "$sha" >/dev/null 2>&1 || true
has_commit "$path" "$sha"
}
regress() {
if [ "$skip" = "1" ]; then
echo "warn: PIN_REGRESSION_SKIP=1 — $* (deliberate downgrade; requires owner review)" >&2
else
echo "pin: $*" >&2
fail=1
fi
}
while read -r mode _typ new path; do
[ "$mode" = "160000" ] || continue
old=${main_pins["$path"]:-}
if [ -z "$old" ]; then
echo "ok $path (new, not on $base)"
continue
fi
if [ "$old" = "$new" ]; then
echo "ok $path"
continue
fi
if ! own_repo "$path"; then
regress "$path is not checked out; cannot verify ${new:0:12} descends from $base ${old:0:12}"
continue
fi
if ! ensure_commit "$path" "$old"; then
regress "$path $base pin $old is missing locally and could not be fetched; cannot verify no regression"
continue
fi
if ! ensure_commit "$path" "$new"; then
regress "$path HEAD pin $new is missing locally and could not be fetched; cannot verify no regression"
continue
fi
if git -C "$path" merge-base --is-ancestor "$old" "$new"; then
echo "ok $path (forward ${old:0:12}..${new:0:12})"
continue
fi
regress "$path moves BACKWARD: $base is ${old:0:12}, HEAD is ${new:0:12} (not a descendant)." \
"This is the PR #682 pattern (a stale branch resetting pins over main): merge $base and re-pin," \
"or set PIN_REGRESSION_SKIP=1 for an owner-reviewed deliberate downgrade"
done < <(git ls-tree -r HEAD)
if [ "$fail" -ne 0 ]; then
exit 1
fi
echo "pin regression ok"
-244
View File
@@ -1,244 +0,0 @@
#!/usr/bin/env python3
"""Compare the DHF inventory, immutable originals and one RDM asset catalog.
This checks provenance and publication metadata. It cannot decide document
meaning or Word rendering fidelity; those require the per-asset review.
"""
import argparse
from collections import Counter
from datetime import datetime
import hashlib
import json
from pathlib import Path
import re
import subprocess
import sys
SOURCE_PREFIX = (".templates", "DHF 文件模板")
STATES = {"needs-review", "blocked", "published", "retired"}
SHA256 = re.compile(r"[0-9a-f]{64}\Z")
COMMIT = re.compile(r"[0-9a-f]{40}\Z")
RFC3339 = re.compile(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})\Z")
def digest(raw):
return hashlib.sha256(raw).hexdigest()
def source_path(dev_root, source):
path = Path(source)
if (path.is_absolute() or path.parts[:2] != SOURCE_PREFIX
or ".." in path.parts or path.suffix.lower() not in {".doc", ".docx"}):
raise ValueError(f"unsafe or non-Word source path: {source}")
segment = dev_root
for part in path.parts:
segment = segment / part
if segment.is_symlink():
raise ValueError(f"source path symlink: {source}")
absolute = dev_root / path
if not absolute.resolve().is_relative_to(dev_root.resolve()) or absolute.is_symlink():
raise ValueError(f"source path leaves the Dev tree: {source}")
return absolute
def package_digest(root, file_ref):
relative = file_ref.get("path")
expected = file_ref.get("sha256")
if not isinstance(relative, str) or not isinstance(expected, str) or not SHA256.fullmatch(expected):
raise ValueError("published asset file reference missing path or hash")
path = Path(relative)
if path.is_absolute() or ".." in path.parts or path == Path("."):
raise ValueError("published asset file reference is unsafe")
segment = root
for part in path.parts:
segment = segment / part
if segment.is_symlink():
raise ValueError("published asset file symlink")
absolute = root / path
if not absolute.resolve().is_relative_to(root.resolve()) or absolute.is_symlink() or not absolute.is_file():
raise ValueError("published asset file missing or escapes catalog")
if digest(absolute.read_bytes()) != expected:
raise ValueError("published asset file hash mismatch")
return expected
def audit(dev_root, inventory, catalog, expected_count, require_published=False,
catalog_root=None, identity_baseline=None):
records = inventory.get("templates")
assets = catalog.get("assets")
if not isinstance(records, list) or not isinstance(assets, list):
raise ValueError("inventory/templates or catalog/assets is missing")
if len(records) != expected_count or len(assets) != expected_count:
raise ValueError(f"expected {expected_count} logical sources and assets")
by_path = {}
ids = set()
for asset in assets:
provenance = asset.get("sourceProvenance") or {}
path = provenance.get("path")
template_id = asset.get("templateId")
if path in by_path or not isinstance(path, str):
raise ValueError("duplicate or missing provenance path")
if template_id in ids or not isinstance(template_id, str) or not template_id:
raise ValueError("duplicate or missing logical template ID")
by_path[path] = asset
ids.add(template_id)
if identity_baseline is not None:
prior = identity_baseline.get("assets")
if not isinstance(prior, list) or len(prior) != expected_count:
raise ValueError("identity baseline is incomplete")
prior_ids = {}
for asset in prior:
if not isinstance(asset, dict):
raise ValueError("identity baseline has invalid asset")
path = (asset.get("sourceProvenance") or {}).get("path")
if path in prior_ids or not isinstance(path, str):
raise ValueError("identity baseline has duplicate source")
prior_ids[path] = asset.get("templateId")
for path, asset in by_path.items():
if prior_ids.get(path) != asset["templateId"]:
raise ValueError(f"template identity drift: {path}")
seen = set()
states = Counter()
hashes = set()
candidate_differences = []
for record in records:
relative = record.get("source")
if not isinstance(relative, str) or relative in seen or relative not in by_path:
raise ValueError(f"inventory source missing, duplicate or unmapped: {relative}")
seen.add(relative)
asset = by_path[relative]
expected = record.get("sourceSha256")
found = (asset.get("source") or {}).get("sha256")
if not isinstance(expected, str) or not SHA256.fullmatch(expected) or found != expected:
raise ValueError(f"catalog source hash mismatch: {relative}")
path = source_path(dev_root, relative)
if not path.is_file() or digest(path.read_bytes()) != expected:
raise ValueError(f"checkout hash mismatch: {relative}")
provenance = asset["sourceProvenance"]
commit = provenance.get("commit")
if provenance.get("repository") != "Agent-System-Dev" or not isinstance(commit, str) or not COMMIT.fullmatch(commit):
raise ValueError(f"untrusted source provenance: {relative}")
historical = subprocess.run(
["git", "-C", str(dev_root), "show", f"{commit}:{relative}"],
capture_output=True, check=False,
)
if historical.returncode or digest(historical.stdout) != expected:
raise ValueError(f"committed source hash mismatch: {relative}")
if (asset.get("source") or {}).get("format") != path.suffix.lower()[1:]:
raise ValueError(f"catalog format mismatch: {relative}")
applicability = asset.get("applicability") or {}
catalog_types = applicability.get("docTypes", [])
if not isinstance(catalog_types, list):
raise ValueError(f"invalid catalog docTypes: {relative}")
if record.get("proposedDocType") not in catalog_types:
candidate_differences.append({
"path": relative,
"inventoryCandidate": record.get("proposedDocType"),
"catalogCandidates": catalog_types,
"confirmed": bool(applicability.get("confirmed")),
})
state = asset.get("state")
if state not in STATES:
raise ValueError(f"invalid asset state: {relative}")
if state == "published":
review = asset.get("review") or {}
normalized = asset.get("normalizedDocx") or {}
condition = applicability.get("condition")
if (not normalized or not catalog_types or applicability.get("confirmed") is not True
or not isinstance(condition, str) or not condition.strip()
or review.get("decision") != "approved"
or review.get("sourceSha256") != expected
or not asset.get("structure") or not asset.get("render")):
raise ValueError(f"published asset lacks approved binding: {relative}")
if (normalized.get("format") != "docx" or asset["structure"].get("format") != "json"
or asset["render"].get("format") != "docx"):
raise ValueError(f"published asset has invalid derived formats: {relative}")
reviewer = review.get("reviewer")
evidence = review.get("evidence")
reviewed_at = review.get("reviewedAt")
if (not isinstance(reviewer, str) or not reviewer.strip()
or not isinstance(evidence, str) or not evidence.strip()
or not isinstance(reviewed_at, str)):
raise ValueError(f"published asset lacks reviewer evidence: {relative}")
if not RFC3339.fullmatch(reviewed_at):
raise ValueError(f"published asset has invalid review time: {relative}")
try:
at = datetime.fromisoformat(reviewed_at.replace("Z", "+00:00"))
except ValueError as exc:
raise ValueError(f"published asset has invalid review time: {relative}") from exc
if at.tzinfo is None:
raise ValueError(f"published asset has invalid review time: {relative}")
converter = asset.get("converter") or {}
if (asset["source"].get("format") == "doc" or
asset["source"].get("sha256") != normalized.get("sha256")):
if (converter.get("inputSha256") != expected or
converter.get("outputSha256") != normalized.get("sha256") or
any(not isinstance(converter.get(field), str) or not converter[field].strip()
for field in ("name", "version", "configuration"))):
raise ValueError(f"published asset lacks conversion provenance: {relative}")
if any(issue.get("status") != "resolved" for issue in asset.get("issues", [])):
raise ValueError(f"published asset has unresolved issues: {relative}")
if (review.get("structureSha256") != asset["structure"].get("sha256")
or review.get("renderSha256") != asset["render"].get("sha256")
or review.get("normalizedSha256") != normalized.get("sha256")):
raise ValueError(f"published asset review hash mismatch: {relative}")
if catalog_root is not None:
package_digest(catalog_root, asset["source"])
package_digest(catalog_root, normalized)
package_digest(catalog_root, asset["structure"])
package_digest(catalog_root, asset["render"])
states[state] += 1
hashes.add(expected)
if require_published and states.get("published", 0) != expected_count:
raise ValueError(f"{expected_count - states.get('published', 0)} assets not published")
return {
"source": "SELF mechanical provenance check",
"matched": len(seen),
"logicalTemplateIds": len(ids),
"uniqueSourceBytes": len(hashes),
"published": states.get("published", 0),
"states": dict(sorted(states.items())),
"candidateTypeDifferences": candidate_differences,
"identityBaselineVerified": identity_baseline is not None,
"publicationValidation": "NOT_RUN: RDM LoadDHFAssetCatalog and human content/Word review are authoritative",
"limits": "This checks provenance and obvious metadata errors; state counts do not prove published bundles are valid.",
}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--dev-root", type=Path, required=True)
parser.add_argument("--inventory", type=Path, required=True)
parser.add_argument("--catalog", type=Path, required=True)
parser.add_argument("--expected-count", type=int, default=44)
parser.add_argument("--identity-baseline", type=Path)
parser.add_argument("--require-published", action="store_true")
args = parser.parse_args()
try:
if args.expected_count < 1:
raise ValueError("expected-count must be positive")
inventory_raw = args.inventory.read_bytes()
catalog_raw = args.catalog.read_bytes()
baseline_raw = args.identity_baseline.read_bytes() if args.identity_baseline else None
result = audit(args.dev_root, json.loads(inventory_raw), json.loads(catalog_raw),
args.expected_count, args.require_published, args.catalog.parent,
json.loads(baseline_raw) if baseline_raw is not None else None)
if args.catalog.read_bytes() != catalog_raw:
raise ValueError("catalog changed during check")
result["catalogSha256"] = digest(catalog_raw)
result["inventorySha256"] = digest(inventory_raw)
if baseline_raw is not None:
result["identityBaselineSha256"] = digest(baseline_raw)
if args.require_published:
raise ValueError("RDM publication validator required for full bundle safety and human fidelity")
except (OSError, ValueError, json.JSONDecodeError) as exc:
print(f"dhf catalog guard: {exc}", file=sys.stderr)
return 1
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
+6 -3
View File
@@ -60,8 +60,9 @@ done
# ── 1. 构建 ─────────────────────────────────────────────
# RDM 源码经 git archive 从本地对象导出(不建 worktree、不触远端——Gitea 抖动时
# submodule 克隆会挂死);pins/* 从 RDM 主检出的已物化 submodule 快照拷贝(cp 排除
# .git,39MB 级),构建输入由此固定为 RDM origin/main + 其 gitlink 指向的本地内容。
# submodule 克隆会挂死);pins/* 从 RDM 主检出的已物化 submodule 快照拷贝(tar 排除
# .git;含 go.mod replace 引用的全部 pin,不仅 backend),构建输入由此固定为
# RDM origin/main + 其 gitlink 指向的本地内容。
log "build RDM binary (archive origin/main + snapshot pins from local checkout)"
RDM_WT="$OUT/rdm-src"
RDM_SHA=$(git -C "$RDM_REPO" rev-parse origin/main) || die "no origin/main in RDM repo"
@@ -75,7 +76,9 @@ PIN_SHA_WANT=$(git -C "$RDM_REPO" ls-tree "$RDM_SHA" pins/agent-system-backend |
[ "$PIN_SHA_MAIN" = "$PIN_SHA_WANT" ] \
|| die "RDM checkout pins/backend ($PIN_SHA_MAIN) != origin/main pin ($PIN_SHA_WANT); git -C $RDM_REPO submodule update first"
mkdir -p "$RDM_WT/pins"
tar -C "$RDM_REPO/pins" --exclude=.git -cf - agent-system-backend | tar -C "$RDM_WT/pins" -xf -
# 快照全部 pins/*(go.mod replace 依赖 agent-document-renderer、agent-squad 等,
# 仅拷贝 backend 会导致 RDM 构建缺 pin);--exclude=.git 保持不变。
tar -C "$RDM_REPO/pins" --exclude=.git -cf - . | tar -C "$RDM_WT/pins" -xf -
cleanup() {
[ -n "${API_PID:-}" ] && { kill "$API_PID" 2>/dev/null || true; wait "$API_PID" 2>/dev/null || true; }
# Preview runs directly as one owned Vite process. Verify its command before
+2 -2
View File
@@ -4,7 +4,7 @@
# 用法:make facts-verify [ARGS=--update] (--update:把 PASS 项 last_verified 刷为当天并写回)
# 表内验证命令约定不含竖线;含 "\|" 转义时按字面还原后执行。
# 登记表引用的探针子命令(单独运行时在 stderr 说明判定,不输出凭据):
# api-token URL URL 须逐字等于登记端点 https://git-home.u1680832.nyat.app:30319/api/v1/user,
# api-token URL URL 须逐字等于登记端点 https://gitea.naitangbaobao.cn/api/v1/user,
# 校验通过后才进程内读 ~/.secrets/gitea HOME 段 ACCESS_TOKEN 并 GET(不跟随重定向);
# 0=接受 3=缺失 4=格式不符 5=请求失败/被拒/重定向 6=非登记端点
# tls-handshake-fails HOST PORT 仅当 TCP 已连通且 TLS 层握手报错时 0;
@@ -20,7 +20,7 @@ import sys, urllib.request
sys.path.insert(0, sys.argv[1])
import task_triage
ENDPOINT = "https://git-home.u1680832.nyat.app:30319/api/v1/user"
ENDPOINT = "https://gitea.naitangbaobao.cn/api/v1/user"
if sys.argv[2] != ENDPOINT:
print("api-token: URL 不是 policy/facts.md F2 登记端点,拒绝发送凭据", file=sys.stderr)
sys.exit(6)
+1 -1
View File
@@ -144,7 +144,7 @@ SRC_DIR="${SVC_SRC_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/agent-system-svc/src}"
# 独立 RDM 源仓(下游组合仓 Agent-System-RDM 的干净克隆;SVC_RDM_SRC_DIR 覆盖路径,
# SVC_RDM_ORIGIN 覆盖克隆来源)。rdm 源的解析/列举/物化全部基于它,语义与 SRC_DIR 一致。
RDM_SRC_DIR="${SVC_RDM_SRC_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/agent-system-svc/rdm-src}"
RDM_ORIGIN_DEFAULT="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-RDM.git"
RDM_ORIGIN_DEFAULT="ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-RDM.git"
# 提示信息走 stderr:stdout 只留给数据(提交表/服务表/DSN),便于 $( ) 捕获组合。
c_info() { [ "${CLI_QUIET:-0}" = 1 ] && return 0; printf '\033[1;34m[svc]\033[0m %s\n' "$*" >&2; }
+3 -3
View File
@@ -813,7 +813,7 @@ card_merge_squash() { # $1=branch $2=ref → squash/rebase 落地没有 merge
# 仅查最近 5 页(250 条):card_merge 的 merge 提交路径仍是主路径,此兜底面向新近任务卡。
local token="${GITEA_TOKEN:-}" web_base url repo owner api payload pg found sha
[ -n "$token" ] || return 1
web_base="${TASK_CARD_WEB_BASE:-https://git-home.u1680832.nyat.app:30319}"
web_base="${TASK_CARD_WEB_BASE:-https://gitea.naitangbaobao.cn}"
url=$(git remote get-url origin 2>/dev/null) || return 1
url="${url%.git}"
repo=$(basename "$url"); owner=$(basename "$(dirname "$url")")
@@ -951,7 +951,7 @@ cmd_close_self() {
esac
pr="$nums"
fi
web_base="${TASK_CARD_WEB_BASE:-https://git-home.u1680832.nyat.app:30319}"
web_base="${TASK_CARD_WEB_BASE:-https://gitea.naitangbaobao.cn}"
url=$(git remote get-url origin); url="${url%.git}"
repo=$(basename "$url"); owner=$(basename "$(dirname "$url")")
link="${web_base}/${owner}/${repo}/pulls/${pr}"
@@ -981,7 +981,7 @@ cmd_close() {
fetch_target
# 默认值取远端通告的 Web 面(git push 输出的 PR 建议链接);可用 TASK_CARD_WEB_BASE 覆盖。
# git-panel 前缀已失效(TLS 握手失败),默认值改为实测可用的 git-home(AGENTS.md 访问事实节)。
local web_base="${TASK_CARD_WEB_BASE:-https://git-home.u1680832.nyat.app:30319}"
local web_base="${TASK_CARD_WEB_BASE:-https://gitea.naitangbaobao.cn}"
local url owner repo
url=$(git remote get-url origin); url="${url%.git}"
repo=$(basename "$url"); owner=$(basename "$(dirname "$url")")
+16 -1
View File
@@ -13,6 +13,8 @@
不联网、不需要 token;非 pull_request 事件跳过(退出 0)。
期望目标:child → immediate_target;其余(initiative / standalone / 无卡)→ root_target(无卡即 main)。
local 与 ci 均运行 check_pin_regression.sh(gitlink 相对 origin/main 不得倒退);非零即拒绝,
PIN_REGRESSION_SKIP=1 由该脚本降级为告警(有意降级须 owner Review)。
退出码:0 通过;1 门禁拒绝(PR_CHECK_FAILED);2 用法;6 远端无法核验(REMOTE_UNVERIFIED,fail closed)。
仅使用标准库,复用 task_triage 的 Gitea 客户端与 token 读取。token 不打印、不写入任何产物。
@@ -33,6 +35,7 @@ EXIT_USAGE = 2
PRE_MERGE_CLOSED = "已完成(合入前闭合)"
CHILD_COLUMNS = ("子任务分支", "必需", "状态", "PR")
DONE_STATES = ("已合入", "已延期")
PIN_REGRESSION = Path(__file__).resolve().parent / "check_pin_regression.sh"
def sh(*args):
@@ -216,6 +219,17 @@ def final_problems(api, slug, token, branch, meta, text):
return problems
def pin_regression_problems():
proc = subprocess.run(["bash", str(PIN_REGRESSION)], capture_output=True, text=True,
encoding="utf-8", errors="replace")
for line in (proc.stdout + proc.stderr).splitlines():
print(f"[pin-regression] {line}")
if proc.returncode != 0:
return [f"pin regression gate failed (exit {proc.returncode}): a gitlink moves backward against "
"origin/main or cannot be verified; PIN_REGRESSION_SKIP=1 only for owner-reviewed downgrades"]
return []
def verdict(problems, kind, base, head):
if problems:
for problem in problems:
@@ -264,6 +278,7 @@ def cmd_local(args):
problems.append(f"parent initiative {expected} has no open PR into {meta['root_target']}")
if args.final and kind == "initiative":
problems.extend(final_problems(api, slug, token, branch, meta, text))
problems.extend(pin_regression_problems())
return verdict(problems, kind, expected, head)
@@ -281,7 +296,7 @@ def cmd_ci(_args):
if base != expected:
raise Stop(EXIT_FAILED, f"PR base {base!r} differs from expected {expected!r} "
f"for {meta['kind']} branch {head}")
return verdict([], meta["kind"], base, head)
return verdict(pin_regression_problems(), meta["kind"], base, head)
def main(argv=None):
+1 -1
View File
@@ -29,7 +29,7 @@ import urllib.parse
import urllib.request
SCHEMA = "agent-system/task-triage/v1"
DEFAULT_API = "https://git-home.u1680832.nyat.app:30319/api/v1"
DEFAULT_API = "https://gitea.naitangbaobao.cn/api/v1"
DEFAULT_TARGET = "main"
DEFAULT_MAX_AGE = 14400
PAGE_LIMIT = 50
+6 -5
View File
@@ -1,12 +1,13 @@
# RDM 制品钉扎。三行都是 40 位 hex。升级走 PR,不在 CI 里执行候选文件。
# sha:生命周期套件的目标版本(6-pin 布局)。
# sha:生命周期套件的目标版本(6-pin 布局);本次钉扎为增量 D(W11 DHF U2-U6)交付版本,
# 即 RDM main 上增量 D 合并 a3c721ae4 之后的 tip。
# prev_sha:来回部署身份稳定性测试的起点。选取受两条硬约束——与 sha 的 pins 布局一致,
# 且两者之间无跨 schema 迁移(scripts/svc.sh 的 schema 兼容闸会在停旧服务前拒绝不兼容切换)。
# 取上一个已钉住的 sha:同为 6-pin 布局,与 sha 之间无 schema/迁移变更,在 RDM 主线上与 sha
# 相距 59 个提交,往返部署覆盖的版本跨度大于仅隔一次合并的相邻提交。
# 取上一个已钉住的 sha:同为 6-pin 布局,与 sha 之间无 store schema 迁移(W11/W8 变更走事件
# 重放而非 schema),往返部署覆盖的正是上一交付版本到增量 D 的真实升级路径。
# legacy_sha:承载「无身份」语义(没有 version --json),必然早于 6-pin 布局。
# 三者的 pins 布局可能不同;CI 按每个 pin 自身的 gitlink 清单物化并逐个断言,不要求布局统一。
# 来回切换的 schema 兼容不由钉扎保证,由真实生命周期套件检验。
sha=ee8c2cdf4a0ed88cdc4037f4b43501e1eebc4c5b
prev_sha=bc8db886606e88201e7f7210a1357d22dc84124b
sha=9176476bf35d23e7886bf6ccb7c3a688067d357f
prev_sha=15fdd479a9fe60a59559139305b8d760931cec93
legacy_sha=72bb1fec79d64c2af5e49416640712320816c3b4
+187
View File
@@ -0,0 +1,187 @@
"""check_pin_regression.sh:gitlink 相对 origin/main 只能前进(PR #682 事故形态)。
全部离线:临时目录内的普通 Git 仓库充当子仓,origin 只指向本地 bare 仓库。
"""
import os
import shutil
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "check_pin_regression.sh"
PR_CHECK = ROOT / "scripts" / "task_pr_check.py"
COMP = "deps/comp"
class PinRegressionTests(unittest.TestCase):
def setUp(self):
self.tmp = Path(tempfile.mkdtemp())
self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True)
cfg = self.tmp / "gitconfig"
cfg.write_text("")
self.env = dict(
os.environ,
GIT_CONFIG_GLOBAL=str(cfg),
GIT_CONFIG_NOSYSTEM="1",
GIT_AUTHOR_NAME="t",
GIT_AUTHOR_EMAIL="t@example.invalid",
GIT_COMMITTER_NAME="t",
GIT_COMMITTER_EMAIL="t@example.invalid",
)
for key in ("PIN_REGRESSION_SKIP", "PIN_REGRESSION_NO_FETCH"):
self.env.pop(key, None)
self.dev = self.tmp / "dev"
self.dev.mkdir()
self.git(self.dev, "init", "-q")
# 子仓:A ← B,另有从 A 分叉的 C。
self.comp = self.dev / COMP
self.comp.mkdir(parents=True)
self.git(self.comp, "init", "-q")
self.a = self.commit(self.comp, "a")
self.b = self.commit(self.comp, "b")
self.git(self.comp, "checkout", "-q", "-b", "side", self.a)
self.c = self.commit(self.comp, "c")
def git(self, cwd, *args):
return subprocess.run(
["git", *args], cwd=cwd, env=self.env, check=True, capture_output=True, text=True
).stdout.strip()
def commit(self, repo, text):
(repo / "f").write_text(text)
self.git(repo, "add", "f")
self.git(repo, "commit", "-qm", text)
return self.git(repo, "rev-parse", "HEAD")
def pin(self, sha, path=COMP):
self.git(self.dev, "update-index", "--add", "--cacheinfo", f"160000,{sha},{path}")
self.git(self.dev, "commit", "-qm", f"pin {path} {sha[:7]}")
return self.git(self.dev, "rev-parse", "HEAD")
def compose(self, main_pin, head_pin):
"""origin/main 钉 main_pin,HEAD(PR 分支)钉 head_pin。"""
main = self.pin(main_pin)
self.git(self.dev, "update-ref", "refs/remotes/origin/main", main)
if head_pin != main_pin:
self.pin(head_pin)
def run_check(self, **extra):
return subprocess.run(
["bash", str(SCRIPT)], cwd=self.dev, env=self.env | extra, capture_output=True, text=True
)
def test_same_pin_passes(self):
self.compose(self.a, self.a)
res = self.run_check()
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn(f"ok {COMP}\n", res.stdout)
self.assertIn("pin regression ok", res.stdout)
def test_forward_pin_passes(self):
self.compose(self.a, self.b)
res = self.run_check()
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn(f"ok {COMP} (forward", res.stdout)
def test_pr682_stale_branch_carrying_old_pin_fails(self):
self.compose(self.b, self.a)
res = self.run_check()
self.assertEqual(res.returncode, 1, res.stdout)
self.assertIn(f"pin: {COMP} moves BACKWARD", res.stderr)
self.assertIn("PR #682", res.stderr)
self.assertIn("PIN_REGRESSION_SKIP=1", res.stderr)
self.assertNotIn("pin regression ok", res.stdout)
def test_diverged_pin_fails(self):
self.compose(self.b, self.c)
res = self.run_check()
self.assertEqual(res.returncode, 1, res.stdout)
self.assertIn(f"pin: {COMP} moves BACKWARD", res.stderr)
def test_skip_env_downgrades_to_warning(self):
self.compose(self.b, self.a)
res = self.run_check(PIN_REGRESSION_SKIP="1")
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn("warn: PIN_REGRESSION_SKIP=1", res.stderr)
self.assertIn("requires owner review", res.stderr)
def test_missing_origin_main_warns_and_passes(self):
self.pin(self.a)
res = self.run_check()
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn("warn: origin/main is not resolvable locally", res.stderr)
def test_new_component_not_on_main_passes(self):
self.compose(self.a, self.a)
other = self.dev / "deps" / "other"
other.mkdir()
self.git(other, "init", "-q")
self.pin(self.commit(other, "o"), "deps/other")
res = self.run_check()
self.assertEqual(res.returncode, 0, res.stderr)
self.assertIn("ok deps/other (new, not on origin/main)", res.stdout)
def test_missing_old_object_with_fetch_disabled_fails(self):
self.compose("1" * 40, self.a)
res = self.run_check(PIN_REGRESSION_NO_FETCH="1")
self.assertEqual(res.returncode, 1, res.stdout)
self.assertIn(f"pin: {COMP} origin/main pin {'1' * 40} is missing locally", res.stderr)
def test_missing_old_object_unfetchable_from_local_origin_fails(self):
bare = self.tmp / "comp-origin.git"
self.git(self.tmp, "init", "-q", "--bare", str(bare))
self.git(self.comp, "remote", "add", "origin", str(bare))
self.compose("2" * 40, self.a)
res = self.run_check()
self.assertEqual(res.returncode, 1, res.stdout)
self.assertIn("could not be fetched", res.stderr)
def test_missing_old_object_is_fetched_from_local_origin(self):
upstream = self.tmp / "upstream"
self.git(self.tmp, "clone", "-q", str(self.comp), str(upstream))
newer = self.commit(upstream, "z")
bare = self.tmp / "comp-origin.git"
self.git(self.tmp, "clone", "-q", "--bare", str(upstream), str(bare))
self.git(self.comp, "remote", "add", "origin", str(bare))
self.compose(newer, self.b)
res = self.run_check()
self.assertEqual(res.returncode, 1, res.stdout)
self.assertNotIn("could not be fetched", res.stderr)
self.assertIn(f"pin: {COMP} moves BACKWARD", res.stderr)
self.git(self.comp, "cat-file", "-e", f"{newer}^{{commit}}")
def test_uninitialized_component_cannot_be_verified(self):
self.compose(self.b, self.a)
shutil.rmtree(self.comp)
self.comp.mkdir()
res = self.run_check()
self.assertEqual(res.returncode, 1, res.stdout)
self.assertIn(f"pin: {COMP} is not checked out", res.stderr)
def run_pr_check_ci(self, **extra):
env = self.env | {"GITHUB_EVENT_NAME": "pull_request", "GITHUB_BASE_REF": "main",
"GITHUB_HEAD_REF": "feature/stale", "TASK_TARGET_BRANCH": "main"} | extra
return subprocess.run([sys.executable, str(PR_CHECK), "ci"], cwd=self.dev, env=env,
capture_output=True, text=True, timeout=60)
def test_task_pr_check_ci_hard_fails_on_regression(self):
self.compose(self.b, self.a)
res = self.run_pr_check_ci()
self.assertEqual(res.returncode, 1, res.stdout + res.stderr)
self.assertIn(f"[pin-regression] pin: {COMP} moves BACKWARD", res.stdout)
self.assertIn("[pr-check] FAIL pin regression gate failed", res.stdout)
self.assertIn("[verdict] PR_CHECK_FAILED", res.stdout)
def test_task_pr_check_ci_skip_env_passes(self):
self.compose(self.b, self.a)
res = self.run_pr_check_ci(PIN_REGRESSION_SKIP="1")
self.assertEqual(res.returncode, 0, res.stdout + res.stderr)
self.assertIn("[pin-regression] warn: PIN_REGRESSION_SKIP=1", res.stdout)
self.assertIn("[verdict] PR_CHECK_OK", res.stdout)
if __name__ == "__main__":
unittest.main()
+17
View File
@@ -8,6 +8,7 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "check-pins.sh"
REGRESSION = ROOT / "scripts" / "check_pin_regression.sh"
CONTAINERS = ("modules/backend", "deps/agent-native", "deps/agent-squad", "deps/agent-intent")
@@ -29,6 +30,7 @@ class CheckPinsTests(unittest.TestCase):
self.dev = self.tmp / "dev"
(self.dev / "scripts").mkdir(parents=True)
shutil.copy(SCRIPT, self.dev / "scripts" / "check-pins.sh")
shutil.copy(REGRESSION, self.dev / "scripts" / "check_pin_regression.sh")
self.git(self.dev, "init", "-q")
def git(self, cwd, *args):
@@ -112,6 +114,21 @@ class CheckPinsTests(unittest.TestCase):
self.assertEqual(res.returncode, 1)
self.assertIn("has no Dev pin", res.stderr)
def test_pin_regression_against_origin_main_fails(self):
old, new = self.repo("deps/error-code-system", "e1", "e2")
self.build({"error-code-system": old}, {"deps/error-code-system": old})
self.git(self.dev, "commit", "-qm", "pr")
stale = self.git(self.dev, "rev-parse", "HEAD")
self.link(self.dev, "deps/error-code-system", new)
self.git(self.dev, "commit", "-qm", "main")
self.git(self.dev, "update-ref", "refs/remotes/origin/main", "HEAD")
self.git(self.dev, "reset", "-q", stale)
res = self.run_pins()
self.assertEqual(res.returncode, 1, res.stderr)
self.assertIn("ok modules/backend error-code-system", res.stdout)
self.assertIn("pin: deps/error-code-system moves BACKWARD", res.stderr)
self.assertNotIn("pins ok", res.stdout)
if __name__ == "__main__":
unittest.main()
-256
View File
@@ -1,256 +0,0 @@
import hashlib
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
from copy import deepcopy
ROOT = Path(__file__).resolve().parents[1]
GUARD = ROOT / "scripts" / "dhf_catalog_guard.py"
class DHFCatalogGuardTest(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.addCleanup(self.tmp.cleanup)
self.root = Path(self.tmp.name)
self.dev = self.root / "dev"
self.dev.mkdir()
subprocess.run(["git", "init", "-q", str(self.dev)], check=True)
self.items = []
self.assets = []
for index, value in enumerate((b"source-one", b"source-two"), 1):
path = f".templates/DHF 文件模板/阶段{index}/模板{index}.docx"
absolute = self.dev / path
absolute.parent.mkdir(parents=True)
absolute.write_bytes(value)
digest = hashlib.sha256(value).hexdigest()
self.items.append({
"source": path,
"sourceSha256": digest,
"proposedDocType": f"type-{index}",
})
self.assets.append({
"templateId": f"dhf.logical-{index}",
"version": "1.0.0",
"state": "needs-review",
"source": {"sha256": digest, "format": "docx"},
"sourceProvenance": {"repository": "Agent-System-Dev", "path": path},
"applicability": {"docTypes": [f"type-{index}"], "confirmed": False},
})
subprocess.run(["git", "-C", str(self.dev), "add", ".templates"], check=True)
subprocess.run([
"git", "-C", str(self.dev), "-c", "user.name=Test",
"-c", "user.email=test@example.invalid", "commit", "-qm", "sources",
], check=True)
commit = subprocess.check_output(
["git", "-C", str(self.dev), "rev-parse", "HEAD"], text=True,
).strip()
for asset in self.assets:
asset["sourceProvenance"]["commit"] = commit
self.inventory = self.root / "inventory.json"
self.catalog = self.root / "catalog.json"
self.save()
def save(self):
self.inventory.write_text(json.dumps({"templates": self.items}))
self.catalog.write_text(json.dumps({"schemaVersion": "dhf-assets/v1", "assets": self.assets}))
def run_guard(self, *extra):
return subprocess.run([
sys.executable, str(GUARD), "--dev-root", str(self.dev),
"--inventory", str(self.inventory), "--catalog", str(self.catalog),
"--expected-count", "2", *extra,
], capture_output=True, text=True)
def publish_fixture(self, index=0, *, structure=b'{"blocks":[]}', render=b"rendered-docx"):
asset = self.assets[index]
number = index + 1
source = (self.dev / self.items[index]["source"]).read_bytes()
names = {"source": f"source{number}.docx", "structure": f"structure{number}.json",
"render": f"render{number}.docx"}
for label, raw in [("source", source), ("structure", structure), ("render", render)]:
(self.root / names[label]).write_bytes(raw)
asset["state"] = "published"
asset["applicability"].update({"confirmed": True, "condition": "test scope"})
asset["source"]["path"] = names["source"]
asset["normalizedDocx"] = {"path": names["source"], "format": "docx",
"sha256": hashlib.sha256(source).hexdigest()}
asset["structure"] = {"path": names["structure"], "format": "json",
"sha256": hashlib.sha256(structure).hexdigest()}
asset["render"] = {"path": names["render"], "format": "docx",
"sha256": hashlib.sha256(render).hexdigest()}
asset["review"] = {
"decision": "approved", "reviewer": "reviewer", "reviewedAt": "2026-10-14T00:00:00Z",
"evidence": "review-record", "sourceSha256": self.items[index]["sourceSha256"],
"normalizedSha256": asset["normalizedDocx"]["sha256"],
"structureSha256": asset["structure"]["sha256"],
"renderSha256": asset["render"]["sha256"],
}
return asset
def test_accepts_matching_immutable_sources_but_does_not_call_them_published(self):
result = self.run_guard()
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
report = json.loads(result.stdout)
self.assertEqual(report["matched"], 2)
self.assertEqual(report["states"], {"needs-review": 2})
self.assertEqual(report["published"], 0)
def test_rejects_changed_checkout_even_when_catalog_matches_historical_commit(self):
(self.dev / self.items[0]["source"]).write_bytes(b"changed")
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("checkout hash mismatch", result.stderr)
def test_rejects_original_in_symlinked_parent_directory(self):
source = self.dev / self.items[0]["source"]
original_parent = source.parent
moved_parent = original_parent.parent / "alias-target"
original_parent.rename(moved_parent)
original_parent.symlink_to(moved_parent, target_is_directory=True)
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("source path symlink", result.stderr)
def test_rejects_false_publication(self):
self.assets[0]["state"] = "published"
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset lacks", result.stderr)
def test_reports_revised_candidate_type_without_approving_publication(self):
self.assets[0]["applicability"]["docTypes"] = ["unrelated"]
self.save()
result = self.run_guard()
self.assertEqual(result.returncode, 0, result.stderr)
report = json.loads(result.stdout)
self.assertEqual(report["published"], 0)
self.assertEqual(report["candidateTypeDifferences"], [{
"path": self.items[0]["source"],
"inventoryCandidate": "type-1",
"catalogCandidates": ["unrelated"],
"confirmed": False,
}])
def test_publication_gate_does_not_accept_a_complete_inventory_as_delivery(self):
result = self.run_guard("--require-published")
self.assertNotEqual(result.returncode, 0)
self.assertIn("not published", result.stderr)
def test_rejects_published_asset_whose_review_does_not_bind_bundle_bytes(self):
asset = self.publish_fixture()
asset["review"]["structureSha256"] = "0" * 64
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset review hash mismatch", result.stderr)
def test_rejects_bundle_file_changed_after_approval(self):
asset = self.publish_fixture()
self.save()
(self.root / asset["render"]["path"]).write_bytes(b"modified-after-review")
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset file hash mismatch", result.stderr)
def test_rejects_published_asset_with_unresolved_fidelity_issue(self):
asset = self.publish_fixture()
asset["issues"] = [{"id": "fidelity", "status": "open"}]
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset has unresolved issues", result.stderr)
def test_publication_flag_never_claims_authoritative_rdm_validation(self):
for index in range(2):
self.publish_fixture(index, structure=b"not-a-valid-structure", render=b"not-a-valid-docx")
self.save()
result = self.run_guard("--require-published")
self.assertNotEqual(result.returncode, 0)
self.assertIn("RDM publication validator required", result.stderr)
def test_rejects_swapped_logical_ids_against_fixed_identity_baseline(self):
baseline = self.root / "identity-baseline.json"
baseline.write_text(json.dumps({"assets": deepcopy(self.assets)}))
self.assets[0]["templateId"], self.assets[1]["templateId"] = (
self.assets[1]["templateId"], self.assets[0]["templateId"])
self.save()
result = self.run_guard("--identity-baseline", str(baseline))
self.assertNotEqual(result.returncode, 0)
self.assertIn("template identity drift", result.stderr)
def test_report_binds_exact_catalog_bytes(self):
result = self.run_guard()
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(json.loads(result.stdout)["catalogSha256"],
hashlib.sha256(self.catalog.read_bytes()).hexdigest())
def test_rejects_published_package_through_symlink_directory(self):
asset = self.publish_fixture()
real = self.root / "real"
real.mkdir()
for key in ["source", "normalizedDocx", "structure", "render"]:
p = self.root / asset[key]["path"]
(real / p.name).write_bytes(p.read_bytes())
asset[key]["path"] = "alias/" + p.name
(self.root / "alias").symlink_to(real, target_is_directory=True)
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("symlink", result.stderr)
def test_rejects_string_false_and_null_applicability(self):
asset = self.publish_fixture()
asset["applicability"]["confirmed"] = "false"
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset lacks approved binding", result.stderr)
asset["applicability"]["confirmed"] = True
asset["applicability"]["condition"] = None
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset lacks approved binding", result.stderr)
def test_rejects_null_reviewer_and_non_rfc3339_timestamp(self):
asset = self.publish_fixture()
asset["review"]["reviewer"] = None
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset lacks reviewer evidence", result.stderr)
asset["review"]["reviewer"] = "reviewer"
asset["review"]["reviewedAt"] = "2026-10-14 00:00:00Z"
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset has invalid review time", result.stderr)
def test_rejects_changed_normalized_file_without_named_converter(self):
asset = self.publish_fixture()
normalized = b"changed-normalized-docx"
(self.root / "normalized.docx").write_bytes(normalized)
asset["normalizedDocx"] = {
"path": "normalized.docx", "format": "docx", "sha256": hashlib.sha256(normalized).hexdigest(),
}
asset["review"]["normalizedSha256"] = asset["normalizedDocx"]["sha256"]
asset["converter"] = {
"inputSha256": self.items[0]["sourceSha256"],
"outputSha256": asset["normalizedDocx"]["sha256"],
}
self.save()
result = self.run_guard()
self.assertNotEqual(result.returncode, 0)
self.assertIn("published asset lacks conversion provenance", result.stderr)
if __name__ == "__main__":
unittest.main()
+16 -15
View File
@@ -256,7 +256,7 @@ class FactsVerifyTests(unittest.TestCase):
self.assert_status(result.stdout, "F2", "PASS")
requests = self.stub_events("http")
self.assertEqual(len(requests), 1, requests)
self.assertEqual(requests[0]["url"], "https://git-home.u1680832.nyat.app:30319/api/v1/user")
self.assertEqual(requests[0]["url"], "https://gitea.naitangbaobao.cn/api/v1/user")
self.assertEqual(requests[0]["authorization"], "token " + HOME_TOKEN)
self.assertEqual(self.dates(), {"F2": self.today, "F8": self.today, "F9": OLD_DATE})
self.assertTrue(receipt.exists(), result.stderr)
@@ -285,7 +285,7 @@ class FactsVerifyTests(unittest.TestCase):
self.assert_status(result.stdout, "F2", "FAIL")
self.assertEqual(self.stub_events("http"), [], "no request without a valid HOME token")
self.assertEqual(self.dates()["F2"], OLD_DATE)
direct = self.run_script("api-token", "https://git-home.u1680832.nyat.app:30319/api/v1/user")
direct = self.run_script("api-token", "https://gitea.naitangbaobao.cn/api/v1/user")
self.assertNotEqual(direct.returncode, 0)
self.assertIn("ACCESS_TOKEN", direct.stderr)
self.assert_no_secrets(result.stdout, result.stderr, direct.stdout, direct.stderr,
@@ -299,7 +299,7 @@ class FactsVerifyTests(unittest.TestCase):
result = self.run_script("--update", http=http)
self.assert_status(result.stdout, "F2", "FAIL")
self.assertEqual(self.dates(), {"F2": OLD_DATE, "F8": self.today, "F9": OLD_DATE})
direct = self.run_script("api-token", "https://git-home.u1680832.nyat.app:30319/api/v1/user",
direct = self.run_script("api-token", "https://gitea.naitangbaobao.cn/api/v1/user",
http=http)
self.assertNotEqual(direct.returncode, 0)
self.assertNotIn("Authorization", direct.stderr)
@@ -307,17 +307,18 @@ class FactsVerifyTests(unittest.TestCase):
def test_f2_rejects_unregistered_destination_before_reading_credentials(self):
bad_urls = [
"http://git-home.u1680832.nyat.app:30319/api/v1/user",
"http://gitea.naitangbaobao.cn/api/v1/user",
"https://evil.invalid/api/v1/user",
"https://git-home.u1680832.nyat.app:30320/api/v1/user",
"https://git-home.u1680832.nyat.app/api/v1/user",
"https://user:pw@git-home.u1680832.nyat.app:30319/api/v1/user",
"https://git-home.u1680832.nyat.app:30319@evil.invalid/api/v1/user",
"https://git-home.u1680832.nyat.app:30319/api/v1/user#frag",
"https://git-home.u1680832.nyat.app:30319/api/v1/user?next=https://evil.invalid",
"https://git-home.u1680832.nyat.app:30319/api/v1/users",
"https://git-home.u1680832.nyat.app:30319/api/v1/user/../admin",
"https://git-home.u1680832.nyat.app:30319/api/v1/user ",
"https://git-home.u1680832.nyat.app:30319/api/v1/user",
"https://gitea.naitangbaobao.cn:30320/api/v1/user",
"https://gitea.naitangbaobao.cn:443/api/v1/user",
"https://user:pw@gitea.naitangbaobao.cn/api/v1/user",
"https://gitea.naitangbaobao.cn@evil.invalid/api/v1/user",
"https://gitea.naitangbaobao.cn/api/v1/user#frag",
"https://gitea.naitangbaobao.cn/api/v1/user?next=https://evil.invalid",
"https://gitea.naitangbaobao.cn/api/v1/users",
"https://gitea.naitangbaobao.cn/api/v1/user/../admin",
"https://gitea.naitangbaobao.cn/api/v1/user ",
]
for secrets_present in (True, False):
if not secrets_present:
@@ -337,12 +338,12 @@ class FactsVerifyTests(unittest.TestCase):
for code in ("301", "302", "303", "307", "308"):
with self.subTest(code):
self.stub_log.unlink(missing_ok=True)
direct = self.run_script("api-token", "https://git-home.u1680832.nyat.app:30319/api/v1/user",
direct = self.run_script("api-token", "https://gitea.naitangbaobao.cn/api/v1/user",
http=code)
self.assertEqual(direct.returncode, 5, direct.stderr)
requests = self.stub_events("http")
self.assertEqual([r["url"] for r in requests],
["https://git-home.u1680832.nyat.app:30319/api/v1/user"], "no follow-up request")
["https://gitea.naitangbaobao.cn/api/v1/user"], "no follow-up request")
self.assertNotIn("redirect-target", direct.stdout + direct.stderr)
self.assert_no_secrets(direct.stdout, direct.stderr)
+47 -31
View File
@@ -296,12 +296,14 @@ class SvcDbRecoveryTests(unittest.TestCase):
# ---- 1. 存量 exec= DSN:连续启动两次均恢复,进程参数无秘密 ----
def test_legacy_exec_dsn_survives_consecutive_restarts(self):
self.register_pg("pg1", 18890, password="legacy-pw-1")
dsn = "postgresql://agent:legacy-pw-1@127.0.0.1:18890/agent"
pg_port = free_test_port()
self.register_pg("pg1", pg_port, password="legacy-pw-1")
dsn = "postgresql://agent:legacy-pw-1@127.0.0.1:%d/agent" % pg_port
d = self.runtime("dev")
self.seed_agent("dev", 18791,
"--addr 127.0.0.1:18791 --data %s --plugins %s --auth auto --dsn %s"
% (d / "data", d / "plugins", dsn))
port = free_test_port()
self.seed_agent("dev", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto --dsn %s"
% (port, d / "data", d / "plugins", dsn))
for _ in range(2):
self.clear_serve_record()
self.svc("dev", "restart")
@@ -322,12 +324,14 @@ class SvcDbRecoveryTests(unittest.TestCase):
# ---- 2. 仅 dbref:裸 restart 与重新部署均保留绑定 ----
def test_dbref_binding_survives_bare_restart_and_redeploy(self):
self.register_pg("pg1", 18891, password="bind-pw-2")
dsn = "postgresql://agent:bind-pw-2@127.0.0.1:18891/agent"
pg_port = free_test_port()
self.register_pg("pg1", pg_port, password="bind-pw-2")
dsn = "postgresql://agent:bind-pw-2@127.0.0.1:%d/agent" % pg_port
d = self.runtime("dev")
self.seed_agent("dev", 18792,
"--addr 127.0.0.1:18792 --data %s --plugins %s --auth auto"
% (d / "data", d / "plugins"),
port = free_test_port()
self.seed_agent("dev", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto"
% (port, d / "data", d / "plugins"),
extra_rows=[("dbref", "pg1/agent"), ("db", "pg")])
self.clear_serve_record()
self.svc("dev", "restart")
@@ -349,18 +353,21 @@ class SvcDbRecoveryTests(unittest.TestCase):
self.register_pg("pg1", 18892, password="addr-pw-3")
dsn = "postgresql://agent:addr-pw-3@127.0.0.1:18892/agent"
d = self.runtime("dev")
self.seed_agent("dev", 18793,
"--addr 127.0.0.1:18793 --data %s --plugins %s --auth auto"
% (d / "data", d / "plugins"),
with socket.socket() as reservation:
reservation.bind(("127.0.0.1", 0))
port = reservation.getsockname()[1]
self.seed_agent("dev", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto"
% (port, d / "data", d / "plugins"),
extra_rows=[("dbref", "pg1/agent"), ("db", "pg")])
self.clear_serve_record()
self.svc("dev", "restart", "--addr", "127.0.0.1:18794")
self.svc("dev", "restart", "--addr", "127.0.0.1:%d" % port)
record = self.serve_record()
self.assertIn("AGENT_SYSTEM_DSN=%s" % dsn, record)
self.assertIn("--auth auto", record)
self.assertEqual(self.kv("dev", "dbref"), "pg1/agent")
self.assertEqual(self.kv("dev", "addr"), "127.0.0.1:18794")
self.assertIn("--addr 127.0.0.1:18794", self.kv("dev", "exec"))
self.assertEqual(self.kv("dev", "addr"), "127.0.0.1:%d" % port)
self.assertIn("--addr 127.0.0.1:%d" % port, self.kv("dev", "exec"))
self.assertEqual(self.kv("dev", "db"), "pg")
# ---- 4. 外部直连与配置文件来源:后续无参数启动仍恢复 ----
@@ -410,9 +417,10 @@ class SvcDbRecoveryTests(unittest.TestCase):
def test_refusals_keep_registration_without_sqlite_fallback(self):
d = self.runtime("a1")
self.seed_agent("a1", 18796,
"--addr 127.0.0.1:18796 --data %s --plugins %s --auth auto"
% (d / "data", d / "plugins"),
port = free_test_port()
self.seed_agent("a1", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto"
% (port, d / "data", d / "plugins"),
extra_rows=[("dbref", "pgmissing/agent"), ("db", "pg")])
self.clear_serve_record()
result = self.svc("a1", "restart", check=False)
@@ -422,33 +430,41 @@ class SvcDbRecoveryTests(unittest.TestCase):
self.assertEqual(self.kv("a1", "dbref"), "pgmissing/agent") # 可恢复配置保留
# 实例登记不全(缺 password)→ 拒启。
self.register_pg("pginc", 18895, complete=False)
self.register_pg("pginc", free_test_port(), complete=False)
d = self.runtime("a2")
self.seed_agent("a2", 18797,
"--addr 127.0.0.1:18797 --data %s --plugins %s --auth auto"
% (d / "data", d / "plugins"),
port = free_test_port()
self.seed_agent("a2", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto"
% (port, d / "data", d / "plugins"),
extra_rows=[("dbref", "pginc/agent"), ("db", "pg")])
result = self.svc("a2", "restart", check=False)
self.assertNotEqual(result.returncode, 0)
self.assertIn("拒绝", result.stdout)
# dbref 与 dsn= 指向不同库 → 配置冲突拒启。
self.register_pg("pg1", 18896, password="clash-pw")
pg_port = free_test_port()
self.register_pg("pg1", pg_port, password="clash-pw")
other_pg_port = free_test_port()
while other_pg_port == pg_port:
other_pg_port = free_test_port()
d = self.runtime("a3")
self.seed_agent("a3", 18798,
"--addr 127.0.0.1:18798 --data %s --plugins %s --auth auto"
% (d / "data", d / "plugins"),
port = free_test_port()
self.seed_agent("a3", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto"
% (port, d / "data", d / "plugins"),
extra_rows=[("dbref", "pg1/agent"), ("db", "pg"),
("dsn", "postgresql://u:p@127.0.0.1:18999/otherdb")])
("dsn", "postgresql://u:p@127.0.0.1:%d/otherdb"
% other_pg_port)])
result = self.svc("a3", "restart", check=False)
self.assertNotEqual(result.returncode, 0)
self.assertIn("拒绝", result.stdout)
# db=pg 但无可恢复 DSN → 拒启。
d = self.runtime("a4")
self.seed_agent("a4", 18799,
"--addr 127.0.0.1:18799 --data %s --plugins %s --auth auto"
% (d / "data", d / "plugins"),
port = free_test_port()
self.seed_agent("a4", port,
"--addr 127.0.0.1:%d --data %s --plugins %s --auth auto"
% (port, d / "data", d / "plugins"),
extra_rows=[("db", "pg")])
result = self.svc("a4", "restart", check=False)
self.assertNotEqual(result.returncode, 0)
+7 -1
View File
@@ -10,11 +10,15 @@ import os
import shutil
import sqlite3
import subprocess
import sys
import tempfile
import time
import unittest
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
SVC_SCRIPT = SOURCE / "scripts" / "svc.sh"
@@ -67,7 +71,9 @@ class SvcAgentBackupTests(unittest.TestCase):
self.assertEqual(proc.returncode, 0, proc.stdout)
return proc
def register_agent(self, name="t1", port=8899):
def register_agent(self, name="t1", port=None):
if port is None:
port = free_test_port()
d = self.root / "runtime" / name
(d / "data").mkdir(parents=True, exist_ok=True)
(d / "svc.env").write_text(
+6 -2
View File
@@ -2,9 +2,13 @@
import importlib.util
import json
import os
import sys
import unittest
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location(
"tsi", SOURCE / "tests" / "test_svc_identity.py")
@@ -46,7 +50,7 @@ class DeployTxnTests(unittest.TestCase):
new.chmod(0o755)
fx.stub.write_text(old.read_text())
fx.stub.chmod(0o755)
fx.seed_agent("txn", 9471)
fx.seed_agent("txn", free_test_port())
fx.start_ok("txn")
pid = fx.pid_of("txn")
script = fx.root / "scripts" / "svc.sh"
@@ -68,7 +72,7 @@ class DeployTxnTests(unittest.TestCase):
def test_forward_only_requires_confirm_and_backup(self):
fx = self.fx
fx.seed_agent("fwd", 9472)
fx.seed_agent("fwd", free_test_port())
fx.start_ok("fwd")
iid = json.loads((fx.runtime("fwd") / "manifest.json").read_text())["instance_id"]
base = fx.stub.read_text()
+36 -16
View File
@@ -12,10 +12,14 @@ import os
import shutil
import sqlite3
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
SVC_SCRIPT = SOURCE / "scripts" / "svc.sh"
@@ -56,7 +60,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T1 连续裸启停:同一身份与数据根 ----
def test_T1_bare_restart_stable_identity(self):
self.seed_agent("id1", 9431)
port = free_test_port()
self.seed_agent("id1", port)
self.start_ok("id1")
m1 = self.manifest("id1")
self.assertIsNotNone(m1, "start 应完成 manifest 迁移")
@@ -79,7 +84,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T2 只改端口:数据/DB 锚点不动 ----
def test_T2_port_change_keeps_anchors(self):
self.seed_agent("id2", 9432)
port = free_test_port()
self.seed_agent("id2", port)
self.start_ok("id2")
anchor = self.manifest("id2")["identity"]
self.svc("id2", "stop")
@@ -95,7 +101,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T3 数据根漂移:拒绝启动,不新建空系统 ----
def test_T3_data_drift_rejected(self):
self.seed_agent("id3", 9434)
port = free_test_port()
self.seed_agent("id3", port)
self.start_ok("id3")
self.svc("id3", "stop")
other = self.root / "other-data"
@@ -111,7 +118,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T4 迁移窗口与损坏:不猜测 ----
def test_T4a_leftover_new_file_ignored(self):
self.seed_agent("id4", 9435)
port = free_test_port()
self.seed_agent("id4", port)
# 模拟 rename 前崩溃残留:.new 半成品必须被忽略/覆盖,不影响迁移结果
(self.runtime("id4") / "manifest.json.new").write_text("{ truncated")
self.start_ok("id4")
@@ -121,7 +129,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.svc("id4", "stop")
def test_T4b_corrupt_manifest_blocks(self):
self.seed_agent("id5", 9436)
port = free_test_port()
self.seed_agent("id5", port)
self.start_ok("id5")
self.svc("id5", "stop")
(self.runtime("id5") / "manifest.json").write_text("{ not json")
@@ -133,7 +142,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T5 marker/manifest 事件:缺一即阻塞,不自动新建 ----
def test_T5a_missing_marker_blocks(self):
self.seed_agent("id6", 9437)
port = free_test_port()
self.seed_agent("id6", port)
self.start_ok("id6")
self.svc("id6", "stop")
m = self.manifest("id6")
@@ -145,7 +155,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.assertFalse(self.running("id6"))
def test_T5b_foreign_marker_blocks(self):
self.seed_agent("id7", 9438)
port = free_test_port()
self.seed_agent("id7", port)
self.start_ok("id7")
self.svc("id7", "stop")
m = self.manifest("id7")
@@ -158,7 +169,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.assertFalse(self.running("id7"))
def test_T5c_lost_manifest_blocks_not_rebuild(self):
self.seed_agent("id8", 9439)
port = free_test_port()
self.seed_agent("id8", port)
self.start_ok("id8")
m0 = self.manifest("id8")
iid = m0["instance_id"]
@@ -178,7 +190,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T6 cwd 无关:从别处调用身份不变 ----
def test_T6_cwd_independent_identity(self):
self.seed_agent("id9", 9440)
port = free_test_port()
self.seed_agent("id9", port)
self.start_ok("id9")
iid = self.manifest("id9")["instance_id"]
self.svc("id9", "stop")
@@ -320,7 +333,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
旧服务继续运行、旧制品与登记不变(2026-10-12 rdm1/rdmcand 反例:停服→
覆盖→启动即拒,只剩混合状态)。"""
remote, old_sha, new_sha = self.make_rdm_repo(self.noid_stub())
self.seed_agent("rdx", 9451)
port = free_test_port()
self.seed_agent("rdx", port)
self.start_ok("rdx") # 已建立身份,有能力制品在运行
self.set_kv("rdx", "source", "rdm@%s" % old_sha)
pid = self.pid_of("rdx")
@@ -344,7 +358,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
"""已建立身份后删行:update 在停服前拒绝,不自动补行,旧进程保持。
补行只走 adopt --confirm。"""
old_sha, new_sha = self.make_src_repo()
self.seed_agent("rowx", 9452)
port = free_test_port()
self.seed_agent("rowx", port)
self.start_ok("rowx")
self.set_kv("rowx", "source", "dev@%s" % old_sha)
db = Path(self.manifest("rowx")["identity"]["data_root"]) / "agent-system.db"
@@ -364,7 +379,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
def test_U1_bare_start_missing_row_is_event_init_recovers(self):
"""普通启动只验证不补行:DB 行缺失 → 拒绝且不建空行(缺行即事件);
显式 init 补齐后恢复。"""
self.seed_agent("rowm", 9453)
port = free_test_port()
self.seed_agent("rowm", port)
self.start_ok("rowm")
iid = self.manifest("rowm")["instance_id"]
self.svc("rowm", "stop")
@@ -416,7 +432,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
def test_U1_adopt_identityless_artifact_reports_pending(self):
"""已装制品无 identity 能力:adopt 的 ensure 静默跳过,marker 留在 pending——
输出必须如实报 pending,不得宣称 db_marker=established。"""
self.seed_agent("adx", 9454)
port = free_test_port()
self.seed_agent("adx", port)
self.start_ok("adx")
iid = self.manifest("adx")["instance_id"]
self.svc("adx", "stop")
@@ -437,7 +454,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
cand.chmod(0o755)
remote, old_sha, _ = self._make_track_repo(cand, "agent-system")
self.git_ok(self.root, "clone", str(remote), str(self.root / "srccache"))
self.seed_agent("scx", 9455)
port = free_test_port()
self.seed_agent("scx", port)
self.start_ok("scx")
self.set_kv("scx", "source", "dev@%s" % old_sha)
mpath = self.runtime("scx") / "manifest.json"
@@ -459,7 +477,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.svc("scx", "stop")
def test_I3_start_ensures_sqlite_identity(self):
self.seed_agent("idb1", 9441)
port = free_test_port()
self.seed_agent("idb1", port)
self.start_ok("idb1")
iid = self.manifest("idb1")["instance_id"]
rows = self.db_identity_row("idb1")
@@ -470,7 +489,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.svc("idb1", "stop")
def test_I3_wrong_db_identity_blocks_start(self):
self.seed_agent("idb2", 9442)
port = free_test_port()
self.seed_agent("idb2", port)
self.start_ok("idb2")
iid = self.manifest("idb2")["instance_id"]
self.svc("idb2", "stop")
+9 -2
View File
@@ -1,9 +1,14 @@
"""生命周期隔离:调用方的 AGENT_SYSTEM_* 不得进入 serve,serve.env 为 0600。"""
import importlib.util
import json
import os
import shutil
import sys
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
tsr = importlib.util.module_from_spec(_spec)
@@ -17,7 +22,8 @@ class LifecycleIsolationTests(tsr.SvcAutoRecoverTests):
self.root / "scripts" / "svc_manifest.py")
def test_caller_identity_env_does_not_reach_serve(self):
self.seed_agent("iso", 9461)
port = free_test_port()
self.seed_agent("iso", port)
env = dict(self.env)
env["AGENT_SYSTEM_DSN"] = "postgres://leak-user:leak-pass@127.0.0.1/leak"
env["AGENT_SYSTEM_DATA"] = "/tmp/leak-data"
@@ -38,7 +44,8 @@ class LifecycleIsolationTests(tsr.SvcAutoRecoverTests):
self.svc("iso", "stop")
def test_two_bare_restarts_keep_identity(self):
self.seed_agent("iso2", 9462)
port = free_test_port()
self.seed_agent("iso2", port)
self.svc("iso2", "start")
manifest = json.loads((self.runtime("iso2") / "manifest.json").read_text())
iid = manifest["instance_id"]
+29 -12
View File
@@ -11,12 +11,17 @@
夹具复用 tests/test_svc_recover.py(桩不需要运行——台账操作是 SQLite 直读直写)。
"""
import importlib.util
import os
import shutil
import sqlite3
import subprocess
import sys
import unittest
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
@@ -64,21 +69,24 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- show ----
def test_show_prints_ledger_and_flags_unknown_owner(self):
self.seed_agent("ra1", 9461)
port = free_test_port()
self.seed_agent("ra1", port)
self.seed_dbs("ra1", ledger_owner="u7-admin", base_owners=("weichen",))
out = self.svc("ra1", "rdm-admin", "show").stdout
self.assertIn("RDM 域管理员 u7-admin", out)
self.assertIn("不在基座用户表", out) # u7-admin 不在 users → 残留警示
def test_show_known_owner_no_warning(self):
self.seed_agent("ra2", 9462)
port = free_test_port()
self.seed_agent("ra2", port)
self.seed_dbs("ra2", ledger_owner="weichen")
out = self.svc("ra2", "rdm-admin").stdout # 缺省子命令 = show
self.assertIn("RDM 域管理员 weichen", out)
self.assertNotIn("不在基座用户表", out)
def test_show_empty_ledger_hint(self):
self.seed_agent("ra3", 9463)
port = free_test_port()
self.seed_agent("ra3", port)
self.seed_dbs("ra3", ledger_owner=None)
out = self.svc("ra3", "rdm-admin").stdout
self.assertIn("台账为空", out)
@@ -87,7 +95,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- transfer ----
def test_transfer_rewrites_single_row_with_provenance(self):
self.seed_agent("ra4", 9464)
port = free_test_port()
self.seed_agent("ra4", port)
self.seed_dbs("ra4", ledger_owner="u7-admin")
out = self.svc("ra4", "rdm-admin", "transfer", "--to", "weichen").stdout
self.assertIn("受信部署通道", out)
@@ -97,13 +106,15 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
self.assertEqual(added_by, "svc:rdm-admin:u7-admin") # 前任可追溯
def test_transfer_idempotent_when_already_owner(self):
self.seed_agent("ra5", 9465)
port = free_test_port()
self.seed_agent("ra5", port)
self.seed_dbs("ra5", ledger_owner="weichen")
out = self.svc("ra5", "rdm-admin", "transfer", "--to", "weichen").stdout
self.assertIn("已是 weichen", out)
def test_transfer_rejects_owner_missing_from_base_users(self):
self.seed_agent("ra6", 9466)
port = free_test_port()
self.seed_agent("ra6", port)
self.seed_dbs("ra6", ledger_owner="weichen")
proc = self.svc("ra6", "rdm-admin", "transfer", "--to", "nobody", check=False)
self.assertEqual(proc.returncode, 1, proc.stdout)
@@ -111,7 +122,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
self.assertEqual(self.ledger_owner("ra6")[0], "weichen") # 台账未被动
def test_transfer_rejects_empty_ledger(self):
self.seed_agent("ra7", 9467)
port = free_test_port()
self.seed_agent("ra7", port)
self.seed_dbs("ra7", ledger_owner=None)
proc = self.svc("ra7", "rdm-admin", "transfer", "--to", "weichen", check=False)
self.assertEqual(proc.returncode, 1, proc.stdout)
@@ -120,7 +132,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- 绑定合同与用法 ----
def test_refuses_when_rdm_db_missing(self):
self.seed_agent("ra8", 9468)
port = free_test_port()
self.seed_agent("ra8", port)
self.seed_dbs("ra8") # 建基座库后删 rdm.db
(self.runtime("ra8") / "data" / "rdm.db").unlink()
proc = self.svc("ra8", "rdm-admin", check=False)
@@ -128,13 +141,15 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
self.assertIn("无 RDM 域库", proc.stdout)
def test_refuses_when_base_db_missing(self):
self.seed_agent("ra9", 9469)
port = free_test_port()
self.seed_agent("ra9", port)
proc = self.svc("ra9", "rdm-admin", check=False)
self.assertEqual(proc.returncode, 1, proc.stdout)
self.assertIn("既有库不存在", proc.stdout)
def test_unknown_subcommand_usage_exit_2(self):
self.seed_agent("raa", 9470)
port = free_test_port()
self.seed_agent("raa", port)
proc = self.svc("raa", "rdm-admin", "bogus", check=False)
self.assertEqual(proc.returncode, 2, proc.stdout)
self.assertIn("用法", proc.stdout)
@@ -142,14 +157,16 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- status 巡检行 ----
def test_status_lists_rdm_admin_row_and_warning(self):
self.seed_agent("rab", 9471)
port = free_test_port()
self.seed_agent("rab", port)
self.seed_dbs("rab", ledger_owner="u7-admin", base_owners=("weichen",))
out = self.svc("rab", "status").stdout
self.assertIn("RDM 域管理员 u7-admin", out)
self.assertIn("不在基座用户表", out)
def test_status_silent_without_rdm_db(self):
self.seed_agent("rac", 9472)
port = free_test_port()
self.seed_agent("rac", port)
self.seed_dbs("rac")
(self.runtime("rac") / "data" / "rdm.db").unlink()
out = self.svc("rac", "status").stdout
+2 -1
View File
@@ -49,6 +49,7 @@ def ci_git_env():
if not (CI_SERVER and CI_TOKEN):
return {}
scheme = CI_SERVER.split("://", 1)[0]
# 子模块已改用权威 HTTPS 端点;这里只保留权威 SSH 端点的改写,供仍以 SSH 声明 pins 的仓库使用。
return {
"GIT_CONFIG_COUNT": "4",
"GIT_CONFIG_KEY_0": "protocol.%s.allow" % scheme,
@@ -56,7 +57,7 @@ def ci_git_env():
"GIT_CONFIG_KEY_1": "http.%s/.extraheader" % CI_SERVER,
"GIT_CONFIG_VALUE_1": "AUTHORIZATION: token " + CI_TOKEN,
"GIT_CONFIG_KEY_2": "url.%s/weichen/.insteadOf" % CI_SERVER,
"GIT_CONFIG_VALUE_2": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/",
"GIT_CONFIG_VALUE_2": "ssh://git@gitea.naitangbaobao.cn:52222/weichen/",
"GIT_CONFIG_KEY_3": "core.hooksPath",
"GIT_CONFIG_VALUE_3": "/dev/null",
}
+18 -7
View File
@@ -12,9 +12,13 @@ import os
import shlex
import shutil
import subprocess
import sys
import unittest
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
@@ -106,7 +110,8 @@ class U2ReleaseTests(tsi.IdentityTests):
clock.chmod(0o755)
self.env["PATH"] = str(clock_bin) + os.pathsep + self.env["PATH"]
self.make_src_repo() # 预克隆 srccache(本用例走 --from local,仅保环境一致)
self.seed_agent("u2a", 9461)
port = free_test_port()
self.seed_agent("u2a", port)
self.start_ok("u2a") # legacy 运行中(期望态=running)
self.assertTrue(self.running("u2a"))
@@ -147,7 +152,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T2:构建失败 → 旧服务保持运行、current 不动 ----
def test_U2_build_failure_keeps_old_running(self):
self.seed_agent("u2b", 9462)
port = free_test_port()
self.seed_agent("u2b", port)
self.set_makefile(self.stub)
self.svc("u2b", "deploy", "--from", "local")
cur1 = self.cur_release("u2b")
@@ -164,7 +170,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T3:中断切换(journal switched)→ start 入口回退并恢复 ----
def test_U2_journal_interrupt_resolved_on_start(self):
self.seed_agent("u2c", 9463)
port = free_test_port()
self.seed_agent("u2c", port)
self.set_makefile(self.stub)
self.svc("u2c", "deploy", "--from", "local")
v1 = self.cur_release("u2c")
@@ -190,7 +197,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T4:schema 前进 → 回退阻断,不触碰业务库 ----
def test_U2_schema_advance_blocks_rollback(self):
self.seed_agent("u2d", 9464)
port = free_test_port()
self.seed_agent("u2d", port)
self.set_makefile(self.stub)
self.svc("u2d", "deploy", "--from", "local")
v1 = self.cur_release("u2d")
@@ -230,7 +238,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T5:legacy 布局未迁移 → 裸 start/restart 仍走原路径(兼容) ----
def test_U2_fault_after_switch_rolls_back_on_next_start(self):
self.seed_agent("u2f", 9466)
port = free_test_port()
self.seed_agent("u2f", port)
self.set_makefile(self.stub)
self.svc("u2f", "deploy", "--from", "local")
v1 = self.cur_release("u2f")
@@ -248,7 +257,8 @@ class U2ReleaseTests(tsi.IdentityTests):
self.svc("u2f", "stop")
def test_U2_health_timeout_rolls_back(self):
self.seed_agent("u2g", 9467)
port = free_test_port()
self.seed_agent("u2g", port)
self.set_makefile(self.stub)
self.svc("u2g", "deploy", "--from", "local")
v1 = self.cur_release("u2g")
@@ -277,7 +287,8 @@ class U2ReleaseTests(tsi.IdentityTests):
return p
def test_U2_legacy_layout_bare_lifecycle_still_works(self):
self.seed_agent("u2e", 9465)
port = free_test_port()
self.seed_agent("u2e", port)
self.start_ok("u2e")
self.assertFalse((self.runtime("u2e") / "current").exists())
self.assertTrue((self.runtime("u2e") / "bin" / "agent-system").exists())
+14 -5
View File
@@ -9,9 +9,13 @@ import importlib.util
import json
import os
import shutil
import sys
import unittest
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _port_alloc import free_test_port # noqa: E402
SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
@@ -57,7 +61,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T1 合法 manifest:user list 绑定 data_root + --open-existing ----
def test_T1_user_list_binds_manifest_data(self):
self.seed_agent("ub1", 9441)
port = free_test_port()
self.seed_agent("ub1", port)
self.start_ok("ub1")
self.svc("ub1", "stop")
root = self.manifest("ub1")["identity"]["data_root"]
@@ -74,7 +79,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T2 禁止覆盖 --data;未绑定默认目录拒绝 ----
def test_T2_reject_override_data_flag(self):
self.seed_agent("ub2", 9442)
port = free_test_port()
self.seed_agent("ub2", port)
self.start_ok("ub2")
self.svc("ub2", "stop")
self.touch_db("ub2")
@@ -106,7 +112,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T3 删除 data 根:OpenExisting 失败,不建空库 ----
def test_T3_missing_data_root_rejected(self):
self.seed_agent("ub3", 9444)
port = free_test_port()
self.seed_agent("ub3", port)
self.start_ok("ub3")
self.svc("ub3", "stop")
root = Path(self.manifest("ub3")["identity"]["data_root"])
@@ -124,7 +131,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T4 隐藏 flock:user/deploy 拒绝;已运行服务仍在 ----
def test_T4_no_flock_rejects_user_and_deploy(self):
self.seed_agent("ub4", 9445)
port = free_test_port()
self.seed_agent("ub4", port)
self.start_ok("ub4")
self.assertTrue(self.running("ub4"))
self.touch_db("ub4")
@@ -158,7 +166,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T5 recovery U1 身份冒烟(完整套件见 test_svc_identity)----
def test_T5_identity_regression_smoke(self):
self.seed_agent("ub5", 9446)
port = free_test_port()
self.seed_agent("ub5", port)
self.start_ok("ub5")
iid = self.manifest("ub5")["instance_id"]
self.svc("ub5", "stop")