@ikon85/agent-workflow-kit 0.39.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -52,7 +52,7 @@ For a cross-cutting plan, run `python3 .claude/hooks/drift-guard.py --census-sta
52
52
 
53
53
  ## Plan-lock — writing PLAN.md
54
54
 
55
- Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root (gitignored since, doesn't travel over git — consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
55
+ Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root. `PLAN.md` is **expected** to be ignored by git so it never travels over git — the kit never edits your `.gitignore` by itself, but `/setup-workflow` offers to add that rule (consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
56
56
 
57
57
  ## Re-grill reconcile — execute-ready (Wave 26)
58
58
 
@@ -40,7 +40,7 @@ For a cross-cutting plan, run `python3 .claude/hooks/drift-guard.py --census-sta
40
40
 
41
41
  ## Plan-lock — writing PLAN.md
42
42
 
43
- Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root (gitignored since, doesn't travel over git — consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
43
+ Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root. `PLAN.md` is **expected** to be ignored by git so it never travels over git — the kit never edits your `.gitignore` by itself, but `/setup-workflow` offers to add that rule (consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
44
44
 
45
45
  </plan-lock>
46
46
 
@@ -146,8 +146,8 @@ replace the ~30-second heartbeat; otherwise the standing heartbeat remains requi
146
146
  points there). Bring its branch to current `main`:
147
147
  `git -C <wave> merge --ff-only origin/main` (if your repo guards destructive
148
148
  git, ff-merge is the safe path — not `reset --hard`). Install dependencies with
149
- your package manager after (the lockfile may have moved). A gitignored plan doc
150
- survives the merge.
149
+ your package manager after (the lockfile may have moved). A plan doc the repository
150
+ ignores survives the merge; a tracked one may not (`/setup-workflow` offers those rules).
151
151
  5. **Run project setup steps (`§Setup`)** the later verify needs — e.g. a DB
152
152
  tunnel or service the live-verify depends on. Absent layer → start whatever your
153
153
  live-verify environment requires before Phase 4.
@@ -332,8 +332,8 @@ written · merge order documented.
332
332
  - **Release this run's slice claims.** A landed slice's PR supersedes its claim;
333
333
  for a pulled or abandoned slice remove the claim this run planted (unassign +
334
334
  `claim released` comment) so it stays grabbable. Foreign ones stay untouched.
335
- - **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions
336
- log, gitignored at worktree-root) and propagate each build-time assumption marker
335
+ - **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions log at
336
+ the worktree root, **expected** to be ignored by git — `/setup-workflow` offers that rule) and propagate each build-time assumption marker
337
337
  to the sibling issue it carries. A hand-driven multi-PR / migration landing does
338
338
  NOT run `wrapup`'s assumption-propagation step — this is the only place it
339
339
  happens; `worktree remove` deletes the log.
@@ -37,6 +37,7 @@ This is a prompt-driven skill, not a deterministic script. Explore, present what
37
37
  | `docs/agents/workflow-capabilities.json` + capability assets | consumer-owned Worktree Lifecycle, Memory Lifecycle, Workflow Advisories, and Safety Guardrails choices (Sections A4–A7) |
38
38
  | `.claude/settings.json` | additive activation of the advisory kit-origin Edit/Write hint (Section A8) |
39
39
  | user-local routing profile | familiar agent surfaces + switching autonomy (Section A9; never package- or repository-owned) |
40
+ | `.gitignore` | **offered only** — one previewed, append-only marker block with the ignore rules for the planning artifacts the skills write (Section A11) |
40
41
 
41
42
  ## Idempotency contract — read before writing anything
42
43
 
@@ -405,6 +406,55 @@ machine, checkout path, repository name, credentials, or current GitHub login.
405
406
  Even a valid capability authorizes local preparation only; a pull request,
406
407
  push, publish, or merge remains a separate explicit approval.
407
408
 
