Compare commits

...
Author SHA1 Message Date
weichen 0156e7c5d7 Record the diagnostics conclusions and pause unit dispatch
Why: the svc flake is machine-load-dependent (load 66 during failures,
idle-machine runs pass 553/553) and the .gitmodules rewrite did not
reproduce under controlled materialize tests; agent-unit dispatch is
not viable at current load.
Evidence: two idle full-suite runs 553/553 green; controlled
materialize test with unchanged .gitmodules md5.
Impact: task metadata only.
Refs: feature/recall-misexec-fixes (environment findings)
2026-10-23 15:45:30 +00:00
weichen c34f2876c0 Record the scripts-robustness design in the task card
Why: fix the two approved script robustness issues: the intermittent
svc manifest-migration skip and the materialization .gitmodules
rewrite, both diagnosed in session.
Evidence: session diagnostics (standalone-pass vs full-suite-fail;
82+ restored .gitmodules files).
Impact: task metadata only.
Refs: feature/recall-misexec-fixes (environment findings)
2026-10-23 14:42:34 +00:00
weichen aa569636b1 Record the task card for feature-scripts-robustness-fixes
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-scripts-robustness-fixes.md; R0=d1ea338fe9932fddf21429d826ffe354817e8fde.

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

Refs: .task/feature-scripts-robustness-fixes.md
2026-10-23 14:37:43 +00:00
weichen d1ea338fe9 Merge pull request 'Audit review minors cleanup across the five components' (#721) from feature/audit-review-minors-cleanup into main
ci / svc-realcombo (push) Successful in 3m28s
ci / test (push) Successful in 10m59s
ci / test-pg (push) Successful in 15m8s
2026-10-23 13:37:45 +00:00
weichen 7ce5c1eebc Merge authoritative main into the task branch
ci / test-pg (pull_request) Successful in 24m34s
ci / svc-realcombo (pull_request) Successful in 5m8s
ci / test (pull_request) Successful in 13m19s
Why: include the current integration baseline before merge (carries the RDM submodule URL fix).

Evidence: fetched origin/main=f0221f75.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-23 13:09:23 +00:00
weichen 4dcf8a0d9a Record the review BLOCK and the m1-m4 reapplication
ci / test-pg (pull_request) Successful in 20m23s
ci / svc-realcombo (pull_request) Failing after 4m14s
ci / test (pull_request) Successful in 10m39s
Why: the reviewer correctly flagged the missing m1-m4 fixes; the repair
replayed the preserved transport diff onto the current tip and the pin
follows.
Evidence: a1m-run.json repair receipt; verify-a1m.json exit=0.
Impact: task metadata + backend pin note.
Refs: PR #721
2026-10-23 12:53:51 +00:00
weichen 84530464a8 Repin modules/backend to the reapplied m1-m4 tip
Why: the backend branch tip advances with the reapplied A1 m1-m4 fixes
that the independent review flagged as absent.
Evidence: repair transport (minorgb3-run.json) reusing the preserved
min-sess diff; per-package tests green (verify-a1m.json exit=0).
Impact: one component gitlink.
Refs: PR #721
2026-10-23 12:45:19 +00:00
weichen f0221f756f Merge pull request 'Record ECS dev 8788 deployment, role setup and the merged fixes' (#720) from feature/ecs-deploy-dev8788-and-kb into main
ci / svc-realcombo (push) Successful in 4m10s
ci / test (push) Successful in 11m22s
ci / test-pg (push) Successful in 15m15s
2026-10-23 12:41:01 +00:00
agent-exec-transport 5b049635f2 agent-exec transport a585136683482f35894f1bc0d75761a0/c202188f5f7b
ci / svc-realcombo (pull_request) Successful in 4m30s
ci / test (pull_request) Successful in 10m29s
ci / test-pg (pull_request) Successful in 14m5s
2026-10-23 12:25:46 +00:00
agent-exec-transport e3c3b60ba6 agent-exec transport 021b667f52d7b20eaa4908730b7fd2ac/4738f0d4ecdb 2026-10-23 12:24:08 +00:00
weichen f8377960cc Record the minors-cleanup unit receipts and combination results
ci / svc-realcombo (pull_request) Failing after 2m38s
ci / test (pull_request) Successful in 9m37s
ci / test-pg (pull_request) Successful in 13m59s
Why: audit trail for the six units, the pi disable/codex routing change
and the green combination run.
Evidence: verify-min-native/minm2c4/min-cmd/min-int3/min-sess2/min-diag/
minors-combo4 all exit=0.
Impact: task metadata only.
Refs: feature/audit-review-minors-cleanup
2026-10-23 12:06:20 +00:00
weichen b7a9879af2 Repin backend to the nested-command tip and align three containers
Why: complete the minors composition closure: native nested intent,
squad nested intent/native, backend nested intent/native/squad/command
all consistent with the Dev-level pins.
Evidence: integration transports (minorg6/minorgb-run.json); pins
checks and full make test re-run below.
Impact: three component gitlinks.
Refs: feature/audit-review-minors-cleanup
2026-10-23 11:58:09 +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
agent-exec-transport 7539da5029 agent-exec transport 16de9aef520b8c16e15cc47bb4822860/9fb8d9c5d839 2026-10-23 11:42:22 +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 f0d94360f9 Advance five component pins to the review-minors cleanup tips
Why: land the review-minors fixes across native (session identity
encoding), squad (direct copy, comment, save-failure consistency),
intent (baseline caveat, slice assertion), command (trusted-marker
roundtrip) and backend (diagnostics minors, session minors).
Evidence: per-unit receipts (min-native/min-squad*/min-cmd/min-int/
min-sess2/min-diag-run.json); pins checks and full make test re-run
below.
Impact: five component gitlinks.
Refs: feature/audit-review-minors-cleanup
2026-10-23 10:45:53 +00:00
weichen faf815f997 Record the minors-cleanup unit breakdown in the task card
Why: consolidate the 18 review minors into six per-repo units with
fixed scope.
Evidence: consolidated from the four review reports.
Impact: task metadata only.
Refs: .task/reviews/ reports
2026-10-23 07:52:38 +00:00
weichen 3a8c81bd92 Record the task card for feature-audit-review-minors-cleanup
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-audit-review-minors-cleanup.md; R0=0650e81133b853f27e8e53f516de8f6c1e73e4a4.

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

Refs: .task/feature-audit-review-minors-cleanup.md
2026-10-23 07:46:24 +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 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
32 changed files with 2233 additions and 82 deletions
+41 -4
View File
@@ -178,6 +178,31 @@ jobs:
tar -C /usr/local --strip-components=1 -xJf "$RUNNER_TEMP/node.tar.xz" tar -C /usr/local --strip-components=1 -xJf "$RUNNER_TEMP/node.tar.xz"
- name: Install house-style Python packages - 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 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) - name: make test (boundaries, pins, libs, core, backend, frontend, ui, agent-command)
run: make test run: make test
- name: Build the single binary - name: Build the single binary
@@ -404,7 +429,10 @@ jobs:
# https 基址后再取。只追加 pin 的三个 40 位 hex,不 source pin 文件。 # https 基址后再取。只追加 pin 的三个 40 位 hex,不 source pin 文件。
SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')" SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')"
scheme="${GITHUB_SERVER_URL%%://*}" scheme="${GITHUB_SERVER_URL%%://*}"
export GIT_CONFIG_COUNT=4 # 嵌套 pins 的 SSH 端点有两代(旧 git-ssh.* 与迁移后的 gitea.*:52222);
# 只映射旧端点会让嵌套克隆退回真实 SSH,CI 无 key 时必然 host key 失败。
# 两个 insteadOf 同键多值,git 会依次匹配。
export GIT_CONFIG_COUNT=5
export GIT_CONFIG_KEY_0="protocol.$scheme.allow" export GIT_CONFIG_KEY_0="protocol.$scheme.allow"
export GIT_CONFIG_VALUE_0="always" export GIT_CONFIG_VALUE_0="always"
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader" export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
@@ -413,6 +441,8 @@ jobs:
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/" export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
export GIT_CONFIG_KEY_3="core.hooksPath" export GIT_CONFIG_KEY_3="core.hooksPath"
export GIT_CONFIG_VALUE_3="/dev/null" 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 git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
mapfile -t pins < <(python3 - <<'PY' mapfile -t pins < <(python3 - <<'PY'
import pathlib import pathlib
@@ -479,7 +509,8 @@ jobs:
done done
unset GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0 \ 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_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 unset SUBMODULE_TOKEN
- name: Install Node 22 - name: Install Node 22
run: | run: |
@@ -692,7 +723,10 @@ jobs:
# https 基址后再取。 # https 基址后再取。
SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')" SERVER="$(printf '%s' "$GITHUB_SERVER_URL" | sed 's:/*$::')"
scheme="${GITHUB_SERVER_URL%%://*}" scheme="${GITHUB_SERVER_URL%%://*}"
export GIT_CONFIG_COUNT=4 # 嵌套 pins 的 SSH 端点有两代(旧 git-ssh.* 与迁移后的 gitea.*:52222);
# 只映射旧端点会让嵌套克隆退回真实 SSH,CI 无 key 时必然 host key 失败。
# 两个 insteadOf 同键多值,git 会依次匹配。
export GIT_CONFIG_COUNT=5
export GIT_CONFIG_KEY_0="protocol.$scheme.allow" export GIT_CONFIG_KEY_0="protocol.$scheme.allow"
export GIT_CONFIG_VALUE_0="always" export GIT_CONFIG_VALUE_0="always"
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader" export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
@@ -701,6 +735,8 @@ jobs:
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/" export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
export GIT_CONFIG_KEY_3="core.hooksPath" export GIT_CONFIG_KEY_3="core.hooksPath"
export GIT_CONFIG_VALUE_3="/dev/null" 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 git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
# 凭据环境须保持到 pins 子模块取完(insteadOf + token 头覆盖嵌套 SSH URL), # 凭据环境须保持到 pins 子模块取完(insteadOf + token 头覆盖嵌套 SSH URL),
# 之后再 unset。 # 之后再 unset。
@@ -708,7 +744,8 @@ jobs:
echo "RDM commit: $(git -C rdm rev-parse HEAD)" echo "RDM commit: $(git -C rdm rev-parse HEAD)"
unset GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0 \ 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_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 unset SUBMODULE_TOKEN
make -C rdm build make -C rdm build
- name: Run real-combination lifecycle gates (SQLite, U3, required) - 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,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/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,158 @@
# feature/audit-review-minors-cleanup 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 0650e81133b853f27e8e53f516de8f6c1e73e4a4
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-audit-review-minors-cleanup(worktree);分支:feature/audit-review-minors-cleanup
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=8093a20aeb1bf2cdf72035222ea6296c93a89d1f9af5a33174b7b4e137b203ff;triage_receipt=/tmp/triage-minors-1792741494.json;receipt_sha256=f971d66ba14af677a56e68112fb842731e90066b0a5dd9ce66a746c86561257a
- 授权与交付终点:用户已批准启动评审 minor 打包收口(四份评审报告的非阻塞跟进项,M5 与批二收据注记已在先前任务完成)。范围内连续推进:按仓库拆 6 个单元实施、验证、组合、Review、PR/CI/合入。未授权:A4、部署、svc 测试环境与 .gitmodules 镜像改写排查(另行诊断任务)。
- 单元拆分:U1 native(会话身份编码防碰撞);U2 squad(探针改直拷、过期注释、保存失败回写内存态);U3 command(unknown 回执 JSON 往返契约文档/再水化);U4 intent(基线漂移说明、fmt.Sprint 逐元素比较);U5 backend-session(intent_session 注释同步、取消拒绝原因、过期 fail-closed、落槽归属用例锁定);U6 backend-diag(终态抑制 wait 映射、截断注记、优先级组合测试)。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:18 条 minor 中全部有效代码/文档项收口(含 A1 评审 m1-m4、批二 B-1/B-2/B-3/B-5),逐条对照评审报告原文验证。
**非目标**:A4;svc 测试 flake 与 .gitmodules 改写排查(另行诊断);任何行为语义变更(各 minor 均为卫生级,保持既有语义,仅消除隐患/失实/脆弱)。
## 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 |
|---|---|---|---|
| 启动 | 0650e81133b853f27e8e53f516de8f6c1e73e4a4 | 0650e81133b853f27e8e53f516de8f6c1e73e4a4 | 2026-10-23T07:46:24Z |
## 证据(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 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- 实施收据:U1 native(cursor,会话身份编码,verify-min-native exit=0);U2 squad(pi 三连终态记录解码失败后 codex 承接——/pi 禁用与 codex 入列的理由入档,M2 直拷+M4 注释+B-3 回写,verify-minm2c4 exit=0);U3 command(M3 往返标记,verify-min-cmd exit=0);U4 intent(基线说明+逐元素比较,verify-min-int3 exit=0);U5 backend-session(m1-m4,verify-min-sess2 exit=0);U6 backend-diag(MI1-3+B-1/B-2,verify-min-diag exit=0);pin 级联集成(test 角色,minorg6-run.json)。
- 组合验证:全量 make test PASS(verify-minors-combo4.json exit=0)。
- Review 记录:独立 CLI 评审单元 minors-cleanup-independent-review(收据 /tmp/agent-stack-b2/reviewmin-run.json);结论 BLOCK(BL1 属实:backend 分支从未包含 m1-m4——min-sess2 的 apply 因我误读输出被跳过)→ 修复单元 a1m-fix(从保留的 transport diff 重放,backend 7776399)→ 已入分支;报告 .task/reviews/2026-10-22-minors-cleanup-independent-review.md;backend pin 随之更新(84530464)。
- 冲突记录: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-23T07:45:30.253011+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "0650e81133b853f27e8e53f516de8f6c1e73e4a4",
"after_head": "0650e81133b853f27e8e53f516de8f6c1e73e4a4",
"branch": "main",
"target_branch": "main",
"target_head": "0650e81133b853f27e8e53f516de8f6c1e73e4a4",
"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=0650e81133",
"[remote] origin/main=0650e81133 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/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] 0650e81133(完整:0650e81133b853f27e8e53f516de8f6c1e73e4a4)",
"[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": "c1734e4f72604116deae298cf460045ba0adade340c8ef670bf95d4e9f8de5d6",
"receipt_sha256": "629046bbfcce1b86b48f1f7e1333a2a3d3ca84ce78376de9c2f41a8661e77902",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/629046bbfcce1b86b48f1f7e1333a2a3d3ca84ce78376de9c2f41a8661e77902.json"
}
```
+680
View File
@@ -0,0 +1,680 @@
# feature/ecs-deploy-dev8788-and-kb 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= cb36b59accd0418c5ca952912d7c181b83038a4c
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb(worktree);分支:feature/ecs-deploy-dev8788-and-kb
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=420311b8d5e0543749bb9743c05ae6757cc0244c7cfda204e6c28bc92eaf8b87;triage_receipt=/tmp/ecs-kb-deploy-triage.json;receipt_sha256=7a0bf8e0d2b9f1adcac5e58cbe70204473007a4dfd04a96f495dde3c0dd71ddb
- 授权与交付终点:owner 2026-10-22 指令“将当前的二进制服务部署到 imc-tx-ecs:先备份远端机器上的服务和数据库;将本机的知识库也部署在远端上;然后部署本机 8788 上的二进制服务;尽可能减少远端服务下线时间并保证服务可用;更换二进制前先告知 owner 确认”,并于 2026-10-23 追加“先把配置弄好,superadmin 账号使用 imc-tx-ecs 上的 sundehui,密码 12345678,第一次登录需要重置密码(把已有用户变成超级管理员)”。交付终点:ECS 8788 运行与本机 dev 同版本二进制(sha256 00ead2cf…),ECS 承载本机 kbreg 知识库且检索可用,远端用户数据零丢失,切换带自动回滚并留存冷备与异地副本。仓库写入仅本任务卡。未授权:修改产品代码、改 Caddy 路由/域名、删除远端既有备份或旧二进制、改动 sundehui 以外账号的凭据、owner 确认前执行二进制切换。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进;切换二进制属人工决策点,先备齐再请确认)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:实施与自检(I1 备份 → I2 知识库 → I3 演练;I4 切换待 owner 确认);当前增量:I3(远端演练,零停机)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
预期结果:ECS(imc-tx-ecs,43.143.211.203,Ubuntu 22.04,2 vCPU/3.6GiB/49GiB 可用;Caddy `imcrd-agent.imcbot.work` → 127.0.0.1:8788)上:
1. 本机 8788 dev 二进制服务原样上线——`runtime/dev/current` 指向 `releases/rdm-ee8c2cd-20261022T055052Z-637762`,`bin/agent-system` sha256 `00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de`(141509195 B),同版 htdocs;systemd 用户单元 `agent-system-dev.service` 的 ExecStart 参数不变。
2. 本机知识库供给到 ECS——本机 kbreg(PostgreSQL 16.15 + pgvector,127.0.0.1:5436,3.1 GB)在 ECS 以原生 PostgreSQL 16.15 + pgvector(回环 5436)承载,语料、已发布修订与索引逐表可核;服务侧经 `serve.env`(`KBREG_*`)+ systemd drop-in `EnvironmentFile` 启用。
3. 远端用户数据零丢失——`data/agent-system.db`(schema v35,24 MB + WAL)与 `rdm.db`(1.5 MB + WAL)经 SQLite 在线备份 API 一致落盘,切换前后以 `ecs-dbsnap.py manifest/compare` 逐行对账 `problems=[]`。
受影响:ECS `runtime/dev/{bin,htdocs,plugins,data,backups,serve.env,svc.env,history.jsonl}`、`~/.config/systemd/user/agent-system-dev.service.d/`、ECS 新增 PostgreSQL 16 集群。本仓:仅 `.task/**`。
非目标:不改产品代码与发布物;不改 Caddy 路由、域名与 TLS;不迁移本机业务数据到 ECS(仅知识库);不删除远端既有备份、旧二进制与 `agent-system-admin/cli`;不动账号、凭据与登录 Key(远端无 `super-admin.env`,切换后仍无,与现状一致);不引入 Docker(远端无容器运行时且不可达镜像仓库)。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 无(运维任务,无仓库代码单元;仓库写入仅 `.task/**` host 豁免) | — | — | — | — | — | — | — | — | — | — |
## 关联方向与规划
- 适用状态:适用但不同阶段——`feature/container-storage-plan`(PR #697,open)是容器化部署形态 initiative,其章程把“生产迁移执行(O1)”列为非目标并要求另获窗口授权;本任务是该形态落地前的既有 SQLite 二进制运维部署,与 U1—U6 无依赖,分流 verdict=NEW(理由见分流收据)。
- 主记录路径/版本:`docs/superpowers/plans/2026-10-22-container-storage-plan.md`(位于 feature/container-storage-plan 分支,未合入 main;本卡引用其 O1 边界,不复制正文)
- 对应里程碑:不在其 M1—M3 内;本任务为独立运维增量 I1—I4
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 先备份远端服务与数据库 | 符合(owner 指令;沿用 `ecs-dbsnap.py` 在线备份 API) | P0 | 远端 `backups/<TS>-warm-pre-ee8c2cd/` 含 data/bin-old/htdocs-old/config + SHA256SUMS 校验通过 + 本机异地副本逐文件 sha 通过 | 无 | 达成(见证据) |
| R2 | 本机知识库部署到远端 | 符合(远端无容器运行时且镜像仓库不可达,按同主版本原生 PostgreSQL 16.15 + pgvector 供给) | P0 | ECS 127.0.0.1:5436/kbreg 可连;`schema_migrations` 0001—0005;关键表行数与本机一致;向量检索返回命中 | 无 | 达成(见证据) |
| R3 | 部署本机 8788 二进制服务且最小停机 | 符合(owner 指令) | P0 | 运行中 exe sha256=00ead2cf…;本地与域名 HTTP 200;停机窗口 ≤ 演练实测 + 人工确认 | R1、R2 | **未达成**:技术切换完成(停机 6.88 s、三处 200),但业务验收 `extension: project context unavailable: not-found`,已回退到旧版本 |
| R4 | 服务可用性保障(回滚) | 符合(切换脚本含健康门失败自动回滚) | P0 | 演练实例证明新版本可启动并迁移 v35→最新;回滚路径演练可用 | R3 | 达成(回退装备 sha 通过 + rollback-now.sh 已就位) |
| R5 | 用户数据零丢失 | 符合 | P0 | 冷备 manifest ↔ 切换后逐行对账 `problems=[]`;settings 明文密钥与 `secret_keys` 逐把一致 | R1、R3 | 达成(切换后与回退后两次对账均 `problems=[]`、零缺失;回退期间曾因脚本嵌套缺陷短暂运行空库,已从冷备真实路径恢复并核验) |
| R6 | 超级管理员 = 既有账号 sundehui(口令 12345678,首次登录强制改密) | 符合(owner 2026-10-23 追加指令) | P0 | 库中仅 sundehui 带超管标记且 `is_admin=1`、`must_change_password` 置位;服务以 `SUPER_ADMIN_OWNER=sundehui` 启动日志为 `already established`(无冲突);`POST /api/auth/login` 200 且 `isSuperAdmin=true`、`sessionScope=set_password_only` | 切换时达成并验证;回退后该标记随冷备数据撤回(远端现无超管标记,下次切换需重跑提升步骤) |
| R7 | 仓库侧交付(任务卡 + PR) | 符合 | P1 | Review 通过、CI 通过、PR 合入 main、任务卡闭合 | R1—R6 | 待收口 |
## 方案与计划
### 对象版本(本机发布物,运行中 /proc/652953/exe)
- 二进制:`/home/weichen/projects/Agent-System-Dev/runtime/dev/current/bin/agent-system`,sha256 `00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de`,141509195 B;来源 `rdm@ee8c2cd`(`runtime/dev/svc.env`),started 2026-10-22T05:51:02Z,监听 127.0.0.1:8788。
- 前端:`current/htdocs`(148 KB,与本机 release 同源);`current/plugins` 为空(远端 plugins 亦为空)。
- 知识库:本机容器 `kbreg-postgres-1`(`pgvector/pgvector:pg16`,PostgreSQL 16.15),库 `kbreg` 3.1 GB;`schema_migrations` 0001—0005;regulations/editions 2897、legal_nodes 1701178、index_entries 191557、retrieval_chunks 64076、ingest_runs 2943。
- 远端现状:`agent-system.db` schema_max=35(58 表 / 28072 行)、`rdm.db`(28 表 / 3578 行,无 `schema_migrations`,由 `schema_version` 管理)、data 树 367 MB、bin 178 MB。
### 增量与步骤
- I1 备份(零停机):`~/ecs-ops/backup-warm.sh warm-pre-ee8c2cd`——SQLite 在线备份 API 取两个库的一致快照 + rsync 文件树(排除库本体)+ bin/htdocs/plugins/systemd 单元/Caddyfile/svc.env/svc.pid/history.jsonl + `manifest` 活库基线 + 相对路径 SHA256SUMS;随后 `~/ecs-ops/offsite-copy.sh` 流式拉回本机 `~/backups/imc-tx-ecs/<同名>/` 并逐文件校验。
- I2 知识库(零停机):远端加 PGDG apt 源 → 安装 `postgresql-16`(16.15)+ `postgresql-16-pgvector`(0.8.7)→ 集群改 `port=5436`、`listen_addresses=localhost` → 建 `kbreg` 角色与库 → 本机 `pg_dump -Fc`(容器内 16.15 客户端,与服务端同主版本)流式传输 → `pg_restore --no-owner --no-privileges` → 逐表行数与 `schema_migrations` 核对 → 向量检索冒烟 → 从本机 `serve.env` 只取 `KBREG_*` 行落远端 `runtime/dev/serve.env`(600,凭据值不出管道)→ systemd drop-in `20-serve-env.conf` + `daemon-reload`(不重启服务)。
- I3 演练(零停机):新二进制与 htdocs 预置到远端 `runtime/dev/stage/<版本>/`;`rsync -a` 复制 data 为 `rehearsal/data`;以 `127.0.0.1:8789` 启动演练实例(带 KBREG 环境)——实测启动+迁移耗时、HTTP 200、schema 版本、关键表行数、日志无 error、KB 检索可用;结束后清理演练目录。
- I4 切换(待 owner 确认后执行):停 recover timer → 停服务 → 库文件冷拷到新备份目录 → `install`+`mv` 原子换二进制、换 htdocs → 启动 → 健康门(本地 200、域名 200、pid/exe sha、schema、KB)→ 失败自动回滚(旧二进制 + 冷备 data + 旧 htdocs)→ 更新 svc.env/svc.pid/history.jsonl → 启 recover timer。
- I5 收口:切换后逐行对账 `compare`、密钥一致性、启动日志、证据写入、Review、PR/CI、合入。
### 停机时间控制
- I1—I3 全程不动线上进程;数据与文件预置在切换窗口之前完成。
- 切换窗口只做:停服务 → 拷两个库(24 MB + 1.5 MB + WAL)→ 原子换二进制 → 启动 → 健康检查。库迁移(v35→最新)在新进程启动时执行,耗时以 I3 演练实测为准;演练若显示迁移显著耗时,再评估预迁移 + 增量拷贝方案后才切换。
### 测试计划
- I1:远端 `sha256sum -c SHA256SUMS` 通过 + 本机异地副本同样通过 + `manifest` 生成成功(28,072 + 3,578 行)。
- I2:`psql` 连接成功;`schema_migrations` 5 条;`select count(*)` 关键表与本机一致(差异即 FAIL);`revision verify` 等价核验(staged/computed sha 一致);一条向量相似度查询返回非空命中;演练实例带 KBREG 启动无 KB 连接错误。
- I3:演练实例 `/` 200、`/healthz` 200;`schema_migrations` 升到目标版本;`users/conversations/runs` 行数与冷备一致(迁移不丢数据);日志 grep 无 `error|panic|fatal`。
- I4/I5:运行中 exe sha256 前缀 `00ead2cf`;`127.0.0.1:8788` 与 `https://imcrd-agent.imcbot.work/` 均 200;`compare MANIFEST-LIVE-PRE.json data` → `problems=[]`;`secret-check.py` 明文密钥与 `secret_keys` 逐把一致;停机窗口秒数由脚本记录。
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | R1—R6 | 已完成 | 主模型 + triage NEW | 2026-10-22 | /tmp/ecs-kb-deploy-triage.json |
| 需求评估 | 对象版本与远端现状核对 | 已完成 | 主模型 | 2026-10-22 | 本卡“方案与计划” |
| 需求表确认 | R1—R6 | 已完成 | owner 指令即验收边界 | 2026-10-22 | owner 2026-10-22 指令 |
| 方案设计 | I1—I5 | 已完成 | 主模型 | 2026-10-22 | 本卡“方案与计划” |
| 实施计划 | I1 备份 / I2 知识库 / I3 演练 / I4 切换 / I5 收口 | 已完成 | 主模型 | 2026-10-22 | 同上 |
| 实施与自检 | I1—I3b(rdm@ee8c2cd,备份/知识库/演练/超管配置) | 已完成 | 主模型 | 2026-10-23 | 证据表 |
| 正式测试与验收 | I4 切换后核验 | **失败并回退**(`project context unavailable: not-found`) | 主模型 + owner 指令回退 | 2026-10-23 | 证据表(回退后 `problems=[]`) |
| 代码 Review | 待收口 | 待执行 | — | — | — |
| 合入 | 待收口 | 待执行 | — | — | — |
| 合入核验与收口 | 待收口 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| I3 远端演练实例(8789 + 复制 data + KBREG 环境) | 新版本能在 v35 旧库上完成迁移并在带知识库环境下健康启动 | 远端副本,不接流量、不写线上库 | 迁移失败或超 5 分钟 → 停下先修迁移/换方案,不进入切换窗口 | owner 指令“保证服务可用、最小停机” | 待执行 | 无(演练目录用后清理) | 是(切换前重放同一演练) |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | cb36b59accd0418c5ca952912d7c181b83038a4c | cb36b59accd0418c5ca952912d7c181b83038a4c | 2026-10-22T13:41:37Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果(I1 备份,零停机):远端 `backups/20261022T134400Z-warm-pre-ee8c2cd/`(539 MB、629 文件,SQLite 在线备份 API 取两个库的一致快照 + 文件树 rsync + bin/htdocs/plugins/systemd 单元/Caddyfile/svc 登记 + 活库基线 MANIFEST-LIVE-PRE.json)远端 `sha256sum -c` 通过;本机异地副本 `~/backups/imc-tx-ecs/20261022T134400Z-warm-pre-ee8c2cd/` 逐文件校验通过(629 文件)。线上进程全程未动(pid 4080336 自 2026-10-18 14:20:26 运行至今)。
- 结果(I2 知识库):远端装 PostgreSQL 16.15(PGDG,jammy)+ pgvector 0.8.7,回环 `127.0.0.1:5436`;角色/库 `kbreg`;本机容器 `pg_dump -Fc`(16.15 客户端,同主版本)→ `pg_restore --no-owner --no-privileges --no-comments`(3m09s);`serve.env`(600,仅 KBREG_*)与单元 drop-in `20-serve-env.conf` 已就位(daemon-reload,未重启服务)。
- 结果(I3 演练,零停机):`stage/rdm-ee8c2cd-20261022T055052Z-637762/bin/agent-system` sha256 与本机运行中制品一致(`00ead2cf…`);复制 data(367 MB)后以 8789 启动新二进制 + KBREG 环境:**1.02 s 健康(HTTP 200)、schema v35→v51 自动迁移完成、users 18→19(多出的就是本次演练的超级管理员账号)、conversations/runs/messages 不变、日志无 error/panic/fatal**;冷拷 data 实测 1.14 s、只拷库 0.05 s。
- 结果(I3b 超级管理员演练,零停机):因为产品只在启动时从 `SUPER_ADMIN_*` 建立超管,且**拒绝把已有账号直接指定为超管**(`configured owner belongs to an existing account without the super-admin marker`),采用与产品 bootstrap 同形的等价写入(`~/ecs-ops/seed-superadmin.py`:一个事务内更新 `users` 的 `is_admin/is_super_admin/password_hash(argon2id)/must_change_password/auth_version/credential_origin/initialization_state/state_version` + 按 v49 动作集写 `system_grants`(12 项)+ `account_events` + `audit_events`)。演练实测:阶段 A `--auth off` 迁移 v35→v51 用时 **0.27 s**;阶段 B 提升 sundehui(用户数仍为 18,未新增账号);阶段 C 以 `--auth on` + `SUPER_ADMIN_OWNER=sundehui` 启动,日志 `super admin: account "sundehui" already established`,健康 **0.27 s**;`POST /api/auth/login` 返回 `isSuperAdmin=true`、`sessionScope=set_password_only`(首次登录只能改密),`/api/me/profile` 403 `set-password session only`,日志无 error/panic/conflict。
- 配置就绪(远端,零停机):`runtime/dev/super-admin.env`(600,`SUPER_ADMIN_OWNER=sundehui`);drop-in `20-serve-env.conf` 同时引用 `serve.env` 与 `super-admin.env`(已 `daemon-reload`,未重启服务);待用口令哈希文件 `~/ecs-stage/seed.hash`(600)已就位;切换脚本 `~/ecs-ops/cutover-ee8c2cd.sh` 已按 A/B/C 三阶段重写并通过语法检查。
- 结果(I4 切换 → **验收失败 → 已回退**):08:43:27 CST 停服、08:43:30 CST 新版本健康,**停机 6.88 s**;新版本 pid 1617793、exe sha256 `00ead2cf…`、schema v51、本地/healthz/域名 200、sundehui 受限登录 200。**但业务验收出现 `extension: project context unavailable: not-found`(RDM 项目上下文解析为 not-found),owner 08:47 要求立即回退。** 回退分两步:首次执行 `rollback-now.sh` 因脚本缺陷(`mkdir -p $B/data` 后 `cp -a $R/data $B/data` 产生嵌套 `data/data/`,回退取到空目录)使服务短暂运行在空库;发现 users=0 后立即从冷备真实路径 `$B/data/data` 恢复,08:48:35 起服务运行旧版本,数据完整。两个脚本已修复并同步远端。
- 回退装备(保留可用):`runtime/dev/rollback/kit-20261023T004302Z`(旧二进制 sha `1f45f640…`、htdocs、单元、Caddyfile,12 文件 sha 通过)+ 修复后的 `rollback-now.sh`(嵌套目录探测、`rm -rf $R/data` 避免合并)+ 修复后的 `cutover-ee8c2cd.sh`(不再预建 `$B/data`)+ 冷备 `backups/20261023T004322Z-cold-pre-ee8c2cd`(真实数据在 `data/data`)+ 切换后的 v51 数据留存于 `runtime/dev/data.rolled-back` 供定位。
- 回退后核验(逐项,证据均为 SELF 收据):旧二进制 exe sha256 `1f45f640…`、pid 1619863、schema v35、`rdm.db` schema_version=6、本地/healthz/域名 200、recover timer 恢复;数据 users 18 / conversations 19 / runs 110 / messages 246,与热备基线逐行对账 **`problems=[]`、零缺失**(605→609 文件,新增 4 个为基线后新产生的用户文件);回退装备 SHA 通过;知识库仍在(legal_nodes 1701178、index_entries 191557)且 drop-in 已移除,旧二进制不读取它。热备/冷备/本机异地副本 SHA 全部通过;知识库指纹与端到端检索(隧道 + `kbreg migrate/search`)通过;演练迁移/健康/超管提升/受限登录通过;**浏览器端业务验收 FAIL**(`extension: project context unavailable: not-found`)。
- 影响与剩余项:
- 业务浏览器端验收(sundehui 首次登录改密、界面检索)NOT_RUN:需真人用真实账号密码登录,本任务不代持口令做交互验证。
- 回滚会丢失切换后新产生的数据(旧版本读不了 v51 库),执行前需 owner 确认。
- `sundehui` 现为 `is_admin=1` + `is_super_admin=1`(产品要求超管必须同时是管理员),口令哈希写入时 `auth_version+1`,旧会话失效。
- 知识库检索状态与本机一致为 degraded(本机向量索引同样为空);恢复向量索引属后续独立增量。
- 远端知识库为原生 PostgreSQL 16.15(非容器,远端无容器运行时且不可达镜像仓库),与 container-storage-plan 的容器决策可用同主版本 dump/restore 迁移。
- 结果(I6 修复合入,2026-10-23):owner 验收通过后按治理流程合入——所有代码变更都经 `scripts/agent-exec run` 的 worker transport 与 `apply` 进入分支(admit 门禁只放行 transport 或豁免路径),逐仓 CI 通过后合并:
- Agent-System-Backend PR #250「Carry project-scope defaults for roles with project management」→ main `1d04f07`;`go test ./internal/store ./internal/app ./internal/server` 通过,transport diff 与上线版本逐字一致。
- Agent-System-Frontend PR #129「Hide system actions from the role editor」→ main `9cc7113`;`npm run build` 与 717 个 vitest 通过。注意:PR #127(一次性密码改端点、恢复提案下线、侧栏无项目对话入口)在合入前发现上游 main 已自行实现同等能力,已关闭并以 #129 取代。
- Agent-System-RDM PR #482「Resolve host project ids in context and fall back to member defaults」→ main `d879839`;pin 同步到已合入的基座与前端 main,`go test ./...` 通过。
- Agent-System-Dev:main 的 `modules/backend` pin(`bd5c0f39`)已包含基座合并,无需再改;Dev 不跟踪 RDM 仓。
## 规划进展与下一步
- 本次推进/剩余:I1—I5 完成(首次切换因业务错误回退 → 三处修复并在 58788 验证 → 重建后二次切换停机 6.13 s 成功 → 角色/超管/模型配置就位 → 修复全部经 worker transport 合入 main)。剩余:合并后的产物(前端来自已合入 main)与线上二进制不同,需要你决定是否再切一次。
- 首选下一任务:本任务 I5(不新建任务)。
- 推荐依据:验收失败必须先消除阻塞项,不得以“技术切换成功”替代业务可用(`policy/delivery.md#目标优先范围控制与问题分流`)。
- 前置条件/待确认:定位材料——触发错误的入口(页面/会话)与其客户端响应;`data.rolled-back` 中已迁移的 v51 库可离线复现。
- 预期产物/验收条件:离线复现或代码级定位 `not-found` 成因;演练新增带项目上下文的真实请求并通过;再请 owner 确认切换窗口。
- 已知缺口:I3 演练只验证启动/迁移/登录/超管接口,**未发起带项目上下文的真实业务请求**,因此未能提前发现该错误。
- 重复任务核对:已核对 `.task/archive/feature-ecs-sync-local-dev.md`(2026-10-18 同机切换)与 feature/container-storage-plan(容器化形态,O1 生产迁移不在其范围);无重复在途任务。
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T13:28:34.782723+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-bootstrap-r0",
"before_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"after_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"branch": "HEAD",
"target_branch": "main",
"target_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-bootstrap-r0'",
"[repo] branch=HEAD head=cb36b59acc",
"[remote] origin/main=cb36b59acc ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=9",
"[recycle] merged un-recycled branches: fix/gitea-address-migration fix/svc-test-port-governance-batch1",
"[cards] 已合入未闭合任务卡:fix-svc-test-port-governance-batch1.md——make task-close 回填归档(主检出运行)",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] cb36b59acc(完整:cb36b59accd0418c5ca952912d7c181b83038a4c)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-bootstrap-r0'"
],
"output_sha256": "37096e9c91f721e54d19452b169e8558a0ddd1e0699512acf8d17d8331046441",
"receipt_sha256": "57bedc8bb759f306f6a2623b48f7117ef650a0a0c7951719ef6a25f5f51276eb",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/57bedc8bb759f306f6a2623b48f7117ef650a0a0c7951719ef6a25f5f51276eb.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:22:01.538077+00:00",
"command": "bash ~/ecs-ops/verify-local.sh",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "a06b59bf58b89bcbe5ce8d8ca204d6d376fd61fd86af9b0ffbd7133a8d7c5b21",
"after_tracked_diff_sha256": "a06b59bf58b89bcbe5ce8d8ca204d6d376fd61fd86af9b0ffbd7133a8d7c5b21",
"output_tail": [
"=== 本机异地副本 ===",
"OFFSITE_SHA_OK files=629",
"539M\t/home/weichen/backups/imc-tx-ecs/20261022T134400Z-warm-pre-ee8c2cd",
"=== 知识库指纹比对:本机容器 vs ECS(经隧道) ===",
"KB_FINGERPRINT_IDENTICAL",
"md5_regulations|56bcaad63aab3f505f115d867faeb12b",
"md5_editions|a93c46f75144e3359ef8c78ca1b67b2d",
"md5_index_entries|7e599356f4aeb45631e074f6bbc99f6e",
"md5_revision_members|5322ba17aff3ffbd1d23ba48248522d0",
"legal_nodes_bytes|888742683"
],
"output_sha256": "5c4ca6b9861b52bd9dd704794bbfdbfac60ad80af5ce1daa77caf38766aea3c9",
"receipt_sha256": "7eb168bc415a5a89d4d30baea6989c77f7026b8b54aa72a689ab03a7808cb34d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/7eb168bc415a5a89d4d30baea6989c77f7026b8b54aa72a689ab03a7808cb34d.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:23:11.116009+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/verify-remote.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "bc02c637e5aa7caf698d242f47e2c4565469c1d97e695b71f8ac8c75a8d4c07f",
"after_tracked_diff_sha256": "bc02c637e5aa7caf698d242f47e2c4565469c1d97e695b71f8ac8c75a8d4c07f",
"output_tail": [
"version=agent-system 0.1.0-dev",
"started=2026-10-18T14:20:27+08:00",
"local8788=200",
"domain=200",
"=== 线上库 schema ===",
"agent-system.db schema_max 35",
" users 18",
" conversations 18",
" runs 109",
" messages 244",
"rdm.db schema_version [(6,)]",
" users ERR no such table: users",
" conversations ERR no such table: conversations",
" runs ERR no such table: runs",
" messages ERR no such table: messages",
"=== 远端热备校验 ===",
"backup=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261022T134400Z-warm-pre-ee8c2cd",
"REMOTE_BACKUP_SHA_OK files=629",
"539M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261022T134400Z-warm-pre-ee8c2cd",
"=== 待上线制品 ===",
"00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/stage/rdm-ee8c2cd-20261022T055052Z-637762/bin/agent-system",
"app.css",
"app.js",
"index.html",
"htdocs_files=6",
"=== 知识库供给 ===",
"active",
"Ver Cluster Port Status Owner Data directory Log file",
"16 main 5436 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log",
"LISTEN 0 200 127.0.0.1:5436 0.0.0.0:* users:((\"postgres\",pid=1462333,fd=6)) ",
"SET",
"regulations=2897",
"legal_nodes=1701178",
"index_entries=191557",
"retrieval_chunks=64076",
"/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/serve.env 600 ubuntu",
"[Service]",
"# 知识库供给环境(KBREG_*,来自受保护的 serve.env,权限 600)",
"EnvironmentFile=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/serve.env",
"EnvironmentFiles=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/serve.env (ignore_errors=no)"
],
"output_sha256": "b9d015bb32fed01af4e0490ca20745495bfa63fed1c4495d3dab9b3bc8d64682",
"receipt_sha256": "80f27d8775a7454eecc9279266ffdb8486c1fc9056770bd305f20fc5810b35fe",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/80f27d8775a7454eecc9279266ffdb8486c1fc9056770bd305f20fc5810b35fe.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:23:24.616557+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal.sh'",
"exit_code": 1,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "a4d29aaed46c125f0ea41b93903130a71287e2a36a10e457a5d6f54f94f05f28",
"after_tracked_diff_sha256": "a4d29aaed46c125f0ea41b93903130a71287e2a36a10e457a5d6f54f94f05f28",
"output_tail": [
"[rehearsal] copying data 2026-10-22T23:23:26+08:00",
"367M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data",
"[rehearsal] pid=1475116 start=2026-10-22T23:23:27+08:00",
"[rehearsal] healthy=1 after=1.034965419s http=200",
"[rehearsal] schema:",
"agent-system schema_max = 51",
" users = 19",
" conversations = 18",
" runs = 109",
" messages = 244",
"Traceback (most recent call last):",
" File \"<stdin>\", line 9, in <module>",
"sqlite3.OperationalError: no such column: username"
],
"output_sha256": "633a16b70f361c207045e23bc573e0e8f9bd39eae69c648f1d4a4ee64c2e31ee",
"receipt_sha256": "86751433905579872d89a49231a54af8bf53abae1ba91b93c7c5e96b96e9ffa5",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/86751433905579872d89a49231a54af8bf53abae1ba91b93c7c5e96b96e9ffa5.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T15:23:34.788033+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"after_head": "c8d22d6ddb6e81b082c8c4eef513417000fd172c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "c3fc389b9f7060ee590439a7a26bffc45f454be8",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "ea88c0fc9ecb0d0c01399696327bda7c3c2f3eefd9c4249afc3c39ab53286428",
"after_tracked_diff_sha256": "ea88c0fc9ecb0d0c01399696327bda7c3c2f3eefd9c4249afc3c39ab53286428",
"output_tail": [
"[rehearsal] copying data 2026-10-22T23:23:36+08:00",
"367M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data",
"[rehearsal] pid=1475273 start=2026-10-22T23:23:37+08:00",
"[rehearsal] healthy=1 after=1.016955899s http=200",
"[rehearsal] schema:",
"agent-system schema_max = 51",
" users = 19",
" conversations = 18",
" runs = 109",
" messages = 244",
" super_admins = [('rehearsal-admin',)]",
"[rehearsal] data tree files: 613",
"[rehearsal] log grep (error/panic/fatal):",
"[rehearsal] log tail:",
"2026/10/22 23:23:37 super admin: established account \"rehearsal-admin\"",
"2026/10/22 23:23:37 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/22 23:23:37 exec tools: backend=sandbox (bwrap: no network, ro root, session-only writes, proc limit)",
"2026/10/22 23:23:37 skills: wrote 0, upgraded 4 into /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data/skills",
"2026/10/22 23:23:37 auth: API key required (create with: agent-system apikey create --owner <name>)",
"2026/10/22 23:23:37 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[rehearsal] done 2026-10-22T23:23:38+08:00"
],
"output_sha256": "5e6268752d60e253de77c8979bfcfcac69ca8df0bd357dd3c2f1630d1965c7c0",
"receipt_sha256": "37a1f94a8b71c31ff766ac284ea2599dac2df25c12e065b33d2a91c7602e9632",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/37a1f94a8b71c31ff766ac284ea2599dac2df25c12e065b33d2a91c7602e9632.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T23:08:23.850986+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal-superadmin.sh'",
"exit_code": 4,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"after_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"[rehearsal] copying data 2026-10-23T07:08:25+08:00",
"seed failed: no such column: is_super_admin"
],
"output_sha256": "6df9fb628078ad393282ce681f1fb69e6034f689237fe97e6a692da490a3f3ab",
"receipt_sha256": "4000943bcb84808a35cd147886eea4d6fd81a2982a9d8db37e6239d874d7789c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/4000943bcb84808a35cd147886eea4d6fd81a2982a9d8db37e6239d874d7789c.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T23:08:52.895328+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal-superadmin.sh'",
"exit_code": 1,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"after_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "04b1dba8da2af5a53de394e5e62fdf4a46ab168aa73346127d42bd67546e5c20",
"after_tracked_diff_sha256": "04b1dba8da2af5a53de394e5e62fdf4a46ab168aa73346127d42bd67546e5c20",
"output_tail": [
"[rehearsal] copying data 2026-10-23T07:08:54+08:00",
"[phase A] migrate-only start (auth off)",
"[phase A] healthy after .529100167s (pid=1593264)",
"2026/10/23 07:08:54 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/23 07:08:55 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[phase A] schema_max = 51",
"[phase B] elevate existing account",
"Traceback (most recent call last):",
" File \"/home/ubuntu/ecs-ops/seed-superadmin.py\", line 116, in <module>",
" sys.exit(main())",
" File \"/home/ubuntu/ecs-ops/seed-superadmin.py\", line 85, in main",
" instance = db.execute(\"SELECT instance_id FROM agent_system_identity\").fetchone()[0] or \"\"",
"TypeError: 'NoneType' object is not subscriptable"
],
"output_sha256": "bbeabf52756b45a9e3fc87670b7bdbbdcab5b5b35ab5682138d45462939306b5",
"receipt_sha256": "a88ff605df0338fb6cb529f9ab45900833c0120a528ee835b0b11628f9e66b50",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/a88ff605df0338fb6cb529f9ab45900833c0120a528ee835b0b11628f9e66b50.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-22T23:09:02.539134+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/rehearsal-superadmin.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"after_head": "68ca3f5fb1b29ea18a70a30230ef9a2930241b1c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "39b40acc28963d9413e554781ec8e65ed09774268e49cecb19496ac456e9a4d3",
"after_tracked_diff_sha256": "39b40acc28963d9413e554781ec8e65ed09774268e49cecb19496ac456e9a4d3",
"output_tail": [
"[rehearsal] copying data 2026-10-23T07:09:03+08:00",
"[phase A] migrate-only start (auth off)",
"[phase A] healthy after .267909096s (pid=1593451)",
"2026/10/23 07:09:04 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/23 07:09:04 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[phase A] schema_max = 51",
"[phase B] elevate existing account",
"seeded: {'owner': 'sundehui', 'is_admin': 1, 'is_super_admin': 1, 'must_change_password': <redacted>, 'auth_version': 2, 'credential_origin': '<redacted>', 'initialization_state': 'initialized', 'has_pw': 1} system_grants_allowed: 12",
"[phase C] start with auth on, super admin owner=sundehui",
"[phase C] healthy=1 after=.268576176s http=200",
"2026/10/23 07:09:06 super admin: account \"sundehui\" already established",
"2026/10/23 07:09:06 storage tier: auto (dialect=sqlite pool=0/0 idleSec=0 lifetimeSec=0 schema=v51)",
"2026/10/23 07:09:06 agent-system serving on http://127.0.0.1:8789 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rehearsal/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"[check] login as sundehui",
"{\"auth\":true,\"isAdmin\":true,\"isSuperAdmin\":true,\"mustChangePassword\":<redacted>,\"name\":\"\",\"owner\":\"sundehui\",\"passwordChangeMode\":\"<redacted>\",\"passwordSet\":<redacted>,\"sessionScope\":\"set_password_only\"}",
"",
"HTTP=200",
"[check] profile with session",
"forbidden: set-password session only",
"",
"HTTP=403",
"[check] super-admin gated endpoint",
"admin_users_http=403",
"[check] schema and account state",
"schema_max = 51",
"super admins = [('sundehui',)]",
"users total = 18",
"[check] log errors:",
"[rehearsal] done 2026-10-23T07:09:06+08:00"
],
"output_sha256": "690a87c97b30c36d517a47c90a6d951c307a094feefbf525ac6e7124c2f5c421",
"receipt_sha256": "47666f79ea5cbd315d5de3f89da4f90e19956fba77e4f880cb3f9bfca7c9df95",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/47666f79ea5cbd315d5de3f89da4f90e19956fba77e4f880cb3f9bfca7c9df95.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:44:11.563406+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/verify-post-cutover.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"after_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"grep: SHA256SUMS: No such file or directory",
"COLD_META_SHA_SKIPPED(部分行需整体校验)",
"479M\t/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261023T004322Z-cold-pre-ee8c2cd",
"=== 回滚装备 ===",
"ROLLBACK_KIT_SHA_OK files=12",
"kit created 20261023T004302Z",
"source_binary=1f45f64077b8dffd25d80513e3aaf5f06c71c8a09248c21af22f9d33eab516b9",
"data_source=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261022T134400Z-warm-pre-ee8c2cd",
"=== 服务 ===",
"active",
"active",
"pid=1617793 started=Fri Oct 23 08:43:29 2026 exe_sha256=00ead2cfcb967441058d0413850467ba710738b6a9510d4f983894f00bc0b3de",
"pid=1617793",
"addr=0.0.0.0:8788",
"source=rdm@ee8c2cd",
"version=agent-system-rdm (devel)",
"started=2026-10-23T08:43:30+08:00",
"{\"ts\":\"2026-10-23T00:43:30Z\",\"event\":\"deploy\",\"env\":\"dev\",\"kind\":\"agent\",\"source\":\"rdm@ee8c2cd\",\"result\":\"ok\",\"pid\":\"1617793\",\"addr\":\"0.0.0.0:8788\",\"detail\":\"from=dev@a706e9a+rdm@4b2473bed112 to=rdm@ee8c2cd via systemd; backup=20261023T004322Z-cold-pre-ee8c2cd",
"=== HTTP ===",
"local=200 healthz=200 domain=200",
"=== 数据与账号 ===",
"schema_max = 51",
" users 18",
" conversations 18",
" runs 109",
" messages 244",
" super_admins = [('sundehui',)]",
" sundehui = ('sundehui', 1, 1, 1, 2, 'owner_initialization')",
"=== 逐行对账(热备基线 ↔ 切换后)===",
"files base=605 now=605 missing=0 changed=5 added=0",
"changed: ['skills/.builtin-manifest.json', 'skills/docx-author/SKILL.md', 'skills/house-style/SKILL.md', 'skills/house-style/tests/test_housestyle.py', 'skills/house-style/housestyle/build.py']",
"tables with missing/changed rows: {\"agent-system.db.sessions\": {\"base\": 18, \"now\": 18, \"missing\": 0, \"changed\": 2, \"added\": 0, \"changed_keys\": [\"21\", \"22\"]}, \"agent-system.db.users\": {\"base\": 18, \"now\": 18, \"missing\": 0, \"changed\": 1, \"added\": 0, \"changed_keys\": [\"12\"]}}",
"problems: []",
"=== 密钥一致性 ===",
"owner='' scope=system models.rerank -> secret_keys match=True",
"owner='' scope=system tools.tavily -> secret_keys match=True",
"settings_snapshots=11 mismatches=0",
"=== 知识库 ===",
"active",
"SET",
"legal_nodes=1701178",
"index_entries=191557",
"=== 切换后错误扫描 ===",
"Failed to parse timestamp: 2026-10-23T00:24:14",
"(以上为空即无错误)"
],
"output_sha256": "52fc124a0e4e6e890949349d93afc89bd2228f460e780e14555160002da29282",
"receipt_sha256": "af18be0166d5bfe3abed4f5a433cb9d57e4dfdfa6f1eb60b828bc33496318e3b",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/af18be0166d5bfe3abed4f5a433cb9d57e4dfdfa6f1eb60b828bc33496318e3b.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:44:39.306471+00:00",
"command": "bash ~/ecs-ops/kb-check-fast.sh",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"after_head": "f9a953831b63d78faf4e123068db2e5c68397db8",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "1c4f20b9e2398f9fb813dfe305e789f20a8abad1c41f18ed847517dd35981cad",
"after_tracked_diff_sha256": "1c4f20b9e2398f9fb813dfe305e789f20a8abad1c41f18ed847517dd35981cad",
"output_tail": [
" \"version\": \"fts-v1\"",
" }",
" ],",
" \"hits\": [",
" {",
" \"regulation_id\": \"reg_3939376174cc5e1eb146d10b\",",
" \"edition_id\": \"ed_2e7d6d945848614ab386bdbc\",",
" \"node_id\": \"nd_79ccfca59982317806810fb3\",",
" \"kind\": \"guidance\",",
" \"title\": \"国家药监局关于发布医疗器械注册质量管理体系核查指南的通告(2022年第50号\",",
" \"edition_label\": \"src-5f55893f9096\",",
"KB_FAST_CHECK_OK"
],
"output_sha256": "cc655d17a77eb65ad064cfaaf4a903a3fe6adb05879dc8e2a70b16be36f93a09",
"receipt_sha256": "eda1eaba245f1c76e329747c66a6739435ddf8524ce0223fc86baac4b9bc92fd",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/eda1eaba245f1c76e329747c66a6739435ddf8524ce0223fc86baac4b9bc92fd.json"
}
```
| 同步(记录前对象) | 6ced938a126981ee2a4fab671a2da94f49cb56c5 | d436d6718ca997e575ad8be3d149efefca8cedd8 | 2026-10-23T00:46:40Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-23T00:49:39.764923+00:00",
"command": "ssh -o BatchMode=yes imc-tx-ecs 'bash ~/ecs-ops/verify-rollback.sh'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-deploy-dev8788-and-kb",
"before_head": "2487b561bb61103bd066d96f4be0135621daf66c",
"after_head": "2487b561bb61103bd066d96f4be0135621daf66c",
"branch": "feature/ecs-deploy-dev8788-and-kb",
"target_branch": "main",
"target_head": "6ced938a126981ee2a4fab671a2da94f49cb56c5",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"=== 回退后运行态 ===",
"active",
"active",
"pid=1619863 exe_sha256=1f45f64077b8dffd25d80513e3aaf5f06c71c8a09248c21af22f9d33eab516b9 started=Fri Oct 23 08:48:35 2026",
"local=200 healthz=200 domain=200",
"=== 数据核对 ===",
"schema_max 35",
" users 18",
" conversations 19",
" runs 110",
" messages 246",
"rdm schema_version [(6,)]",
"files base=605 now=609 missing=0 changed=0 added=4",
"problems: []",
"tables missing/changed: {\"agent-system.db.sessions\": {\"base\": 18, \"now\": 19, \"missing\": 0, \"changed\": 2, \"added\": 1, \"changed_keys\": [\"21\", \"22\"]}}",
"=== 回退装备 ===",
"kit=/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/rollback/kit-20261023T004302Z",
"ROLLBACK_KIT_SHA_OK",
"/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data.rolled-back",
"=== 知识库仍在(旧二进制不读取,环境文件已移除)===",
"active",
"SET",
"legal_nodes=1701178",
"index_entries=191557"
],
"output_sha256": "d8f3dd94b561810a63a8515bc6cd1188a7f83e379a592c2106a88233258dbe51",
"receipt_sha256": "8c4cc241b55f8df83e9e6802d6bf15584553cfafe845bda647a2a8add611041c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/8c4cc241b55f8df83e9e6802d6bf15584553cfafe845bda647a2a8add611041c.json"
}
```
| 同步(记录前对象) | 0650e81133b853f27e8e53f516de8f6c1e73e4a4 | 1a3f9a1e5f08d25cedc82024ba1354b186932777 | 2026-10-23T11:13:15Z |
+166
View File
@@ -0,0 +1,166 @@
# feature/scripts-robustness-fixes 任务卡
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= d1ea338fe9932fddf21429d826ffe354817e8fde
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-scripts-robustness-fixes(worktree);分支:feature/scripts-robustness-fixes
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=8a1d5a7fcdd4f0e7da30b4886b871d626690cfc4d9989c8e0e4e0487615804fd;triage_receipt=/tmp/triage-scripts-1792766148.json;receipt_sha256=d1804f49128e964cdcf7d6967bf9dcea49dff102d3d5e86511e9e2d06045b38e
- 授权与交付终点:用户已批准启动 Dev 仓脚本健壮性两修。范围内连续推进:诊断、实施、验证、组合、Review、PR/CI/合入。未授权:组件仓改动、A4、部署。
- 设计决定(2026-10-22,host):
1. svc manifest 迁移间歇跳过:先复现(全量 discover vs 单模块对照),定位环境差异根因(python3 探测/MANIFEST_PY 解析/并发工作目录),修复为确定性(绝对路径锚定+失败可见化,禁止静默跳过——失败必须可见或重试成功)。
2. 物化后 .gitmodules 改写:复现机制(新 worktree 物化 → 对比 .gitmodules),定位写回源(check-worktree.py materialize / git 行为 / 本地 URL 配置传播),修复为不再改写(或物化后自动还原),并加守卫测试。
3. 两个修复均需回归测试证明(flake 复现用例或守卫用例)。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
**目标**:svc manifest 迁移确定性(全量跑不再间歇跳过);物化后 .gitmodules 不再被改写(或自动还原+守卫测试)。
**非目标**:组件仓行为变更;A4;部署;svc settle 等待事件驱动化重构(另行评估)。
## 诊断结论(2026-10-22 晚,host)
1. **svc flake = 机器负载依赖**:失败时段机器 load average 66(27 用户共享机,并行会话重负载 + 残留 agent CLI);空闲后全量 governance 两次 553 测试全过(含 svc 23/23)。非脚本缺陷;修复候选:svc settle 等待改轮询+deadline(负载鲁棒性增强),或在低负载窗口跑治理套件。
2. **.gitmodules 改写机制未复现**:实测 materialize/`submodule update --init --jobs 8` 均不改写(md5 不变);疑似并行会话共享检出操作所致。已还原 82+ 处;缓解=checkout 扫还原(已验证)。机制需上游排查。
3. **agent 单元派发在负载 66 下不可行**(cursor 配额死、pi 输出截断、时序 flake)——本任务暂停派发,待负载回落。
## 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 |
|---|---|---|---|
| 启动 | d1ea338fe9932fddf21429d826ffe354817e8fde | d1ea338fe9932fddf21429d826ffe354817e8fde | 2026-10-23T14:37:42Z |
## 证据(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-23T14:36:07.805032+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "d1ea338fe9932fddf21429d826ffe354817e8fde",
"after_head": "d1ea338fe9932fddf21429d826ffe354817e8fde",
"branch": "main",
"target_branch": "main",
"target_head": "d1ea338fe9932fddf21429d826ffe354817e8fde",
"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=d1ea338fe9",
"[remote] origin/main=d1ea338fe9 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=10",
"[recycle] merged un-recycled branches: chore/migrate-gitea-endpoints feature/exec-recovery-diagnostics-a2 fix/gitea-endpoint-facts tmp-fe-inspect",
"[cards] 已合入未闭合任务卡:feature-audit-review-minors-cleanup.md feature-ecs-deploy-dev8788-and-kb.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] d1ea338fe9(完整:d1ea338fe9932fddf21429d826ffe354817e8fde)",
"[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": "7460323cc7f093d85d9b964d7fb7197080ebe1ff84e117ad869031991633cc3e",
"receipt_sha256": "aae150e36af3cb529115df35e766063e5849329b55eda357da693bde2a000f9e",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/aae150e36af3cb529115df35e766063e5849329b55eda357da693bde2a000f9e.json"
}
```
@@ -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,90 @@
# Independent Code Review — feature/audit-review-minors-cleanup (minors cleanup)
- Reviewer: independent CLI review session (minors-cleanup-independent-review unit; fresh session, not the implementer)
- Date: 2026-10-23 (UTC), report file per unit packet naming
- Review object: Dev superrepo @ `f8377960` (branch `feature/audit-review-minors-cleanup`) versus main merge point `0650e811` (R0 per task card; no `origin/*` refs exist in this sandbox, `git merge-base HEAD 0650e811 = 0650e811`, so `git diff 0650e811...HEAD` ≡ `git diff origin/main...HEAD`).
- Dev-level diff: `.task/feature-audit-review-minors-cleanup.md` (new, host domain) + five gitlinks, nothing else:
- `deps/agent-native` `be556f46..4183ea77` (2 commits: M1 fix + nested intent pin)
- `deps/agent-squad` `95b387d7..2d27389d` (3 commits: routing config, M2, M4+B-3 + nested pins)
- `deps/agent-intent` `7f3ff6a1..78312281` (1 commit: A3-1 + A3-2)
- `deps/agent-command` `fe7987dc..d5bb4254` (1 commit: M3)
- `modules/backend` `bd5c0f39..67102901` (1 transport commit: A2 MI1-MI3 + B-1 + B-2 + nested pins — **but NOT A1 m1-m4, see Blocker 1**)
- Fix-item trace: the packet says "the four reports in `.task/reviews/`"; the 16 claimed items actually trace across **five** reports: b1 (`2026-10-21-agent-stack-b1-…`: M1/M2/M3/M4), a1 (`2026-10-22-a1-intent-multi-turn-…`: m1-m4), a2 (`2026-10-22-a2-diagnostics-…`: MI1-MI3), a3 (`2026-10-22-a3-recall-eval-…`: minors 1-2), b2 (`2026-10-22-agent-stack-b2-…`: minors 1/2/3 = B-1/B-2/B-3). All five were used as the comparison baseline.
- Method: full read of every changed file plus the surrounding code each fix touches (migration manifest, cancel handler, intentsession service, native loop serialization, squad recovery paths); gitlink- and tree-level trace of every intermediate dev/component pin on this branch; stdlib-only probe for the one encoding claim tested below. Findings only — the report file is the only change made.
## 1. Verification runs (this session, foreground; honest exits)
| Check | Result |
|---|---|
| `git diff 0650e811...HEAD --stat` | exactly task card + 5 gitlinks; matches declared scope |
| `git status --porcelain` (dev + all 5 components) at review start | clean; all checkouts at pinned SHAs, 0 dirty files |
| `bash scripts/check-pins.sh` | exit 0, `pins ok`; guidelines/manager deltas warn-only by design; `pin regression check skipped` (no `origin/main` locally — same as prior review sessions) |
| Nested pin agreement (`git ls-tree` at all levels) | command `d5bb4254` (Dev=backend), intent `78312281` (Dev=backend=native=squad), native `4183ea77` (Dev=backend=squad), squad `2d27389d` (Dev=backend) — all agree |
| `deps/agent-command`: `GOWORK=off go test -count=1 ./...` | **ok** (2 packages); focused `-run "Trusted|Misplaced|ReceiptJSON|Untrusted"`: 6/6 PASS — M3 verified by execution |
| `deps/agent-native`: `GOWORK=off go test -count=1 ./exec/ ./runtime/session/ ./runtime/tools/` | **ok** (tools 11.4s) |
| `deps/agent-native`: `GOWORK=off go build ./adapters/native/` (M1 package) | **NOT_RUN** — module setup fails on unmaterialized `deps/error-code-system`/`logging-system` (empty gitlinks, objects absent, network forbidden, submodule ops forbidden) |
| squad / intent / backend builds (M2/B-3/M4, A3-2, A2/B-1/B-2 packages) | **NOT_RUN** — same unmaterialized replace-target reason; static line review + git-trace instead |
| `gofmt -l` sweep over all 15 changed Go files | clean except `deps/agent-squad/squad/engine.go` — **pre-existing** (identical deviation at old pin `95b387d7`, struct-literal alignment at :870; the changed hunks :1069-1090 are clean) |
| A3 baseline immobility | `sha256sum intent/testdata/recall_corpus.json` = `53d26cfc4caad994…` == `corpus_digest` in `evaluation/metrics.json` — corpus untouched, as the fix commit claims |
| M1 encoding probe (verbatim extraction of `scopeIdentity`, /tmp, deleted after) | reproduced a **cross-path collision** (see Minor 1) |
| Task-card-recorded receipts (`verify-min-*`, `verify-minors-combo4`, `make test PASS`) | **[未经证实]** — not re-executable in this sandbox; per packet `make test` was not run |
## 2. Findings
### Blocker
**BL1 — A1 m1-m4 are claimed in the backend range `bd5c0f3..6710290` but are absent from it; the range does not contain the four claimed fixes (lens 1 fails for 4 of 16 items).**
The unit packet and the task card (unit split U5 "intent_session 注释同步、取消拒绝原因、过期 fail-closed、落槽归属用例锁定"; receipt row "U5 backend-session(m1-m4,verify-min-sess2 exit=0)") claim these four a1-review minors are fixed in this PR's backend advance. They are not, at any point in the branch's backend history:
- **m1 (store comment sync) — unfixed.** `internal/store/intent_session.go:11-13` still says the table 「不进 storage-migrate 的 copyOrder(同 admission_leases…)」, while `cmd/storage-migrate/main.go:313` ships `intent_session` in `copyOrder` (mandated by the dynamic manifest check in `cmd/storage-migrate/main_test.go:213-219` — the fix direction is the comment, as the a1 report concluded). Verbatim the state the a1 report flagged.
- **m2 (cancel rejection reason) — unfixed.** `internal/server/intent_cancel.go:142` still sets `result.Accepted=false` on bus rejection with no `Reason`; the local path sets `Reason` only on dispatch error (:162). The bus-rejected asymmetry stands exactly as reported.
- **m3 (expiry fail-closed) — unfixed.** `internal/intentsession/intentsession.go:366-374`: `live()` still returns `true` when `ExpiresAt` is zero (unparseable/missing expiry = never expires), the fail-open the a1 report asked to invert.
- **m4 (slot-ownership tightening) — unfixed.** `internal/server/intent_session.go:203` still accepts explicit `set_slot`/`change_slot` 不看意图归属 (comment unchanged), and no ownership-locking test was added (`intent_session_test.go` still has the same 8 tests from the A1 development; no cross-intent lock case).
History trace (this is not a transport-rebuild artifact): every backend pin on this dev branch was examined — `faf815f9`→`bd5c0f3` (unchanged), `f0d94360`→`a6d0c650`, `7539da50`→`3647f980`, `b7a9879a`/`f8377960`→`67102901`. `git diff bd5c0f3..a6d0c650` contains only the U6 diag/runtime changes; `a6d0c650..3647f980` and `3647f980..67102901` are nested-gitlink-only. `git log --all` in the backend checkout (branch `fix/audit-minors-cleanup`, full cloned history) shows **no commit has ever touched** `internal/store/intent_session.go`, `internal/server/intent_cancel.go`, `internal/server/intent_session.go`, or `internal/intentsession/intentsession.go` after their original A1 development commits (`0fb64c4`, `c2e3104`). The U5 work therefore never landed in any commit this PR ships; the task card's U5 receipt does not correspond to any object in the reviewed history and must be reconciled by the host before merge.
Blocking because lens (1) — "each minor actually fixed as its review report described" — is the core acceptance criterion of this unit, and 4 of the 16 claimed items silently failed it while the card records them as green.
### Minor
**MN1 — M1's new encoding is collision-free within each path but not across paths (residual, low practical reachability).**
`adapters/native/contract_bind.go:76-80` length-prefixes only when a component contains `/`; slash-free scopes keep the legacy `t+"/"+p+"/"+sess` join (byte-identical filename preservation — verified by `TestScopeIdentityLegacySlashFreeUnchanged`, and correct: legacy join is injective when no component contains `/`; the prefixed form is self-delimiting and injective within its own path). But a legacy-encoded string and a prefixed-encoded string can coincide: probe-verified —
- legacy scope `{tenant:"3:a", project:"b3:c", session:"d0:"}` (all slash-free) → `"3:a/b3:c/d0:"`
- prefixed scope `{tenant:"a/b", project:"c/d", session:""}` → `"3:a/b3:c/d0:"`
Same identity → same hashed transcript path; the store's exact-match check passes for whichever scope binds first, so two distinct logical scopes silently share one session transcript. Reachability today is nil (product identifiers contain no `/` per the b1 review's own note, so the prefixed branch never fires; legacy identifiers would additionally need digit-led colon-bearing shapes), and the failure mode is fail-safe at first contact only in the lucky ordering. Non-blocking, but the doc comment's "collision-free" claim (contract_bind.go:61-66) overstates: suggest either documenting the cross-path gap, or versioning the encoding (e.g. prefix the whole identity with a scheme byte) in a follow-up. The new tests (`contract_regression_test.go:177/199/210`) cover the intra-prefixed case, legacy stability, and mismatch refusal — none cover cross-path.
### Notes (non-defects, recorded for the merge decision)
1. **Routing config (declared infra, reviewed for YAML correctness only).** Net squad `AGENT-EXECUTION.md` delta 95b387d→2d27389: `emergency_profile: codex` removed; `implementation` gains `codex`; cursor stays disabled with refreshed reason; antigravity stays disabled (reason from 2026-10-21); **pi is enabled in the final tree** — it was disabled mid-range in `e0d58e6` (three terminal-record decode failures, reason recorded) and re-enabled in `681c303` (micro-packet mitigation, reason recorded). The packet's wording "disable cursor/antigravity/pi" matches the mid-range state, not the net-final state; both transitions carry recorded reasons per the file's own convention, all referenced profiles exist, and the roles/profiles YAML is well-formed. Not blocking per packet instruction; noted so the merge author knows the net state re-enables pi.
2. **A2 MI1 (terminal-state suppression) — fixed and correctly scoped.** `rundiag.go:249-264` nils stale card/decision/confirm on terminal runs and names each leftover in a note (`staleWaitRecords`, :434-447); `run.status` stays visible. Recovery holds are deliberately *not* treated as stale on terminal runs — correct, an open hold on a failed run is operationally meaningful and the switch keeps `recovery_hold`/`HoldUnknown` precedence (fail-closed ordering untouched). `isTerminalRun` (:423-432) is exactly failed/completed/cancelled; cancelled+leftovers maps to `unknown` (unmapped-status default) with no confirm advice — asserted by test.
3. **A2 MI2 (truncation notes) — fixed.** Package doc gains the "有界读取也要说出来" bullet (:10-11); confirms-cap note (:196-199), audit-scan-cap note (:215-219), and `side_effects` cap note via the new `sideEffects` truncation flag (:386-401, consumed at :230-236). The flag semantics preserve the old cap set byte-for-byte (cap check moved before append; first over-cap matching envelope returns `out, true`).
4. **A2 MI3 (precedence combinations) — fixed with the two combinations the a2 report named:** released-hold + open HITL card → `reconciling` (table case :112), decision outranks pending confirm → `waiting_hitl` (:123), plus terminal+leftover (:135); dedicated `TestBuildTerminalRunSuppressesStaleWaitEvidence` (:459, failed/completed/cancelled/live quadrants) and `TestBuildReportsReadCapsInsteadOfSilentTruncation` (:520, three caps + uncapped no-noise).
5. **B-1 (sink contract) — fixed as documentation** (`squad_events.go:62-68` on `squadEventLog`, :86-87 on `onEvent`): synchronous/fast/non-blocking sink contract, with the trade-off (moving Emit out of the lock sacrifices same-order invariant) spelled out — matches the b2 report's recommendation.
6. **B-2 (queued-access invariant) — fixed as documentation**, and its factual premise verified in the pinned native: `runtime/loop.go:228` wraps `Config.OnEvent` via `serializeHostCallbacks` (:610-619, mutex around inner), so the llm_direct comment's claim (parallel `tool_execution_start` events serialize through `onEvent`; queued need no lock; inflight/finalParts do) is accurate (`llm_direct.go:57`, `:766-774`, `:1452-1456`).
7. **M2 (direct field copy) — fixed, behavior-preserving.** `register.go:230-231` copies `SideEffects` (string-underlying conversion `exec.SideEffects`→`squad.ExecSideEffects`, values `none`/`possible` identical on both sides) and `Canceled`; `Aborted` stays zero — correct, native `exec.Result` has no `Aborted` field (grep: absent), so the old JSON probe could never have set it either; the old probe and its rationale are deleted, and the replacement comment explains the compile-time-pinning argument. `TestFromNativeCopiesTerminalFidelityDirectly` (register_test.go:18-93) is additive; no pre-existing test was removed. All prior register tests retained.
8. **M4 (stale comment) — fixed accurately.** The rewritten `recoverInterrupted` doc (engine.go:1069-1090) was checked line-by-line against the code: the only "一次重试" path is the 1c branch (`SideEffects=none` + missing files + `attempts<2`, engine.go:1140-1154); interactive synthesizes the HITL hold; auto/disabled/default land in `RunWaitingReconciliation` and nothing fails directly — the comment now says exactly this.
9. **B-3 (save-failure memory consistency) — fixed at both cited sites.** `gcFinish` (groupchat.go:344-349) and `runReviewDriver` (review.go:331-336) rewrite `st.Meta.Status` and `wf.Status` to `RunFailed` inside the same critical section before unlocking and returning the failed result. `cancelRun`'s save-failure path is intentionally out of B-3 scope (returns RunCancelled by design, per the b2 report's own wording). Three new tests in `terminal_state_consistency_test.go` capture the in-memory `*RunState` at `SaveRun` and assert memory==result, including a degraded→failed control-group fixture that proves the degraded branch is really exercised.
10. **A3-1 (baseline-drift caveat) — fixed**: `evaluation/BASELINE.md:74-83` states engine changes do not trigger baseline invalidation and manual re-run is required, in the a3 report's own terms; corpus digest unchanged (see §1).
11. **A3-2 (element-wise slice assertion) — fixed**: `intent/corpus.go:194-204` adds `equalStringSlices` (nil==empty, order-sensitive by documented intent) used at :235; `fmt` still used elsewhere so the import stays live.
12. **M3 (trusted-marker JSON roundtrip) — fixed and executed green in this session.** Wire field `operationIdTrusted` (omitempty ⇒ bytes for non-trusted receipts unchanged), marker restored only from the wire (never sticky on the receiver — tested), misplaced marker rejected via `ErrMisplacedTrustedMarker` (including mutated trusted→committed shape), `ParseExecReceipt` rehydrates+validates. Format risk contained: `AuditEnvelope` carries `State` as a plain string, not an embedded receipt, so no persisted payload gains the new key. Error-message change in `Validate` (:151) has no stale string assertions anywhere (grepped).
13. **Composition consistency**: `check-pins.sh` exit 0; nested pins agree at every level (§1); dev-level intermediate pins were transport-rebuilt on the same trees (native `9ec1bf7a`→`4183ea77` differs only by the nested intent gitlink; squad `5c752e0b`→`2d27389d` only by nested pins; backend `3647f980` is not an ancestor of `67102901` but their tree delta is exactly the nested `agent-command` gitlink) — the established transport pattern from prior PRs, no content drift found at dev or component level beyond the declared items.
14. **NOT_RUN matrix** (environment, not code — identical constraint to every prior review in this repo): native `adapters/native`, squad (all packages), intent (all packages), backend (all packages). The backend's A2/B-1/B-2 changes and squad's M2/M4/B-3 changes are verified statically; their recorded author receipts remain SELF-level and unreplayed here. Combined with BL1, the PR cannot claim lens (4) coverage for the four missing A1 items at all.
## 3. Lens summaries
1. **Fixes-as-reported** — 12 of 16 claimed items verified fixed with file:line evidence and (where testable) executed or read tests; **4 of 16 (A1 m1-m4) absent from the shipped backend range while claimed by packet and task card → Blocker BL1**.
2. **No behavior regressions** — for everything actually present: `fromNative` output proven identical field-for-field (M2 + test); legacy identity encoding byte-preserved (M1 legacy test); M3 wire format additive/omitempty with no embedded-receipt consumers; sideEffects cap set unchanged; terminal-suppression only diverts advisory output for terminal runs; check-pins green. No regression found in shipped code; the unshipped A1 fixes are simply missing.
3. **Composition consistency** — pass for what ships (pins, nested pins, card); fail as a claim: the card's U5 receipt references work absent from history (BL1).
4. **Tests assert fixed behaviors** — pass for the 12 shipped items (new tests target the exact trigger conditions, incl. fault injection for B-3 and cap/stale matrices for A2); N/A for the four missing items; M1's new tests miss the cross-path collision (MN1).
## 4. Conclusion
The twelve shipped minor fixes (M1-M4, B-1/B-2/B-3, A2 MI1-MI3, A3-1/A3-2) are real, scoped, behavior-preserving, and test-pinned where it matters; composition and routing-config hygiene are in order. But the unit's own acceptance lens fails: the backend range does not contain the four A1 session-minor fixes the packet and task card claim (store comment sync, cancel rejection reason, expiry fail-closed, slot-ownership tightening), no commit in the branch's history ever contained them, and the card records a U5 receipt for work that does not exist in any reviewed object. The PR must not merge as the "18-minor cleanup" it advertises until those four fixes actually land in a backend advance on this branch (and the U5 receipt is reconciled), after which a follow-up re-review of the backend delta alone would suffice.
Blocking reasons: BL1 (A1 m1-m4 missing from `modules/backend bd5c0f3..6710290`; card receipt/object mismatch). Non-blocking follow-ups: MN1 (cross-path identity collision residual), Note 1 (pi net-state vs packet wording), Note 14 (NOT_RUN replay at merge gate per policy).
REVIEW VERDICT: BLOCK
@@ -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
+3
View File
@@ -51,6 +51,8 @@
"backend/rag backend/settings", "backend/rag backend/settings",
"backend/rag backend/store", "backend/rag backend/store",
"backend/route backend/intentgate", "backend/route backend/intentgate",
"backend/rundiag backend/cmdbus",
"backend/rundiag backend/store",
"backend/runmgr backend/bus", "backend/runmgr backend/bus",
"backend/runmgr backend/cardsvc", "backend/runmgr backend/cardsvc",
"backend/runmgr backend/docgen", "backend/runmgr backend/docgen",
@@ -85,6 +87,7 @@
"backend/server backend/prompts", "backend/server backend/prompts",
"backend/server backend/ratelimit", "backend/server backend/ratelimit",
"backend/server backend/route", "backend/server backend/route",
"backend/server backend/rundiag",
"backend/server backend/runmgr", "backend/server backend/runmgr",
"backend/server backend/settings", "backend/server backend/settings",
"backend/server backend/store", "backend/server backend/store",
+3 -3
View File
@@ -15,9 +15,9 @@
| ID | 事实 | 验证命令 | last_verified | TTL(天) | | 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 | | 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) | `bash scripts/facts-verify.sh api-token https://git-home.u1680832.nyat.app:30319/api/v1/user` | 2026-10-14 | 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 可达: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 | | 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 | | 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 | | 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 | | 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. 构建 ───────────────────────────────────────────── # ── 1. 构建 ─────────────────────────────────────────────
# RDM 源码经 git archive 从本地对象导出(不建 worktree、不触远端——Gitea 抖动时 # RDM 源码经 git archive 从本地对象导出(不建 worktree、不触远端——Gitea 抖动时
# submodule 克隆会挂死);pins/* 从 RDM 主检出的已物化 submodule 快照拷贝(cp 排除 # submodule 克隆会挂死);pins/* 从 RDM 主检出的已物化 submodule 快照拷贝(tar 排除
# .git,39MB 级),构建输入由此固定为 RDM origin/main + 其 gitlink 指向的本地内容。 # .git;含 go.mod replace 引用的全部 pin,不仅 backend),构建输入由此固定为
# RDM origin/main + 其 gitlink 指向的本地内容。
log "build RDM binary (archive origin/main + snapshot pins from local checkout)" log "build RDM binary (archive origin/main + snapshot pins from local checkout)"
RDM_WT="$OUT/rdm-src" RDM_WT="$OUT/rdm-src"
RDM_SHA=$(git -C "$RDM_REPO" rev-parse origin/main) || die "no origin/main in RDM repo" 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" ] \ [ "$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" || 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" 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() { cleanup() {
[ -n "${API_PID:-}" ] && { kill "$API_PID" 2>/dev/null || true; wait "$API_PID" 2>/dev/null || true; } [ -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 # 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 刷为当天并写回) # 用法:make facts-verify [ARGS=--update] (--update:把 PASS 项 last_verified 刷为当天并写回)
# 表内验证命令约定不含竖线;含 "\|" 转义时按字面还原后执行。 # 表内验证命令约定不含竖线;含 "\|" 转义时按字面还原后执行。
# 登记表引用的探针子命令(单独运行时在 stderr 说明判定,不输出凭据): # 登记表引用的探针子命令(单独运行时在 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(不跟随重定向); # 校验通过后才进程内读 ~/.secrets/gitea HOME 段 ACCESS_TOKEN 并 GET(不跟随重定向);
# 0=接受 3=缺失 4=格式不符 5=请求失败/被拒/重定向 6=非登记端点 # 0=接受 3=缺失 4=格式不符 5=请求失败/被拒/重定向 6=非登记端点
# tls-handshake-fails HOST PORT 仅当 TCP 已连通且 TLS 层握手报错时 0; # tls-handshake-fails HOST PORT 仅当 TCP 已连通且 TLS 层握手报错时 0;
@@ -20,7 +20,7 @@ import sys, urllib.request
sys.path.insert(0, sys.argv[1]) sys.path.insert(0, sys.argv[1])
import task_triage 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: if sys.argv[2] != ENDPOINT:
print("api-token: URL 不是 policy/facts.md F2 登记端点,拒绝发送凭据", file=sys.stderr) print("api-token: URL 不是 policy/facts.md F2 登记端点,拒绝发送凭据", file=sys.stderr)
sys.exit(6) sys.exit(6)
+6 -5
View File
@@ -1,12 +1,13 @@
# RDM 制品钉扎。三行都是 40 位 hex。升级走 PR,不在 CI 里执行候选文件。 # 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 布局一致, # prev_sha:来回部署身份稳定性测试的起点。选取受两条硬约束——与 sha 的 pins 布局一致,
# 且两者之间无跨 schema 迁移(scripts/svc.sh 的 schema 兼容闸会在停旧服务前拒绝不兼容切换)。 # 且两者之间无跨 schema 迁移(scripts/svc.sh 的 schema 兼容闸会在停旧服务前拒绝不兼容切换)。
# 取上一个已钉住的 sha:同为 6-pin 布局,与 sha 之间无 schema/迁移变更,在 RDM 主线上与 sha # 取上一个已钉住的 sha:同为 6-pin 布局,与 sha 之间无 store schema 迁移(W11/W8 变更走事件
# 相距 59 个提交,往返部署覆盖的版本跨度大于仅隔一次合并的相邻提交。 # 重放而非 schema),往返部署覆盖的正是上一交付版本到增量 D 的真实升级路径。
# legacy_sha:承载「无身份」语义(没有 version --json),必然早于 6-pin 布局。 # legacy_sha:承载「无身份」语义(没有 version --json),必然早于 6-pin 布局。
# 三者的 pins 布局可能不同;CI 按每个 pin 自身的 gitlink 清单物化并逐个断言,不要求布局统一。 # 三者的 pins 布局可能不同;CI 按每个 pin 自身的 gitlink 清单物化并逐个断言,不要求布局统一。
# 来回切换的 schema 兼容不由钉扎保证,由真实生命周期套件检验。 # 来回切换的 schema 兼容不由钉扎保证,由真实生命周期套件检验。
sha=ee8c2cdf4a0ed88cdc4037f4b43501e1eebc4c5b sha=9176476bf35d23e7886bf6ccb7c3a688067d357f
prev_sha=bc8db886606e88201e7f7210a1357d22dc84124b prev_sha=15fdd479a9fe60a59559139305b8d760931cec93
legacy_sha=72bb1fec79d64c2af5e49416640712320816c3b4 legacy_sha=72bb1fec79d64c2af5e49416640712320816c3b4
+16 -15
View File
@@ -256,7 +256,7 @@ class FactsVerifyTests(unittest.TestCase):
self.assert_status(result.stdout, "F2", "PASS") self.assert_status(result.stdout, "F2", "PASS")
requests = self.stub_events("http") requests = self.stub_events("http")
self.assertEqual(len(requests), 1, requests) 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(requests[0]["authorization"], "token " + HOME_TOKEN)
self.assertEqual(self.dates(), {"F2": self.today, "F8": self.today, "F9": OLD_DATE}) self.assertEqual(self.dates(), {"F2": self.today, "F8": self.today, "F9": OLD_DATE})
self.assertTrue(receipt.exists(), result.stderr) self.assertTrue(receipt.exists(), result.stderr)
@@ -285,7 +285,7 @@ class FactsVerifyTests(unittest.TestCase):
self.assert_status(result.stdout, "F2", "FAIL") self.assert_status(result.stdout, "F2", "FAIL")
self.assertEqual(self.stub_events("http"), [], "no request without a valid HOME token") self.assertEqual(self.stub_events("http"), [], "no request without a valid HOME token")
self.assertEqual(self.dates()["F2"], OLD_DATE) 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.assertNotEqual(direct.returncode, 0)
self.assertIn("ACCESS_TOKEN", direct.stderr) self.assertIn("ACCESS_TOKEN", direct.stderr)
self.assert_no_secrets(result.stdout, result.stderr, direct.stdout, 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) result = self.run_script("--update", http=http)
self.assert_status(result.stdout, "F2", "FAIL") self.assert_status(result.stdout, "F2", "FAIL")
self.assertEqual(self.dates(), {"F2": OLD_DATE, "F8": self.today, "F9": OLD_DATE}) 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) http=http)
self.assertNotEqual(direct.returncode, 0) self.assertNotEqual(direct.returncode, 0)
self.assertNotIn("Authorization", direct.stderr) self.assertNotIn("Authorization", direct.stderr)
@@ -307,17 +307,18 @@ class FactsVerifyTests(unittest.TestCase):
def test_f2_rejects_unregistered_destination_before_reading_credentials(self): def test_f2_rejects_unregistered_destination_before_reading_credentials(self):
bad_urls = [ 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://evil.invalid/api/v1/user",
"https://git-home.u1680832.nyat.app:30320/api/v1/user", "https://git-home.u1680832.nyat.app:30319/api/v1/user",
"https://git-home.u1680832.nyat.app/api/v1/user", "https://gitea.naitangbaobao.cn:30320/api/v1/user",
"https://user:pw@git-home.u1680832.nyat.app:30319/api/v1/user", "https://gitea.naitangbaobao.cn:443/api/v1/user",
"https://git-home.u1680832.nyat.app:30319@evil.invalid/api/v1/user", "https://user:pw@gitea.naitangbaobao.cn/api/v1/user",
"https://git-home.u1680832.nyat.app:30319/api/v1/user#frag", "https://gitea.naitangbaobao.cn@evil.invalid/api/v1/user",
"https://git-home.u1680832.nyat.app:30319/api/v1/user?next=https://evil.invalid", "https://gitea.naitangbaobao.cn/api/v1/user#frag",
"https://git-home.u1680832.nyat.app:30319/api/v1/users", "https://gitea.naitangbaobao.cn/api/v1/user?next=https://evil.invalid",
"https://git-home.u1680832.nyat.app:30319/api/v1/user/../admin", "https://gitea.naitangbaobao.cn/api/v1/users",
"https://git-home.u1680832.nyat.app:30319/api/v1/user ", "https://gitea.naitangbaobao.cn/api/v1/user/../admin",
"https://gitea.naitangbaobao.cn/api/v1/user ",
] ]
for secrets_present in (True, False): for secrets_present in (True, False):
if not secrets_present: if not secrets_present:
@@ -337,12 +338,12 @@ class FactsVerifyTests(unittest.TestCase):
for code in ("301", "302", "303", "307", "308"): for code in ("301", "302", "303", "307", "308"):
with self.subTest(code): with self.subTest(code):
self.stub_log.unlink(missing_ok=True) 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) http=code)
self.assertEqual(direct.returncode, 5, direct.stderr) self.assertEqual(direct.returncode, 5, direct.stderr)
requests = self.stub_events("http") requests = self.stub_events("http")
self.assertEqual([r["url"] for r in requests], 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.assertNotIn("redirect-target", direct.stdout + direct.stderr)
self.assert_no_secrets(direct.stdout, direct.stderr) self.assert_no_secrets(direct.stdout, direct.stderr)
+6 -2
View File
@@ -2,9 +2,13 @@
import importlib.util import importlib.util
import json import json
import os import os
import sys
import unittest import unittest
from pathlib import Path 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] SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location( _spec = importlib.util.spec_from_file_location(
"tsi", SOURCE / "tests" / "test_svc_identity.py") "tsi", SOURCE / "tests" / "test_svc_identity.py")
@@ -46,7 +50,7 @@ class DeployTxnTests(unittest.TestCase):
new.chmod(0o755) new.chmod(0o755)
fx.stub.write_text(old.read_text()) fx.stub.write_text(old.read_text())
fx.stub.chmod(0o755) fx.stub.chmod(0o755)
fx.seed_agent("txn", 9471) fx.seed_agent("txn", free_test_port())
fx.start_ok("txn") fx.start_ok("txn")
pid = fx.pid_of("txn") pid = fx.pid_of("txn")
script = fx.root / "scripts" / "svc.sh" script = fx.root / "scripts" / "svc.sh"
@@ -68,7 +72,7 @@ class DeployTxnTests(unittest.TestCase):
def test_forward_only_requires_confirm_and_backup(self): def test_forward_only_requires_confirm_and_backup(self):
fx = self.fx fx = self.fx
fx.seed_agent("fwd", 9472) fx.seed_agent("fwd", free_test_port())
fx.start_ok("fwd") fx.start_ok("fwd")
iid = json.loads((fx.runtime("fwd") / "manifest.json").read_text())["instance_id"] iid = json.loads((fx.runtime("fwd") / "manifest.json").read_text())["instance_id"]
base = fx.stub.read_text() base = fx.stub.read_text()
+36 -16
View File
@@ -12,10 +12,14 @@ import os
import shutil import shutil
import sqlite3 import sqlite3
import subprocess import subprocess
import sys
import tempfile import tempfile
import unittest import unittest
from pathlib import Path 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] SOURCE = Path(__file__).resolve().parents[1]
SVC_SCRIPT = SOURCE / "scripts" / "svc.sh" SVC_SCRIPT = SOURCE / "scripts" / "svc.sh"
@@ -56,7 +60,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T1 连续裸启停:同一身份与数据根 ---- # ---- T1 连续裸启停:同一身份与数据根 ----
def test_T1_bare_restart_stable_identity(self): 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") self.start_ok("id1")
m1 = self.manifest("id1") m1 = self.manifest("id1")
self.assertIsNotNone(m1, "start 应完成 manifest 迁移") self.assertIsNotNone(m1, "start 应完成 manifest 迁移")
@@ -79,7 +84,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T2 只改端口:数据/DB 锚点不动 ---- # ---- T2 只改端口:数据/DB 锚点不动 ----
def test_T2_port_change_keeps_anchors(self): 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") self.start_ok("id2")
anchor = self.manifest("id2")["identity"] anchor = self.manifest("id2")["identity"]
self.svc("id2", "stop") self.svc("id2", "stop")
@@ -95,7 +101,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T3 数据根漂移:拒绝启动,不新建空系统 ---- # ---- T3 数据根漂移:拒绝启动,不新建空系统 ----
def test_T3_data_drift_rejected(self): 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.start_ok("id3")
self.svc("id3", "stop") self.svc("id3", "stop")
other = self.root / "other-data" other = self.root / "other-data"
@@ -111,7 +118,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T4 迁移窗口与损坏:不猜测 ---- # ---- T4 迁移窗口与损坏:不猜测 ----
def test_T4a_leftover_new_file_ignored(self): def test_T4a_leftover_new_file_ignored(self):
self.seed_agent("id4", 9435) port = free_test_port()
self.seed_agent("id4", port)
# 模拟 rename 前崩溃残留:.new 半成品必须被忽略/覆盖,不影响迁移结果 # 模拟 rename 前崩溃残留:.new 半成品必须被忽略/覆盖,不影响迁移结果
(self.runtime("id4") / "manifest.json.new").write_text("{ truncated") (self.runtime("id4") / "manifest.json.new").write_text("{ truncated")
self.start_ok("id4") self.start_ok("id4")
@@ -121,7 +129,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.svc("id4", "stop") self.svc("id4", "stop")
def test_T4b_corrupt_manifest_blocks(self): 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.start_ok("id5")
self.svc("id5", "stop") self.svc("id5", "stop")
(self.runtime("id5") / "manifest.json").write_text("{ not json") (self.runtime("id5") / "manifest.json").write_text("{ not json")
@@ -133,7 +142,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T5 marker/manifest 事件:缺一即阻塞,不自动新建 ---- # ---- T5 marker/manifest 事件:缺一即阻塞,不自动新建 ----
def test_T5a_missing_marker_blocks(self): 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.start_ok("id6")
self.svc("id6", "stop") self.svc("id6", "stop")
m = self.manifest("id6") m = self.manifest("id6")
@@ -145,7 +155,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.assertFalse(self.running("id6")) self.assertFalse(self.running("id6"))
def test_T5b_foreign_marker_blocks(self): 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.start_ok("id7")
self.svc("id7", "stop") self.svc("id7", "stop")
m = self.manifest("id7") m = self.manifest("id7")
@@ -158,7 +169,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.assertFalse(self.running("id7")) self.assertFalse(self.running("id7"))
def test_T5c_lost_manifest_blocks_not_rebuild(self): 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") self.start_ok("id8")
m0 = self.manifest("id8") m0 = self.manifest("id8")
iid = m0["instance_id"] iid = m0["instance_id"]
@@ -178,7 +190,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
# ---- T6 cwd 无关:从别处调用身份不变 ---- # ---- T6 cwd 无关:从别处调用身份不变 ----
def test_T6_cwd_independent_identity(self): 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") self.start_ok("id9")
iid = self.manifest("id9")["instance_id"] iid = self.manifest("id9")["instance_id"]
self.svc("id9", "stop") self.svc("id9", "stop")
@@ -320,7 +333,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
旧服务继续运行、旧制品与登记不变(2026-10-12 rdm1/rdmcand 反例:停服→ 旧服务继续运行、旧制品与登记不变(2026-10-12 rdm1/rdmcand 反例:停服→
覆盖→启动即拒,只剩混合状态)。""" 覆盖→启动即拒,只剩混合状态)。"""
remote, old_sha, new_sha = self.make_rdm_repo(self.noid_stub()) 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.start_ok("rdx") # 已建立身份,有能力制品在运行
self.set_kv("rdx", "source", "rdm@%s" % old_sha) self.set_kv("rdx", "source", "rdm@%s" % old_sha)
pid = self.pid_of("rdx") pid = self.pid_of("rdx")
@@ -344,7 +358,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
"""已建立身份后删行:update 在停服前拒绝,不自动补行,旧进程保持。 """已建立身份后删行:update 在停服前拒绝,不自动补行,旧进程保持。
补行只走 adopt --confirm。""" 补行只走 adopt --confirm。"""
old_sha, new_sha = self.make_src_repo() 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.start_ok("rowx")
self.set_kv("rowx", "source", "dev@%s" % old_sha) self.set_kv("rowx", "source", "dev@%s" % old_sha)
db = Path(self.manifest("rowx")["identity"]["data_root"]) / "agent-system.db" 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): def test_U1_bare_start_missing_row_is_event_init_recovers(self):
"""普通启动只验证不补行:DB 行缺失 → 拒绝且不建空行(缺行即事件); """普通启动只验证不补行:DB 行缺失 → 拒绝且不建空行(缺行即事件);
显式 init 补齐后恢复。""" 显式 init 补齐后恢复。"""
self.seed_agent("rowm", 9453) port = free_test_port()
self.seed_agent("rowm", port)
self.start_ok("rowm") self.start_ok("rowm")
iid = self.manifest("rowm")["instance_id"] iid = self.manifest("rowm")["instance_id"]
self.svc("rowm", "stop") self.svc("rowm", "stop")
@@ -416,7 +432,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
def test_U1_adopt_identityless_artifact_reports_pending(self): def test_U1_adopt_identityless_artifact_reports_pending(self):
"""已装制品无 identity 能力:adopt 的 ensure 静默跳过,marker 留在 pending—— """已装制品无 identity 能力:adopt 的 ensure 静默跳过,marker 留在 pending——
输出必须如实报 pending,不得宣称 db_marker=established。""" 输出必须如实报 pending,不得宣称 db_marker=established。"""
self.seed_agent("adx", 9454) port = free_test_port()
self.seed_agent("adx", port)
self.start_ok("adx") self.start_ok("adx")
iid = self.manifest("adx")["instance_id"] iid = self.manifest("adx")["instance_id"]
self.svc("adx", "stop") self.svc("adx", "stop")
@@ -437,7 +454,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
cand.chmod(0o755) cand.chmod(0o755)
remote, old_sha, _ = self._make_track_repo(cand, "agent-system") remote, old_sha, _ = self._make_track_repo(cand, "agent-system")
self.git_ok(self.root, "clone", str(remote), str(self.root / "srccache")) 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.start_ok("scx")
self.set_kv("scx", "source", "dev@%s" % old_sha) self.set_kv("scx", "source", "dev@%s" % old_sha)
mpath = self.runtime("scx") / "manifest.json" mpath = self.runtime("scx") / "manifest.json"
@@ -459,7 +477,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.svc("scx", "stop") self.svc("scx", "stop")
def test_I3_start_ensures_sqlite_identity(self): 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") self.start_ok("idb1")
iid = self.manifest("idb1")["instance_id"] iid = self.manifest("idb1")["instance_id"]
rows = self.db_identity_row("idb1") rows = self.db_identity_row("idb1")
@@ -470,7 +489,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
self.svc("idb1", "stop") self.svc("idb1", "stop")
def test_I3_wrong_db_identity_blocks_start(self): 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") self.start_ok("idb2")
iid = self.manifest("idb2")["instance_id"] iid = self.manifest("idb2")["instance_id"]
self.svc("idb2", "stop") self.svc("idb2", "stop")
+9 -2
View File
@@ -1,9 +1,14 @@
"""生命周期隔离:调用方的 AGENT_SYSTEM_* 不得进入 serve,serve.env 为 0600。""" """生命周期隔离:调用方的 AGENT_SYSTEM_* 不得进入 serve,serve.env 为 0600。"""
import importlib.util import importlib.util
import json import json
import os
import shutil import shutil
import sys
from pathlib import Path 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] SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py") _spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
tsr = importlib.util.module_from_spec(_spec) tsr = importlib.util.module_from_spec(_spec)
@@ -17,7 +22,8 @@ class LifecycleIsolationTests(tsr.SvcAutoRecoverTests):
self.root / "scripts" / "svc_manifest.py") self.root / "scripts" / "svc_manifest.py")
def test_caller_identity_env_does_not_reach_serve(self): 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 = dict(self.env)
env["AGENT_SYSTEM_DSN"] = "postgres://leak-user:leak-pass@127.0.0.1/leak" env["AGENT_SYSTEM_DSN"] = "postgres://leak-user:leak-pass@127.0.0.1/leak"
env["AGENT_SYSTEM_DATA"] = "/tmp/leak-data" env["AGENT_SYSTEM_DATA"] = "/tmp/leak-data"
@@ -38,7 +44,8 @@ class LifecycleIsolationTests(tsr.SvcAutoRecoverTests):
self.svc("iso", "stop") self.svc("iso", "stop")
def test_two_bare_restarts_keep_identity(self): 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") self.svc("iso2", "start")
manifest = json.loads((self.runtime("iso2") / "manifest.json").read_text()) manifest = json.loads((self.runtime("iso2") / "manifest.json").read_text())
iid = manifest["instance_id"] iid = manifest["instance_id"]
+29 -12
View File
@@ -11,12 +11,17 @@
夹具复用 tests/test_svc_recover.py(桩不需要运行——台账操作是 SQLite 直读直写)。 夹具复用 tests/test_svc_recover.py(桩不需要运行——台账操作是 SQLite 直读直写)。
""" """
import importlib.util import importlib.util
import os
import shutil import shutil
import sqlite3 import sqlite3
import subprocess import subprocess
import sys
import unittest import unittest
from pathlib import Path 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] SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py") _spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
@@ -64,21 +69,24 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- show ---- # ---- show ----
def test_show_prints_ledger_and_flags_unknown_owner(self): 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",)) self.seed_dbs("ra1", ledger_owner="u7-admin", base_owners=("weichen",))
out = self.svc("ra1", "rdm-admin", "show").stdout out = self.svc("ra1", "rdm-admin", "show").stdout
self.assertIn("RDM 域管理员 u7-admin", out) self.assertIn("RDM 域管理员 u7-admin", out)
self.assertIn("不在基座用户表", out) # u7-admin 不在 users → 残留警示 self.assertIn("不在基座用户表", out) # u7-admin 不在 users → 残留警示
def test_show_known_owner_no_warning(self): 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") self.seed_dbs("ra2", ledger_owner="weichen")
out = self.svc("ra2", "rdm-admin").stdout # 缺省子命令 = show out = self.svc("ra2", "rdm-admin").stdout # 缺省子命令 = show
self.assertIn("RDM 域管理员 weichen", out) self.assertIn("RDM 域管理员 weichen", out)
self.assertNotIn("不在基座用户表", out) self.assertNotIn("不在基座用户表", out)
def test_show_empty_ledger_hint(self): 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) self.seed_dbs("ra3", ledger_owner=None)
out = self.svc("ra3", "rdm-admin").stdout out = self.svc("ra3", "rdm-admin").stdout
self.assertIn("台账为空", out) self.assertIn("台账为空", out)
@@ -87,7 +95,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- transfer ---- # ---- transfer ----
def test_transfer_rewrites_single_row_with_provenance(self): 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") self.seed_dbs("ra4", ledger_owner="u7-admin")
out = self.svc("ra4", "rdm-admin", "transfer", "--to", "weichen").stdout out = self.svc("ra4", "rdm-admin", "transfer", "--to", "weichen").stdout
self.assertIn("受信部署通道", out) self.assertIn("受信部署通道", out)
@@ -97,13 +106,15 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
self.assertEqual(added_by, "svc:rdm-admin:u7-admin") # 前任可追溯 self.assertEqual(added_by, "svc:rdm-admin:u7-admin") # 前任可追溯
def test_transfer_idempotent_when_already_owner(self): 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") self.seed_dbs("ra5", ledger_owner="weichen")
out = self.svc("ra5", "rdm-admin", "transfer", "--to", "weichen").stdout out = self.svc("ra5", "rdm-admin", "transfer", "--to", "weichen").stdout
self.assertIn("已是 weichen", out) self.assertIn("已是 weichen", out)
def test_transfer_rejects_owner_missing_from_base_users(self): 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") self.seed_dbs("ra6", ledger_owner="weichen")
proc = self.svc("ra6", "rdm-admin", "transfer", "--to", "nobody", check=False) proc = self.svc("ra6", "rdm-admin", "transfer", "--to", "nobody", check=False)
self.assertEqual(proc.returncode, 1, proc.stdout) self.assertEqual(proc.returncode, 1, proc.stdout)
@@ -111,7 +122,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
self.assertEqual(self.ledger_owner("ra6")[0], "weichen") # 台账未被动 self.assertEqual(self.ledger_owner("ra6")[0], "weichen") # 台账未被动
def test_transfer_rejects_empty_ledger(self): 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) self.seed_dbs("ra7", ledger_owner=None)
proc = self.svc("ra7", "rdm-admin", "transfer", "--to", "weichen", check=False) proc = self.svc("ra7", "rdm-admin", "transfer", "--to", "weichen", check=False)
self.assertEqual(proc.returncode, 1, proc.stdout) self.assertEqual(proc.returncode, 1, proc.stdout)
@@ -120,7 +132,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- 绑定合同与用法 ---- # ---- 绑定合同与用法 ----
def test_refuses_when_rdm_db_missing(self): 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.seed_dbs("ra8") # 建基座库后删 rdm.db
(self.runtime("ra8") / "data" / "rdm.db").unlink() (self.runtime("ra8") / "data" / "rdm.db").unlink()
proc = self.svc("ra8", "rdm-admin", check=False) proc = self.svc("ra8", "rdm-admin", check=False)
@@ -128,13 +141,15 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
self.assertIn("无 RDM 域库", proc.stdout) self.assertIn("无 RDM 域库", proc.stdout)
def test_refuses_when_base_db_missing(self): 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) proc = self.svc("ra9", "rdm-admin", check=False)
self.assertEqual(proc.returncode, 1, proc.stdout) self.assertEqual(proc.returncode, 1, proc.stdout)
self.assertIn("既有库不存在", proc.stdout) self.assertIn("既有库不存在", proc.stdout)
def test_unknown_subcommand_usage_exit_2(self): 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) proc = self.svc("raa", "rdm-admin", "bogus", check=False)
self.assertEqual(proc.returncode, 2, proc.stdout) self.assertEqual(proc.returncode, 2, proc.stdout)
self.assertIn("用法", proc.stdout) self.assertIn("用法", proc.stdout)
@@ -142,14 +157,16 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
# ---- status 巡检行 ---- # ---- status 巡检行 ----
def test_status_lists_rdm_admin_row_and_warning(self): 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",)) self.seed_dbs("rab", ledger_owner="u7-admin", base_owners=("weichen",))
out = self.svc("rab", "status").stdout out = self.svc("rab", "status").stdout
self.assertIn("RDM 域管理员 u7-admin", out) self.assertIn("RDM 域管理员 u7-admin", out)
self.assertIn("不在基座用户表", out) self.assertIn("不在基座用户表", out)
def test_status_silent_without_rdm_db(self): 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.seed_dbs("rac")
(self.runtime("rac") / "data" / "rdm.db").unlink() (self.runtime("rac") / "data" / "rdm.db").unlink()
out = self.svc("rac", "status").stdout out = self.svc("rac", "status").stdout
+6 -1
View File
@@ -49,8 +49,11 @@ def ci_git_env():
if not (CI_SERVER and CI_TOKEN): if not (CI_SERVER and CI_TOKEN):
return {} return {}
scheme = CI_SERVER.split("://", 1)[0] scheme = CI_SERVER.split("://", 1)[0]
# 嵌套 pins 的 SSH 端点有两代:旧 git-ssh.* 与迁移后的 gitea.*:52222。
# 只映射旧端点会让 pins 取件退回真实 SSH,而 CI 运行器没有 key,必然
# host key verification failed。同键多值,git 会依次匹配。
return { return {
"GIT_CONFIG_COUNT": "4", "GIT_CONFIG_COUNT": "5",
"GIT_CONFIG_KEY_0": "protocol.%s.allow" % scheme, "GIT_CONFIG_KEY_0": "protocol.%s.allow" % scheme,
"GIT_CONFIG_VALUE_0": "always", "GIT_CONFIG_VALUE_0": "always",
"GIT_CONFIG_KEY_1": "http.%s/.extraheader" % CI_SERVER, "GIT_CONFIG_KEY_1": "http.%s/.extraheader" % CI_SERVER,
@@ -59,6 +62,8 @@ def ci_git_env():
"GIT_CONFIG_VALUE_2": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/", "GIT_CONFIG_VALUE_2": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/",
"GIT_CONFIG_KEY_3": "core.hooksPath", "GIT_CONFIG_KEY_3": "core.hooksPath",
"GIT_CONFIG_VALUE_3": "/dev/null", "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")) 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 shlex
import shutil import shutil
import subprocess import subprocess
import sys
import unittest import unittest
from pathlib import Path 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] SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py") _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) clock.chmod(0o755)
self.env["PATH"] = str(clock_bin) + os.pathsep + self.env["PATH"] self.env["PATH"] = str(clock_bin) + os.pathsep + self.env["PATH"]
self.make_src_repo() # 预克隆 srccache(本用例走 --from local,仅保环境一致) 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.start_ok("u2a") # legacy 运行中(期望态=running)
self.assertTrue(self.running("u2a")) self.assertTrue(self.running("u2a"))
@@ -147,7 +152,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T2:构建失败 → 旧服务保持运行、current 不动 ---- # ---- T2:构建失败 → 旧服务保持运行、current 不动 ----
def test_U2_build_failure_keeps_old_running(self): 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.set_makefile(self.stub)
self.svc("u2b", "deploy", "--from", "local") self.svc("u2b", "deploy", "--from", "local")
cur1 = self.cur_release("u2b") cur1 = self.cur_release("u2b")
@@ -164,7 +170,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T3:中断切换(journal switched)→ start 入口回退并恢复 ---- # ---- T3:中断切换(journal switched)→ start 入口回退并恢复 ----
def test_U2_journal_interrupt_resolved_on_start(self): 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.set_makefile(self.stub)
self.svc("u2c", "deploy", "--from", "local") self.svc("u2c", "deploy", "--from", "local")
v1 = self.cur_release("u2c") v1 = self.cur_release("u2c")
@@ -190,7 +197,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T4:schema 前进 → 回退阻断,不触碰业务库 ---- # ---- T4:schema 前进 → 回退阻断,不触碰业务库 ----
def test_U2_schema_advance_blocks_rollback(self): 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.set_makefile(self.stub)
self.svc("u2d", "deploy", "--from", "local") self.svc("u2d", "deploy", "--from", "local")
v1 = self.cur_release("u2d") v1 = self.cur_release("u2d")
@@ -230,7 +238,8 @@ class U2ReleaseTests(tsi.IdentityTests):
# ---- T5:legacy 布局未迁移 → 裸 start/restart 仍走原路径(兼容) ---- # ---- T5:legacy 布局未迁移 → 裸 start/restart 仍走原路径(兼容) ----
def test_U2_fault_after_switch_rolls_back_on_next_start(self): 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.set_makefile(self.stub)
self.svc("u2f", "deploy", "--from", "local") self.svc("u2f", "deploy", "--from", "local")
v1 = self.cur_release("u2f") v1 = self.cur_release("u2f")
@@ -248,7 +257,8 @@ class U2ReleaseTests(tsi.IdentityTests):
self.svc("u2f", "stop") self.svc("u2f", "stop")
def test_U2_health_timeout_rolls_back(self): 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.set_makefile(self.stub)
self.svc("u2g", "deploy", "--from", "local") self.svc("u2g", "deploy", "--from", "local")
v1 = self.cur_release("u2g") v1 = self.cur_release("u2g")
@@ -277,7 +287,8 @@ class U2ReleaseTests(tsi.IdentityTests):
return p return p
def test_U2_legacy_layout_bare_lifecycle_still_works(self): 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.start_ok("u2e")
self.assertFalse((self.runtime("u2e") / "current").exists()) self.assertFalse((self.runtime("u2e") / "current").exists())
self.assertTrue((self.runtime("u2e") / "bin" / "agent-system").exists()) self.assertTrue((self.runtime("u2e") / "bin" / "agent-system").exists())
+14 -5
View File
@@ -9,9 +9,13 @@ import importlib.util
import json import json
import os import os
import shutil import shutil
import sys
import unittest import unittest
from pathlib import Path 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] SOURCE = Path(__file__).resolve().parents[1]
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py") _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 ---- # ---- T1 合法 manifest:user list 绑定 data_root + --open-existing ----
def test_T1_user_list_binds_manifest_data(self): 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.start_ok("ub1")
self.svc("ub1", "stop") self.svc("ub1", "stop")
root = self.manifest("ub1")["identity"]["data_root"] root = self.manifest("ub1")["identity"]["data_root"]
@@ -74,7 +79,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T2 禁止覆盖 --data;未绑定默认目录拒绝 ---- # ---- T2 禁止覆盖 --data;未绑定默认目录拒绝 ----
def test_T2_reject_override_data_flag(self): 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.start_ok("ub2")
self.svc("ub2", "stop") self.svc("ub2", "stop")
self.touch_db("ub2") self.touch_db("ub2")
@@ -106,7 +112,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T3 删除 data 根:OpenExisting 失败,不建空库 ---- # ---- T3 删除 data 根:OpenExisting 失败,不建空库 ----
def test_T3_missing_data_root_rejected(self): 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.start_ok("ub3")
self.svc("ub3", "stop") self.svc("ub3", "stop")
root = Path(self.manifest("ub3")["identity"]["data_root"]) root = Path(self.manifest("ub3")["identity"]["data_root"])
@@ -124,7 +131,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T4 隐藏 flock:user/deploy 拒绝;已运行服务仍在 ---- # ---- T4 隐藏 flock:user/deploy 拒绝;已运行服务仍在 ----
def test_T4_no_flock_rejects_user_and_deploy(self): 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.start_ok("ub4")
self.assertTrue(self.running("ub4")) self.assertTrue(self.running("ub4"))
self.touch_db("ub4") self.touch_db("ub4")
@@ -158,7 +166,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
# ---- T5 recovery U1 身份冒烟(完整套件见 test_svc_identity)---- # ---- T5 recovery U1 身份冒烟(完整套件见 test_svc_identity)----
def test_T5_identity_regression_smoke(self): 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") self.start_ok("ub5")
iid = self.manifest("ub5")["instance_id"] iid = self.manifest("ub5")["instance_id"]
self.svc("ub5", "stop") self.svc("ub5", "stop")