Guard task-start against merged branch names; harden sync evidence scan #211

Merged
weichen merged 14 commits from feature/task-start-merged-guard into main 2026-10-05 12:39:32 +00:00
Owner

feature/task-start-merged-guard 任务卡

任务主记录:<PR 链接,task-finish 时填写>;状态:进行中;owner:weichen

基线与授权

  • 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 43d33aa492
  • 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard(worktree);分支:feature/task-start-merged-guard
  • 授权与交付终点:owner 2026-10-05 授权立项(决策清单 #7);改 scripts/task.sh 加守护 + 测试 + PR 合入为本卡终点;不改 task.sh 其他行为。

目标与非目标

  • 目标:cmd_start 在分支名校验后新增守护——本地或远端存在同名分支且已包含于 origin/main 时拒绝启动(exit 非零),提示「沿用原分支或换新 slug」。
  • 背景:2026-10-05 EXT-1 复核轮实测,合入后再 task-start 同名分支会从新 main 长出第二段历史、空卡覆盖已合入任务卡(两轮证据差点丢失,靠 git show 恢复);旧逻辑只校验本地分支能否创建,不查是否刚合入。
  • 非目标:不改 precheck/task-sync/finish 等其他子命令;不做「恢复原卡」的自动修复(拒绝即可,恢复留给人工);不引入新依赖。
  • 范围变更(2026-10-05 12:33):本卡功能负例的证据命令含 ||,暴露 cmd_sync 证据扫描按裸 | 切行、把转义碎片当 HEAD 传给 git diff 致 fatal 128 杀死 sync 的潜在缺陷(task-sync 门禁被卡死,卡内 12:30–12:32 五次中毒复现)——同 PR 一并修复(非十六进制单元格跳过,WARN 语义不变)。

同步记录

节点 sync_base_sha tested_head_sha checked_at
启动 43d33aa492 43d33aa492 2026-10-05T12:28:26Z

证据(Evidence)

时间(UTC) 命令 被测HEAD exit 来源 sha256(16)

结果与验证(完成后填写)

  • 结果:cmd_start 守护 + cmd_sync 证据扫描加固均落地(见范围变更)。守护:已合入同名分支拒绝启动、提示沿用原分支或换新 slug,负例实测无 worktree 副作用;扫描:含 \|\| 转义行的卡片上 sync 正常完成、WARN 语义不变。
  • 验证:bash -n PASS;功能负例 PASS(exit≠0 断言,无副作用);sync 修复验证 PASS(exit 0);make test 全链 PASS(修复前 94f8d47 与最终 HEAD 两轮,exit 0);权威源为 CI 在 PR HEAD 的 make test+make build(GATE)。
  • 影响与剩余项:仅 scripts/task.sh 两处;下游建仓(Agent-System-RDM)将复制修复后的版本。
    | 2026-10-05T12:28:53Z | bash -n scripts/task.sh | 94f8d4760b | 0 | SELF | e3b0c44298fc1c14 |
$ bash -n scripts/task.sh
[exit 0 | HEAD 94f8d4760b | sha256:e3b0c44298fc1c14] 输出尾部 15 行:

| 2026-10-05T12:28:53Z | bash scripts/task.sh start feature/ext-1-inproc-handler && exit 1 \|\| echo 'guard refused merged branch as expected' | 94f8d4760b | 0 | SELF | 937f2c0a1987b4f7 |

$ bash scripts/task.sh start feature/ext-1-inproc-handler && exit 1 || echo 'guard refused merged branch as expected'
[exit 0 | HEAD 94f8d4760b | sha256:937f2c0a1987b4f7] 输出尾部 15 行:
ERROR: branch feature/ext-1-inproc-handler already merged into origin/main — reuse the original branch or pick a new slug (task-start must not recreate merged cards)
guard refused merged branch as expected

| 2026-10-05T12:29:05Z | make test | 94f8d4760b | 0 | SELF | 84092b2ad053ee79 |

$ make test
[exit 0 | HEAD 94f8d4760b | sha256:84092b2ad053ee79] 输出尾部 20 行:

 ✓ test/ui.test.tsx (6 tests) 66ms
 ✓ test/toolblock.test.tsx (4 tests) 76ms
 ✓ test/overlay-host.test.tsx (6 tests) 68ms
 ✓ test/file-preview.test.tsx (9 tests) 89ms
 ✓ test/inbox.test.tsx (13 tests) 93ms
 ✓ test/card-anchor.test.tsx (4 tests) 96ms
 ✓ test/inline-confirm.test.tsx (7 tests) 107ms
 ✓ test/capability.test.tsx (14 tests) 153ms

 Test Files  14 passed (14)
      Tests  103 passed (103)
   Start at  12:29:37
   Duration  619ms (transform 415ms, setup 0ms, import 1.36s, tests 955ms, environment 3.25s)

knip unused exports 55 <= 55
cd deps/agent-command && go vet ./... && go test -count=1 ./...
ok  	agent-command	0.002s
ok  	agent-command/conformance	0.002s
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'

| 2026-10-05T12:30:24Z | make task-sync | 94f8d4760b | 2 | SELF | c59e97420676c4fa |

$ make task-sync
[exit 2 | HEAD 94f8d4760b | sha256:c59e97420676c4fa] 输出尾部 15 行:
make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
ERROR: dirty tree — 先显式提交;不隐式 stash(collaboration.md:11)
make[1]: *** [Makefile:36: task-sync] Error 1
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'

| 同步前验收 | 43d33aa492 | e58035a8e4 | 2026-10-05T12:30:36Z |
| 2026-10-05T12:30:36Z | make task-sync | e58035a8e4 | 2 | SELF | 12717b8736ff03bf |

$ make task-sync
[exit 2 | HEAD e58035a8e4 | sha256:12717b8736ff03bf] 输出尾部 15 行:
make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'
Already up to date.
make[1]: *** [Makefile:36: task-sync] Error 128
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'

| 同步前验收 | 43d33aa492 | 879bf64b94 | 2026-10-05T12:30:49Z |
| 同步前验收 | 43d33aa492 | 09aa6e59b0 | 2026-10-05T12:31:08Z |
| 同步前验收 | 43d33aa492 | 9e30c5f656 | 2026-10-05T12:31:17Z |
| 同步前验收 | 43d33aa492 | b3a5a31d10 | 2026-10-05T12:31:59Z |
| 同步前验收 | 43d33aa492 | 2fec8b4e82 | 2026-10-05T12:32:00Z |
| 2026-10-05T12:32:55Z | bash -n scripts/task.sh && bash scripts/task.sh sync && echo 'sync survives escaped-pipe evidence row' | 278bff9a31 | 1 | SELF | afc745546e4eb5ba |

$ bash -n scripts/task.sh && bash scripts/task.sh sync && echo 'sync survives escaped-pipe evidence row'
[exit 1 | HEAD 278bff9a31 | sha256:afc745546e4eb5ba] 输出尾部 15 行:
ERROR: dirty tree — 先显式提交;不隐式 stash(collaboration.md:11)

| 同步前验收 | 43d33aa492 | 1e0508e8a7 | 2026-10-05T12:33:06Z |
| 同步前验收 | 43d33aa492 | 9a3ebe6539 | 2026-10-05T12:33:16Z |
| 2026-10-05T12:33:16Z | bash -n scripts/task.sh && bash scripts/task.sh sync >/dev/null 2>&1 && echo 'sync survives escaped-pipe evidence row' | 9a3ebe6539 | 0 | SELF | 2a3457acb8b31495 |

$ bash -n scripts/task.sh && bash scripts/task.sh sync >/dev/null 2>&1 && echo 'sync survives escaped-pipe evidence row'
[exit 0 | HEAD 9a3ebe6539 | sha256:2a3457acb8b31495] 输出尾部 15 行:
sync survives escaped-pipe evidence row

| 2026-10-05T12:33:22Z | make test | de75f1ede9 | 0 | SELF | 9a4f394d8e0f5c60 |

$ make test
[exit 0 | HEAD de75f1ede9 | sha256:9a4f394d8e0f5c60] 输出尾部 20 行:
 ✓ test/collapsible.test.tsx (5 tests) 79ms
 ✓ test/ui.test.tsx (6 tests) 70ms
 ✓ test/tabstrip.test.tsx (3 tests) 79ms
 ✓ test/file-preview.test.tsx (9 tests) 84ms
 ✓ test/overlay-host.test.tsx (6 tests) 79ms
 ✓ test/inbox.test.tsx (13 tests) 90ms
 ✓ test/inline-confirm.test.tsx (7 tests) 106ms
 ✓ test/card-anchor.test.tsx (4 tests) 107ms
 ✓ test/capability.test.tsx (14 tests) 157ms

 Test Files  14 passed (14)
      Tests  103 passed (103)
   Start at  12:33:50
   Duration  651ms (transform 432ms, setup 0ms, import 1.42s, tests 993ms, environment 3.42s)

knip unused exports 55 <= 55
cd deps/agent-command && go vet ./... && go test -count=1 ./...
ok  	agent-command	0.002s
ok  	agent-command/conformance	0.002s
make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard'

PR 说明:与任务卡同一份文档。两处 scripts/task.sh 修复:① cmd_start 拒绝已合入 origin/main 的同名分支(EXT-1 复核轮实测事故的根因);② cmd_sync 证据扫描跳过非十六进制单元格(证据命令含 || 时转义碎片曾致 git diff fatal 128 杀死 sync)。审阅重放集:bash scripts/task.sh start feature/ext-1-inproc-handler(应拒绝);在含转义管道证据行的卡片上 bash scripts/task.sh sync(应正常完成)。

# feature/task-start-merged-guard 任务卡 任务主记录:<PR 链接,task-finish 时填写>;状态:进行中;owner:weichen ## 基线与授权 - 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 43d33aa4921078bc202393b99cba017d7f731b98 - 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard(worktree);分支:feature/task-start-merged-guard - 授权与交付终点:owner 2026-10-05 授权立项(决策清单 #7);改 scripts/task.sh 加守护 + 测试 + PR 合入为本卡终点;不改 task.sh 其他行为。 ## 目标与非目标 - **目标**:`cmd_start` 在分支名校验后新增守护——本地或远端存在同名分支且已包含于 `origin/main` 时拒绝启动(exit 非零),提示「沿用原分支或换新 slug」。 - **背景**:2026-10-05 EXT-1 复核轮实测,合入后再 `task-start` 同名分支会从新 main 长出第二段历史、空卡覆盖已合入任务卡(两轮证据差点丢失,靠 git show 恢复);旧逻辑只校验本地分支能否创建,不查是否刚合入。 - **非目标**:不改 precheck/task-sync/finish 等其他子命令;不做「恢复原卡」的自动修复(拒绝即可,恢复留给人工);不引入新依赖。 - **范围变更(2026-10-05 12:33)**:本卡功能负例的证据命令含 `||`,暴露 `cmd_sync` 证据扫描按裸 `|` 切行、把转义碎片当 HEAD 传给 `git diff` 致 fatal 128 杀死 sync 的潜在缺陷(task-sync 门禁被卡死,卡内 12:30–12:32 五次中毒复现)——**同 PR 一并修复**(非十六进制单元格跳过,WARN 语义不变)。 ## 同步记录 | 节点 | sync_base_sha | tested_head_sha | checked_at | |---|---|---|---| | 启动 | 43d33aa4921078bc202393b99cba017d7f731b98 | 43d33aa4921078bc202393b99cba017d7f731b98 | 2026-10-05T12:28:26Z | ## 证据(Evidence) <!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 --> | 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) | |---|---|---|---|---|---| ## 结果与验证(完成后填写) - 结果:cmd_start 守护 + cmd_sync 证据扫描加固均落地(见范围变更)。守护:已合入同名分支拒绝启动、提示沿用原分支或换新 slug,负例实测无 worktree 副作用;扫描:含 `\|\|` 转义行的卡片上 sync 正常完成、WARN 语义不变。 - 验证:bash -n PASS;功能负例 PASS(exit≠0 断言,无副作用);sync 修复验证 PASS(exit 0);make test 全链 PASS(修复前 94f8d47 与最终 HEAD 两轮,exit 0);权威源为 CI 在 PR HEAD 的 make test+make build(GATE)。 - 影响与剩余项:仅 scripts/task.sh 两处;下游建仓(Agent-System-RDM)将复制修复后的版本。 | 2026-10-05T12:28:53Z | `bash -n scripts/task.sh` | 94f8d4760b | 0 | SELF | e3b0c44298fc1c14 | <!-- evidence:run 2026-10-05T12:28:53Z --> ``` $ bash -n scripts/task.sh [exit 0 | HEAD 94f8d4760b | sha256:e3b0c44298fc1c14] 输出尾部 15 行: ``` | 2026-10-05T12:28:53Z | `bash scripts/task.sh start feature/ext-1-inproc-handler && exit 1 \|\| echo 'guard refused merged branch as expected'` | 94f8d4760b | 0 | SELF | 937f2c0a1987b4f7 | <!-- evidence:run 2026-10-05T12:28:53Z --> ``` $ bash scripts/task.sh start feature/ext-1-inproc-handler && exit 1 || echo 'guard refused merged branch as expected' [exit 0 | HEAD 94f8d4760b | sha256:937f2c0a1987b4f7] 输出尾部 15 行: ERROR: branch feature/ext-1-inproc-handler already merged into origin/main — reuse the original branch or pick a new slug (task-start must not recreate merged cards) guard refused merged branch as expected ``` | 2026-10-05T12:29:05Z | `make test` | 94f8d4760b | 0 | SELF | 84092b2ad053ee79 | <!-- evidence:run 2026-10-05T12:29:05Z --> ``` $ make test [exit 0 | HEAD 94f8d4760b | sha256:84092b2ad053ee79] 输出尾部 20 行: ✓ test/ui.test.tsx (6 tests) 66ms ✓ test/toolblock.test.tsx (4 tests) 76ms ✓ test/overlay-host.test.tsx (6 tests) 68ms ✓ test/file-preview.test.tsx (9 tests) 89ms ✓ test/inbox.test.tsx (13 tests) 93ms ✓ test/card-anchor.test.tsx (4 tests) 96ms ✓ test/inline-confirm.test.tsx (7 tests) 107ms ✓ test/capability.test.tsx (14 tests) 153ms Test Files 14 passed (14) Tests 103 passed (103) Start at 12:29:37 Duration 619ms (transform 415ms, setup 0ms, import 1.36s, tests 955ms, environment 3.25s) knip unused exports 55 <= 55 cd deps/agent-command && go vet ./... && go test -count=1 ./... ok agent-command 0.002s ok agent-command/conformance 0.002s make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard' ``` | 2026-10-05T12:30:24Z | `make task-sync` | 94f8d4760b | 2 | SELF | c59e97420676c4fa | <!-- evidence:run 2026-10-05T12:30:24Z --> ``` $ make task-sync [exit 2 | HEAD 94f8d4760b | sha256:c59e97420676c4fa] 输出尾部 15 行: make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard' ERROR: dirty tree — 先显式提交;不隐式 stash(collaboration.md:11) make[1]: *** [Makefile:36: task-sync] Error 1 make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard' ``` | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | e58035a8e4b60dc291d9245d669c5a3a561fd699 | 2026-10-05T12:30:36Z | | 2026-10-05T12:30:36Z | `make task-sync` | e58035a8e4 | 2 | SELF | 12717b8736ff03bf | <!-- evidence:run 2026-10-05T12:30:36Z --> ``` $ make task-sync [exit 2 | HEAD e58035a8e4 | sha256:12717b8736ff03bf] 输出尾部 15 行: make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard' Already up to date. make[1]: *** [Makefile:36: task-sync] Error 128 make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard' ``` | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 879bf64b94a6f1c3b126ec52a778b1f8c7630266 | 2026-10-05T12:30:49Z | | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 09aa6e59b08ff74ca3e5c78ab1bffc55e386993c | 2026-10-05T12:31:08Z | | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 9e30c5f656ccaf3186c966c7452df2da3d75292f | 2026-10-05T12:31:17Z | | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | b3a5a31d10d03dabe13e03ddbf29c736f892dea2 | 2026-10-05T12:31:59Z | | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 2fec8b4e829bdb27006c924d51d56016331bde44 | 2026-10-05T12:32:00Z | | 2026-10-05T12:32:55Z | `bash -n scripts/task.sh && bash scripts/task.sh sync && echo 'sync survives escaped-pipe evidence row'` | 278bff9a31 | 1 | SELF | afc745546e4eb5ba | <!-- evidence:run 2026-10-05T12:32:55Z --> ``` $ bash -n scripts/task.sh && bash scripts/task.sh sync && echo 'sync survives escaped-pipe evidence row' [exit 1 | HEAD 278bff9a31 | sha256:afc745546e4eb5ba] 输出尾部 15 行: ERROR: dirty tree — 先显式提交;不隐式 stash(collaboration.md:11) ``` | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 1e0508e8a7071bcd92e78089c6c30c41caf1b594 | 2026-10-05T12:33:06Z | | 同步前验收 | 43d33aa4921078bc202393b99cba017d7f731b98 | 9a3ebe6539d97445a7b5705a0a48bd9a1124aa90 | 2026-10-05T12:33:16Z | | 2026-10-05T12:33:16Z | `bash -n scripts/task.sh && bash scripts/task.sh sync >/dev/null 2>&1 && echo 'sync survives escaped-pipe evidence row'` | 9a3ebe6539 | 0 | SELF | 2a3457acb8b31495 | <!-- evidence:run 2026-10-05T12:33:16Z --> ``` $ bash -n scripts/task.sh && bash scripts/task.sh sync >/dev/null 2>&1 && echo 'sync survives escaped-pipe evidence row' [exit 0 | HEAD 9a3ebe6539 | sha256:2a3457acb8b31495] 输出尾部 15 行: sync survives escaped-pipe evidence row ``` | 2026-10-05T12:33:22Z | `make test` | de75f1ede9 | 0 | SELF | 9a4f394d8e0f5c60 | <!-- evidence:run 2026-10-05T12:33:22Z --> ``` $ make test [exit 0 | HEAD de75f1ede9 | sha256:9a4f394d8e0f5c60] 输出尾部 20 行: ✓ test/collapsible.test.tsx (5 tests) 79ms ✓ test/ui.test.tsx (6 tests) 70ms ✓ test/tabstrip.test.tsx (3 tests) 79ms ✓ test/file-preview.test.tsx (9 tests) 84ms ✓ test/overlay-host.test.tsx (6 tests) 79ms ✓ test/inbox.test.tsx (13 tests) 90ms ✓ test/inline-confirm.test.tsx (7 tests) 106ms ✓ test/card-anchor.test.tsx (4 tests) 107ms ✓ test/capability.test.tsx (14 tests) 157ms Test Files 14 passed (14) Tests 103 passed (103) Start at 12:33:50 Duration 651ms (transform 432ms, setup 0ms, import 1.42s, tests 993ms, environment 3.42s) knip unused exports 55 <= 55 cd deps/agent-command && go vet ./... && go test -count=1 ./... ok agent-command 0.002s ok agent-command/conformance 0.002s make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-task-start-merged-guard' ``` --- PR 说明:与任务卡同一份文档。两处 scripts/task.sh 修复:① cmd_start 拒绝已合入 origin/main 的同名分支(EXT-1 复核轮实测事故的根因);② cmd_sync 证据扫描跳过非十六进制单元格(证据命令含 || 时转义碎片曾致 git diff fatal 128 杀死 sync)。审阅重放集:`bash scripts/task.sh start feature/ext-1-inproc-handler`(应拒绝);在含转义管道证据行的卡片上 `bash scripts/task.sh sync`(应正常完成)。
weichen added 14 commits 2026-10-05 12:34:51 +00:00
Why: 合入后再 task-start 同名分支会从新 main 长出第二段历史并覆盖已合入任务卡
(2026-10-05 EXT-1 复核轮实测,两轮证据差点丢失);原校验只看本地分支能否创建。
Evidence: bash -n 通过;功能负例——start feature/ext-1-inproc-handler 被拒且无
worktree 副作用;make test 全链 exit 0;task-sync 基线 43d33aa。
Impact: 仅 scripts/task.sh cmd_start 增加已合入同名分支检查,其余子命令行为不变。
Refs: EXT-1 任务卡复核轮记录(.task/archive/feature-ext-1-inproc-handler.md)。
Why: 证据命令含 || 时 evidence.sh 把表格单元格里的管道转义为 \|\|,cmd_sync 按裸 |
切行把碎片当 HEAD 传给 git diff,fatal 128 在 set -e 下杀死 sync(本卡功能负例行实测触发,
task-sync 门禁被卡死)。
Evidence: bash -n 通过;含转义管道行的本卡上 bash scripts/task.sh sync 正常完成(WARN 照发、
exit 0);修复后 make test 全链重跑。
Impact: 仅 cmd_sync 证据扫描加十六进制过滤;WARN 语义不变。
Refs: 本卡 12:30-12:32 五次 sync 中毒复现记录。
weichen added 10 commits 2026-10-05 12:34:53 +00:00
Why: 证据命令含 || 时 evidence.sh 把表格单元格里的管道转义为 \|\|,cmd_sync 按裸 |
切行把碎片当 HEAD 传给 git diff,fatal 128 在 set -e 下杀死 sync(本卡功能负例行实测触发,
task-sync 门禁被卡死)。
Evidence: bash -n 通过;含转义管道行的本卡上 bash scripts/task.sh sync 正常完成(WARN 照发、
exit 0);修复后 make test 全链重跑。
Impact: 仅 cmd_sync 证据扫描加十六进制过滤;WARN 语义不变。
Refs: 本卡 12:30-12:32 五次 sync 中毒复现记录。
weichen merged commit 04e07dea89 into main 2026-10-05 12:39:32 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weichen/Agent-System-Dev#211