409
+ ### 2j. Section A11 — Planning-artifact ignore rules (offered)
410
+
411
+ > The planning skills write `PLAN.md`, `PLAN-REVIEW-LOG.md`, and `ANNAHMEN.md`
412
+ > into a session worktree. `.gitignore` is the consumer's file: the kit does not
413
+ > own it and never touches it during `init` or `update`, so those artifacts are
414
+ > ignored only if this repository already says so. Without the rules every
415
+ > planning worktree reports a permanently dirty tree, the Worktree Lifecycle
416
+ > cleanup refuses to remove it, and a plan doc can be committed by accident.
417
+
418
+ Read the current state first. The preview is read-only and writes nothing:
419
+
420
+ ```bash
421
+ python3 scripts/worktree-lifecycle/ignore_seed.py preview
422
+ ```
423
+
424
+ - `nothing-to-do` — this repository already ignores every declared artifact.
425
+ Report it and ask nothing.
426
+ - `blocked` — the marker block exists but no longer covers everything. That
427
+ block is consumer-owned: name the uncovered artifacts, let the user edit
428
+ `.gitignore` themselves, and never repair or rewrite it.
429
+ - `append` — show the exact lines the preview printed, the whole marker block
430
+ verbatim and nothing summarized, then ask: *"Should setup add these ignore
431
+ rules to `.gitignore`?"*
432
+
433
+ Offer exactly two choices:
434
+
435
+ - **Add the rules** — run the seeder once. It appends that one marker block and
436
+ touches nothing else:
437
+
438
+ ```bash
439
+ python3 scripts/worktree-lifecycle/ignore_seed.py apply
440
+ ```
441
+
442
+ - **Not now** — write nothing. Explain that the planning skills still work, that
443
+ the artifacts will keep showing up as untracked changes, and that re-running
444
+ `/setup-workflow` offers this again.
445
+
446
+ The write is append-only inside one idempotent marker block: it never rewrites,
447
+ reorders, or removes an existing line; a re-run after an approval is a
448
+ byte-identical no-op; and a decline leaves the file exactly as it was. An
449
+ artifact already committed to history is reported separately — an ignore rule
450
+ cannot untrack it, and setup never runs `git rm`. Only this explicit, approved
451
+ step may write `.gitignore`; `init` and `update` reconciliation never reach the
452
+ seeder.
453
+
454
+ Report `appended · nothing to do (already ignored) · declined · blocked
455
+ (consumer-edited block)`. After an approval — and only then — the Section A4
456
+ `scratchPatterns` derivation has real ignored planning artefacts to read.
457
+
408
458
  ### 3. Section B — Triage labels
409
459
 
