feat(狀態回報): 收尾寫一筆 skill-end 事件

現行紀錄只記「被叫用」,沒有成敗也沒有結束碼。跑完整輪的技能與開場就
中止的技能,在紀錄裡長得一模一樣。

start 由技能用量 hook 順手發,不必改技能文件。end 只能由技能自己在收尾
步驟寫——hook 接在技能工具呼叫上,而實際工作發生在之後的模型輪次,它在
原理上看不到成敗。有 start 沒有配對的 end,就是那一輪中止了。

status 五選一,每支技能各自寫明什麼情況選哪一個。找不到回報腳本就安靜
跳過,回報失敗一律不改變技能自己的結論。
This commit is contained in:
2026-09-02 16:01:17 +08:00
parent 484357feae
commit d472f81cd2
4 changed files with 63 additions and 12 deletions
+17
View File
@@ -54,6 +54,23 @@ Review changed code against `references/smells.md` (from the book *Refactoring*)
Then close the run down in two moves. Delete the step 1 snapshot file; nothing else ever reads it, and left behind it accumulates one stale diff per review. Release the review lock by running `jsc-hooks/hooks/write-guard.sh release`, which clears `$JSC_HOME/sessions/{sid}.lastskill`. That file is how the guard recognizes the running skill, and no event tells the guard a skill ended: leave it in place and the caller's first fix — the fix this very report asked for — is blocked by the audit that just finished. State the fallback in the report either way, because an older `jsc-hooks` treats `release` as an unknown mode and exits `0` without clearing anything: the lock then lifts by itself once the file is older than `JSC_WRITE_GUARD_TTL` (900 seconds by default), and `JSC_WRITE_GUARD=off` opens it immediately.
Completion condition: the report is handed to the caller, the snapshot is deleted, the release command has been run and the wait plus the `JSC_WRITE_GUARD=off` escape hatch are stated, and the fix decision is left to them.
5. Record how this run ended, as the very last thing this skill does — after the snapshot deletion and the release, so a cleanup that did not complete is still visible to it:
`jsc-hooks/tools/report-status.sh skill-end jsc-review:code-review {status} {exit} "{detail}"`
Resolve that path the way step 4 already resolves `jsc-hooks/hooks/write-guard.sh` — the sibling plugin directory, no separate lookup rule for this one call. **A missing script is not a failure here: skip this step in silence and let the run end as it stands.** The script swallows its own write errors and exits 0 even then, so nothing branches on its code either. This skill writes no code; it must not start failing over a line it could not write about itself.
| status | This skill's case |
| --- | --- |
| `ok` | All six groups returned and the merged list reached the caller, the snapshot is deleted and the lock is clear. A `merge-findings.sh` exit 1 is `ok` too: six groups read the diff and none had anything to report, which is a real answer |
| `blocked` | The review scope never existed, so no sub agent ran: step 1's `git diff` refused — not a repository, an unknown base revision, or an unreadable object. Nothing was reviewed and nothing could be |
| `degraded` | The report is handed over but the close-out is short: the step 1 snapshot is still on disk, or `write-guard.sh release` did not clear `$JSC_HOME/sessions/{sid}.lastskill` and the lock lingers until `JSC_WRITE_GUARD_TTL` |
| `failed` | The six groups ran and their findings never reached a report: `merge-findings.sh` exit 2, or a second exit 3 with malformed rows still on the table |
| `aborted` | There was nothing to review — the step 1 snapshot came back empty, so the diff holds no changed line, the file was deleted and no sub agent was spawned. Keep this apart from the `ok` above: both end in 「無發現」, and only the event tells a clean review from a review that never had a subject |
`{exit}` is the exit code of whatever decided the status, `0` for `ok`. `{detail}` is one short line well under 200 characters: changed-file and finding counts plus exit codes, never file paths, code excerpts, branch names, or personal data.
Completion condition: the command has run, or the script was absent and this step was skipped.
## Notes