@ikon85/agent-workflow-kit 0.43.0 → 0.44.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.
Files changed (126) hide show
  1. package/.agents/skills/grill-me/SKILL.md +3 -1
  2. package/.agents/skills/grill-with-docs/SKILL.md +3 -1
  3. package/.agents/skills/kit-update/SKILL.md +9 -11
  4. package/.agents/skills/orchestrate-wave/SKILL.md +8 -8
  5. package/.agents/skills/setup-workflow/SKILL.md +20 -18
  6. package/.agents/skills/setup-workflow/board-sync.md +4 -1
  7. package/.agents/skills/setup-workflow/workflow-advisories.md +3 -2
  8. package/.agents/skills/setup-workflow/worktree-lifecycle.md +36 -31
  9. package/.agents/skills/to-issues/SKILL.md +43 -0
  10. package/.agents/skills/wrapup/SKILL.md +98 -54
  11. package/.claude/skills/grill-me/SKILL.md +3 -1
  12. package/.claude/skills/grill-me-codex/SKILL.md +3 -1
  13. package/.claude/skills/grill-with-docs/SKILL.md +3 -1
  14. package/.claude/skills/grill-with-docs-codex/SKILL.md +3 -1
  15. package/.claude/skills/kit-update/SKILL.md +9 -11
  16. package/.claude/skills/orchestrate-wave/SKILL.md +8 -8
  17. package/.claude/skills/setup-workflow/SKILL.md +20 -18
  18. package/.claude/skills/setup-workflow/board-sync.md +4 -1
  19. package/.claude/skills/setup-workflow/workflow-advisories.md +3 -2
  20. package/.claude/skills/setup-workflow/worktree-lifecycle.md +36 -31
  21. package/.claude/skills/to-issues/SKILL.md +43 -0
  22. package/.claude/skills/wrapup/SKILL.md +98 -54
  23. package/README.md +249 -7
  24. package/agent-workflow-kit.package.json +42 -42
  25. package/package.json +16 -12
  26. package/scripts/marker_lib.py +3 -0
  27. package/scripts/profile_globs.py +26 -45
  28. package/scripts/release-delta-guard.mjs +26 -9
  29. package/scripts/worktree-lifecycle/README.md +57 -160
  30. package/scripts/worktree-lifecycle/capabilities.json +2 -3
  31. package/scripts/worktree-lifecycle/classify.py +480 -0
  32. package/scripts/worktree-lifecycle/cleanup.py +9 -29
  33. package/scripts/worktree-lifecycle/core.py +68 -1429
  34. package/scripts/worktree-lifecycle/ignore_seed.py +1 -1
  35. package/scripts/worktree-lifecycle/profile.py +46 -29
  36. package/scripts/worktree-lifecycle/setup.py +7 -19
  37. package/scripts/wrapup-land.py +1292 -545
  38. package/src/consumer-migrations.json +1 -16
  39. package/src/lib/bundle.mjs +31 -1
  40. package/docs/adr/0001-consumer-divergence-policy.md +0 -53
  41. package/docs/adr/0002-capability-gated-orchestration.md +0 -70
  42. package/docs/adr/0003-kit-core-and-project-extension-lifecycle.md +0 -63
  43. package/docs/adr/0004-release-intent-is-a-version-tag.md +0 -64
  44. package/docs/adr/0005-to-issues-is-the-planning-facade.md +0 -42
  45. package/docs/adr/0006-routing-knowledge-access-and-policy-are-separate.md +0 -95
  46. package/docs/adr/0007-session-teardown-requires-provenance-bound-ownership.md +0 -88
  47. package/docs/adr/0008-planning-ignore-rules-are-offered-never-installed.md +0 -84
  48. package/docs/adr/0009-teardown-authority-is-stateless-repository-classification.md +0 -101
  49. package/docs/adr/0010-model-roster-replaces-the-optimization-dial.md +0 -87
  50. package/docs/agents/board-sync.md +0 -74
  51. package/docs/agents/code-review.md +0 -14
  52. package/docs/agents/workflow-capabilities.json +0 -28
  53. package/docs/research/agent-task-taxonomy-benchmark-coverage.md +0 -451
  54. package/docs/research/benchlm-routing-source.md +0 -198
  55. package/docs/research/consumer-owned-protocol-files.md +0 -238
  56. package/docs/research/frontend-agent-benchmarks.md +0 -282
  57. package/docs/research/model-effort-routing-benchmarks.md +0 -261
  58. package/docs/research/provider-neutral-agent-routing.md +0 -207
  59. package/docs/research/wave-152-consumer-acceptance.md +0 -98
  60. package/docs/research/wave-43-script-hook-census.md +0 -128
  61. package/scripts/build-kit.mjs +0 -117
  62. package/scripts/build-kit.test.mjs +0 -207
  63. package/scripts/census/census.test.mjs +0 -252
  64. package/scripts/census/state.test.mjs +0 -15
  65. package/scripts/census/transaction.test.mjs +0 -103
  66. package/scripts/census-contract.test.mjs +0 -227
  67. package/scripts/check-kit-staleness.mjs +0 -45
  68. package/scripts/check-kit-staleness.test.mjs +0 -19
  69. package/scripts/codex-exec-scenarios/fake-codex.mjs +0 -165
  70. package/scripts/codex-exec.test.mjs +0 -871
  71. package/scripts/grill-census-wiring-guard.mjs +0 -87
  72. package/scripts/grill-census-wiring-guard.test.mjs +0 -107
  73. package/scripts/kit-release.test.mjs +0 -273
  74. package/scripts/kit-update-pr.test.mjs +0 -151
  75. package/scripts/lib/audit-refs.mjs +0 -146
  76. package/scripts/lib/scrub.mjs +0 -113
  77. package/scripts/lib/scrub.test.mjs +0 -187
  78. package/scripts/memory-lifecycle/memory-lifecycle.test.mjs +0 -170
  79. package/scripts/portability_profile_scan.py +0 -53
  80. package/scripts/release-delta-guard.test.mjs +0 -174
  81. package/scripts/release-parity.test.mjs +0 -90
  82. package/scripts/release-state.test.mjs +0 -360
  83. package/scripts/test_anchor_table.py +0 -69
  84. package/scripts/test_board_bootstrap.py +0 -348
  85. package/scripts/test_board_sync.py +0 -208
  86. package/scripts/test_board_sync_create_idempotency.py +0 -117
  87. package/scripts/test_board_sync_wave_title.py +0 -120
  88. package/scripts/test_census_backstop.py +0 -712
  89. package/scripts/test_census_forward_contract.py +0 -91
  90. package/scripts/test_census_update_contract.test.mjs +0 -454
  91. package/scripts/test_codex_adapter_sync_contract.py +0 -169
  92. package/scripts/test_dist_kit_smoke.py +0 -220
  93. package/scripts/test_drift_guard_diagnostics.py +0 -295
  94. package/scripts/test_issue_claim_contract.py +0 -169
  95. package/scripts/test_kit_docs_language_census.py +0 -178
  96. package/scripts/test_marker_lib.py +0 -162
  97. package/scripts/test_orchestrate_wave_contract.py +0 -381
  98. package/scripts/test_pr_body_check.py +0 -264
  99. package/scripts/test_profile_globs.py +0 -280
  100. package/scripts/test_program_planning_contract.py +0 -133
  101. package/scripts/test_release_authorization_contract.py +0 -101
  102. package/scripts/test_render_anchor.py +0 -267
  103. package/scripts/test_retro_wrapup_contract.py +0 -153
  104. package/scripts/test_skill_code_review_seed.py +0 -89
  105. package/scripts/test_skill_codex_exec_lifecycle.py +0 -123
  106. package/scripts/test_skill_frontmatter_lint.py +0 -234
  107. package/scripts/test_skill_gh_lint.py +0 -124
  108. package/scripts/test_skill_language_census.py +0 -254
  109. package/scripts/test_skill_optional_readiness.py +0 -171
  110. package/scripts/test_skill_portability_lint.py +0 -866
  111. package/scripts/test_skill_precommit_template.py +0 -30
  112. package/scripts/test_skill_publish_audit.py +0 -358
  113. package/scripts/test_skill_readiness_contract.py +0 -264
  114. package/scripts/test_skill_readiness_preflight.py +0 -180
  115. package/scripts/test_skill_required_readiness.py +0 -233
  116. package/scripts/test_skill_selfcontainment_lint.py +0 -255
  117. package/scripts/test_skill_setup_workflow_seeds.py +0 -691
  118. package/scripts/test_skill_stale_name_lint.py +0 -126
  119. package/scripts/test_skill_surface_refs.py +0 -300
  120. package/scripts/test_skill_trailing_artifact_lint.py +0 -71
  121. package/scripts/test_tdd_contract.py +0 -78
  122. package/scripts/test_worktree_ignore_seed.py +0 -320
  123. package/scripts/test_worktree_setup_base_guard.py +0 -140
  124. package/scripts/test_worktree_wrapup_contract.py +0 -1737
  125. package/scripts/test_wrapup_land.py +0 -428
  126. package/scripts/worktree-lifecycle/session.py +0 -1857