410
460
  > When `triage` processes an incoming issue it applies labels (or your tracker's equivalent). It needs strings you've actually configured, or it creates duplicates.
@@ -82,12 +82,34 @@ The exact kit-owned commands are:
82
82
  Preserve unrelated settings, hook groups, profile sections, and unknown keys.
83
83
  Repeated reconciliation with the same choice is byte-identical.
84
84
 
85
+ ## Planning-artifact ignore rules (offered, never installed)
86
+
87
+ The planning artefacts the shipped skills write live in the worktree, but
88
+ `.gitignore` is a consumer file the kit does not own: `init` and `update` never
89
+ touch it. Setup may therefore only **offer** the rules, from Section A11, using
90
+ `python3 scripts/worktree-lifecycle/ignore_seed.py`. The kit-owned declaration
91
+ of which artefacts those are is `scripts/worktree-lifecycle/plan-artifacts.json`.
92
+
93
+ | State | Setup action |
94
+ |---|---|
95
+ | `append` | Show the exact marker block, then ask. |
96
+ | approve | Run `ignore_seed.py apply` once: it appends that one block, append-only. |
97
+ | decline | Write nothing; a later rerun offers it again. |
98
+ | already ignored | Report `nothing to do`; ask nothing and write nothing. |
99
+ | re-run after approval | Byte-identical no-op; never a second block. |
100
+ | consumer-edited block | `blocked` — report the uncovered artefacts and leave the file untouched. |
101
+
102
+ The seeder never rewrites, reorders, or removes an existing line, and a tracked
103
+ artefact is reported rather than untracked for the consumer. Only this explicit,
104
+ approved step may write `.gitignore`.
105
+
85
106
  ## Scratch classification and sweep
86
107
 
87
108
  Reconcile an explicit `scratchPatterns` array when enabling a new profile.
88
109
  Derive its glob values from the consumer's ignored planning artefacts; an empty
89
110
  array is valid. Existing values are consumer-owned and remain byte-identical on
90
- adoption or rerun. Core never supplies filename defaults.
111
+ adoption or rerun. Core never supplies filename defaults — the offered ignore
112
+ rules above are what give that derivation something real to read.
91
113
 
92
114
  Also reconcile an explicit
93
115
  `wrapup.landingGeneratedArtifactPatterns` array. Derive candidates from the
@@ -52,7 +52,7 @@ For a cross-cutting plan, run `python3 .claude/hooks/drift-guard.py --census-sta
52
52
 
53
53
  ## Plan-lock — writing PLAN.md
54
54
 
55
- Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root (gitignored since, doesn't travel over git — consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
55
+ Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root. `PLAN.md` is **expected** to be ignored by git so it never travels over git — the kit never edits your `.gitignore` by itself, but `/setup-workflow` offers to add that rule (consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
56
56
 
57
57
  ## Re-grill reconcile — execute-ready (Wave 26)
58
58
 
@@ -40,7 +40,7 @@ For a cross-cutting plan, run `python3 .claude/hooks/drift-guard.py --census-sta
40
40
 
41
41
  ## Plan-lock — writing PLAN.md
42
42
 
43
- Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root (gitignored since, doesn't travel over git — consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
43
+ Once all decisions are made (plan locked, before sign-off/handoff) and the session runs in a **worktree** → write the locked plan as `PLAN.md` to the worktree root. `PLAN.md` is **expected** to be ignored by git so it never travels over git — the kit never edits your `.gitignore` by itself, but `/setup-workflow` offers to add that rule (consistent with CLAUDE.md "plan inside the worktree"). This way the locked plan survives a session cut and `to-prd` finds its default source. Continuing same-session work **without** a worktree stays allowed (conversation = source); but for a deliberate **session cut** before `to-prd`, `PLAN.md` is mandatory. (The `-codex` variant already writes `PLAN.md` anyway.)
44
44
 
45
45
  </plan-lock>
46
46
 
@@ -146,8 +146,8 @@ replace the ~30-second heartbeat; otherwise the standing heartbeat remains requi
146
146
  points there). Bring its branch to current `main`:
147
147
  `git -C <wave> merge --ff-only origin/main` (if your repo guards destructive
148
148
  git, ff-merge is the safe path — not `reset --hard`). Install dependencies with
149
- your package manager after (the lockfile may have moved). A gitignored plan doc
150
- survives the merge.
149
+ your package manager after (the lockfile may have moved). A plan doc the repository
150
+ ignores survives the merge; a tracked one may not (`/setup-workflow` offers those rules).
151
151
  5. **Run project setup steps (`§Setup`)** the later verify needs — e.g. a DB
152
152
  tunnel or service the live-verify depends on. Absent layer → start whatever your
153
153
  live-verify environment requires before Phase 4.
@@ -332,8 +332,8 @@ written · merge order documented.
332
332
  - **Release this run's slice claims.** A landed slice's PR supersedes its claim;
333
333
  for a pulled or abandoned slice remove the claim this run planted (unassign +
334
334
  `claim released` comment) so it stays grabbable. Foreign ones stay untouched.
335
- - **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions
336
- log, gitignored at worktree-root) and propagate each build-time assumption marker
335
+ - **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions log at
336
+ the worktree root, **expected** to be ignored by git — `/setup-workflow` offers that rule) and propagate each build-time assumption marker
337
337
  to the sibling issue it carries. A hand-driven multi-PR / migration landing does
338
338
  NOT run `wrapup`'s assumption-propagation step — this is the only place it
339
339
  happens; `worktree remove` deletes the log.
@@ -37,6 +37,7 @@ This is a prompt-driven skill, not a deterministic script. Explore, present what
37
37
  | `docs/agents/workflow-capabilities.json` + capability assets | consumer-owned Worktree Lifecycle, Memory Lifecycle, Workflow Advisories, and Safety Guardrails choices (Sections A4–A7) |
38
38
  | `.claude/settings.json` | additive activation of the advisory kit-origin Edit/Write hint (Section A8) |
39
39
  | user-local routing profile | familiar agent surfaces + switching autonomy (Section A9; never package- or repository-owned) |
40
+ | `.gitignore` | **offered only** — one previewed, append-only marker block with the ignore rules for the planning artifacts the skills write (Section A11) |
40
41
 
