Compare commits

..
Author SHA1 Message Date
agent-exec-transport d55ff23b0c Explain why CI keeps both submodule SSH endpoint mappings
ci / svc-realcombo (pull_request) Successful in 2m55s
ci / test (pull_request) Successful in 10m1s
ci / test-pg (pull_request) Successful in 13m54s
Why: After the Gitea migration some repositories still declare the legacy
endpoint in .gitmodules while facts F3 names the new one as authoritative. Both
endpoints currently resolve and serve git, so CI needs both insteadOf mappings;
dropping either one makes that batch of pins fall back to real SSH and the
svc-realcombo job fails on host key verification.

Evidence: 2026-10-23 measurement from this machine — both endpoints answer
git ls-remote with the same HEAD; Agent-System-Dev declares 14 submodule URLs on
the legacy endpoint, Agent-System-Backend 10, Agent-System-RDM 8 and
Agent-System-KB-Regulations 2 on the new one.

Impact: comments only; no GIT_CONFIG key, job structure or credential handling
changes.

Refs: feature/ecs-deploy-dev8788-and-kb
2026-10-23 13:06:55 +00:00
weichen 05b1e34dc5 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/feature-ecs-deploy-dev8788-and-kb.md -> .task/archive/feature-ecs-deploy-dev8788-and-kb.md; status 已完成(合入前闭合); PR #720 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/720.
Impact: task metadata only; the card is archived within PR #720 and lands with its merge commit.
Refs: task.sh close --self
2026-10-23 12:42:04 +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
34 changed files with 2216 additions and 551 deletions
+49 -4
View File
@@ -178,6 +178,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
@@ -404,7 +429,14 @@ jobs:
# https 基址后再取。只追加 pin 的三个 40 位 hex,不 source pin 文件。
SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')"
scheme="${GITHUB_SERVER_URL%%://*}"
export GIT_CONFIG_COUNT=4
# 嵌套 pins 的 SSH 端点有两代:旧 git-ssh.*:31411 与迁移后的 gitea.*:52222。
# 两个 insteadOf 必须同时保留,直到本仓与所有组件仓的 .gitmodules 全部迁到
# 新端点(policy/facts.md F3 已把新端点列为权威;2026-10-23 实测本仓
# .gitmodules 仍有旧端点子模块,Agent-System-Backend 亦然):
# · 去掉旧端点映射 → 旧端点声明的子模块退回真实 SSH,CI 无 key 必失败;
# · 去掉新端点映射 → RDM/KB 等已迁移的 pins 同样退回真实 SSH 而失败。
# 同键多值,git 会依次匹配。
export GIT_CONFIG_COUNT=5
export GIT_CONFIG_KEY_0="protocol.$scheme.allow"
export GIT_CONFIG_VALUE_0="always"
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
@@ -413,6 +445,8 @@ jobs:
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
export GIT_CONFIG_KEY_3="core.hooksPath"
export GIT_CONFIG_VALUE_3="/dev/null"
export GIT_CONFIG_KEY_4="url.$SERVER/weichen/.insteadOf"
export GIT_CONFIG_VALUE_4="ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
mapfile -t pins < <(python3 - <<'PY'
import pathlib
@@ -479,7 +513,8 @@ jobs:
done
unset GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0 \
GIT_CONFIG_KEY_1 GIT_CONFIG_VALUE_1 GIT_CONFIG_KEY_2 \
GIT_CONFIG_VALUE_2 GIT_CONFIG_KEY_3 GIT_CONFIG_VALUE_3
GIT_CONFIG_VALUE_2 GIT_CONFIG_KEY_3 GIT_CONFIG_VALUE_3 \
GIT_CONFIG_KEY_4 GIT_CONFIG_VALUE_4
unset SUBMODULE_TOKEN
- name: Install Node 22
run: |
@@ -692,7 +727,14 @@ jobs:
# https 基址后再取。
SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')"
scheme="${GITHUB_SERVER_URL%%://*}"
export GIT_CONFIG_COUNT=4
# 嵌套 pins 的 SSH 端点有两代:旧 git-ssh.*:31411 与迁移后的 gitea.*:52222。
# 两个 insteadOf 必须同时保留,直到本仓与所有组件仓的 .gitmodules 全部迁到
# 新端点(policy/facts.md F3 已把新端点列为权威;2026-10-23 实测本仓
# .gitmodules 仍有旧端点子模块,Agent-System-Backend 亦然):
# · 去掉旧端点映射 → 旧端点声明的子模块退回真实 SSH,CI 无 key 必失败;
# · 去掉新端点映射 → RDM/KB 等已迁移的 pins 同样退回真实 SSH 而失败。
# 同键多值,git 会依次匹配。
export GIT_CONFIG_COUNT=5
export GIT_CONFIG_KEY_0="protocol.$scheme.allow"
export GIT_CONFIG_VALUE_0="always"
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
@@ -701,6 +743,8 @@ jobs:
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
export GIT_CONFIG_KEY_3="core.hooksPath"
export GIT_CONFIG_VALUE_3="/dev/null"
export GIT_CONFIG_KEY_4="url.$SERVER/weichen/.insteadOf"
export GIT_CONFIG_VALUE_4="ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
# 凭据环境须保持到 pins 子模块取完(insteadOf + token 头覆盖嵌套 SSH URL),
# 之后再 unset。
@@ -708,7 +752,8 @@ jobs:
echo "RDM commit: $(git -C rdm rev-parse HEAD)"
unset GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0 \
GIT_CONFIG_KEY_1 GIT_CONFIG_VALUE_1 GIT_CONFIG_KEY_2 \
GIT_CONFIG_VALUE_2 GIT_CONFIG_KEY_3 GIT_CONFIG_VALUE_3
GIT_CONFIG_VALUE_2 GIT_CONFIG_KEY_3 GIT_CONFIG_VALUE_3 \
GIT_CONFIG_KEY_4 GIT_CONFIG_VALUE_4
unset SUBMODULE_TOKEN
make -C rdm build
- name: Run real-combination lifecycle gates (SQLite, U3, required)
@@ -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,686 @@
# feature/ecs-deploy-dev8788-and-kb 任务卡
任务主记录:PR #720 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/720;状态:已完成(合入前闭合);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 |
## 闭合记录(合入前折叠)
- 本卡在 PR #720(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/720)合入前闭合并归档,随该 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。
@@ -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,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 |
-179
View File
@@ -1,179 +0,0 @@
# feature/container-storage-plan 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;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-container-storage-plan(worktree);分支:feature/container-storage-plan
- 分支类型:initiative;initiative_id:feature-container-storage-plan;root_target:main;immediate_target:main;accepting_requirements:true
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=53a3aac8b5638347861577e2ab6f487c182b364e44b1fb0b563df0fdb5834870;triage_receipt=/tmp/container-storage-plan-triage-20261022-b.json;receipt_sha256=31e6accb098e8572e3698e04e3dbafc340fd9ef300df7a09110f1cb249aabb44
- 授权与交付终点:按已审阅方案实施 U1—U6(M1—M3)并交付到 main;含各仓代码/测试/文档变更、PR/CI/合入。不含:生产迁移 O1、生产数据读取/写入、部署到生产、数据库大版本升级。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:实施与自检(M1/U1 起);当前增量:I1=U1
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
### 章程(charter)
**用途与目标**:按已审阅方案(`docs/superpowers/plans/2026-10-22-container-storage-plan.md`)把部署形态改造为:一个完整应用服务二进制、两个 PostgreSQL 容器(业务基座库 + RDM 领域库)、知识库 PostgreSQL/pgvector 容器(第三个逻辑库)、外置持久文件根;生产/测试/验证三套环境独立配置、数据、身份与凭据;形成可验证的完整备份恢复与环境克隆隔离流程(需求 R1—R8、决策 KTD1—KTD7 见方案)。
**接纳范围**:方案 Implementation Units U1—U6 及其测试;各仓仅做阻塞目标的最小接线。U1 环境与数据归属合同;U2 容器数据库与 svc 接线;U3 迁移与文件引用兼容;U4 组合备份与恢复新目标;U5 测试/验证克隆与环境选择;U6 单二进制与组合验收、运维交付。
**非目标**:生产迁移执行(方案 O1,另获窗口授权后单独安排);高可用平台、Kubernetes、托管云数据库、全量对象存储、应用微服务化;零停机/实时复制/PITR;删除既有 SQLite/原生 PG 路径;PG 大版本升级。
**分级测试策略**:L2→L1 用 `make test-affected` 最小直接检查;L1→main 最终窗口跑完整组合(`make test`,含 `test-pg`、`svc-realcombo`、`test-regulations-kb`);容器与文件恢复必须有真实临时环境验证,缺 DSN 的跳过不计通过。
**验收条件**:方案 Definition of Done——单二进制在目标环境启动并符合两容器三库边界;三环境独立可启停重建且隔离实测;完整备份恢复到新目录且原文/引用不变;真实迁移 fixture 对账通过;精确组件组合、测试证据、独立 Review、必需 CI 与规范文档齐备。
**追加领域规则**:manifest 是身份与期望态唯一权威,Compose 只作版本化模板(KTD3);普通启停/重建不隐式删卷、不隐式恢复旧备份、不在数据库失败时回退空 SQLite(R7);镜像按选定 digest/扩展版本逐项核对(KTD7);秘密不入仓不入日志(baseline 硬边界 2)。
**生命周期**:M1(U1→U2)→ M2(U3→U4)→ M3(U5→U6)→ M4 生产切换(O1 另行授权,不在本 initiative 内)。U1 完成后按实测数据规模细化后续工期;全部必需子任务合入后置 `accepting_requirements=false` 收口合入 main。
**外部前置阻塞(2026-10-22 登记影响 M1 合入门禁)**:Backend 仓代码编译依赖旧一代 deps API(agent-command/agent-intent/agent-native/agent-squad)。pin 一致性门禁(test-pins)要求 Dev/backend 嵌套 pin 与 Dev 顶层一致(最新 main),但把 backend 的这四个依赖 pin 推到最新 main 会让 Backend vet/build 失败(SideEffects/ProcessEvent 等符号缺失,已在 gitea-endpoint-migration 任务实测)。同时 Gitea 服务器迁移后旧端点已死,Dev CI checkout allowlist 只接受新端点 URL,因此 pin 又必须前移。**解除条件:先完成 Backend 依赖 API 升级集成任务**——该任务已于 2026-10-23 完成并合入 Backend main(Backend PR #248:四依赖前移 + API 适配 + 行为修复,Review r1 FAIL→修复→r2 PASS,CI 绿)。**剩余阻塞缩小为 Agent-Command 双线语义冲突**:command main(新 receipt API,Backend #248 已适配)vs Dev main 现 pin 的 fe7987dc governance line(trusted-unknown-receipts 旧式 API,被其他在途工作依赖);两线合并会使 Backend intentgate 回归。需 owner 决策 command 两线归一方向后 re-pin。在此之前 U1(PR #710)与 #697 的 CI 无法通过,M1 合入门禁暂停;U2—U6 的代码实施可继续在分支上推进,不受影响。
## 子任务登记
| 子任务分支 | 必需 | 状态 | PR |
|---|---|---|---|
| feature/container-storage-plan-u1 | 是 | 已完成待合入(PR #710,CI 受外部前置阻塞) | #710 |
| feature/container-storage-plan-u2 | 是 | 未开始 | — |
| feature/container-storage-plan-u3 | 是 | 未开始 | — |
| feature/container-storage-plan-u4 | 是 | 未开始 | — |
| feature/container-storage-plan-u5 | 是 | 未开始 | — |
| feature/container-storage-plan-u6 | 是 | 未开始 | — |
## 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 | — |
## 关联方向与规划
- 适用状态:适用(本 initiative 的方案与实施计划)
- 主记录路径/版本:`docs/superpowers/plans/2026-10-22-container-storage-plan.md`(2026-10-22 审阅快照,含落库状态注记)
- 对应里程碑:M1(U1→U2)→ M2(U3→U4)→ M3(U5→U6);M4/O1 生产切换不在本 initiative
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1—R8 | 见方案 Requirements 表(R1 单二进制、R2 容器化、R3 环境绑定、R4 恢复可核对、R5 迁移覆盖、R6 克隆隔离、R7 无隐式破坏、R8 操作记录) | 符合(方案已核对现有 svc/manifest/迁移器/KB Compose 能力) | 高 | 见方案各单元完成条件与 Definition of Done | U1←无;U2←U1;U3←U1/U2;U4←U2/U3;U5←U4;U6←U1—U5 | 纳入本增量(U1—U6) |
## 方案与计划
- 方案引用:`docs/superpowers/plans/2026-10-22-container-storage-plan.md`(2026-10-22 审阅快照;Product Contract、KTD1—KTD7、High-Level Technical Design)
- 实施计划引用:同上 Implementation Units U1—U6 与里程碑 M1—M3(M4/O1 不在本 initiative)
- 测试计划引用:同上 Verification Contract 与各单元测试文件/场景清单
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 方案 Requirements R1—R8 | 已完成 | 主模型(方案会话)+ triage NEW | 2026-10-22 | /tmp/container-storage-plan-triage-20261022-b.json |
| 需求评估 | 方案 Problem Frame/边界假设 | 已完成 | 三视角文档审阅 + 主模型复核 | 2026-10-22 | /tmp/container-storage-plan-20261022/review.md |
| 需求表确认 | R1—R8 纳入 U1—U6 | 已完成 | 主模型 | 2026-10-22 | 方案 Requirements 表 |
| 方案设计 | KTD1—KTD7 | 已完成 | 方案会话(已审阅) | 2026-10-22 | plan.md |
| 实施计划 | U1—U6 + M1—M4 | 已完成 | 方案会话(已审阅) | 2026-10-22 | plan.md Implementation Units |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 955a32de2bb49171348bad5f566cce935df19212 | 955a32de2bb49171348bad5f566cce935df19212 | 2026-10-22T09:09:21Z |
## 证据(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-22T09:08:28.920468+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",
"[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": "ed0263b348ce265d081aab1faa0d1370f2a9478410fadfc3b9cec8a810c1295f",
"receipt_sha256": "124a47e6bfbb43cbbbc398ad10bf42e3d448373a80affd297ed25c41d8b2b07a",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/124a47e6bfbb43cbbbc398ad10bf42e3d448373a80affd297ed25c41d8b2b07a.json"
}
```
@@ -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,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
@@ -1,266 +0,0 @@
---
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
date: 2026-10-22
title: 单一应用二进制与容器化数据库、知识库存储改造方案
---
> **落库状态(2026-10-22)**:方案已获审阅并授权实施。任务以 L1 initiative
> `feature/container-storage-plan` 重新登记(R0=955a32de2bb49171348bad5f566cce935df19212)。
> 原始规划工作区(基线 9a80897)因子模块物化失败已保留现场并对账后回收:
> 全部子模块 HEAD 均在远端分支上、无独有提交、无未跟踪文件,任务卡副本存于
> `/tmp/container-storage-plan-20261022/card-auto-generated.md`。本文正文为审阅时快照,
> 其中基线 9a80897 与工作区失败描述属历史记录;实施以本卡与各子任务卡为准。
# 单一应用二进制与容器化数据库、知识库存储改造方案
本文是待用户审阅的方案与实施计划,不代表业务实施、部署或迁移授权。应用二进制及数据库容器的总体方向来自本次会话;具体分工、步骤与验收为本方案建议。
计划归属 Agent-System-Dev;本文因新工作区子模块物化失败暂存仓外,尚未提交或合入。路径以各标明仓库的根目录为基准。后续正规落点建议为 Dev `docs/superpowers/plans/2026-10-22-container-storage-plan.md`。
## Goal Capsule
- **目标**:运维人员能重建生产、测试、验证环境,把一个完整环境迁到新机器或新目录,并通过恢复验证确认账号、项目、文档、文件和知识库引用仍可用。
- **手段**:一个应用服务二进制,两个 PostgreSQL 容器,三套逻辑数据库,外置持久文件;同一制品使用独立环境配置(KTD1—KTD4)。
- **当前授权**:制定方案和计划。产品代码、容器部署、生产数据读取/复制、迁移切换均未在本轮执行;后续按用户明确授权范围实施。
- **执行责任**:各仓遵循自身 AGENTS;Dev 范围的可独立实施单元按 AGENT-EXECUTION.md 分配全新外部 Agent 会话,host 管理范围、验证、独立 Review 和交付。任务进度放任务卡,不在本文伪装已完成。
- **停止条件**:需要新增数据库类型、改变业务权限、无法完整迁移现有数据、需要丢弃新写入或扩大业务范围时停止相关动作,提交最小决策;不为容器化引入高可用平台、通用运维平台或应用微服务化。
## Product Contract
### Summary
保留前后端、Agent、RDM、知识库接入在一个应用进程内;数据库依赖使用 Compose。业务 PostgreSQL 容器分别承载基座库和 RDM 领域库,知识库 PostgreSQL/pgvector 容器承载语料与检索索引。生产、测试、验证环境分别建立,不通过临时修改生产连接串来“切环境”。
### Problem Frame
现有宿主数据库运维、应用快照、RDM 领域备份和知识库恢复各有入口,但尚未形成可核验的完整环境恢复闭环。容器化只改变数据库运行方式,必须同时处理身份绑定、数据库与文件的一致恢复点,以及复制环境后的副作用隔离。
### Requirements
| ID | 要求与可核验结果 |
|---|---|
| R1 | 完整应用服务只需一个可执行文件,包含前端资源、后端、Agent、RDM、知识库接入;运行机无需源码、Go 或 Node 构建环境。 |
| R2 | 业务库和知识库存储容器化,明确持久卷、镜像版本、扩展版本及生命周期;容器重建后业务数据仍在。 |
| R3 | 每环境独立绑定基座库、RDM 库、知识库、文件根、实例身份、端口和凭据;错误绑定拒绝启动。 |
| R4 | 从备份恢复到新目录/主机后,账号、权限、业务记录、原文和历史引用可核对;成功备份必须是一个可解释的一致恢复点。 |
| R5 | 从当前实际 SQLite/宿主 PG 迁移时覆盖所有必需持久数据所有者,保留业务标识、引用与原始内容,缺失或未知数据阻止切换。 |
| R6 | 测试/验证克隆获得新实例身份及独立凭据,启动前隔离生产密钥、会话、自动任务和外部副作用;生产实例保持固定绑定。 |
| R7 | 普通启停、重建、升级不隐式删卷、不执行数据库大版本升级、不恢复旧备份、不在数据库失败时回退到空 SQLite。 |
| R8 | 形成可重复的组合验证和生产切换/回滚操作记录;实现完成、测试通过、生产迁移完成、业务验收通过分别记录。 |
### 边界与假设
- “单一二进制”按用户原话“最终的服务”解释为一个常驻应用服务。允许部署配置、脚本和离线迁移工具存在;不新增常驻 admin、KB HTTP 或前端服务。本期不为统一离线工具而重构全部 CLI。
- 一期面向单机部署,每套环境独立;可在同机不同端口运行,也可迁到不同主机。宿主应用通过回环地址连接本机容器。
- 知识库容器化指语料数据库及向量索引容器化;检索编排、权限与引用业务仍在应用二进制内。原始文档使用外置持久存储。
- 允许维护窗口,先实现可验证的停写备份与迁移,不承诺零停机、实时复制、PITR 或自动故障切换。
- 保留既有 SQLite/原生 PG 运行路径用于兼容与受控回退;本方案目标环境使用容器 PG,不顺带删除旧实现。
- 公有知识库共享、跨环境共用只读卷、Kubernetes、托管云数据库、全量对象存储替换均不进入首期。
- 生产停写窗口、源实例、机器容量、实际源版本与数据规模在 U1 核实;它们不妨碍方案审阅,但未核实前不能安排生产切换。规划不承诺未经测量的 RTO/RPO。
## Planning Contract
### 当前依据与可复用基础
本轮主仓基线 Dev `9a80897cb7e9108091d302e849f59662f21ce260`。以下是源码/文档核查,未探测实际生产实例,也未运行产品测试。
| 范围 | 已核对的依据 | 本次改造含义 |
|---|---|---|
| 单二进制 | Dev `Makefile`;Backend `web/embed.go`;RDM `main.go`、`scripts/build-product.sh` | 已有静态组合和前端嵌入,复用完整产品构建;不能用只有基座的二进制代替 RDM 产品。 |
| 宿主 PG | Dev `scripts/svc.sh` 的 pg_bindir/db_create/pg_do_start/pg_do_stop/pg_run/pg_dump_run/db_backup/db_restore/db_clone | 容器支持需要完整后端分派,不能只替换启动命令;备份恢复继续使用已有安全边界。 |
| 实例身份 | Dev `scripts/svc_manifest.py` 的 PROTECTED/db_anchor_of/reanchor;`tests/test_svc_identity.py` | manifest 已有权威身份;扩展三库和环境绑定,不另造第二份登记权威。 |
| 基座迁移 | Backend `cmd/storage-migrate/main.go` | 已有 SQLite→PG 工具,但只迁 Backend;artifacts 参数只盘点不复制,不能据此声称迁了整个产品。 |
| RDM 迁移 | RDM `main.go` 的 migrate-to-pg/migrate-check/backup-domain/restore-domain | 独立 RDM_DSN;RDM 领域库和 uploads 必须明确纳入。 |
| KB Compose | KB-Regulations `deploy/compose.yaml`、`deploy/README.md` | 已有本地 pgvector/pgvector:pg16、回环端口、卷与扩展初始化模板;固定项目名 kbreg 不适合作为所有环境的全局名称,已有标签不等于生产版本批准。 |
| 文件迁移 | Backend `internal/blobstore/blobstore.go`;KB-Regulations `migrations/0001_schema.sql`、`docs/operations/corpus-import.md` | 工件目录相关引用、source_assets.storage_uri 中 file 路径会影响异地恢复;不能只做 dump/restore。 |
| 组合恢复 | Dev `scripts/svc.sh` 的 agent_backup_snapshot;`tests/integration/regulations-kb/README.md` | 应用快照不含全套数据库和原始 manifest;KB 测试可复用,但不证明全套外部文件已恢复。 |
RDM 研究对象为兄弟检出 `b14c84c6dcc945bd4d0a9ad446cf1ec980396491`,KB 为 `393555bec8d964f294f932616aa69ab833a06de1`;它们与 Dev `tests/integration/regulations-kb/components.pin` 的固定组合不同。本方案引用它们用于定位能力,正式实施前必须选定并验证精确组件组合,不能把研究检出当作已采纳版本。
已有恢复设计 `modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md` 是设计约束来源,本文沿用其停写一致恢复点、恢复新目标、旧写者隔离思路,不把历史执行状态当现状。
### Key Technical Decisions
**KTD1.应用保持单一服务二进制。** 复用现有产品组合构建,配置和数据外置;容器承载持久数据库依赖,知识库插件不拆进程。落实 R1/R2。(session-settled: user-directed — chosen over containerizing the whole application: user requires the final service to remain a single binary)
**KTD2.两个 PG 容器、三个逻辑库。** 业务容器中分别设基座库与 RDM 库,知识库另用带 vector/pg_trgm 的 PG 容器。数据库使用独立应用角色;引导/迁移角色与应用权限分开,先核对现有启动迁移要求,再安排显式迁移阶段,不能直接收紧权限导致启动失败。落实 R2/R3/R5。
**KTD3.复用 svc 管理入口。** 新增窄的容器驱动和版本化环境配置,保留现有命令语义。manifest 是身份与期望态权威;Compose 文件是版本化模板,环境参数由同一配置解析生成。不得并存两份可独立修改的 DSN/卷权威。只管理明确归属本环境的容器,不启停外部数据库。落实 R3/R7。
**KTD4.稳定绝对数据根与环境独立资源。** 建议形态为 `state/<env>/` 与其外部 `backups/<env>/`,实际根由配置给出绝对路径;不相对代码 checkout/worktree 解析。Compose project、两套卷、各库、角色与端口都显式区分环境。凭据放受保护文件/secret 引用,日志和清单脱敏。文件树示意仅表达归属,不规定最终名称。
**KTD5.先备份完整恢复点,再追求不停机。** 关闭新写入口,排空或隔离在途任务,停止应用、定时任务、KB 导入/索引写者及迁移器;确认其他客户端不再写入后,对三库分别逻辑导出并复制受控文件。三次 dump 各自的快照不自动构成跨库一致性,靠整个窗口无写者保持一致。完成校验后才发布恢复包完成标记。落实 R4/R8。
**KTD6.恢复和克隆是不同操作。** 原实例恢复保留业务与实例身份,但须先停旧写者,绝不双开同一生产身份。测试克隆保留业务 ID 及引用关系,创建新的部署身份和守护绑定、数据库凭据;使生产登录会话/长期 API key 在副本失效,外部 provider 密钥不带入。后台任务与外发能力默认关闭,授权后逐项启用;不通过批量改业务 ID 实现隔离。落实 R3/R6。
**KTD7.迁移与升级分离。** 源 PG 采用同大版本兼容目标与匹配工具链,SQLite 迁移用已有逻辑迁移器;本次不顺带 PG 大版本升级或强制统一业务/KB PG 大版本。实施时固定经过验证的镜像 digest、平台与扩展版本。镜像官方文档说明不同主版本的 PGDATA/卷位置存在差异,配置按选定镜像逐项核对,不能把 KB pg16 的挂载路径盲用到另一主版本。初始化脚本仅负责新卷引导,既有库变更走显式迁移。落实 R2/R5/R7。
### High-Level Technical Design
以下是关系和流程草图,新增配置/命令的最终命名由实现单元在既有接口中确定。
```mermaid
flowchart LR
Client[浏览器] --> App[一个完整应用二进制]
Profile[环境配置与实例 manifest] --> App
Profile --> Compose[Compose 数据依赖]
App --> Base[业务容器 / 基座库]
App --> RDM[业务容器 / RDM 领域库]
App --> KB[知识库容器 / 语料库与索引]
App --> Files[持久文件根 / 工件 uploads 原件]
Compose --> Base
Compose --> RDM
Compose --> KB
```
```text
state/<env>/
instance/ manifest 与受保护配置、应用版本引用
files/ 工件、RDM uploads、KB 原件及必要解析产物
Docker 持久卷:<project>-business、<project>-knowledge(各环境独立)
backups/<env>/<backup-id>/ 三库导出、文件、配置恢复材料、版本与校验清单
```
```mermaid
flowchart LR
A[识别目标与锁定操作] --> B[预检配置/身份/镜像/资源]
B --> C[启动两库容器]
C --> D[认证/扩展/schema/三库身份检查]
D --> E[按需执行显式迁移并核验]
E --> F[启动应用]
F --> G[业务就绪验证]
D -->|失败| H[拒绝启动并保留现场]
```
```mermaid
stateDiagram-v2
[*] --> Running
Running --> Quiescing: 请求一致备份
Quiescing --> Frozen: 写者已停且在途状态已记录
Frozen --> Capturing: 三库与文件导出
Capturing --> Verified: 完整性和清单校验
Capturing --> Incomplete: 失败或中断
Verified --> Running: 发布完成标记后恢复原实例
Incomplete --> Running: 确认现场可安全恢复后解除停写
```
恢复流程:读取完成清单 → 校验兼容版本与文件 hash → 选择空的新目标 → 建库/恢复角色权限及三库 → 还原文件与受控路径映射 → 核对实例模式(原实例/克隆)→ 禁止外部副作用下启动 → 登录、权限、文档、KB 引用验证 → 单独决定是否开放写入。任一步失败保持目标隔离,不覆盖旧系统。
### 完整恢复包合同
- 基座、RDM、KB 三库的逻辑导出及 schema/扩展版本;必需角色/权限用受控恢复定义记录,不能盲目导入生产全局超级用户。
- 工件、uploads、KB 原件及必要解析产物;包含全部必需插件声明的数据。对对象存储记录不可变版本/校验值及可恢复获取方式;无法获取的必需对象阻止完整恢复声明。
- 原始实例 manifest、部署配置、应用制品及插件/前端组合的 SHA、容器镜像 digest、平台信息;配置清单不含明文秘密,恢复秘密通过独立受保护介质或重新注入。仅含引用时必须验证引用在目标可解析,不能称恢复包独立可恢复。
- 文件清单与 hash、数据所有者清单、停写时间和操作状态、恢复工具版本、校验结果及完成标记。备份与 runtime 卷分离,至少验证一份异机/独立存储副本可读取。
- 原件路径变更仅调整定位信息,不改变内容 hash、语料修订、节点 ID、历史 excerpt 和审计封印。受保护审计内容若包含原路径,必须通过解析映射兼容,禁止重写封印记录。
- 向量索引可重建,但 embedding 模型/维度和语料版本要记录;恢复测试不依赖付费重新嵌入,优先复用保存的向量重建索引。
## Implementation Units
### U1.环境与数据归属合同
- **需求**:R1/R3/R5/R6,KTD1—KTD4。
- **目标**:一份可解析配置确定完整实例资源,明确现有数据来源和迁移边界。
- **主要文件**:Dev `scripts/svc_manifest.py`、`scripts/svc.sh`、`docs/svc.md`、`PROJECT.md`;新增环境 schema/示例置于 Dev `deploy/`(建议路径)。
- **做法**:扩展现有 manifest 绑定基座/RDM/KB,版本化旧配置升级;保护环境命令不受调用者环境变量污染。列出各数据所有者、类型、源版本、目录、体量、表/对象清单、引用形式和唯一写者。不输出秘密或业务内容。生产盘点需先获得对应访问授权。
- **测试文件**:扩展 `tests/test_svc_identity.py`、`tests/test_svc_lifecycle_isolation.py`、`tests/test_svc_precheck.py`。
- **场景**:旧配置升级保留身份;错库/错根/foreign marker 拒绝;同名项目或冲突端口在修改前失败;在另一 checkout 调用仍定位同一资源;三库中任一必需绑定缺失不能静默新建空库。
- **完成条件**:配置、归属清单和迁移范围有唯一解释;明确需迁移的每个数据所有者。依赖:无。
### U2.容器数据库与 svc 接线
- **需求**:R2/R3/R7,KTD2—KTD4/KTD7。依赖 U1。
- **主要文件**:Dev `scripts/svc.sh`(后端分派)、新增 `scripts/svc_containers.sh` 和 `deploy/compose.storage.yaml`(建议路径);KB-Regulations `deploy/compose.yaml`、`deploy/initdb/01-extensions.sql`、`deploy/README.md` 作为复用来源,避免复制成两套互相漂移的模板。
- **做法**:start/stop/status/SQL/dump/restore 覆盖同一容器驱动;记录明确所有权;卷重建、普通停止和数据销毁分别处理。应用仅连 loopback 发布端口。引导创建基座/RDM 独立库与角色,KB 创建扩展;后续变更使用显式迁移。启动顺序验证真实认证、扩展和身份,不能只依赖 pg_isready。
- **测试文件**:新增 Dev `tests/test_svc_containers.py`;扩展 `tests/test_svc_precheck.py`、`tests/test_svc_realcombo.py`。
- **场景**:prod/test/verify 同时运行互不冲突;停止/重建一套不影响其他套且不丢数据;缺 Docker/镜像/磁盘/凭据时在破坏性动作前失败;密码变更不误以为改 env 就改变已初始化库;容器意外停止时应用不得写入 SQLite。
- **完成条件**:用固定制品及临时环境完成两容器三库启动、持久化、重建与失败路径验证。运行冒烟优先,不用大量模拟测试替代真实容器验证。
### U3.迁移与文件引用兼容
- **需求**:R4/R5/R7,KTD5—KTD7。依赖 U1/U2。
- **主要文件**:Backend `cmd/storage-migrate/`、`internal/blobstore/blobstore.go`;RDM `main.go` 与其现有领域迁移实现;KB-Regulations 的 source_assets 读取/原件定位实现及 `docs/operations/corpus-import.md`。函数名在实施启动时定点核对,不另建并行迁移框架。
- **做法**:基座和 RDM 分别复用现有迁移器;覆盖实际 schema 的新增表、外键、序列/标识和身份记录;未知表不能悄悄遗漏。已有 PG 走兼容逻辑恢复。文件迁移校验内容和所有权,新增受控资产根映射或兼容相对引用,维持旧引用可读取。禁止迁移时跨出允许根或追随外部软链复制未知文件。
- **测试文件**:Backend `cmd/storage-migrate/main_test.go`、`integration_test.go`、`seeded_singletons_test.go` 与 `internal/blobstore/` 对应测试;RDM 现有领域迁移测试(实施前定位);KB-Regulations `tests/integration/recovery_pg_test.go`。
- **场景**:SQLite 基座+RDM 迁入不同逻辑库;原 PG 同版本恢复;空库与真实结构 fixture;失败/重跑/非空目标拒绝;未知表拒绝;不同根目录恢复后读取旧工件与 file URI 原件;越界路径拒绝;历史 citation/审计 hash 不变。
- **完成条件**:逐所有者对账,不仅比较行数,还核对 ID、关键引用、内容 hash、权限和新写入;不能完成的必需所有者阻止继续生产准备。
### U4.组合备份与恢复新目标
- **需求**:R4/R5/R8,KTD5/KTD7。依赖 U2/U3。
- **主要文件**:Dev `scripts/svc.sh` 的 backup/restore 入口;新增组合恢复辅助实现(建议 `scripts/svc_bundle.py`);`docs/svc.md`、恢复操作说明;各组件只提供必要导出/校验接口。
- **做法**:按恢复包合同采集全部数据,锁定同环境操作,停写并确认所有写者;失败包无完成标记。完整备份默认只恢复到空的新目标;应用制品和 schema 兼容预检先于开放写入。秘密处理有明确备份/重新注入路径及权限校验。
- **测试文件**:扩展 `tests/test_svc_backup.py`;新增 `tests/test_svc_bundle.py`;扩展 `tests/ops/run_backup_drill.sh` 的不同目标根场景。
- **场景**:三库与文件可恢复;备份中断、空间不足、错包、hash 损坏、缺原件、缺必要 secret、镜像不兼容拒绝;目标非空拒绝;不得覆盖生产;重新启动源实例不把未完成包发布为成功;保留原生产身份恢复时,目标接管前必须隔离旧写者;独立克隆从已完成的一致备份恢复,源实例可在备份完成后继续运行,但目标首次启动前必须完成新身份、独立凭据及副作用隔离。
- **完成条件**:干净环境恢复完整产品并生成可复核清单;实测备份大小、停写时长和恢复用时。
### U5.测试/验证克隆与环境选择
- **需求**:R3/R6/R8,KTD4/KTD6。依赖 U4。
- **主要文件**:Dev `scripts/svc.sh` 的 clone/启动接线、`scripts/svc_manifest.py`;Backend/RDM 现有身份、会话和任务控制入口仅作必要接线;测试数据 fixture 与说明。
- **做法**:以明确目标环境创建新实例。业务 ID 不改,部署身份、守护与凭据换新;登录会话/API key 不在副本继续有效,账号密码处理按克隆用途明确。需要复制生产敏感数据时先落实访问范围和脱敏策略;常规自动验收优先合成数据。外部密钥、自动调度与恢复任务副作用默认禁用,并在首次启动前生效。
- **测试文件**:扩展 `tests/test_svc_identity.py`、`tests/test_svc_lifecycle_isolation.py`;新增 `tests/test_svc_environment_clone.py`。
- **场景**:克隆后生产仍正常;新身份不触发原守护冲突;旧 token 无法访问副本;待执行任务不自动发信/调用真实 provider/写生产目录;选择 test 不修改 prod 配置;操作摘要明确目标环境。
- **完成条件**:三套环境同机并存,隔离由实际读写与副作用拒绝验证,不靠名称或配置声明。
### U6.单二进制与组合验收、运维交付
- **需求**:R1—R8,KTD1—KTD7。依赖 U1—U5。
- **主要文件**:Dev `Makefile`、`tests/test_svc_realcombo.py`、`tests/integration/regulations-kb/run.sh`、`components.pin`、`PROJECT.md`、`docs/svc.md`;RDM `scripts/build-product.sh`;各仓必要 runbook/组合指针。
- **做法**:固定完整产品与镜像组合,在没有源码及 Go/Node 的机器/隔离环境用同一应用制品启动。把恢复、克隆、数据库容器重启加入组合验证。必要管理操作优先复用同一产品已有入口,离线工具不成为常驻依赖。受影响仓独立验证后再推进 Dev 组合,不重做发布体系。
- **场景**:UI/API、正常账号登录、角色边界、项目/会话、RDM 上传/文档原件读取、知识库检索、历史引用解析;两库容器依次重启;新目录恢复;test/verify 重建不影响 prod;客户端制品无 secret。
- **完成条件**:满足 Definition of Done;输出生产切换操作单与回滚分界,实测停写时间供用户安排窗口。生产执行属于下面 O1,不由代码测试替代。
## Verification Contract
- 本轮是规划:产品测试、真实容器试验、迁移演练、生产盘点/部署均为 **NOT_RUN**;源码核查属于 SELF,不能提升为 GATE 或 REPLAY。
- 实施每单元先运行其最小直接检查,容器与文件恢复必须有真实临时环境验证。禁止把缺 DSN 导致的跳过计作通过;真实测试仅指向显式临时环境。
- Backend 真 PG 迁移测试使用 `AGENT_PG_TEST_DSN`;法规组合门禁使用 `KBREG_TEST_DATABASE_URL`、精确 RDM/KB pin 及既有 `make test-regulations-kb`。
- Dev 治理脚本确有修改时运行 `make test-governance`;最终组合按项目要求执行 `make test`,并以当前 CI 要求核对 `test-pg`、`svc-realcombo` 等检查,不能凭旧清单声称全部通过。
- 推进 Dev gitlink 前完成所需组合验证;命令原始输出经 `make evidence` 写任务卡。正式 Review 前重放最小集合、同步权威目标;合入信任来自精确 HEAD 的必需 CI 或独立 REPLAY。
- 全量检查只在最终候选或有必要时运行;发现无关非阻塞问题不扩大本次任务。
## O1.生产迁移与回滚计划(另行授权执行)
1. **确认源与窗口**:记录实际源实例、三库/文件清单、schema、版本、容量、现有身份、备份位置及授权范围;确认恢复演练达标和可接受停写时间。
2. **提前准备目标**:拉取固定镜像、准备空库/角色/持久目录、验证磁盘与网络;用演练副本验证完整应用制品。此阶段不改生产连接。
3. **冻结生产写入**:暂停入口及所有后台/外部写者,排空或隔离在途工作,确认旧实例不会被 supervisor 自动拉起;记录已确认写入的对账点。
4. **最终备份与迁移**:按 U3/U4 生成最终完整包并恢复目标;核对所有必需数据与文件,运行只读业务验证;保持外部副作用关闭。
5. **受控切换**:以迁移操作更新目标绑定、身份和文件路径;先验证登录/权限/文档/知识库,再开放写入及经确认的后台任务。避免两个生产写者同时存在。
6. **观察与保留**:保留旧数据及最终备份,只读保护并记录新系统写入开始时间;到达业务验收及约定保留期后才单独安排旧资源回收。
回滚分界必须写入操作单:
- **新目标尚无业务写入**:停止新实例,确认无新数据后恢复旧配置/旧写者;不可让双方同时写。
- **新目标已有业务写入**:停止写入并保存新数据,禁止简单切回旧库;评估向前修复或经过验证的数据对账/回迁。未经确认不丢弃新写入。
- **schema 已改变**:旧应用制品不一定兼容。代码回滚、数据库恢复和业务数据回迁分别验证,不能用“换回旧二进制”代替恢复方案。
## Definition of Done
代码交付完成须同时满足:
- 一个完整应用服务二进制在目标运行环境启动,业务/RDM/KB 数据存储符合两容器三逻辑库边界。
- prod/test/verify 可独立启动、停止、重建与选择,配置/数据/身份/权限隔离已验证。
- 完整备份可以恢复到不同根目录;原文可读、业务引用和历史法规引用不变;缺失数据时明确失败。
- 真实迁移 fixture 对账通过,重启与容器重建不丢数据,失败不会回退空系统或启动外部副作用。
- 精确组件组合、测试证据、独立 Review、所需 CI 及规范文档齐全;没有遗留试验实现进入最终 diff。
- O1 的执行另记:代码完成不等于生产迁移完成,恢复演练也不等于业务验收。
## 顺序与建议里程碑
| 里程碑 | 工作 | 出口 |
|---|---|---|
| M1 最小可运行 | U1 → U2 | 同一应用连接两容器三库,test/verify 并存,持久化与错误绑定验证通过 |
| M2 可迁移可恢复 | U3 → U4 | 完整数据恢复到新目录,原文和历史引用可核对 |
| M3 可安全切环境 | U5 → U6 | 克隆隔离、完整产品组合验证、操作说明齐备 |
| M4 生产落地 | O1 | 获得窗口授权后迁移、业务验收,旧数据按约定保留 |
U1 完成后再按实际 schema 覆盖、文件规模及演练用时细化工期;当前不把未测量的数据量换算为承诺日期。每个里程碑只处理阻塞目标的问题。
## 外部依据与待核验项
本轮尝试读取 Docker Compose、PostgreSQL 备份与 pgvector 官方文档;网络读取不完整。成功获取 Docker Official Image 的 PostgreSQL 说明(docker-library/docs 的 postgres/README.md),其中确认 PGDATA/卷位置随主版本变化、初始化参数仅对新数据目录生效、密码支持文件注入。这些仅作为镜像适配约束,未确定最终镜像 digest,也未验证某个部署平台。
实施 U2 前需针对所选精确版本再次核对 Compose/镜像/pgvector 官方资料,并做真实冒烟;失败则阻止该镜像采用,不阻止本方案的源码设计工作。
+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 |
+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)
+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
+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)
+38 -25
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")
@@ -413,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)
@@ -425,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)
+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
+7 -1
View File
@@ -49,8 +49,12 @@ def ci_git_env():
if not (CI_SERVER and CI_TOKEN):
return {}
scheme = CI_SERVER.split("://", 1)[0]
# 嵌套 pins 的 SSH 端点有两代:旧 git-ssh.*:31411 与迁移后的 gitea.*:52222。
# 两个 insteadOf 必须同时保留,直到所有 .gitmodules 迁到新端点(policy/facts.md
# F3 已把新端点列为权威;本仓 .gitmodules 仍有旧端点子模块):任去掉一个,
# 对应那批 pins 都会退回真实 SSH,而 CI 运行器没有 key,必然 host key 失败。
return {
"GIT_CONFIG_COUNT": "4",
"GIT_CONFIG_COUNT": "5",
"GIT_CONFIG_KEY_0": "protocol.%s.allow" % scheme,
"GIT_CONFIG_VALUE_0": "always",
"GIT_CONFIG_KEY_1": "http.%s/.extraheader" % CI_SERVER,
@@ -59,6 +63,8 @@ def ci_git_env():
"GIT_CONFIG_VALUE_2": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/",
"GIT_CONFIG_KEY_3": "core.hooksPath",
"GIT_CONFIG_VALUE_3": "/dev/null",
"GIT_CONFIG_KEY_4": "url.%s/weichen/.insteadOf" % CI_SERVER,
"GIT_CONFIG_VALUE_4": "ssh://git@gitea.naitangbaobao.cn:52222/weichen/",
}
PG = os.environ.get("SVC_TEST_PG") == "1" and bool(os.environ.get("AGENT_PG_TEST_DSN"))
+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")