Archive task file on /close instead of deleting it - #19
Merged
Conversation
- Add archive-task.sh: move tasks/<name>.md to tasks/archive/<name>.md with a closed-stamp (date, PR + short merge SHA, branch), append a one-line tasks/archive/_index.md entry, collision-safe (-2/-3 suffix) - Adaptive tracking with no .gitignore surgery: archive inherits tasks/'s ignore status; helper reports tracked=yes/no, /close asks before commit and stages only tasks/archive/ + the removed file - Rewrite /close step 10 + path-rule example + summary to use the helper - /list: show archived count in the summary - Bump work-system to 1.5.0; update README and curate knowledge Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
- Flatten slash-bearing task names (adopted feature/a/b branches) so the archive write can't crash mid-/close, after the worktree/branch are gone - Key _index.md entries and the final summary to the actual archived filename so a -2/-3 collision entry maps back to its file - Make the archive write atomic (tmp + mv) so an interrupted write can't orphan a truncated, real-looking archive file - Rename the helper's tracked= output to committable= (check-ignore measures "not ignored", not "tracked") and reword /close accordingly - Extract precise commit staging into an archive-task.sh `stage` subcommand (no blanket `git add tasks/`); scope /close's status display too - Source the merge SHA from task-status.sh `assess` instead of a second `gh pr view` round-trip; fix a merge_sha local-var collision - Anchor index-title extraction to the first heading line (skip shebangs / fenced `#` comments) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
- Revert the merge-SHA fold into task-status.sh assess: re-fetch it via a separate best-effort `gh pr view` in /close so the safety-critical pr_state lookup never depends on the optional `mergeCommit` json field (old-gh safe) - Require a value for archive-task.sh --pr/--sha so a bare trailing flag errors instead of silently stamping a merged task as "closed manually" - Record the _index.md line before dropping the source, so a failed index write leaves the original intact and /close re-runnable - Catch a failed archive write, clean the temp, and abort with the source kept - Chain /close's `stage && commit` so a stage failure can't commit the wrong tree - Sync the knowledge doc's merge-SHA-source note to the restored design Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
When tasks/ is committable, /close left the archive commit on local main, unpushed — diverging from origin/main and breaking the next /close's --ff-only sync. Fold the push into the same approval: commit, then push the archive as a clean fast-forward onto origin/main (step 5 already synced main, so it sits one commit on top). A failed push (protected/offline/ pre-existing divergence) is non-fatal and never force-pushed — the commit stays local with a "push when ready" note. Update README + knowledge doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
- Stop stamping "merged @ null": guard --jq with `// empty` and have
archive-task.sh treat a literal "null" sha as no-sha
- /kickoff: enumerate tasks with the `tasks/*.md` glob so the new
tasks/archive/ dir is no longer offered as a fake task
- Anchor /close's `gh pr view` SHA fetch to the main repo via a scoped
subshell cd, so the inside-worktree path (cwd removed in step 7) still resolves
- Encapsulate stage -> commit -> ff-push in a tested `commit-push` helper
(replaces the SKILL-prose orchestration); it refuses to commit when the
main repo isn't on <main-branch>, and stages a previously-tracked task
file's removal even when the archive path is gitignored
- archive: roll the moved file back if the _index.md write fails, so a
re-run leaves no orphaned, unrecorded archive
- Fix the stale /close subtitle ("delete task file" -> "archive"), the
committable=no wording, and trim the knowledge index line
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
Correctness bugs introduced by the round-3 commit-push helper: - Commit with an explicit pathspec (`git commit -- <archive> <index> <removal>`) so unrelated pre-staged work is never swept into the "Archive task" commit and pushed to origin/main - Report result=commit-failed on a non-zero commit (rejecting hook, GPG, locked index) instead of masking it as nothing-to-commit - Flatten the source lookup (foo/bar -> tasks/foo-bar.md), so an adopted multi-segment task is actually found and archived, not silently skipped - Make the source rm non-fatal: a remove failure now warns and still emits the archive output (no silent duplicate-with-no-output mid-/close) - /close: handle archive exit != 3 as a real failure, and add the commit-failed branch; fix the wrong-branch "staged" wording (nothing is staged) - /kickoff: enumerate with `find` (nullglob-immune) instead of `ls tasks/*.md` Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
Both correctness bugs trace back to round-4's non-fatal rm + batched add: - Revert the non-fatal source rm to a fatal remove with archive rollback, done BEFORE the index write: if the source can't be removed, roll the moved archive back, keep the source intact, and exit non-zero (/close's exit!=3 branch reports it). This stops commit-push from ever seeing a leftover source and committing a pushed duplicate of source + archive. - commit-push: stage each path independently and commit only the paths that actually carry a staged change, so one non-matching pathspec (a stale archived_path) can no longer abort the whole `git add` and silently drop the real source deletion as a false nothing-to-commit. - Index write is now best-effort (the archive file is the record); warn instead of aborting on a failed log append. - /kickoff: show "No tasks found" by checking for empty `find` output (find exits 0 on no matches, so the `|| echo` fallback never fired). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
- Scope the archive push: only push when the archive commit is the SOLE
commit ahead of origin/<main-branch> (ahead == 1). A pre-existing unpushed
commit on main is no longer published under the archive-only approval —
commit-push reports committed-local reason=unpushed-history instead
- Add an integrity guard: when the archive file was meant to be committed
but failed to stage (stale/lost archived_path), return archive-not-staged
and unstage, rather than committing the source deletion alone and claiming
the task was archived
- Emit archive_committed=yes|no so /close words a gitignored-archive close
honestly ("removal committed; archive kept local") instead of claiming the
archive file was committed
- Document the new result codes in the script header, SKILL, and knowledge doc
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bEuNsKPWrfHPQX9dZ4HfY
3 tasks
gering
added a commit
that referenced
this pull request
Jul 16, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix: per-lens split live — gate pruned style, 10 xhigh finders + codex gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus). Fixes the agreed findings: - Never auto-accept an all-untagged consensus cluster: no tagged lens backs it, so it is verified like a solo. Verify/auto-accept now derive from ONE needsVerify predicate (structural exactly-once partition); kind vote in clearer every-form (#1, consensus critical; #21, #22) - Design verifier sees the finding's recommendation — the proposal the applicability rubric actually tests — and carries an escape hatch: a genuine defect mis-filed under a design lens is not refuted away (#12, #3); "solo" dropped from verifier prompts (#4) - Untagged findings from multi-lens cluster finders fall back to 'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent free-text lens validated, majority-member fallback (#9) - Improvement invitation scoped to design finder units — defect-lens finders stay defect-only (#8); merge prompt clusters by issue, not only defect (#13); schema descriptions generalized for design findings (#14) - LENS_BRIEF startup assertion (#6); gate prompt interpolates LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5) - Workflow assigns stable finding num (defects first, shared sequence); presenter/pr-post render it verbatim (#20) - pr-post.py: design lens is the backup kind signal when the handoff drops kind (explicit defect still wins); single-pass partition (#17, #24) - Balance: REFUTED is its own segment (refuted ⊄ solo since design consensus can be refuted) (#2); LOCKED design-table column precedence in --loop rounds clarified (#11); "verifies solos" doc sweep across manifests/README/knowledge (#4); cluster failure-isolation trade-off documented (#10); knowledge index line trimmed (#15) Declined: #16 (JS test harness for sandbox code; lens-sync test covers the drift class), #18 (gate-fail under --max runs all lenses — the documented never-silently-narrower degrade), #23 (micro-opt vs readability). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering
added a commit
that referenced
this pull request
Jul 17, 2026
Swarm loop round 3 — 3 findings, all in the probe. Rather than patch a probe that had a security jail bolted on (rounds 1-3 all fixed jail-adjacent bugs), this removes the jail: a readiness check passes no untrusted diff, so it never needed one — the sibling `codex login status` in ready_check is unjailed too. - Run `grok models` directly, not through sandboxed(). This roots out the round-3 CRITICAL (#18): the jail's `_init_sandbox` builds its deny profile with python3, so routing the probe through it made python3 a hard dependency of the formerly-local `ready`/`list` paths — and a missing python3 then misreported as "grok models failed (rc=65)". No jail, no python3 dep, honest reasons. - Bound with `timeout -k 3` (#17): plain `timeout` only SIGTERMs, so a grok that ignores SIGTERM (or forks a stdout-inheriting child) kept the command substitution blocking past the deadline — the "must never hang" hole. `-k` SIGKILLs after a grace period. rc 124 (SIGTERM at the deadline) reports as "timed out"; rc 137 (SIGKILL) reports as "killed" — almost always our own `-k`, but an OOM/external kill shares the code, so the message doesn't assert a timeout that may not have happened. - Take only the FIRST id per bullet line (#19): scanning the whole line also matched a grok-4.5 mentioned in prose on another model's line ("* grok-5 (successor to grok-4.5)"), reporting a retired model as offered. - Fold _build_jail back into sandboxed(). It existed ONLY to share the jail with the probe; with the probe unjailed, the split — and the shared-warning (#12) and per-backend-memo (#15) fixes it forced last round — are moot. sandboxed() is back to its pre-split shape; _init_sandbox keeps the backend key (harmless, strictly more correct). - Fix a stale swarm-review.js input-contract comment ("subset of the three" → codex, grok). - Docs (header/README/CHANGELOG/knowledge) drop the jail claim. The knowledge entry records the real lesson: five rounds of patching a jailed probe ended the moment the jail was deleted — a feature added to be safe that generates every round's bugs is a shape problem; cut it, don't harden it. The composer removal (the PR's subject) drew zero findings across all five rounds. Verified: live grok ready; SIGTERM-ignoring grok bounded by -k in ~5s, reported as killed; SIGTERM-obeying grok reported as timed out; model-gone → honest hint, no warning; probe rc=1 → warn + trust-auth; NO python3 invoked on the ready path; review path still fully jailed (sandbox-exec + AWS/GH secret stripping); end-to-end review returns a schema-valid finding. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gering
added a commit
that referenced
this pull request
Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix: per-lens split live — gate pruned style, 10 xhigh finders + codex gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus). Fixes the agreed findings: - Never auto-accept an all-untagged consensus cluster: no tagged lens backs it, so it is verified like a solo. Verify/auto-accept now derive from ONE needsVerify predicate (structural exactly-once partition); kind vote in clearer every-form (#1, consensus critical; #21, #22) - Design verifier sees the finding's recommendation — the proposal the applicability rubric actually tests — and carries an escape hatch: a genuine defect mis-filed under a design lens is not refuted away (#12, #3); "solo" dropped from verifier prompts (#4) - Untagged findings from multi-lens cluster finders fall back to 'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent free-text lens validated, majority-member fallback (#9) - Improvement invitation scoped to design finder units — defect-lens finders stay defect-only (#8); merge prompt clusters by issue, not only defect (#13); schema descriptions generalized for design findings (#14) - LENS_BRIEF startup assertion (#6); gate prompt interpolates LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5) - Workflow assigns stable finding num (defects first, shared sequence); presenter/pr-post render it verbatim (#20) - pr-post.py: design lens is the backup kind signal when the handoff drops kind (explicit defect still wins); single-pass partition (#17, #24) - Balance: REFUTED is its own segment (refuted ⊄ solo since design consensus can be refuted) (#2); LOCKED design-table column precedence in --loop rounds clarified (#11); "verifies solos" doc sweep across manifests/README/knowledge (#4); cluster failure-isolation trade-off documented (#10); knowledge index line trimmed (#15) Declined: #16 (JS test harness for sandbox code; lens-sync test covers the drift class), #18 (gate-fail under --max runs all lenses — the documented never-silently-narrower degrade), #23 (micro-opt vs readability). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering
added a commit
that referenced
this pull request
Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix: per-lens split live — gate pruned style, 10 xhigh finders + codex gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus). Fixes the agreed findings: - Never auto-accept an all-untagged consensus cluster: no tagged lens backs it, so it is verified like a solo. Verify/auto-accept now derive from ONE needsVerify predicate (structural exactly-once partition); kind vote in clearer every-form (#1, consensus critical; #21, #22) - Design verifier sees the finding's recommendation — the proposal the applicability rubric actually tests — and carries an escape hatch: a genuine defect mis-filed under a design lens is not refuted away (#12, #3); "solo" dropped from verifier prompts (#4) - Untagged findings from multi-lens cluster finders fall back to 'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent free-text lens validated, majority-member fallback (#9) - Improvement invitation scoped to design finder units — defect-lens finders stay defect-only (#8); merge prompt clusters by issue, not only defect (#13); schema descriptions generalized for design findings (#14) - LENS_BRIEF startup assertion (#6); gate prompt interpolates LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5) - Workflow assigns stable finding num (defects first, shared sequence); presenter/pr-post render it verbatim (#20) - pr-post.py: design lens is the backup kind signal when the handoff drops kind (explicit defect still wins); single-pass partition (#17, #24) - Balance: REFUTED is its own segment (refuted ⊄ solo since design consensus can be refuted) (#2); LOCKED design-table column precedence in --loop rounds clarified (#11); "verifies solos" doc sweep across manifests/README/knowledge (#4); cluster failure-isolation trade-off documented (#10); knowledge index line trimmed (#15) Declined: #16 (JS test harness for sandbox code; lens-sync test covers the drift class), #18 (gate-fail under --max runs all lenses — the documented never-silently-narrower degrade), #23 (micro-opt vs readability). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/closenow archives the finished task file instead ofrm-ing it: it movestasks/<name>.mdintotasks/archive/<name>.mdwith a closed-stamp and logs a one-line entry, so finished-task context (goal, acceptance criteria, shipping PR) is no longer lost —tasks/is untracked by design and had no git history to fall back on.archive-task.sh);close/SKILL.mdonly branches on itskey=valueoutput, per the prose-drift convention.Changes
scripts/archive-task.sh— move + closed-stamp (date · PR + short merge SHA · branch, or "closed manually (no merged PR)"), append-onlytasks/archive/_index.mdlog, collision-safe (-2/-3suffix, never clobbers), reportstracked=yes/no..gitignoresurgery — the archive inherits whatevertasks/does: gitignored → local-only; tracked → committable. The script never commits;/closeasks first and stages onlytasks/archive/+ the removed file, never a blanketgit add tasks/./closestep 10 rewritten to use the helper (merged + manual paths), plus the top-of-file path-rule example and the final summary./listshows an archived count in its summary.plugin.json+marketplace.json); README updated; knowledge entry curated.Readiness
features/task-archiving-on-close.md)check-structure.py— 0 errors (2 pre-existing warnings in unrelated plugins)Test plan
tasks/archive/withPR #N (merged @ <sha>)stamp +_index.mdline-2, prior archive untouchedtasks/→tracked=no(local-only, no commit prompt); trackedtasks/→ commit stages only the archive/listsummary shows the archived count🤖 Generated with Claude Code