@@ -1,19 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "migrations": [
4
- {
5
- "id": "wrapup-landing-artifact-policy",
6
- "requiredFrom": "0.38.0",
7
- "title": "Explicit landing-artifact policy",
8
- "workflow": "setup-workflow",
9
- "decision": "wrapup.landingGeneratedArtifactPatterns",
10
- "detect": {
11
- "type": "json-key",
12
- "path": "docs/agents/workflow-capabilities.json",
13
- "key": ["wrapup", "landingGeneratedArtifactPatterns"]
14
- },
15
- "consequence": "wrapup-land fails closed before landing until the decision is committed.",
16
- "remediation": "Run setup-workflow, review the wrapup.landingGeneratedArtifactPatterns decision it writes into docs/agents/workflow-capabilities.json, and commit that profile change. kit-update never chooses cleanup patterns for you."
17
- }
18
- ]
3
+ "migrations": []
19
4
  }
@@ -144,7 +144,7 @@ export const HELPER_FILES = [
144
144
  { path: 'scripts/worktree-lifecycle/profile.py', kind: 'script', mode: 0o644 },
145
145
  { path: 'scripts/worktree-lifecycle/setup.py', kind: 'script', mode: 0o755 },
146
146
  { path: 'scripts/worktree-lifecycle/cleanup.py', kind: 'script', mode: 0o755 },
147
- { path: 'scripts/worktree-lifecycle/session.py', kind: 'script', mode: 0o755 },
147
+ { path: 'scripts/worktree-lifecycle/classify.py', kind: 'script', mode: 0o644 },
148
148
  { path: 'scripts/worktree-lifecycle/capabilities.json', kind: 'doc', mode: 0o644 },
149
149
  { path: 'scripts/worktree-lifecycle/README.md', kind: 'doc', mode: 0o644 },
150
150
  // Offered planning-artifact ignore rules for /setup-workflow Section A11.
@@ -232,6 +232,36 @@ export const STUB_TARGETS = [
232
232
  'docs/conventions/spec-completeness.md',
233
233
  ];
234
234
 
235
+ /**
236
+ * Source paths `package.json:"files"` deliberately keeps out of the npm payload:
237
+ * test sources, the build-time tooling that materializes `dist-kit/`, and this
238
+ * repository's own maintainer documentation and project layer. None of them is
239
+ * an install-manifest entry and nothing resolves them from an installed kit, so
240
+ * a removal here narrows the publish scope rather than breaking a consumer —
241
+ * the release guard classifies it accordingly. Kept in sync with that `"files"`
242
+ * field, and asserted against the real tarball by the publish-scope audit.
243
+ */
244
+ export const PUBLISH_EXCLUDED_FILES = [
245
+ 'scripts/build-kit.mjs',
246
+ 'scripts/check-kit-staleness.mjs',
247
+ 'scripts/grill-census-wiring-guard.mjs',
248
+ 'scripts/portability_profile_scan.py',
249
+ 'docs/agents/board-sync.md',
250
+ 'docs/agents/code-review.md',
251
+ 'docs/agents/workflow-capabilities.json',
252
+ ];
253
+
254
+ const PUBLISH_EXCLUDED_PATTERNS = [
255
+ /\.test\.mjs$/,
256
+ /(^|\/)test_[^/]+\.py$/,
257
+ /^scripts\/codex-exec-scenarios\//,
258
+ /^scripts\/lib\//,
259
+ /^docs\/(adr|research)\//,
260
+ ];
261
+
262
+ export const isPublishExcluded = (path) => PUBLISH_EXCLUDED_FILES.includes(path)
263
+ || PUBLISH_EXCLUDED_PATTERNS.some((pattern) => pattern.test(path));
264
+
235
265
  const SURFACE_DIR = { claude: '.claude/skills', codex: '.agents/skills' };
236
266
 
237
267
  /** Skills with publish:true, each with the surfaces it installs into. */
@@ -1,53 +0,0 @@
1
- # Consumer divergence policy: clean shipped files, owned exceptions, upstream route as a question
2
-
3
- Status: accepted (2026-07-18, issue #130)
4
-
5
- Partially superseded by ADR-0003: consumer ownership remains valid for genuine
6
- project files, but no longer applies to Kit Core or to mixed core/extension
7
- registries.
8
-
9
- Since the consumer-source cutover the kit is SSOT for shipped files, but
10
- consumers keep learning: edits made directly on a shipped file in a consumer
11
- silently fork it, and every subsequent `kit-update` reports a permanent
12
- conflict (observed: 6 recurring conflicts in testreporter on 0.27.1).
13
-
14
- We decided on a three-part policy:
15
-
16
- 1. **Clean shipped files.** A kit-shipped file in a consumer carries no
17
- project-specific content — including no project issue references in
18
- comments. Generic improvements are ported upstream (reference-free,
19
- English) and return via `kit-update`; project-specific needs live in
20
- consumer-native files or consumer-owned paths.
21
- 2. **Consumer-owned paths as the marked exception.** A consumer may claim a
22
- genuinely forking file via `own <path>` (manifest `origin: 'consumer'`).
23
- The reconciler then skips it entirely: no overwrite, no conflict report, no
24
- deletion prompt. The cost — forgoing all future kit improvements to that
25
- file — is deliberate and made visible on demand via `diff --owned`, never
26
- as warning noise in normal updates.
27
- 3. **Upstream route as a question.** When a shipped file is about to be
28
- edited in a consumer (retro finding or direct edit), the shipped rule asks
29
- the user whether the change should go upstream as a kit issue
30
- (`gh issue create --repo iKon85/agent-workflow-kit`, lightweight: title +
31
- short body). It never assumes the user is the kit maintainer and never
32
- files automatically.
33
-
34
- ## Considered options
35
-
36
- - **`own` for mixed scripts too** (e.g. `scripts/board-sync.py` with both
37
- generic timeout fixes and project issue-reference comments): rejected —
38
- owning the kit's most active script means no upstream fix ever reaches it
39
- again.
40
- - **Accepting perpetual conflicts**: rejected — that is exactly the noise
41
- this policy removes; conflict reports must stay meaningful.
42
- - **Routing rule in the maintainer's global config or a standalone
43
- convention doc**: rejected — the rule must ship with the kit (retro skill,
44
- kit-update skill, enforcement hook) so it reaches every consumer,
45
- versioned, including consumers not run by the maintainer.
46
-
47
- ## Consequences
48
-
49
- - Consumers lose the habit of annotating shipped scripts with their own
50
- issue numbers; provenance for shipped files lives in the kit's history.
51
- - The reconciler gains an `own`/`disown` surface and a `consumerOwned`
52
- report bucket; owned files fall permanently behind the kit unless
53
- explicitly disowned after a peek.
@@ -1,70 +0,0 @@
1
- # Capability-gated orchestration: scripted-workflow / native-subagents / direct, fail-closed, no emulation
2
-
3
- Status: accepted (2026-07-22, issue #167)
4
-
5
- `orchestrate-wave` fans out recon and building across agents. The mechanic that
6
- performs that fan-out is not the same on every host: one host exposes a scripted
7
- workflow runtime, another exposes native subagent spawn/wait primitives, a third
8
- exposes neither. The skill ships from one body for both surfaces, so the mechanic
9
- cannot be baked into the prose — and a wrong guess is expensive, because a wave
10
- that half-dispatches leaves worktrees and branches behind.
11
-
12
- We decided to select the mechanic from **proven, host-supplied capability
13
- evidence**, never from a surface name and never from the model's own belief
14
- about what it can call.
15
-
16
- 1. **A capability matrix over normalized tool entries.** The host supplies an
17
- inventory; `capabilityAdapter.claude` / `.codex` only normalize what was
18
- handed to them and perform no ambient discovery. Each entry carries
19
- `callable`, `permitted`, a schema, and `capabilities: string[] | "unknown"`.
20
- `classifyCapabilities` returns exactly one of three paths, and
21
- `selectOrchestrationReference` returns one discriminated target: a reference
22
- path for A and B, the inline marker for C.
23
- 2. **Fail closed, A → B → C.** Missing or `unknown` evidence never proves a
24
- capability. Path A additionally requires the *literal* tool name plus every
25
- named primitive individually proven; Path B requires proven spawn, wait, and
26
- aggregate plus effective concurrency and thread capacity ≥2. Anything short
27
- of that degrades to Path C — direct, serial, in the main thread — which is
28
- always available.
29
- 3. **Never emulate a missing primitive.** A host without a scripted workflow
30
- runtime does not get a hand-rolled imitation of one. The degraded path is a
31
- different, simpler recipe, not the same recipe with the primitive faked.
32
- 4. **The report contract is path-independent.** Every path produces the same
33
- schema-valid recon and builder reports (`src/lib/reportValidator.mjs`, mirrored
34
- in `references/report-contracts.md`), and every path crosses the same
35
- main-thread boundary: schema validation, then `reconcileReconReports`, then
36
- `semanticVerify` on builder reports. A subagent's own PASS is a hypothesis.
37
- 5. **Progressive disclosure.** `SKILL.md` carries only the selector, the
38
- invariants, Path C, and pointers; each path's recipe lives in `references/`
39
- and is loaded only when selected.
40
-
41
- ## Considered options
42
-
43
- - **Route by surface name** (Claude → workflow, Codex → subagents): rejected —
44
- it is a claim, not evidence. A verify spike against codex-cli 0.144.6 found
45
- native spawn and wait callable and concurrency ≥2, yet the host exposed tool
46
- entries with only a name and a description: no schema, no callable/permitted
47
- flags, no thread capacity. Name-based routing would have selected Path B on a
48
- host that cannot prove it.
49
- - **Emulate the missing primitive** (hand-rolled fan-out where no workflow
50
- runtime exists): rejected — it reproduces the failure modes the runtime exists
51
- to prevent (run identity, resume-exactly-once, runtime output validation)
52
- without any of its guarantees, and it fails at the worst moment, mid-wave.
53
- - **Fail open on unknown evidence** (assume a capability when the host is
54
- silent): rejected — the cost asymmetry is severe. A false Path C is slower; a
55
- false Path A or B strands a partially dispatched wave.
56
- - **One monolithic SKILL.md carrying all three recipes**: rejected — every
57
- session would pay for two recipes it will never run.
58
-
59
- ## Consequences
60
-
61
- - The current Codex host selects Path C. `references/dispatch-subagents.md` is
62
- written and tested but **dormant** until a host supplies the complete
63
- normalized inventory; that dormancy is pinned from both sides by tests.
64
- - Adding a path means adding evidence requirements and a reference, not
65
- branching the skill body.
66
- - Hosts that improve their inventory reporting gain a faster path with no skill
67
- change — the selector picks it up as soon as the evidence arrives.
68
- - The B1 fan-out shape (`spawn_agents_on_csv` plus a host-enforced per-agent
69
- `output_schema`) stays out of scope until its own version-pinned verify spike
70
- returns a positive verdict.
@@ -1,63 +0,0 @@
1
- # Kit Core and project extensions have separate identities
2
-
3
- Status: accepted (2026-07-22, issues #190, #194, #196, #197)
4
-
5
- The original divergence policy allowed any shipped path to become
6
- consumer-owned. That is safe for a genuinely project-specific file, but not for
7
- a protocol authority such as the skill/readiness registry: once a consumer
8
- owns that mixed file, new Kit declarations stop arriving while local additions
9
- and stale Kit declarations remain indistinguishable. A real consumer exhibited
10
- exactly this state: the installed readiness harness was current while its owned
11
- registry had no readiness capabilities or declarations.
12
-
13
- We decided to model four explicit lifecycle states instead of treating every
14
- local difference as file ownership:
15
-
16
- 1. **Kit Core** remains upstream-owned under the Kit's canonical identity. A
17
- consumer cannot permanently own it under that same identity.
18
- 2. **Project extensions** live on separate consumer-owned surfaces. Every
19
- shipped skill may load its optional `docs/agents/skills/<skill>.md`; local
20
- skill identities live in a separate local registry. Neither surface changes
21
- the corresponding Kit Core.
22
- 3. A **Contribution bridge** may temporarily retain a registered local Core
23
- experiment. It must resolve into a project extension, a generalized upstream
24
- contribution that returns in a release, or an explicit fork.
25
- 4. An **Explicit fork** has its own identity, version, and update line. Semantic
26
- divergence cannot masquerade indefinitely as the canonical Kit skill.
27
-
28
- An update composes and validates the complete protocol group in an isolated,
29
- manifest-derived staged candidate. It never infers an ownership decision from
30
- `--yes`: an unclassified collision blocks unchanged until a user classifies it.
31
- Existing mixed states migrate semantically, preserving local identities and
32
- project metadata on their new surfaces; an ambiguous semantic change blocks
33
- instead of being overwritten or frozen silently.
34
-
35
- The upstream route is capability-based, not maintainer-specific. At the moment
36
- of contribution, repository permissions and an optional machine-local upstream
37
- checkout determine whether the approved route can use a direct pull request, a
38
- fork, or an issue. No consumer asks who the user is, and no telemetry reports
39
- local edits automatically.
40
-
41
- ## Considered options
42
-
43
- - **Keep arbitrary consumer-owned shipped paths:** rejected because a protocol
44
- authority then stops receiving schema and behavior evolution under the same
45
- identity.
46
- - **Add more merge rules to the mixed registry:** rejected because local skills,
47
- project annotations, readiness declarations, and upstream skill definitions
48
- have different ownership and lifecycle semantics.
49
- - **Overwrite Core and discard local changes:** rejected because it loses valid
50
- project behavior and can destroy unregistered work.
51
- - **Special-case the maintainer:** rejected because identity is irrelevant; the
52
- portable distinction is whether the user has an approved route and the
53
- required repository capabilities.
54
-
55
- ## Consequences
56
-
57
- - ADR-0001 remains valid for genuine consumer-owned files but is narrowed for
58
- Kit Core and mixed registries.
59
- - Core updates can advance without erasing project-specific behavior.
60
- - Consumers gain explicit extension, contribution, and fork lifecycles instead
61
- of permanent accidental divergence.
62
- - Migration requires a one-time semantic classification of existing mixed
63
- states and must fail closed when that classification is ambiguous.
@@ -1,64 +0,0 @@
1
- # Release intent is an explicit version tag
2
-
3
- Status: accepted (2026-07-22, issue #204)
4
-
5
- Clarified 2026-07-25 by issue #239: an explicit AFK end-to-end mandate may
6
- authorize deterministic reversible release preparation, but never the
7
- publication tag itself.
8
-
9
- Amended 2026-07-25 by issue #257: the confirmed Semver authorizes the whole
10
- release, through tag and publish. The separation of integration and publication
11
- below is unchanged — merging still cannot publish, and only an annotated tag
12
- records release intent — but that intent no longer waits for a second human
13
- confirmation. The maintainer chooses the version once; the agent then merges,
14
- tags, and monitors to `released`. The second gate had proven worse than no gate:
15
- it left prepared versions sitting in `awaiting-tag` until someone returned,
16
- which is how 0.34.2 was skipped and buried under 0.34.3 (#243). Safety stays in
17
- the gates that run regardless of who is watching — guard, staleness, suite,
18
- pack, and the workflow's own tag/version/ancestry validation.
19
-
20
- The release workflow currently publishes whenever a merge to `main` changes
21
- `package.json`. That keeps the canonical branch and npm close together, but it
22
- also makes an ordinary merge an irreversible public action whose consequence is
23
- not visible in the merge affordance. A failed post-publish readback can further
24
- make the run red after npm has already accepted the version.
25
-
26
- We decided that integration and publication are separate transitions:
27
-
28
- 1. Merging a prepared version into `main` integrates it but does not publish it.
29
- 2. A matching annotated `v<version>` tag on that `main` commit records Release
30
- intent and starts the normal publish workflow.
31
- 3. The workflow validates tag, package version, canonical-branch ancestry,
32
- artifact integrity, and tests before publishing.
33
- 4. A manual dispatch is a recovery/reconciliation route for one explicit tag,
34
- never the ordinary release trigger.
35
- 5. Publication completes only when npm and the GitHub release are both visible
36
- and match the local version, manifest, and tarball. Eventual-consistency
37
- readbacks use bounded retry and preserve an externally reconstructable state.
38
-
39
- ## Considered options
40
-
41
- - **Merge-triggered publishing:** rejected because merge acceptance and
42
- irreversible publication remain one implicit action.
43
- - **Manual dispatch as the normal route:** rejected because the release identity
44
- is easier to forget and less durable than a version tag.
45
- - **PR label or commit marker:** rejected because it introduces hidden release
46
- semantics without giving the publication a first-class Git identity.
47
- - **Environment approval on the merge-triggered workflow:** rejected as the
48
- primary contract because it adds a UI gate but still does not represent the
49
- approved version as a durable release object.
50
-
51
- ## Consequences
52
-
53
- - A prepared version exists on `main` in an `awaiting-tag` state only for as
54
- long as the agent needs to tag it — not until a human returns (amended by
55
- #257).
56
- - The authorizing act is the confirmed Semver. An explicit AFK Wave/Program
57
- mandate that names release preparation carries the same weight, and either
58
- route reaches through tag and publish for that one target. A narrower
59
- build-only or single-action request never becomes this authority.
60
- - A single-Wave mandate does not authorize the next Program Wave. A later
61
- explicit whole-Program mandate does authorize all planned Waves and remains in
62
- force across their boundaries.
63
- - Reruns reconcile the same tag and never infer that a red workflow means
64
- nothing was published.
@@ -1,42 +0,0 @@
1
- # to-issues is the single planning facade
2
-
3
- Status: accepted (2026-07-22, issue #197)
4
-
5
- The planning workflow exposes two mechanisms after `to-prd`: Feature PRDs are
6
- decomposed by `to-issues`, while Program PRDs are unfolded by a separately
7
- invoked `to-waves` skill which later calls `to-issues` for each wave. This makes
8
- the user identify an internal planning altitude even though the PRD already
9
- carries an explicit, durable identity that can select the correct mechanism.
10
-
11
- We decided that `to-issues` is the single user-facing Planning facade:
12
-
13
- 1. A Feature PRD selects the existing atomic/promote mechanism.
14
- 2. A Program PRD selects the existing program-graph engine currently owned by
15
- `to-waves`, including its complete preview, validation, publication,
16
- per-wave maturation, and execute-ready audits.
17
- 3. Dispatch uses only explicit PRD identity (`prd: program` or its canonical
18
- program type), never size heuristics or model judgment.
19
- 4. The selected mode is reported visibly before mutation. Program mode retains
20
- its full preview approval gate.
21
- 5. `to-waves` remains an independently testable internal mechanism and may keep
22
- a compatibility entrypoint, but routers and normal documentation always send
23
- the user from `to-prd` to `to-issues`.
24
-
25
- ## Considered options
26
-
27
- - **Keep two public next commands:** rejected because it leaks internal
28
- decomposition mechanics and makes users repeat an altitude decision already
29
- encoded in the PRD.
30
- - **Infer the mode from plan size or prose:** rejected because hidden heuristics
31
- make the same command unpredictable and can publish the wrong board shape.
32
- - **Merge all program code physically into `to-issues`:** rejected because the
33
- program graph is a coherent deep module with valuable separate tests; only
34
- its public routing belongs behind the facade.
35
-
36
- ## Consequences
37
-
38
- - The normal user path is always `grill → to-prd → to-issues`.
39
- - Feature and Program behavior remain distinguishable in audit output without
40
- requiring the user to select their implementation skill.
41
- - Router, overview, skill prose, mirrors, and contract tests must agree on the
42
- one-entry contract.
@@ -1,95 +0,0 @@
1
- # Routing knowledge, access, and policy are separate
2
-
3
- Status: accepted (2026-07-22, Program #197) — the optimization-dial clause is
4
- superseded by
5
- [ADR-0010](./0010-model-roster-replaces-the-optimization-dial.md)
6
- (items 3 and the "Model preferences and optimization overrides" sentence below;
7
- everything else stands)
8
-
9
- Planning cannot safely persist a concrete recommended model. Provider catalogs
10
- change, model names age, effort behavior differs by model, agent surfaces expose
11
- different controls, and a surface may reach another provider through a plugin
12
- or CLI transport. A recommendation that is correct in one session can therefore
13
- be nonexistent, unreachable, or unenforceable in the session that implements
14
- the work.
15
-
16
- We decided to keep three identities separate:
17
-
18
- 1. The Kit-maintained **Evidence catalog** contains all known provider models
19
- and observations, whether or not the active surface can use them. Each
20
- decision-grade observation retains the complete configuration identity:
21
- model, effort, harness, workload, source, benchmark version, uncertainty,
22
- freshness, and cost.
23
- 2. The user-local **Access graph** records the native and cross-provider paths
24
- available from each agent surface. Claude Code and Codex attest only their
25
- own runtime capabilities. A detected transport is not automatically approved,
26
- and neither surface claims another surface's unverified capabilities.
27
- 3. The user-local **Routing policy** records allowed surfaces and transports,
28
- switching autonomy, optimization goals, and optional advanced overrides.
29
- Personal choices do not alter catalog facts.
30
-
31
- Durable plans and issues contain only a provider-neutral **Routing intent**.
32
- At execution time a resolver compares all evidence-backed candidates, filters
33
- them through the Access graph and Routing policy, and produces a one-execution
34
- **Route decision**. It reports the best overall route separately from the best
35
- currently executable route. An unreachable preference follows the user's
36
- explicit handoff, fallback, or block policy.
37
-
38
- Every surface adapter declares how independently it can control model and
39
- effort: per spawn, through a named agent definition, through a session default,
40
- or not at all. Environment precedence is part of the capability proof. An AFK
41
- subagent requires enforced model and effort selection and emits a **Dispatch
42
- receipt** containing the requested and applied route, enforcement method, and
43
- policy/evidence revisions. Silent inheritance and unverified degradation are
44
- not valid AFK routes.
45
-
46
- Setup keeps the technical model behind a simple user decision. It presents a
47
- registry-driven list of familiar agent surfaces, preselects detected entries,
48
- and asks whether the Kit may switch automatically, ask before switching, or use
49
- only the current surface. Adapters establish providers, transports, model
50
- selectors, and effort controls. Model preferences and optimization overrides
51
- remain optional advanced settings.
52
-
53
- An existing installation without a routing profile receives this choice once
54
- through setup or the first compatible Kit update. Later updates perform a
55
- read-only preflight and ask again only when the profile is missing, invalid,
56
- materially stale, references a removed route, or a newly detected surface makes
57
- a meaningful choice available. Installing Kit mechanics and changing personal
58
- policy are separate transactions; unattended update never invents a decision.
59
-
60
- BenchLM may populate discovery, catalog, pricing, freshness, coverage, and
61
- corroboration signals. Its aggregate scores are not decision-grade routing
62
- observations because effort and harness identity may be collapsed and missing
63
- evidence may be estimated. DeepSWE, Artificial Analysis, OpenHands, Arena, and
64
- other benchmark-owner artifacts remain authoritative for the claims they
65
- actually measure. Local experience may calibrate policy but does not rewrite
66
- public evidence.
67
-
68
- ## Considered options
69
-
70
- - **Persist a concrete model and effort in every issue:** rejected because the
71
- recommendation ages and may not be executable on the implementing surface.
72
- - **Maintain separate Claude and Codex routing tables:** rejected because it
73
- duplicates evidence, hides cross-provider routes, and lets the two surfaces
74
- drift.
75
- - **Filter the shared table during setup:** rejected because current access is
76
- a user/runtime fact, not a limit on routing knowledge.
77
- - **Ask users to describe transports and enforcement capabilities:** rejected
78
- because these are adapter facts most users cannot answer reliably.
79
- - **Route directly from a composite leaderboard:** rejected because benchmark,
80
- harness, effort, uncertainty, and workload boundaries would be lost.
81
- - **Re-run the routing interview on every Kit update:** rejected because a valid
82
- user-owned profile should remain stable until a material choice changes.
83
-
84
- ## Consequences
85
-
86
- - Model/provider churn updates the catalog and resolver without rewriting
87
- durable issues.
88
- - Both Claude Code and Codex read one local policy while proving their own
89
- execution capabilities independently.
90
- - Cross-provider dispatch is expressible without pretending that every surface
91
- can reach every model.
92
- - The Kit must maintain source adapters, schema migration, capability probes,
93
- last-known-good evidence, and dispatch receipts.
94
- - Different machines do not share personal routing state unless the user later
95
- chooses an explicit export or private synchronization mechanism.
@@ -1,88 +0,0 @@
1
- # Session teardown requires provenance-bound ownership
2
-
3
- Status: superseded by [ADR-0009](./0009-teardown-authority-is-stateless-repository-classification.md) (2026-07-27, #320)
4
-
5
- Long agent sessions create branches, linked worktrees, setup outputs, and
6
- landing-time build artifacts. The desired end state is that every
7
- provenance-captured target created by that session can be removed, including
8
- branches whose changes reached
9
- canonical `main` through patch-equivalent commits rather than ancestry.
10
-
11
- Repository state alone cannot identify that ownership safely. A foreign branch
12
- can have the same name or patch, a user file can match a generated-artifact
13
- pattern, and a path can be replaced between assessment and deletion. Retrying
14
- after a crash adds a time dimension: a fresh snapshot cannot distinguish an
15
- earlier generator output from a file created by the user between attempts.
16
-
17
- We decided that teardown authority must come from **Teardown provenance**, not
18
- from present-day similarity:
19
-
20
- 1. A session records intent before creation, but receives cleanup authority only
21
- through an atomic **Ownership proof**. Branch and proof ref are acquired in
22
- one Git transaction bound to the active wave claim.
23
- 2. Setup, session work, and landing are separate provenance boundaries. Setup
24
- and session cleanup use the worktree-creation baseline; landing cleanup uses
25
- a persisted landing-attempt boundary and freezes the exact outputs of its
26
- generator-capable step.
27
- 3. Paths and patterns select candidates but never prove identity. Cleanup binds
28
- regular files and worktree roots to no-follow object evidence and revalidates
29
- that evidence immediately before mutation.
30
- 4. The **Lifecycle receipt** is a durably replaced state-transition journal.
31
- Prepared Git ref transactions close the worktree-removal race, and committed
32
- intermediate states make known outcomes resumable. An external SIGKILL may
33
- still leave Git's own lock files requiring operator recovery.
34
- 5. Lost evidence is not reconstructed from coincidence. An interrupted landing
35
- attempt without frozen outputs can be archived without claiming or deleting
36
- its files, after which the ambiguous files must be classified before a new
37
- attempt proceeds.
38
-
39
- ## Considered options
40
-
41
- - **Delete branches merged by ancestry:** rejected because squash,
42
- cherry-pick, and patch-equivalent integration leave session-owned branch refs
43
- outside ancestry.
44
- - **Treat a receipt row as ownership:** rejected because another process can
45
- create the named branch or worktree after the absence check but before the
46
- attempted creation.
47
- - **Authorize files by ignored path or generator pattern:** rejected because a
48
- consumer file can occupy the same path before landing or replace an assessed
49
- output afterward.
50
- - **Take a fresh landing snapshot on every retry:** rejected because it protects
51
- prior generator outputs as if they predated landing, while a persistent start
52
- snapshot alone incorrectly claims every later matching user file.
53
- - **Force-remove apparently clean targets:** rejected because force bypasses the
54
- repository and filesystem evidence that distinguishes owned work from foreign
55
- work.
56
- - **Guess ownership after an unjournaled crash window:** rejected because safe
57
- cleanup and guaranteed automatic liveness cannot both be recovered after the
58
- distinguishing evidence is lost.
59
-
60
- ## Consequences
61
-
62
- - A completed session can remove its exact worktrees, branches, proof refs, and
63
- provenance-captured generated artifacts without hiding history or sweeping
64
- unrelated repository state.
65
- - Foreign branches, worktrees, replacement symlinks, replacements, late writes,
66
- and pre-landing consumer files are hard stops or remain outside cleanup
67
- authority. Setup recovery may remove only a symlink whose exact no-follow
68
- identity it captured as setup-created.
69
- - Exact unchanged frozen evidence is deterministically resumable. Started or
70
- drifted frozen attempts can be explicitly relinquished by archiving only the
71
- receipt; every current file then remains protected and must be classified
72
- before another attempt.
73
- - Provenance-less legacy worktrees receive only a conservative baseline after
74
- exact registration, no-follow root, attached branch, and clean tracked/index
75
- checks. Setup reuse defers backfill while tracked work or current
76
- landing-generated blockers remain. Landing classifies those blockers before
77
- writing evidence; after they are moved, all remaining current ignored and
78
- untracked files become protected. Corrupt evidence and active attempts are
79
- never backfilled.
80
- - Before merge, a committed worktree policy may nominate only exact,
81
- identity-bound cleanup candidates; it authorizes no deletion. After merge,
82
- the profile is reloaded directly from canonical `origin/main` and must match
83
- both the candidate and attempt-bound policy digest before any mutation.
84
- Generator evidence is also reauthorized path-by-path against that canonical
85
- policy. Missing policy, an unmerged widening, or branch/canonical drift
86
- preserves every file.
87
- - The lifecycle implementation is necessarily a small transaction protocol,
88
- with more states and race tests than a path-based cleanup script.
@@ -1,84 +0,0 @@
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.