41
42
  ## Idempotency contract — read before writing anything
42
43
 
@@ -405,6 +406,55 @@ machine, checkout path, repository name, credentials, or current GitHub login.
405
406
  Even a valid capability authorizes local preparation only; a pull request,
406
407
  push, publish, or merge remains a separate explicit approval.
407
408
 
409
+ ### 2j. Section A11 — Planning-artifact ignore rules (offered)
410
+
411
+ > The planning skills write `PLAN.md`, `PLAN-REVIEW-LOG.md`, and `ANNAHMEN.md`
412
+ > into a session worktree. `.gitignore` is the consumer's file: the kit does not
413
+ > own it and never touches it during `init` or `update`, so those artifacts are
414
+ > ignored only if this repository already says so. Without the rules every
415
+ > planning worktree reports a permanently dirty tree, the Worktree Lifecycle
416
+ > cleanup refuses to remove it, and a plan doc can be committed by accident.
417
+
418
+ Read the current state first. The preview is read-only and writes nothing:
419
+
420
+ ```bash
421
+ python3 scripts/worktree-lifecycle/ignore_seed.py preview
422
+ ```
423
+
424
+ - `nothing-to-do` — this repository already ignores every declared artifact.
425
+ Report it and ask nothing.
426
+ - `blocked` — the marker block exists but no longer covers everything. That
427
+ block is consumer-owned: name the uncovered artifacts, let the user edit
428
+ `.gitignore` themselves, and never repair or rewrite it.
429
+ - `append` — show the exact lines the preview printed, the whole marker block
430
+ verbatim and nothing summarized, then ask: *"Should setup add these ignore
431
+ rules to `.gitignore`?"*
432
+
433
+ Offer exactly two choices:
434
+
435
+ - **Add the rules** — run the seeder once. It appends that one marker block and
436
+ touches nothing else:
437
+
438
+ ```bash
439
+ python3 scripts/worktree-lifecycle/ignore_seed.py apply
440
+ ```
441
+
442
+ - **Not now** — write nothing. Explain that the planning skills still work, that
443
+ the artifacts will keep showing up as untracked changes, and that re-running
444
+ `/setup-workflow` offers this again.
445
+
446
+ The write is append-only inside one idempotent marker block: it never rewrites,
447
+ reorders, or removes an existing line; a re-run after an approval is a
448
+ byte-identical no-op; and a decline leaves the file exactly as it was. An
449
+ artifact already committed to history is reported separately — an ignore rule
450
+ cannot untrack it, and setup never runs `git rm`. Only this explicit, approved
451
+ step may write `.gitignore`; `init` and `update` reconciliation never reach the
452
+ seeder.
453
+
454
+ Report `appended · nothing to do (already ignored) · declined · blocked
455
+ (consumer-edited block)`. After an approval — and only then — the Section A4
456
+ `scratchPatterns` derivation has real ignored planning artefacts to read.
457
+
408
458
  ### 3. Section B — Triage labels
409
459
 
