@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,198 +0,0 @@
1
- # BenchLM as a routing-evidence source
2
-
3
- **Researched:** 2026-07-22
4
- **Question:** What role, if any, should BenchLM play in the Kit's evidence-backed
5
- model and effort routing, and what does that imply for setup and kit-update?
6
-
7
- ## Decision
8
-
9
- Use BenchLM as a **catalog, discovery, and corroboration source**, not as an
10
- authoritative routing source.
11
-
12
- BenchLM is unusually useful for finding new model families, benchmarks,
13
- pricing changes, supersession relationships, and gaps in current evidence. It
14
- must not directly choose a dispatch route, especially an effort level. A route
15
- observation still has to come from the benchmark owner and retain the complete
16
- configuration identity: model, effort, agent/harness, benchmark version,
17
- quality metric, uncertainty, and task cost.
18
-
19
- This gives the source hierarchy:
20
-
21
- 1. **Benchmark owner artifacts** (DeepSWE, Artificial Analysis, OpenHands,
22
- Code/Design Arena) provide decision evidence.
23
- 2. **BenchLM** discovers and cross-checks those sources and model releases.
24
- 3. **Local user evidence and preferences** calibrate the resulting policy.
25
- 4. The approval-gated policy reconciler proposes, but never silently applies,
26
- routing changes.
27
-
28
- ## What BenchLM contributes
29
-
30
- BenchLM currently tracks 290 models and 323 benchmarks. Its useful coverage
31
- includes agentic work, coding, multimodal work, model pricing, context windows,
32
- runtime signals, release metadata, and supersession chains. Its methodology
33
- currently gives ranking weight to three agentic and five coding benchmarks;
34
- many more sources, including DeepSWE and most frontend sources, are display-only
35
- context ([methodology](https://benchlm.ai/methodology)).
36
-
37
- Frontend coverage is useful primarily as a source map. The current focused page
38
- combines sourced React Native Evals, Design2Code, Vision2Web, and related
39
- browser-task evidence, but calls itself a reporting family rather than a
40
- weighted category, contains only seven eligible models, and warns that models
41
- may have as few as two source rows
42
- ([frontend/app-dev view](https://benchlm.ai/best/frontend-app-dev)). The owners
43
- remain more authoritative: [React Native Evals](https://rn-evals.vercel.app/)
44
- publishes agent success, token, and cost results, while
45
- [Vision2Web](https://vision2web-bench.github.io/) explicitly evaluates
46
- model-plus-framework submissions across visual, interactive, and full-stack
47
- tasks.
48
-
49
- BenchLM also exposes confidence separately from score, 90% score intervals,
50
- `Supported` versus `Estimated` states, source-coverage counts, and a dated
51
- BenchAlign method/frozen-input identifier. That is valuable for shortlisting
52
- and for detecting insufficient evidence, but it is confidence in BenchLM's
53
- composite inference rather than a pass-rate interval for our exact workload
54
- ([confidence method](https://benchlm.ai/benchmark-confidence)).
55
-
56
- ## Why it cannot drive routing directly
57
-
58
- ### Effort and harness can disappear
59
-
60
- BenchLM's exported Sol model row records DeepSWE as `72.7`, but not the effort,
61
- harness, confidence interval, or cost
62
- ([models export](https://benchlm.ai/data/models.json)). The owner artifact shows
63
- that this number is specifically `gpt-5-6-sol + mini-swe-agent + max`: 72.7%
64
- Pass@1 over four whole-benchmark runs, with a 95% run-to-run interval and about
65
- $8.39 mean cost per scored attempt
66
- ([DeepSWE v1.1 artifact](https://deepswe.datacurve.ai/artifacts/v1.1/leaderboard-live.json)).
67
-
68
- This collapsing is fatal for model-plus-effort selection. Some older model
69
- families have explicit `high` or `max` variants in the BenchLM catalog, while
70
- current Sol, Terra, Luna, and Fable evidence can be folded into one base-model
71
- row. The overall/category scores therefore describe mixed published
72
- configurations, not a consistent effort curve.
73
-
74
- ### Composite rankings are editorial inference
75
-
76
- BenchAlign normalizes unlike protocols, combines source families, and imputes
77
- missing evidence with wider uncertainty. BenchLM publishes the method version,
78
- frozen-input identifier, weighted benchmark list, and dated output, but its
79
- public downloads reference internal source files rather than a published,
80
- locally reproducible BenchAlign implementation. The composite is reproducible
81
- as a cached dated output, not independently rebuildable by the Kit from public
82
- code ([methodology](https://benchlm.ai/methodology)).
83
-
84
- Raw source rows are more useful than the composite, but the current
85
- machine-readable model export is a numeric benchmark map without per-row source
86
- URLs or complete execution settings. The Kit must follow the benchmark catalog
87
- to the owner rather than treating `models.json` as normalized routing evidence.
88
-
89
- ### Current semantic inconsistencies require defensive ingestion
90
-
91
- The same-day exports currently contain examples that a production adapter must
92
- reject or downgrade:
93
-
94
- - BenchLM's DeepSWE Markdown page says that source metadata is preserved but
95
- reports zero leaderboard models, while `models.json` contains six DeepSWE
96
- scores.
97
- - `benchmarks.json` currently contains duplicate `sweMultimodal` definitions.
98
- - Its Design2Code and Vision2Web catalog entries currently point to a provider
99
- documentation page rather than the benchmark owners. The official
100
- [Design2Code repository](https://github.com/NoviScl/Design2Code) and
101
- [Vision2Web site](https://vision2web-bench.github.io/) show the correct
102
- provenance.
103
-
104
- These may be transient publishing defects, but they make last-known-good,
105
- semantic validation, and owner verification mandatory.
106
-
107
- ## Machine-readable access, cadence, and legal posture
108
-
109
- BenchLM documents MIT-licensed JSON downloads for leaderboard, models,
110
- benchmarks, pricing, speed, and comparisons. Each export currently has
111
- `schemaVersion`, `generatedAt`, and `sourceLastUpdated`; `updates.json` provides
112
- a cheap change feed. BenchLM says it refreshes several times per week and often
113
- within hours of major launches ([dataset documentation](https://benchlm.ai/data)).
114
-
115
- The adapter should use the documented `/data/*.json` downloads and
116
- `updates.json`, not scrape rendered pages. Fetch at low cadence, send ordinary
117
- conditional requests where supported, retain attribution, and persist the raw
118
- snapshot hash and generation timestamp.
119
-
120
- There is one governance warning: the current Terms page still visibly contains
121
- launch placeholders for operator identity, jurisdiction, effective date, and
122
- contact details. It permits published downloads under their stated licenses
123
- and non-degrading automated access, but this unfinished legal surface reduces
124
- operational confidence. The MIT dataset declaration is clear; nonetheless the
125
- adapter should not depend on high-frequency or undocumented endpoints
126
- ([dataset license](https://benchlm.ai/data),
127
- [terms](https://benchlm.ai/terms)). Underlying benchmark data remains subject
128
- to its original publisher's license.
129
-
130
- ## Concrete adapter contract
131
-
132
- `BenchLmCatalogSource` should ingest only:
133
-
134
- - model/provider/family and release/supersession metadata;
135
- - current pricing and runtime hints;
136
- - benchmark definitions and owner links;
137
- - coverage, freshness, `Supported`/`Estimated`, and confidence metadata;
138
- - the update feed as an invalidation and discovery trigger.
139
-
140
- It should emit `candidate-discovered`, `source-changed`, `pricing-changed`, and
141
- `evidence-gap` events. It must not emit an authoritative
142
- `RouteObservation(model, effort, harness)` unless an owner adapter has verified
143
- the complete row.
144
-
145
- Every refresh must:
146
-
147
- 1. validate the export schema and cross-file referential integrity;
148
- 2. reject duplicate benchmark identities and implausible source changes;
149
- 3. retain the last-known-good snapshot on failure;
150
- 4. classify aggregate scores as `corroborating`, never `decisive`;
151
- 5. resolve relevant rows through the original source adapter;
152
- 6. show a human-readable diff before a personal policy changes.
153
-
154
- ## Setup and kit-update implication
155
-
156
- BenchLM improves discovery, but it does not change ownership: setup asks which
157
- **surfaces/providers the user can and wants to use**, not which model currently
158
- tops a leaderboard. Availability, policy, and benchmark ability are separate.
159
-
160
- For a first setup or an existing installation without a routing profile:
161
-
162
- 1. Detect installed/supported surfaces where possible and ask the user to
163
- confirm the common choices (for example Claude Code, Codex, and explicitly
164
- offered additional providers such as Google or Moonshot/Kimi).
165
- 2. Record availability and dispatch capability separately: subscription/API,
166
- allowed cross-provider execution, per-spawn model control, and per-spawn
167
- effort control.
168
- 3. Ask for the optimization preference and local overrides, or allow the safe
169
- `inherit` mode.
170
- 4. Use BenchLM to discover current candidate families, then owner sources to
171
- construct the proposed model-plus-effort policy.
172
- 5. Preview the policy and require approval before activation.
173
-
174
- The list of “common AIs” must be data-driven and versioned, not hard-coded in a
175
- skill prompt. BenchLM can nominate newly common candidates, while surface
176
- capability checks determine whether they are actually selectable.
177
-
178
- `kit-update` should install updated schemas, adapters, and provider-catalog
179
- logic. It should run a short routing preflight when the profile is absent,
180
- invalid, stale, references a removed model, or when a newly detected surface
181
- changes available choices. It should otherwise report `still valid` without
182
- re-running the whole interview. An update may refresh and cache evidence, but
183
- must never rewrite the user's provider choices, model routes, effort routes, or
184
- global configuration without a separately approved reconcile transaction.
185
-
186
- ## Final classification
187
-
188
- | Use | Classification |
189
- |---|---|
190
- | Discover new models, providers, benchmarks, and releases | Recommended |
191
- | Detect evidence/pricing/freshness changes | Recommended with validation |
192
- | Corroborate owner-source observations | Useful |
193
- | Select a candidate shortlist | Advisory only |
194
- | Select model plus effort for dispatch | Rejected |
195
- | Treat BenchAlign overall/category score as capability truth | Rejected |
196
-
197
- BenchLM therefore adds real value to the planned routing wave, but as the
198
- system's **radar**, not its **autopilot**.
@@ -1,238 +0,0 @@
1
- # Consumer-owned protocol files: evolution without overwrite or starvation
2
-
3
- Verified on 2026-07-22 against `agent-workflow-kit` 0.33.0 in the issue #197
4
- worktree. This note researches how an updater should handle a locally adapted
5
- file that is also part of an evolving upstream protocol. It is decision input,
6
- not a product change.
7
-
8
- ## Finding
9
-
10
- A protocol-critical file must not be both an immutable consumer-owned fork and
11
- the upstream kit's active protocol authority under the same path. Those two
12
- contracts are incompatible: permanent consumer ownership prevents protocol
13
- evolution, while ordinary upstream ownership cannot preserve local policy.
14
-
15
- The durable model is to split the mixed file into:
16
-
17
- 1. an upstream-owned, immutable **protocol core** that ships and evolves with
18
- the kit; and
19
- 2. a consumer-owned, structured **extension overlay** containing only local
20
- declarations and policy.
21
-
22
- The staged update candidate composes core plus overlay and validates the whole
23
- result before activation. A one-time migration extracts existing local
24
- extensions from the mixed file. Ambiguity blocks that migration rather than
25
- overwriting either side. A consumer that needs to change executable protocol
26
- behavior has made a real code fork and needs a separate artifact/version line,
27
- not `origin: consumer` on the upstream path.
28
-
29
- ## Current local contract and failure mode
30
-
31
- The accepted divergence policy defines a consumer-owned path as a deliberate
32
- fork that receives no overwrite, conflict report, deletion prompt, or future
33
- kit improvement ([ADR 0001](../adr/0001-consumer-divergence-policy.md)). The
34
- reconciler implements that literally: as soon as an installed entry has
35
- `origin: 'consumer'`, it carries the old manifest record forward and skips all
36
- upstream comparison
37
- ([`updateReconcile.mjs`](../../src/lib/updateReconcile.mjs)). This is coherent
38
- for an independent local file, but it is update starvation for a protocol
39
- authority.
40
-
41
- Issue #196 exposed the concrete mixed-file shape. The readiness harness and
42
- skills depend on `.claude/skills/skill-manifest.json`, but a real consumer owns
43
- and extends that same registry. The published 0.32.0 artifact was internally
44
- coherent; the consumer combined 15 local skill records and local notes with an
45
- older upstream registry, while the newer kit added five skills, 23 readiness
46
- capabilities, and 15 readiness declarations. Skipping the owned registry thus
47
- allowed a new executable harness to run against an old protocol declaration.
48
-
49
- The candidate transaction already has the right enforcement location: it
50
- checks candidate hashes and destination races before activation and rolls back
51
- all touched paths on failure
52
- ([`updateCandidate.mjs`](../../src/lib/updateCandidate.mjs)). What is missing is
53
- a compositional protocol model and validator; copying more of the consumer or
54
- adding more path exclusions does not solve that ownership contradiction.
55
-
56
- ## Comparable primary-source patterns
57
-
58
- | System | Primary-source behavior | Lesson for the kit |
59
- |---|---|---|
60
- | Git three-way file merge | `git merge-file` combines the changes from a recorded common base to the upstream side with the local side; overlapping edits become explicit conflicts and a clean merge has a distinct successful exit status. [Git documentation](https://git-scm.com/docs/git-merge-file) | The stored installed hash/base makes a one-time three-way migration possible. A merge is evidence to inspect, not permission to silently overwrite. Text merge is unsuitable as the permanent extension mechanism because protocol identity and invariants are semantic, not line based. |
61
- | GitHub forks | Syncing a fork explicitly fetches/merges upstream. Conflicts require a pull request or manual resolution; forcing sync overwrites the destination. [GitHub documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) | A true code fork has its own history and must deliberately integrate upstream. It cannot also promise automatic compatibility under the original identity. |
62
- | Kubernetes Server-Side Apply | Kubernetes tracks ownership per structured field. An attempted value change to another manager's field conflicts; force is an explicit ownership transfer. A manager can also relinquish a field or share ownership by agreeing on the same value. [Kubernetes documentation](https://kubernetes.io/docs/reference/using-api/server-side-apply/) | Ownership below the file level works for schema-defined data. Core fields and consumer extension fields can have separate managers, with collisions rejected and transfers explicit. This model should not be imitated for arbitrary source-code lines. |
63
- | Debian configuration files | Debian requires local configuration changes to survive upgrades. It distinguishes package conffiles from files generated and maintained by idempotent scripts, forbids mangling user configuration without asking, and warns that mixing the two handling styles causes repeated upgrade prompts. [Debian Policy](https://www.debian.org/doc/debian-policy/ch-files.html#behavior) `dpkg` separately exposes explicit keep-old/install-new/default choices for changed conffiles. [dpkg manual](https://manpages.debian.org/bookworm/dpkg/dpkg.1.en.html) | Choose one ownership model per artifact. Do not make one file simultaneously an upstream payload and a consumer-generated extension. Migrations must be idempotent, previewed, and preserve the old value on failure. |
64
- | Terraform provider state | Terraform stores a resource schema version, asks the provider to upgrade older state before planning, rejects unsupported prior versions, and retains prior state when an upgrader reports errors. Each upgrader must produce a complete current-version state. [Terraform Plugin Framework](https://developer.hashicorp.com/terraform/plugin/framework/resources/state-upgrade) | Give the overlay an explicit schema version and deterministic upgraders. Validate the fully upgraded/composed state, not only the changed records. Unsupported or ambiguous inputs block activation without destroying the prior state. |
65
- | Kubernetes API versioning | Kubernetes can serve old and new API versions concurrently, converts between representations, migrates stored objects separately, and removes an old version only after clients and stored objects have migrated. [Kubernetes CRD versioning](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/) | Compatibility needs an announced window: introduce/read both, migrate, count adoption, stop serving old, then remove conversion. A deprecation warning alone is not migration evidence. |
66
- | Homebrew taps | An extracted or alternative formula lives in a separate Git repository/tap; its owner is responsible for maintenance, deprecations, and security updates. Naming or qualification avoids collision with the core formula. [Homebrew tap documentation](https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap) | A real executable fork needs a distinct artifact namespace and maintenance owner. It should not silently shadow the kit's protocol core at the same path. |
67
-
68
- ## Data/config extension versus code fork
69
-
70
- These cases need different contracts.
71
-
72
- ### Structured consumer extension
73
-
74
- Use an overlay when the consumer is adding data the upstream runtime already
75
- knows how to interpret: local skill registrations, local capability evidence,
76
- board values, activation decisions, or project policy. The upstream owns the
77
- schema and executable semantics; the consumer owns values in a declared
78
- extension namespace.
79
-
80
- The overlay should have:
81
-
82
- - its own consumer-native path and `schemaVersion`;
83
- - stable record identities and an explicit allowed extension namespace;
84
- - no ability to redefine reserved upstream/core records;
85
- - deterministic, idempotent schema upgraders;
86
- - a compatibility declaration tying overlay schema versions to supported
87
- protocol-core versions; and
88
- - a composed-state validator that checks references, uniqueness, required
89
- declarations, and executable/declaration parity.
90
-
91
- This is the applicable model for the mixed skill/readiness manifest. The
92
- consumer's local skills are data extensions; the kit's shipped skill registry,
93
- readiness schema, and harness contract are protocol core.
94
-
95
- ### Executable code fork
96
-
97
- Use a true fork when the consumer changes parsing, evaluation, migration, or
98
- other executable protocol behavior. The fork must then have a distinct package
99
- or path identity, its own version and release channel, an explicit upstream
100
- remote/base, and a deliberate sync/rebase/merge process. Compatibility with the
101
- upstream package is no longer automatic.
102
-
103
- Marking such code `consumer`-owned under the upstream path hides that reality:
104
- it keeps the name but abandons the update channel. The Homebrew and GitHub
105
- models make the trade-off honest: local history is preserved, upstream sync is
106
- possible, conflicts are explicit, and maintenance responsibility moves to the
107
- fork owner.
108
-
109
- ## Recommended candidate and ownership contract
110
-
111
- ### 1. Define protocol groups, not only independent files
112
-
113
- The package manifest should declare every protocol-critical group and its
114
- members, for example:
115
-
116
- ```text
117
- readiness protocol
118
- core registry: kit-owned
119
- runtime harness: kit-owned
120
- skill preflights: kit-owned
121
- consumer overlay: consumer-owned structured data
122
- validator/migrators: kit-owned
123
- ```
124
-
125
- The candidate is valid only if every group is coherent as a whole. A
126
- consumer-owned member can therefore no longer make validation disappear.
127
-
128
- ### 2. Keep upstream protocol core unownable under its canonical identity
129
-
130
- `own` should refuse a protocol-core path and point to the supported overlay or
131
- fork route. Existing owned core paths are legacy states to migrate, not states
132
- to perpetuate. This narrows ADR 0001 rather than weakening it: ordinary
133
- consumer-owned files remain immutable and skipped; protocol core is no longer
134
- an eligible ownership unit.
135
-
136
- ### 3. Compose and validate before activation
137
-
138
- For every update, materialize the complete intended kit end state, load and
139
- upgrade the consumer overlay, compose both, and run protocol-specific
140
- invariants. Activation remains all-or-nothing. A bad overlay blocks the
141
- protocol group with a targeted diagnostic; it never causes the updater to
142
- overwrite local data or to activate a mixed-version group.
143
-
144
- Collision rules should be structural:
145
-
146
- - a consumer may add records only in its declared namespace;
147
- - a consumer record that collides with a core identity is rejected unless the
148
- schema explicitly defines a non-overriding augmentation;
149
- - consumer values cannot replace core executable references or protocol
150
- versions;
151
- - dangling references and unsupported overlay versions block activation; and
152
- - ownership transfer is an explicit user decision, never a `--yes` default.
153
-
154
- ### 4. Migrate the legacy mixed file once
155
-
156
- For the existing combined registry, the staged candidate should retain three
157
- inputs: the last installed upstream base, the live consumer file, and the new
158
- upstream core. Migration should semantically classify records rather than
159
- blindly line-merge JSON:
160
-
161
- 1. identify records unchanged from the recorded upstream base;
162
- 2. extract clearly consumer-only records and allowed local policy into the new
163
- overlay;
164
- 3. install the complete new upstream core;
165
- 4. compose and validate the result; and
166
- 5. preview the extraction, backups, ownership changes, and any ambiguous rows.
167
-
168
- If provenance is ambiguous—for example, a consumer modified an upstream record
169
- instead of adding a namespaced one—the update stops at a user gate. The user
170
- chooses to port the change upstream, express it through a supported overlay
171
- field, or create a real fork. A raw three-way merge may help produce the review
172
- diff, but it must not decide semantic ownership.
173
-
174
- ### 5. Version, negotiate, deprecate, then remove
175
-
176
- The protocol core and overlay schema need independent explicit versions and a
177
- supported compatibility matrix. Rollout follows the Kubernetes/Terraform
178
- pattern:
179
-
180
- 1. ship readers and validators for both the legacy combined representation and
181
- the new split representation;
182
- 2. ship the idempotent migration and preview it in the candidate;
183
- 3. activate core plus overlay only after full validation;
184
- 4. report a fresh adoption count (`X of Y` consumers or known legacy states),
185
- not an assumed completion;
186
- 5. stop creating legacy state and make old-state diagnostics actionable; then
187
- 6. remove the legacy reader only after all supported prior states have a
188
- migration path and known consumers have migrated.
189
-
190
- Without remote telemetry, the evidence is local manifest/schema state plus
191
- consumer update/CI results. The kit should therefore use a release-bounded
192
- support window and a deterministic audit command, not claim global adoption.
193
-
194
- ## Proposed rollout for issues #196/#197
195
-
196
- 1. **Inventory and classify.** Derive all protocol-critical groups from shipped
197
- executable references and manifests. Count every member and mark it core,
198
- overlay, generated evidence, or independent file.
199
- 2. **Add validation before enforcement.** Build the kit-only candidate and
200
- protocol-group validator. Initially report legacy mixed ownership and prove
201
- that a #196-style harness/registry mismatch is rejected.
202
- 3. **Introduce the split readiness registry.** Ship an upstream-owned core
203
- registry plus a consumer-owned extension overlay. The runtime reads the
204
- composed view; new consumers start split.
205
- 4. **Adopt existing consumers transactionally.** Extract Testreporter's 15
206
- consumer-only skill records and local policy into the overlay, install the
207
- current core, validate all core and local records, and change ownership only
208
- as part of the verified candidate activation. Preserve a backup/recovery
209
- receipt.
210
- 5. **Guard the seam.** Reject future `own` operations on protocol-core paths;
211
- point users to the overlay for data extensions or to a separately named
212
- package/path for executable forks.
213
- 6. **Sunset the combined format.** Keep the legacy reader for a declared
214
- compatibility window, count locally known adoptions, then remove it in a
215
- release that explicitly declares the minimum supported overlay/core schema.
216
-
217
- ## Rejected rollout shapes
218
-
219
- - **Silently overwrite the owned file:** destroys legitimate local behavior
220
- and violates the existing consumer contract.
221
- - **Keep skipping it forever:** preserves bytes but starves the protocol and
222
- recreates #196 on every coupled evolution.
223
- - **Automatically disown it:** turns an ownership decision into an implicit
224
- destructive migration.
225
- - **Blind three-way merge on every update:** reduces conflicts but leaves a
226
- mixed authority and cannot validate semantic record identity.
227
- - **Field ownership for arbitrary code:** line/AST ownership is not a stable
228
- extension API; local executable changes need an explicit fork.
229
- - **Fork the whole protocol for local records:** imposes permanent merge and
230
- security-update work where a narrow data overlay is sufficient.
231
-
232
- ## Decision implication
233
-
234
- The current definition “owning a path means forgoing all future kit
235
- improvements to it” remains valid for genuine independent forks. It should no
236
- longer be offered for canonical protocol-core paths. For those paths, the
237
- supported local customization mechanism is a versioned consumer overlay; the
238
- honest alternative is a separately identified and maintained code fork.