410
460
  > When `triage` processes an incoming issue it applies labels (or your tracker's equivalent). It needs strings you've actually configured, or it creates duplicates.
@@ -82,12 +82,34 @@ The exact kit-owned commands are:
82
82
  Preserve unrelated settings, hook groups, profile sections, and unknown keys.
83
83
  Repeated reconciliation with the same choice is byte-identical.
84
84
 
85
+ ## Planning-artifact ignore rules (offered, never installed)
86
+
87
+ The planning artefacts the shipped skills write live in the worktree, but
88
+ `.gitignore` is a consumer file the kit does not own: `init` and `update` never
89
+ touch it. Setup may therefore only **offer** the rules, from Section A11, using
90
+ `python3 scripts/worktree-lifecycle/ignore_seed.py`. The kit-owned declaration
91
+ of which artefacts those are is `scripts/worktree-lifecycle/plan-artifacts.json`.
92
+
93
+ | State | Setup action |
94
+ |---|---|
95
+ | `append` | Show the exact marker block, then ask. |
96
+ | approve | Run `ignore_seed.py apply` once: it appends that one block, append-only. |
97
+ | decline | Write nothing; a later rerun offers it again. |
98
+ | already ignored | Report `nothing to do`; ask nothing and write nothing. |
99
+ | re-run after approval | Byte-identical no-op; never a second block. |
100
+ | consumer-edited block | `blocked` — report the uncovered artefacts and leave the file untouched. |
101
+
102
+ The seeder never rewrites, reorders, or removes an existing line, and a tracked
103
+ artefact is reported rather than untracked for the consumer. Only this explicit,
104
+ approved step may write `.gitignore`.
105
+
85
106
  ## Scratch classification and sweep
86
107
 
87
108
  Reconcile an explicit `scratchPatterns` array when enabling a new profile.
88
109
  Derive its glob values from the consumer's ignored planning artefacts; an empty
89
110
  array is valid. Existing values are consumer-owned and remain byte-identical on
90
- adoption or rerun. Core never supplies filename defaults.
111
+ adoption or rerun. Core never supplies filename defaults — the offered ignore
112
+ rules above are what give that derivation something real to read.
91
113
 
92
114
  Also reconcile an explicit
93
115
  `wrapup.landingGeneratedArtifactPatterns` array. Derive candidates from the
package/README.md CHANGED
@@ -469,6 +469,39 @@ the old way. Decision record:
469
469
 
470
470
  ## Release notes
471
471
 
472
+ ### 0.41.0
473
+
474
+ - added: `docs/adr/0009-teardown-authority-is-stateless-repository-classification.md`
475
+ - changed: `agent-workflow-kit.package.json`
476
+ - changed: `docs/adr/0007-session-teardown-requires-provenance-bound-ownership.md`
477
+ - changed: `scripts/pr-body-check.py`
478
+ - changed: `scripts/test_pr_body_check.py`
479
+
480
+ ### 0.40.0 — planning ignore rules are offered, never installed
481
+
482
+ Nothing in this release requires a consumer action. `kit-update` reconciles it.
483
+
484
+ Several skills used to state as fact that `PLAN.md`, `PLAN-REVIEW-LOG.md` and
485
+ `ANNAHMEN.md` are gitignored and live on disk only. In your repository that was
486
+ simply untrue: neither `init` nor `update` has ever touched your `.gitignore`,
487
+ and no installed file added those rules — so planning worktrees looked
488
+ permanently dirty, cleanup refused to remove them, and a plan document could be
489
+ committed by accident.
490
+
491
+ - **The prose is honest now.** The affected skills say the artifacts are
492
+ *expected* to be ignored and name who can add the rule, instead of asserting
493
+ an installed guarantee.
494
+ - **`/setup-workflow` offers the rules.** It previews the exact lines, asks
495
+ first, and appends one idempotent marker block. Declining changes nothing; a
496
+ re-run is a byte-identical no-op; a block you edited yourself is reported, not
497
+ repaired; an artifact already tracked by git is reported separately, because
498
+ an ignore rule cannot untrack it.
499
+ - **`.gitignore` stays yours.** It has no manifest entry, no baseline hash and
500
+ no three-way reconcile — a file the kit cannot reconcile is one it must not
501
+ write uninvited. Ordinary `update` reconciliation never reaches the seeder.
502
+ Decision record:
503
+ [`docs/adr/0008-planning-ignore-rules-are-offered-never-installed.md`](docs/adr/0008-planning-ignore-rules-are-offered-never-installed.md).
504
+
472
505
  ### 0.39.0 — self-explaining guards, one glob dialect, a board you can create
473
506
 
474
507
  Nothing in this release requires a consumer action. `kit-update` reconciles it.
@@ -1,5 +1,5 @@
1
1
  {
2
- "kitVersion": "0.39.0",
2
+ "kitVersion": "0.41.0",
3
3
  "files": [
4
4
  {
5
5
  "path": ".agents/skills/ask-matt/SKILL.md",
@@ -207,7 +207,7 @@
207
207
  "ownerSkill": "grill-me",
208
208
  "surface": "codex",
209
209
  "installRole": "consumer",
210
- "sha256": "e106dbb6f62415cc5eef7d923d864a30e75e108a079d12c0f1624ef7d03d6f6d",
210
+ "sha256": "b13087563adda186f62aa6206a9233034310ff2458535362246294a45e03079f",
211
211
  "mode": 420,
212
212
  "origin": "kit"
213
213
  },
@@ -247,7 +247,7 @@
247
247
  "ownerSkill": "grill-with-docs",
248
248
  "surface": "codex",
249
249
  "installRole": "consumer",
250
- "sha256": "5616f15e6660270f9f84fba245caa647c47d8af8dc9e526045bb503e7f1f5863",
250
+ "sha256": "93694d55fe8d164c4c0e0eef27529bd1211acdaddc18224a921c2b0f3b5a10ed",
251
251
  "mode": 420,
252
252
  "origin": "kit"
253
253
  },
@@ -447,7 +447,7 @@
447
447
  "ownerSkill": "orchestrate-wave",
448
448
  "surface": "codex",
449
449
  "installRole": "consumer",
450
- "sha256": "02862cd5e7e07a5f06dad89792fcebd0a6c17cf2216a27c7e0f724026fdda53a",
450
+ "sha256": "fab4fb2f4d6fee820c9b7a737fa955a5ea2cd398987246bd7a04c5fba2c75b26",
451
451
  "mode": 420,
452
452
  "origin": "kit"
453
453
  },
@@ -687,7 +687,7 @@
687
687
  "ownerSkill": "setup-workflow",
688
688
  "surface": "codex",
689
689
  "installRole": "consumer",
690
- "sha256": "4ef2a06e17e08f0fc0c5cc09e4414af67a186a73ca7634e8c378aab5b5638274",
690
+ "sha256": "29c61411aa42a3f456b3f27fdd15552654b64ef2d72b321bc9c9e11229745626",
691
691
  "mode": 420,
692
692
  "origin": "kit"
693
693
  },
@@ -757,7 +757,7 @@
757
757
  "ownerSkill": "setup-workflow",
758
758
  "surface": "codex",
759
759
  "installRole": "consumer",
760
- "sha256": "bf68e0a80b212159f6838bc2bcd3e85714a70cceeff55ed019f87246175182e7",
760
+ "sha256": "f9fb7ef6d4f4e1ed603a5a480d8f97508fd6c99def8194c7ba0a95c62fd3c743",
761
761
  "mode": 420,
762
762
  "origin": "kit"
763
763
  },
@@ -1489,7 +1489,7 @@
1489
1489
  "ownerSkill": "grill-me",
1490
1490
  "surface": "claude",
1491
1491
  "installRole": "consumer",
1492
- "sha256": "ec8d9f299db153a0412b7ef1d01832dc6a765f1819713ca45dc64294541cf9d4",
1492
+ "sha256": "a63331339ed4e018d770face4e7cfe483225ce758a4a1302f39a50239e8187e1",
1493
1493
  "mode": 420,
1494
1494
  "origin": "kit"
1495
1495
  },
@@ -1569,7 +1569,7 @@
1569
1569
  "ownerSkill": "grill-with-docs",
1570
1570
  "surface": "claude",
1571
1571
  "installRole": "consumer",
1572
- "sha256": "a17521a8d72eb19316c6adb21837e790c9839834ff441abf3ff44d8e1f63809a",
1572
+ "sha256": "0cb1b41fc6bde94d3e71f3377cbb15b9d7a9a4089df66f591fc907dc19b6c1b5",
1573
1573
  "mode": 420,
1574
1574
  "origin": "kit"
1575
1575
  },
@@ -1769,7 +1769,7 @@
1769
1769
  "ownerSkill": "orchestrate-wave",
1770
1770
  "surface": "claude",
1771
1771
  "installRole": "consumer",
1772
- "sha256": "02862cd5e7e07a5f06dad89792fcebd0a6c17cf2216a27c7e0f724026fdda53a",
1772
+ "sha256": "fab4fb2f4d6fee820c9b7a737fa955a5ea2cd398987246bd7a04c5fba2c75b26",
1773
1773
  "mode": 420,
1774
1774
  "origin": "kit"
1775
1775
  },
@@ -2029,7 +2029,7 @@
2029
2029
  "ownerSkill": "setup-workflow",
2030
2030
  "surface": "claude",
2031
2031
  "installRole": "consumer",
2032
- "sha256": "4ef2a06e17e08f0fc0c5cc09e4414af67a186a73ca7634e8c378aab5b5638274",
2032
+ "sha256": "29c61411aa42a3f456b3f27fdd15552654b64ef2d72b321bc9c9e11229745626",
2033
2033
  "mode": 420,
2034
2034
  "origin": "kit"
2035
2035
  },
@@ -2099,7 +2099,7 @@
2099
2099
  "ownerSkill": "setup-workflow",
2100
2100
  "surface": "claude",
2101
2101
  "installRole": "consumer",
2102
- "sha256": "bf68e0a80b212159f6838bc2bcd3e85714a70cceeff55ed019f87246175182e7",
2102
+ "sha256": "f9fb7ef6d4f4e1ed603a5a480d8f97508fd6c99def8194c7ba0a95c62fd3c743",
2103
2103
  "mode": 420,
2104
2104
  "origin": "kit"
2105
2105
  },
@@ -2627,7 +2627,7 @@
2627
2627
  "path": "scripts/pr-body-check.py",
2628
2628
  "kind": "script",
2629
2629
  "installRole": "consumer",
2630
- "sha256": "864dad50be7904cf0c1d70956352c70d2195a350a5a6875de6b866c494f16612",
2630
+ "sha256": "7fa67a672d6f6986b0fba99e78157d51225ab91f61b691a4cc184d316b521882",
2631
2631
  "mode": 493,
2632
2632
  "origin": "kit"
2633
2633
  },
@@ -2815,6 +2815,22 @@
2815
2815
  "mode": 420,
2816
2816
  "origin": "kit"
2817
2817
  },
2818
+ {
2819
+ "path": "scripts/worktree-lifecycle/ignore_seed.py",
2820
+ "kind": "script",
2821
+ "installRole": "consumer",
2822
+ "sha256": "defd667ed94301cffb0f08e0a910873c246be267cb458adf40f5e7b2109ae4d0",
2823
+ "mode": 493,
2824
+ "origin": "kit"
2825
+ },
2826
+ {
2827
+ "path": "scripts/worktree-lifecycle/plan-artifacts.json",
2828
+ "kind": "doc",
2829
+ "installRole": "consumer",
2830
+ "sha256": "fe7f805ca9c698f9d77bdda4372f6f5a516b1e60c46ae732a94de184cb0ce3b4",
2831
+ "mode": 420,
2832
+ "origin": "kit"
2833
+ },
2818
2834
  {
2819
2835
  "path": "scripts/worktree-lifecycle/profile.py",
2820
2836
  "kind": "script",
@@ -2827,7 +2843,7 @@
2827
2843
  "path": "scripts/worktree-lifecycle/README.md",
2828
2844
  "kind": "doc",
2829
2845
  "installRole": "consumer",
2830
- "sha256": "91cfa8ebb74872ccec1160c0a7b28edcfacea3217900805034dca0f0c8f39c05",
2846
+ "sha256": "0dbba4a87d41171f3fce22a4842eecd2a989ea6a5ddf44832d7b2aed9feb4226",
2831
2847
  "mode": 420,
2832
2848
  "origin": "kit"
2833
2849
  },
@@ -1,6 +1,6 @@
1
1
  # Session teardown requires provenance-bound ownership
2
2
 
3
- Status: accepted (2026-07-26, Wave #271)
3
+ Status: superseded by [ADR-0009](./0009-teardown-authority-is-stateless-repository-classification.md) (2026-07-27, #320)
4
4
 
5
5
  Long agent sessions create branches, linked worktrees, setup outputs, and
6
6
  landing-time build artifacts. The desired end state is that every
@@ -0,0 +1,84 @@
1
+ # Planning ignore rules are offered, never installed
2
+
3
+ Status: accepted (2026-07-26, #255)
4
+
5
+ The shipped planning skills write `PLAN.md`, `PLAN-REVIEW-LOG.md`, and
6
+ `ANNAHMEN.md` into a session worktree, and several of them told the agent those
7
+ files were gitignored and lived on disk only. In a consumer repository that was
8
+ simply untrue: `init` and `update` never touch `.gitignore`, and no installed
9
+ file adds the rules. The consequence mirrors what this repository fixed for
10
+ itself in #254 — every planning worktree reports a permanently dirty tree, the
11
+ shipped Worktree Lifecycle cleanup refuses to remove it, genuinely unlanded work
12
+ becomes indistinguishable from plan scratch, and a consumer who never notices
13
+ can commit a plan doc into their history that the prose implied could not be
14
+ committed.
15
+
16
+ The constraint is the consumer contract. Consumer-owned files are written once
17
+ and never overwritten by ordinary reconciliation, and `.gitignore` is stronger
18
+ still: the kit does not own it at all and has no manifest entry, no baseline
19
+ hash, and no three-way reconcile for it. A file the kit cannot reconcile is a
20
+ file the kit must not write uninvited.
21
+
22
+ We decided to close the gap from both ends:
23
+
24
+ 1. **`/setup-workflow` offers the rules as an explicit, previewed, approved
25
+ step.** Section A11 previews with
26
+ `python3 scripts/worktree-lifecycle/ignore_seed.py preview`, shows the exact
27
+ lines verbatim, asks, and only an approval runs `apply`. The write is
28
+ append-only inside one idempotent marker block. It never rewrites, reorders,
29
+ or removes an existing line; a re-run is a byte-identical no-op; a decline
30
+ changes nothing; a repository that already ignores the artefacts reports
31
+ `nothing to do`; and a marker block the consumer has since edited is
32
+ `blocked`, never repaired. Nothing in `init` or `update` can reach the
33
+ seeder.
34
+ 2. **Shipped skill prose states the assumption instead of asserting the fact.**
35
+ A skill now says these artefacts are *expected* to be ignored and names
36
+ `/setup-workflow` as the thing that can make it true, rather than claiming
37
+ the kit already did. The claim is pinned by a census lint over both skill
38
+ trees, so the assertion cannot silently return.
39
+
40
+ This is the same shape the kit shipped for the GitHub-Projects board in 0.39.0
41
+ (#24): offer, preview, obtain an explicit yes, never write an outward or
42
+ consumer-owned artefact silently.
43
+
44
+ Which artefacts the offer covers is a kit-owned fact — the kit knows which files
45
+ its own skills write — declared once in
46
+ `scripts/worktree-lifecycle/plan-artifacts.json`. That is deliberately not the
47
+ consumer's `worktreeLifecycle.scratchPatterns`, which is derived *from* the
48
+ consumer's ignored planning artefacts and would otherwise be circular: before
49
+ this decision there was nothing ignored for it to be derived from.
50
+
51
+ ## Considered options
52
+
53
+ - **Append-only seed at `init`:** rejected. It respects append-only mechanics
54
+ but still writes a file the kit does not own, uninvited, on first install —
55
+ the one action the consumer contract exists to prevent.
56
+ - **Readiness capability only:** rejected. Reporting the gap and letting the
57
+ affected skills degrade honestly leaves the friction in place and fixes
58
+ nothing for the consumer who wants the promise to hold.
59
+ - **Prose-only fix:** rejected as insufficient on its own. It removes the false
60
+ claim but leaves every consumer with dirty planning worktrees and a cleanup
61
+ that refuses to run. It is kept as one half of the decision, not the whole.
62
+ - **Deriving the rules from `worktreeLifecycle.scratchPatterns`:** rejected as
63
+ circular, and because that array is consumer-owned deletion-adjacent policy
64
+ that Core never supplies defaults for.
65
+ - **Untracking an already-committed artefact:** rejected. An ignore rule cannot
66
+ untrack a tracked file, and running `git rm` on consumer history is far past
67
+ what a setup step may do. The seeder reports the tracked artefact and stops.
68
+
69
+ ## Consequences
70
+
71
+ - A consumer who runs `/setup-workflow` and approves gets the guarantee the
72
+ skills describe; a consumer who declines keeps a byte-identical `.gitignore`
73
+ and loses nothing but the convenience.
74
+ - The never-overwrite contract is untouched: the only write is an append behind
75
+ an explicit yes, and `update` reconciliation still never touches
76
+ `.gitignore`.
77
+ - The offer reaches only consumers who run setup again. That is accepted: it is
78
+ the price of not writing an unowned file, and re-running `/setup-workflow` is
79
+ already the documented way to pick up a new project-layer capability.
80
+ - After an approval, `scratchPatterns` derivation finally has real ignored
81
+ planning artefacts to read, so the Worktree Lifecycle scratch classification
82
+ stops being vacuous in a fresh consumer repository.
83
+ - A consumer who edits or deletes the marker block owns the outcome; the kit
84
+ reports and stops rather than restoring its own block.