@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.
- package/.agents/skills/grill-me/SKILL.md +3 -1
- package/.agents/skills/grill-with-docs/SKILL.md +3 -1
- package/.agents/skills/kit-update/SKILL.md +9 -11
- package/.agents/skills/orchestrate-wave/SKILL.md +8 -8
- package/.agents/skills/setup-workflow/SKILL.md +20 -18
- package/.agents/skills/setup-workflow/board-sync.md +4 -1
- package/.agents/skills/setup-workflow/workflow-advisories.md +3 -2
- package/.agents/skills/setup-workflow/worktree-lifecycle.md +36 -31
- package/.agents/skills/to-issues/SKILL.md +43 -0
- package/.agents/skills/wrapup/SKILL.md +98 -54
- package/.claude/skills/grill-me/SKILL.md +3 -1
- package/.claude/skills/grill-me-codex/SKILL.md +3 -1
- package/.claude/skills/grill-with-docs/SKILL.md +3 -1
- package/.claude/skills/grill-with-docs-codex/SKILL.md +3 -1
- package/.claude/skills/kit-update/SKILL.md +9 -11
- package/.claude/skills/orchestrate-wave/SKILL.md +8 -8
- package/.claude/skills/setup-workflow/SKILL.md +20 -18
- package/.claude/skills/setup-workflow/board-sync.md +4 -1
- package/.claude/skills/setup-workflow/workflow-advisories.md +3 -2
- package/.claude/skills/setup-workflow/worktree-lifecycle.md +36 -31
- package/.claude/skills/to-issues/SKILL.md +43 -0
- package/.claude/skills/wrapup/SKILL.md +98 -54
- package/README.md +249 -7
- package/agent-workflow-kit.package.json +42 -42
- package/package.json +16 -12
- package/scripts/marker_lib.py +3 -0
- package/scripts/profile_globs.py +26 -45
- package/scripts/release-delta-guard.mjs +26 -9
- package/scripts/worktree-lifecycle/README.md +57 -160
- package/scripts/worktree-lifecycle/capabilities.json +2 -3
- package/scripts/worktree-lifecycle/classify.py +480 -0
- package/scripts/worktree-lifecycle/cleanup.py +9 -29
- package/scripts/worktree-lifecycle/core.py +68 -1429
- package/scripts/worktree-lifecycle/ignore_seed.py +1 -1
- package/scripts/worktree-lifecycle/profile.py +46 -29
- package/scripts/worktree-lifecycle/setup.py +7 -19
- package/scripts/wrapup-land.py +1292 -545
- package/src/consumer-migrations.json +1 -16
- package/src/lib/bundle.mjs +31 -1
- package/docs/adr/0001-consumer-divergence-policy.md +0 -53
- package/docs/adr/0002-capability-gated-orchestration.md +0 -70
- package/docs/adr/0003-kit-core-and-project-extension-lifecycle.md +0 -63
- package/docs/adr/0004-release-intent-is-a-version-tag.md +0 -64
- package/docs/adr/0005-to-issues-is-the-planning-facade.md +0 -42
- package/docs/adr/0006-routing-knowledge-access-and-policy-are-separate.md +0 -95
- package/docs/adr/0007-session-teardown-requires-provenance-bound-ownership.md +0 -88
- package/docs/adr/0008-planning-ignore-rules-are-offered-never-installed.md +0 -84
- package/docs/adr/0009-teardown-authority-is-stateless-repository-classification.md +0 -101
- package/docs/adr/0010-model-roster-replaces-the-optimization-dial.md +0 -87
- package/docs/agents/board-sync.md +0 -74
- package/docs/agents/code-review.md +0 -14
- package/docs/agents/workflow-capabilities.json +0 -28
- package/docs/research/agent-task-taxonomy-benchmark-coverage.md +0 -451
- package/docs/research/benchlm-routing-source.md +0 -198
- package/docs/research/consumer-owned-protocol-files.md +0 -238
- package/docs/research/frontend-agent-benchmarks.md +0 -282
- package/docs/research/model-effort-routing-benchmarks.md +0 -261
- package/docs/research/provider-neutral-agent-routing.md +0 -207
- package/docs/research/wave-152-consumer-acceptance.md +0 -98
- package/docs/research/wave-43-script-hook-census.md +0 -128
- package/scripts/build-kit.mjs +0 -117
- package/scripts/build-kit.test.mjs +0 -207
- package/scripts/census/census.test.mjs +0 -252
- package/scripts/census/state.test.mjs +0 -15
- package/scripts/census/transaction.test.mjs +0 -103
- package/scripts/census-contract.test.mjs +0 -227
- package/scripts/check-kit-staleness.mjs +0 -45
- package/scripts/check-kit-staleness.test.mjs +0 -19
- package/scripts/codex-exec-scenarios/fake-codex.mjs +0 -165
- package/scripts/codex-exec.test.mjs +0 -871
- package/scripts/grill-census-wiring-guard.mjs +0 -87
- package/scripts/grill-census-wiring-guard.test.mjs +0 -107
- package/scripts/kit-release.test.mjs +0 -273
- package/scripts/kit-update-pr.test.mjs +0 -151
- package/scripts/lib/audit-refs.mjs +0 -146
- package/scripts/lib/scrub.mjs +0 -113
- package/scripts/lib/scrub.test.mjs +0 -187
- package/scripts/memory-lifecycle/memory-lifecycle.test.mjs +0 -170
- package/scripts/portability_profile_scan.py +0 -53
- package/scripts/release-delta-guard.test.mjs +0 -174
- package/scripts/release-parity.test.mjs +0 -90
- package/scripts/release-state.test.mjs +0 -360
- package/scripts/test_anchor_table.py +0 -69
- package/scripts/test_board_bootstrap.py +0 -348
- package/scripts/test_board_sync.py +0 -208
- package/scripts/test_board_sync_create_idempotency.py +0 -117
- package/scripts/test_board_sync_wave_title.py +0 -120
- package/scripts/test_census_backstop.py +0 -712
- package/scripts/test_census_forward_contract.py +0 -91
- package/scripts/test_census_update_contract.test.mjs +0 -454
- package/scripts/test_codex_adapter_sync_contract.py +0 -169
- package/scripts/test_dist_kit_smoke.py +0 -220
- package/scripts/test_drift_guard_diagnostics.py +0 -295
- package/scripts/test_issue_claim_contract.py +0 -169
- package/scripts/test_kit_docs_language_census.py +0 -178
- package/scripts/test_marker_lib.py +0 -162
- package/scripts/test_orchestrate_wave_contract.py +0 -381
- package/scripts/test_pr_body_check.py +0 -264
- package/scripts/test_profile_globs.py +0 -280
- package/scripts/test_program_planning_contract.py +0 -133
- package/scripts/test_release_authorization_contract.py +0 -101
- package/scripts/test_render_anchor.py +0 -267
- package/scripts/test_retro_wrapup_contract.py +0 -153
- package/scripts/test_skill_code_review_seed.py +0 -89
- package/scripts/test_skill_codex_exec_lifecycle.py +0 -123
- package/scripts/test_skill_frontmatter_lint.py +0 -234
- package/scripts/test_skill_gh_lint.py +0 -124
- package/scripts/test_skill_language_census.py +0 -254
- package/scripts/test_skill_optional_readiness.py +0 -171
- package/scripts/test_skill_portability_lint.py +0 -866
- package/scripts/test_skill_precommit_template.py +0 -30
- package/scripts/test_skill_publish_audit.py +0 -358
- package/scripts/test_skill_readiness_contract.py +0 -264
- package/scripts/test_skill_readiness_preflight.py +0 -180
- package/scripts/test_skill_required_readiness.py +0 -233
- package/scripts/test_skill_selfcontainment_lint.py +0 -255
- package/scripts/test_skill_setup_workflow_seeds.py +0 -691
- package/scripts/test_skill_stale_name_lint.py +0 -126
- package/scripts/test_skill_surface_refs.py +0 -300
- package/scripts/test_skill_trailing_artifact_lint.py +0 -71
- package/scripts/test_tdd_contract.py +0 -78
- package/scripts/test_worktree_ignore_seed.py +0 -320
- package/scripts/test_worktree_setup_base_guard.py +0 -140
- package/scripts/test_worktree_wrapup_contract.py +0 -1737
- package/scripts/test_wrapup_land.py +0 -428
- package/scripts/worktree-lifecycle/session.py +0 -1857
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
# Provider-neutral agent routing for shared work items
|
|
2
|
-
|
|
3
|
-
**Researched:** 2026-07-22
|
|
4
|
-
**Question:** How should shared agent-workflow issues express model-routing intent across Claude Code and OpenAI Codex without embedding short-lived provider model names?
|
|
5
|
-
|
|
6
|
-
## Recommendation
|
|
7
|
-
|
|
8
|
-
Persist **task intent, not a model selection**, in shared issues. Use two small,
|
|
9
|
-
provider-neutral fields:
|
|
10
|
-
|
|
11
|
-
```yaml
|
|
12
|
-
routing-intent: judgment | development | mechanical
|
|
13
|
-
reasoning-intent: deep | balanced | light
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
The exact vocabulary is a Kit domain decision; the important constraint is that
|
|
17
|
-
the values describe the work and desired trade-off, not Anthropic or OpenAI
|
|
18
|
-
products. A surface-local resolver maps those values at dispatch time:
|
|
19
|
-
|
|
20
|
-
```text
|
|
21
|
-
shared issue intent
|
|
22
|
-
|
|
|
23
|
-
+-- Claude resolver -> current Claude alias/model + session effort
|
|
24
|
-
|
|
|
25
|
-
`-- Codex resolver -> current Codex model + model_reasoning_effort
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
The default resolution must be `inherit` when no local policy exists or when a
|
|
29
|
-
configured target cannot be proven usable. The orchestrator should report the
|
|
30
|
-
effective resolution at session start, but it should not write that volatile
|
|
31
|
-
result back into the issue.
|
|
32
|
-
|
|
33
|
-
This separates three ownership layers:
|
|
34
|
-
|
|
35
|
-
1. **Kit-owned schema and validation:** allowed intent values, inheritance,
|
|
36
|
-
diagnostics, and dispatch contract.
|
|
37
|
-
2. **User/organization-owned surface policy:** how intent maps to models and
|
|
38
|
-
effort for that account, budget, provider, and current catalog.
|
|
39
|
-
3. **Project-owned constraints, only when genuinely shared:** for example, a
|
|
40
|
-
prohibition on a model or a minimum capability required by every
|
|
41
|
-
collaborator. A project should not carry one maintainer's preferred model
|
|
42
|
-
mapping.
|
|
43
|
-
|
|
44
|
-
## Verified platform facts
|
|
45
|
-
|
|
46
|
-
### Claude Code
|
|
47
|
-
|
|
48
|
-
Claude Code has Managed, User, Project, and Local scopes. For ordinary scalar
|
|
49
|
-
settings, precedence is Managed, command-line, Local, Project, then User. A
|
|
50
|
-
committed `.claude/settings.json` therefore affects all collaborators and
|
|
51
|
-
overrides their user settings, while `.claude/settings.local.json` is personal
|
|
52
|
-
and repository-specific ([Claude Code settings: scopes and precedence](https://code.claude.com/docs/en/settings#configuration-scopes)).
|
|
53
|
-
|
|
54
|
-
Claude accepts provider aliases as well as full model IDs. Aliases such as
|
|
55
|
-
`fable` and `sonnet` resolve to current models, while `default` returns to the
|
|
56
|
-
runtime default for the account or organization. Aliases reduce version churn,
|
|
57
|
-
but remain Claude-specific and do not encode a cross-provider task class
|
|
58
|
-
([Claude Code model aliases](https://code.claude.com/docs/en/model-config#model-aliases)).
|
|
59
|
-
|
|
60
|
-
The main-session model can be changed for a session with `/model` or at launch
|
|
61
|
-
with `--model`; `ANTHROPIC_MODEL` and the persistent `model` setting are also
|
|
62
|
-
supported. Organization restrictions and managed settings can replace or
|
|
63
|
-
reject a requested selection, so a repository cannot assume that a named model
|
|
64
|
-
is usable for every collaborator ([Claude Code model selection](https://code.claude.com/docs/en/model-config#setting-your-model),
|
|
65
|
-
[Claude Code model restrictions](https://code.claude.com/docs/en/model-config#restrict-model-selection)).
|
|
66
|
-
|
|
67
|
-
Claude subagent definitions support an alias, a full ID, or `inherit`; omission
|
|
68
|
-
means `inherit`. Resolution currently considers
|
|
69
|
-
`CLAUDE_CODE_SUBAGENT_MODEL`, a per-invocation value, subagent frontmatter, and
|
|
70
|
-
finally the main conversation model. Excluded selections fall back to the
|
|
71
|
-
inherited model. Extended-thinking configuration is inherited from the main
|
|
72
|
-
conversation and has no per-subagent setting
|
|
73
|
-
([Claude Code subagent model resolution](https://code.claude.com/docs/en/sub-agents#choose-a-model)).
|
|
74
|
-
|
|
75
|
-
Claude effort levels are model-dependent. Unsupported levels are reduced to a
|
|
76
|
-
supported level, organization policy can cap them, and some effort choices are
|
|
77
|
-
session-only. Skill and subagent frontmatter can override the inherited session
|
|
78
|
-
effort, subject to higher-precedence environment and organization constraints.
|
|
79
|
-
Therefore a provider-neutral reasoning intent can be resolved on Claude, but a
|
|
80
|
-
shared issue must not claim that one literal effort value has identical
|
|
81
|
-
enforcement everywhere
|
|
82
|
-
([Claude Code effort levels](https://code.claude.com/docs/en/model-config#adjust-effort-level),
|
|
83
|
-
[Claude Code subagent effort](https://code.claude.com/docs/en/sub-agents#supported-frontmatter-fields)).
|
|
84
|
-
|
|
85
|
-
Anthropic exposes `GET /v1/models`, whose result describes models available to
|
|
86
|
-
that API credential ([Anthropic Models API](https://platform.claude.com/docs/en/api/models/list)).
|
|
87
|
-
That is not a universal Claude Code discovery contract: Claude Code may run
|
|
88
|
-
through a Claude subscription, Bedrock, Vertex, Foundry, or a gateway. Gateway
|
|
89
|
-
discovery is optional, limited to compatible `/v1/models` gateways, cached,
|
|
90
|
-
and falls back to built-in entries if discovery fails
|
|
91
|
-
([Claude Code gateway model discovery](https://code.claude.com/docs/en/llm-gateway#model-selection)).
|
|
92
|
-
|
|
93
|
-
### OpenAI Codex
|
|
94
|
-
|
|
95
|
-
Codex reads personal defaults from `~/.codex/config.toml` and project overrides
|
|
96
|
-
from trusted `.codex/config.toml` files. Its documented precedence is CLI,
|
|
97
|
-
project config, selected user profile, user config, system config, then built-in
|
|
98
|
-
defaults. Consequently, a committed project routing table can override a
|
|
99
|
-
collaborator's personal defaults; untrusted projects skip project-local layers
|
|
100
|
-
entirely ([Codex configuration precedence](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence)).
|
|
101
|
-
|
|
102
|
-
Codex exposes `model` and `model_reasoning_effort` as separate configuration
|
|
103
|
-
values ([Codex common configuration options](https://learn.chatgpt.com/docs/config-file/config-basic#common-configuration-options)).
|
|
104
|
-
For custom subagents, a custom-agent file may override both. Otherwise each is
|
|
105
|
-
resolved independently from an explicit spawn value, the `[agents]` default,
|
|
106
|
-
and the parent session. Omitting a setting inherits it; changing the model
|
|
107
|
-
without an explicit effort uses the selected model's default effort
|
|
108
|
-
([Codex custom-agent resolution](https://learn.chatgpt.com/docs/agent-configuration/subagents#custom-agents)).
|
|
109
|
-
|
|
110
|
-
Official Codex guidance explicitly allows leaving both values unpinned so the
|
|
111
|
-
runtime can balance capability, speed, and price. It also documents that
|
|
112
|
-
available reasoning levels depend on the selected model
|
|
113
|
-
([Codex choosing models and reasoning](https://learn.chatgpt.com/docs/agent-configuration/subagents#choosing-models-and-reasoning)).
|
|
114
|
-
|
|
115
|
-
OpenAI exposes `GET /v1/models` for models available to an API key
|
|
116
|
-
([OpenAI Models API](https://platform.openai.com/docs/api-reference/models/list)).
|
|
117
|
-
The Codex documentation does not provide a stable, public model-discovery API
|
|
118
|
-
for the effective catalog of every Codex/ChatGPT account and local client.
|
|
119
|
-
An API-key catalog therefore cannot safely populate routing for users whose
|
|
120
|
-
Codex authentication, plan, organization policy, or client surface differs.
|
|
121
|
-
|
|
122
|
-
## Options compared
|
|
123
|
-
|
|
124
|
-
| Option | Survives catalog changes | Works across Claude and Codex | Multi-user behavior | Offline/update behavior | Verdict |
|
|
125
|
-
|---|---:|---:|---|---|---|
|
|
126
|
-
| Concrete model names in issues | No. Every rename, replacement, or access change makes existing issues stale. | No. Names and effort controls are provider-specific. | Assumes every collaborator has the same entitlement and budget. | Old issues remain wrong until rewritten. | Reject. Suitable only for an explicit reproducibility pin in a provider-specific experiment. |
|
|
127
|
-
| Stable task intent resolved by user/org surface policy | Yes. Existing issues survive mapping changes. | Yes. Each surface resolves independently or inherits. | Preserves personal and organization choices. | Cached/local policy continues to work; unknown targets can inherit and warn. | **Adopt.** |
|
|
128
|
-
| Project-local concrete routing table | Partly. One table can be updated, but every checkout still receives volatile provider data. | Only by maintaining multiple provider sections. | Project config outranks user config on both surfaces, so the maintainer's preferences can override collaborators. | Fresh clones can start stale; offline discovery cannot repair it. | Reject as the default. Permit only explicit team policy/constraints. |
|
|
129
|
-
|
|
130
|
-
## Setup and update implications
|
|
131
|
-
|
|
132
|
-
### `setup-workflow`
|
|
133
|
-
|
|
134
|
-
`setup-workflow` should install or reconcile only the Kit-owned intent schema,
|
|
135
|
-
templates, validation, and a documented inheritance fallback. It may **offer**
|
|
136
|
-
to create a user-local routing policy for the detected surface, but only with
|
|
137
|
-
explicit consent and never as a committed project default.
|
|
138
|
-
|
|
139
|
-
Setup must not attempt to infer a complete routing table from `/v1/models`:
|
|
140
|
-
|
|
141
|
-
- API discovery requires credentials and network access.
|
|
142
|
-
- API availability is not equivalent to Claude Code or Codex subscription
|
|
143
|
-
availability across all supported providers and account types.
|
|
144
|
-
- A discovered model ID says nothing about the user's desired cost/capability
|
|
145
|
-
trade-off.
|
|
146
|
-
|
|
147
|
-
An interactive setup may validate explicitly selected targets using the active
|
|
148
|
-
surface and show a preview. Failure or absence of discovery should leave the
|
|
149
|
-
policy at `inherit`, not install guessed names.
|
|
150
|
-
|
|
151
|
-
### `kit-update`
|
|
152
|
-
|
|
153
|
-
`kit-update` should update the Kit-owned schema, resolver implementation, and
|
|
154
|
-
provider adapter capabilities transactionally. It must preserve user-owned
|
|
155
|
-
mappings and project-owned constraints. If the schema changes, migration must
|
|
156
|
-
be semantic (for example, rename an intent key), previewed, and reversible;
|
|
157
|
-
ordinary updates must not rewrite historical issues or replace personal model
|
|
158
|
-
choices.
|
|
159
|
-
|
|
160
|
-
At dispatch, the resolver should:
|
|
161
|
-
|
|
162
|
-
1. read the issue's stable intent;
|
|
163
|
-
2. apply organization/user policy and explicit session overrides according to
|
|
164
|
-
the active surface;
|
|
165
|
-
3. resolve or inherit without network-dependent mutation;
|
|
166
|
-
4. reject a malformed intent, but fall back to `inherit` with a visible warning
|
|
167
|
-
when a volatile target is unavailable;
|
|
168
|
-
5. record the effective model and effort in run evidence, not in the durable
|
|
169
|
-
issue contract.
|
|
170
|
-
|
|
171
|
-
This lets a later Kit release improve mappings for users who accept Kit
|
|
172
|
-
defaults while allowing a maintainer's user-local policy to evolve independently.
|
|
173
|
-
|
|
174
|
-
## Implication for #213
|
|
175
|
-
|
|
176
|
-
#213 should not hardcode `sol`, `terra`, `luna`, Claude aliases, or full model
|
|
177
|
-
IDs into the issue template or validator. It should instead establish the
|
|
178
|
-
provider-neutral intent schema and make `to-issues` emit that schema. The
|
|
179
|
-
execute-ready check should reject concrete provider model recommendations in
|
|
180
|
-
shared handoffs, while orchestration resolves the intent on the active surface.
|
|
181
|
-
|
|
182
|
-
The existing free-text `Recommended model: <Model [Effort]>` field conflates a
|
|
183
|
-
durable work classification with a volatile local decision. Replace it with
|
|
184
|
-
machine-readable intent and render the effective local recommendation only
|
|
185
|
-
when a session is actually dispatched.
|
|
186
|
-
|
|
187
|
-
## Open risks and decisions
|
|
188
|
-
|
|
189
|
-
1. **Vocabulary quality:** `judgment/development/mechanical` and
|
|
190
|
-
`deep/balanced/light` need task-based definitions and contract tests so they
|
|
191
|
-
do not become disguised provider tiers.
|
|
192
|
-
2. **Enforcement asymmetry:** Both surfaces can override model and effort for
|
|
193
|
-
subagents, but their precedence, supported values, organization controls,
|
|
194
|
-
and fallback behavior differ. The Kit must promise intent resolution, not
|
|
195
|
-
identical low-level enforcement.
|
|
196
|
-
3. **Unavailable targets:** silent substitution hides policy drift. Inheritance
|
|
197
|
-
should be visible in run evidence, and strict team policies may choose to
|
|
198
|
-
fail instead.
|
|
199
|
-
4. **Organization policy:** managed restrictions outrank personal/project
|
|
200
|
-
wishes. The resolver must treat the surface's effective selection as
|
|
201
|
-
authoritative.
|
|
202
|
-
5. **Reproducibility exception:** a benchmark or regression reproduction may
|
|
203
|
-
legitimately pin a provider/model snapshot. That is a distinct,
|
|
204
|
-
provider-specific execution constraint, not the normal issue-routing field.
|
|
205
|
-
6. **No universal discovery source:** model catalogs are useful validation
|
|
206
|
-
inputs where available, but cannot be the SSOT for setup or updates across
|
|
207
|
-
all supported account types and providers.
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# Wave 152 consumer acceptance and release checklist
|
|
2
|
-
|
|
3
|
-
Verified on 2026-07-19 for candidate `52ea49856a03f6e4bb13f24913990769126f81a8`.
|
|
4
|
-
|
|
5
|
-
## Candidate
|
|
6
|
-
|
|
7
|
-
- Source repository: `iKon85/agent-workflow-kit`
|
|
8
|
-
- Candidate tarball: `/tmp/wave152-final-candidate.8CRnlP/ikon85-agent-workflow-kit-0.28.0.tgz`
|
|
9
|
-
- Extracted kit: `/tmp/wave152-final-package.QQTOvE/package/dist-kit`
|
|
10
|
-
- Disposable consumer checkout: `/tmp/wave152-testreporter.ZZg8zY/checkout`
|
|
11
|
-
- Consumer base: `iKon85/Testreporter` `origin/main` at
|
|
12
|
-
`76bcaa91`
|
|
13
|
-
|
|
14
|
-
The temporary paths record the exact acceptance input. They are not release
|
|
15
|
-
artifacts; a repeat run creates fresh temporary directories and a fresh
|
|
16
|
-
test-only marker identity.
|
|
17
|
-
|
|
18
|
-
## Repeatable procedure
|
|
19
|
-
|
|
20
|
-
1. Build the kit from the candidate commit, create an npm tarball, extract it,
|
|
21
|
-
and run its `kit:build`. Install that built kit into a disposable checkout
|
|
22
|
-
of the consumer's current `origin/main`.
|
|
23
|
-
2. Run `scripts/codex-exec.sh new` with the `review` profile and `read-only`
|
|
24
|
-
mode. Capture the opaque run ID, resume it for round 2, verify both rounds
|
|
25
|
-
return `OK`, then finalize and verify that the run state is deleted.
|
|
26
|
-
3. Run `scripts/codex-exec.sh new` with the `build` profile and
|
|
27
|
-
`workspace-write` mode. Ask it to create only an allowlisted ignored scratch
|
|
28
|
-
file containing a fixed sentinel, verify the sentinel, finalize the run,
|
|
29
|
-
and remove the scratch file.
|
|
30
|
-
4. Create a disposable consumer issue through `scripts/board-sync.py` with a
|
|
31
|
-
unique `wave-stub-source` marker. Resolve it through
|
|
32
|
-
`scripts/find-by-marker.py`, verify one exact match, move its board status to
|
|
33
|
-
Done, close it, and repeat the lookup. The terminal lookup must report the
|
|
34
|
-
closed/user-decision branch and an all-open scan must find zero disposable
|
|
35
|
-
issues.
|
|
36
|
-
|
|
37
|
-
## Acceptance evidence
|
|
38
|
-
|
|
39
|
-
| Smoke | Evidence | Result |
|
|
40
|
-
|---|---|---|
|
|
41
|
-
| `codex-review` read-only | Real new round returned `OK` with a thread; resume round 2 returned `OK`; finalize deleted run state. | PASS |
|
|
42
|
-
| `codex-build` workspace-write | Created only ignored `_ai_temp/wave152-build-smoke.txt` with `WAVE152_BUILD_SMOKE_OK`; finalize succeeded; scratch file removed. | PASS |
|
|
43
|
-
| Marker roundtrip | Identity `wave-stub-source=awkit-wave152-20260719-acceptance-52ea498` created Testreporter issue #2168 through board-sync; exact lookup was unique; board status became Done; issue was closed; final lookup selected closed/user-decision; `openDisposable=0`. | PASS |
|
|
44
|
-
|
|
45
|
-
No open disposable issue or scratch file remained after acceptance. The closed
|
|
46
|
-
issue remains deliberate cleanup evidence and is excluded from open productive
|
|
47
|
-
work by the all-state lookup's closed/user-decision result.
|
|
48
|
-
|
|
49
|
-
## Counted surface census: 31 of 31
|
|
50
|
-
|
|
51
|
-
The denominator is re-derived from the current skill manifest and the delivery
|
|
52
|
-
surfaces, not from the changed-file list.
|
|
53
|
-
|
|
54
|
-
| Surface class | Derivation | Covered |
|
|
55
|
-
|---|---|---:|
|
|
56
|
-
| Skill surfaces | Nine records from `.claude/skills/skill-manifest.json`: four Claude-only Codex skills (4), three dual-surface marker callers (6), dual-surface `to-issues` (2), and dual-surface `wrapup` (2). The four Codex skills intentionally have no invented `.agents` mirrors. | 14/14 |
|
|
57
|
-
| Bundle registrations | The five Wave helpers in `HELPER_FILES`, with their declared kind and mode. | 5/5 |
|
|
58
|
-
| Checked manifest entries | The same five helpers in the freshly built and checked `agent-workflow-kit.package.json`. | 5/5 |
|
|
59
|
-
| Test surfaces | Harness scenarios, thin-skill lifecycle, marker library/CLI, anchor renderer/promotion, wrapup contradiction absence, and bundle/manifest/tarball modes. | 6/6 |
|
|
60
|
-
| Shared board callsite | `scripts/board-sync.py` imports and uses the shared marker parser instead of retaining a second grammar. | 1/1 |
|
|
61
|
-
| **Total** | **No unexplained gap.** | **31/31** |
|
|
62
|
-
|
|
63
|
-
The exact manifest-derived skill set is:
|
|
64
|
-
|
|
65
|
-
- Claude-only: `codex-review`, `codex-build`, `grill-me-codex`,
|
|
66
|
-
`grill-with-docs-codex`.
|
|
67
|
-
- Dual-surface: `to-prd`, `to-waves`, `board-to-waves`, `to-issues`, `wrapup`.
|
|
68
|
-
|
|
69
|
-
The five helper modes are:
|
|
70
|
-
|
|
71
|
-
- `scripts/marker_lib.py` — `0644`
|
|
72
|
-
- `scripts/find-by-marker.py` — `0755`
|
|
73
|
-
- `scripts/codex-exec.sh` — `0755`
|
|
74
|
-
- `scripts/codex_proc.py` — `0644`
|
|
75
|
-
- `scripts/render-anchor.py` — `0755`
|
|
76
|
-
|
|
77
|
-
## Release checklist
|
|
78
|
-
|
|
79
|
-
- [x] K1-K5 integrated into one candidate.
|
|
80
|
-
- [x] K1, K2, and K4 passed independent Standards and Spec reviews.
|
|
81
|
-
- [x] Candidate tarball passed all three real consumer smokes.
|
|
82
|
-
- [x] Disposable consumer issue and scratch file cleaned up; no open disposable
|
|
83
|
-
issue remains.
|
|
84
|
-
- [x] Bundle, built-manifest, and npm-tarball mode assertions cover all five
|
|
85
|
-
helpers.
|
|
86
|
-
- [x] Surface census is 31 of 31 with zero unexplained gaps.
|
|
87
|
-
- [x] Prepared the user-authorized single minor bump from 0.28.0 to 0.29.0 and
|
|
88
|
-
refresh checked release state.
|
|
89
|
-
- [x] `release:prepare -- --version 0.29.0` completed its release guard, full
|
|
90
|
-
test suite, manifest rebuild, and dry-run npm pack.
|
|
91
|
-
- [x] Re-ran the full suite (354 Node tests and 277 Python tests),
|
|
92
|
-
`kit:staleness` (`OK`), and `release:guard` (`OK (minor)`).
|
|
93
|
-
- [x] Created and extracted the final `0.29.0` npm tarball (380 package
|
|
94
|
-
entries); all five helper modes matched both pack metadata and extracted
|
|
95
|
-
filesystem modes.
|
|
96
|
-
- [ ] After merge, let the trusted release workflow publish and verify
|
|
97
|
-
`npm run release:status` reports `released` before declaring the release
|
|
98
|
-
complete.
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Wave 43 script and hook census
|
|
2
|
-
|
|
3
|
-
Verified on 2026-07-15 against `agent-workflow-kit` commit
|
|
4
|
-
`2d47dce23d9204b44951334c3c370bdb997c0943` and Testreporter commit
|
|
5
|
-
[`458747ebe8d67f66840cb3c1e75284cf2be7fb20`](https://github.com/iKon85/Testreporter/tree/458747ebe8d67f66840cb3c1e75284cf2be7fb20).
|
|
6
|
-
This is the research input for issue #59. It records facts only; it does not make
|
|
7
|
-
ship, opt-in, profile-seam, or maintenance decisions.
|
|
8
|
-
|
|
9
|
-
## Method and reconciliation
|
|
10
|
-
|
|
11
|
-
The public-repository denominator is every tracked file below `scripts/**` and
|
|
12
|
-
`.claude/hooks/**`, excluding `test_*.py`, `*.test.mjs`, and the metadata file
|
|
13
|
-
`scripts/.npmignore`. The recount is:
|
|
14
|
-
|
|
15
|
-
```text
|
|
16
|
-
68 tracked entries
|
|
17
|
-
- 31 tests
|
|
18
|
-
- 1 metadata file
|
|
19
|
-
= 36 current script/hook entries
|
|
20
|
-
= 32 scripts + 4 hooks
|
|
21
|
-
= 30 shipped helpers + 6 maintainer-only helpers
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
The shipped/helper split is derived from
|
|
25
|
-
[`src/lib/bundle.mjs`](../../src/lib/bundle.mjs), whose `HELPER_FILES` list is
|
|
26
|
-
the public distribution authority. The historical input is the 26-candidate
|
|
27
|
-
list in [Testreporter #1976](https://github.com/iKon85/Testreporter/issues/1976),
|
|
28
|
-
originally reconciled as 11 portable plus 15 generalize-first candidates in
|
|
29
|
-
[Testreporter #1964](https://github.com/iKon85/Testreporter/issues/1964).
|
|
30
|
-
|
|
31
|
-
Fresh exact-path comparison:
|
|
32
|
-
|
|
33
|
-
```text
|
|
34
|
-
Historical candidates: 26/26 accounted for
|
|
35
|
-
Still present at the exact Testreporter path: 26/26
|
|
36
|
-
Present at the exact public-repo path: 0/26
|
|
37
|
-
Proven exact rename in the public repo: 0/26
|
|
38
|
-
Explicitly retired by a locked decision: 0/26
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Therefore every historical row is classified as **present in the current
|
|
42
|
-
consumer and absent from the current public denominator**. Related public
|
|
43
|
-
primitives are called out only as inputs to the later grill; similarity is not
|
|
44
|
-
treated as proof of a rename or as a ship decision.
|
|
45
|
-
|
|
46
|
-
## Fresh public denominator: 36 of 36
|
|
47
|
-
|
|
48
|
-
| Current path | Distribution status |
|
|
49
|
-
|---|---|
|
|
50
|
-
| `.claude/hooks/_hook_utils.py` | shipped helper |
|
|
51
|
-
| `.claude/hooks/drift-guard.py` | shipped helper |
|
|
52
|
-
| `.claude/hooks/skill-drift-hint.py` | shipped helper |
|
|
53
|
-
| `.claude/hooks/sync-board-status.py` | shipped helper |
|
|
54
|
-
| `scripts/anchor_table.py` | shipped helper |
|
|
55
|
-
| `scripts/board-sync.py` | shipped helper |
|
|
56
|
-
| `scripts/board_config.py` | shipped helper |
|
|
57
|
-
| `scripts/board_fields.py` | shipped helper |
|
|
58
|
-
| `scripts/build-kit.mjs` | maintainer-only |
|
|
59
|
-
| `scripts/census/delta.mjs` | shipped helper |
|
|
60
|
-
| `scripts/census/fingerprint.mjs` | shipped helper |
|
|
61
|
-
| `scripts/census/index.mjs` | shipped helper |
|
|
62
|
-
| `scripts/census/scan.mjs` | shipped helper |
|
|
63
|
-
| `scripts/census/state.mjs` | shipped helper |
|
|
64
|
-
| `scripts/census/transaction.mjs` | shipped helper |
|
|
65
|
-
| `scripts/check-kit-staleness.mjs` | maintainer-only |
|
|
66
|
-
| `scripts/execute-ready-check.py` | shipped helper |
|
|
67
|
-
| `scripts/grill-census-wiring-guard.mjs` | maintainer-only |
|
|
68
|
-
| `scripts/issue_deps.py` | shipped helper |
|
|
69
|
-
| `scripts/kit-release.mjs` | shipped helper |
|
|
70
|
-
| `scripts/kit-update-pr.mjs` | shipped helper |
|
|
71
|
-
| `scripts/lib/audit-refs.mjs` | maintainer-only |
|
|
72
|
-
| `scripts/lib/scrub.mjs` | maintainer-only |
|
|
73
|
-
| `scripts/loc_offender_core.py` | shipped helper |
|
|
74
|
-
| `scripts/loc_offender_gate.py` | shipped helper |
|
|
75
|
-
| `scripts/node_kind.py` | shipped helper |
|
|
76
|
-
| `scripts/portability_profile_scan.py` | maintainer-only |
|
|
77
|
-
| `scripts/pr-body-check.py` | shipped helper |
|
|
78
|
-
| `scripts/program_graph.py` | shipped helper |
|
|
79
|
-
| `scripts/program_graph_parse.py` | shipped helper |
|
|
80
|
-
| `scripts/program_graph_validate.py` | shipped helper |
|
|
81
|
-
| `scripts/program_sync.py` | shipped helper |
|
|
82
|
-
| `scripts/release-delta-guard.mjs` | shipped helper |
|
|
83
|
-
| `scripts/release-parity.mjs` | shipped helper |
|
|
84
|
-
| `scripts/release-state.mjs` | shipped helper |
|
|
85
|
-
| `scripts/wrapup-land.py` | shipped helper |
|
|
86
|
-
|
|
87
|
-
## Historical candidate crosswalk: 26 of 26
|
|
88
|
-
|
|
89
|
-
All Testreporter links below are pinned to the verified consumer commit. “No
|
|
90
|
-
dedicated tracked test found” means the fresh tracked-tree search found no test
|
|
91
|
-
named for that candidate; it is not a statement about runtime correctness.
|
|
92
|
-
|
|
93
|
-
| Historical candidate | Current public status and adjacent evidence | Current consumer dependency | Existing consumer test evidence |
|
|
94
|
-
|---|---|---|---|
|
|
95
|
-
| `scripts/audit_gate.py` | Exact path absent. | [`package.json#L44`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/package.json#L44) and `.githooks/pre-push` invoke it. | [`scripts/test_audit_gate.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_audit_gate.py), [`scripts/test_pre_push_audit_gate.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_pre_push_audit_gate.py) |
|
|
96
|
-
| `scripts/cleanup-worktrees.sh` | Exact path absent. Public `scripts/wrapup-land.py` has adjacent worktree-cleanup behavior, not a proven rename. | No separate tracked consumer found beyond direct/manual use. | No dedicated tracked test found. |
|
|
97
|
-
| `scripts/install-git-hooks.sh` | Exact path absent. | [`package.json#L45`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/package.json#L45) invokes it during postinstall. | [`scripts/test_install_git_hooks.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_install_git_hooks.py) |
|
|
98
|
-
| `scripts/ensure-gitleaks.sh` | Exact path absent. | [`package.json#L45`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/package.json#L45) invokes it during postinstall; `docs/security/secret-scan.md` documents it. | No dedicated tracked test found. |
|
|
99
|
-
| `.claude/hooks/block-bg-double-background.py` | Exact path absent. | [`.claude/settings.json#L85`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L85) wires it. | [`.claude/hooks/test_block_bg_double_background.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_block_bg_double_background.py) |
|
|
100
|
-
| `.claude/hooks/block-npm-install-in-pnpm.py` | Exact path absent. | [`.claude/settings.json#L75`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L75) wires it. | [`.claude/hooks/test_block_npm_install_in_pnpm.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_block_npm_install_in_pnpm.py) |
|
|
101
|
-
| `.claude/hooks/block-secrets.py` | Exact path absent. | [`.claude/settings.json#L56-L65`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L56-L65) wires it at two hook events. | [`.claude/hooks/test_block_secrets_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_block_secrets_smoke.py) |
|
|
102
|
-
| `.claude/hooks/branch-watch.py` | Exact path absent. | [`.claude/settings.json#L161`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L161) wires it. | [`.claude/hooks/test_branch_watch_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_branch_watch_smoke.py) |
|
|
103
|
-
| `.claude/hooks/grep-shim-guard.py` | Exact path absent. | [`.claude/settings.json#L80`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L80) wires it. | [`.claude/hooks/test_grep_shim_guard.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_grep_shim_guard.py) |
|
|
104
|
-
| `.claude/hooks/recon-size-hint.py` | Exact path absent. | [`.claude/settings.json#L134`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L134) wires it. | [`.claude/hooks/test_recon_size_hint.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_recon_size_hint.py) |
|
|
105
|
-
| `.claude/hooks/loc-offender-forewarn.py` | Exact path absent. Public `scripts/loc_offender_core.py` and `scripts/loc_offender_gate.py` are related shipped primitives, not a proven rename. | [`.claude/settings.json#L18`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L18) wires it. | [`scripts/test_loc_offender_forewarn.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_loc_offender_forewarn.py) |
|
|
106
|
-
| `scripts/bump-version.sh` | Exact path absent. Public `scripts/kit-release.mjs` contains tested SemVer and metadata-update behavior, not a proven rename. | No separate consumer wiring found; the script is directly invoked. | No dedicated tracked test found for the historical script. |
|
|
107
|
-
| `scripts/consolidate-memories.sh` | Exact path absent. | The two historical memory templates name it as their consolidator. | No dedicated tracked test found. |
|
|
108
|
-
| `scripts/memory-templates/meta_decision_layer_choice.md` | Exact path absent. | Input consumed by `scripts/consolidate-memories.sh`. | No dedicated tracked test found. |
|
|
109
|
-
| `scripts/memory-templates/meta_memory_lifecycle.md` | Exact path absent. | Input consumed by `scripts/consolidate-memories.sh`. | No dedicated tracked test found. |
|
|
110
|
-
| `scripts/setup-worktree.sh` | Exact path absent. Public workflow prose allows a project helper or plain `git worktree add`; that is not a rename. | Central Testreporter worktree, port, and local-env setup primitive referenced by workflow documentation. | [`scripts/setup-worktree.test.mjs`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/setup-worktree.test.mjs), [`scripts/test_pre_push_loc_gate.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_pre_push_loc_gate.py) |
|
|
111
|
-
| `.claude/hooks/baseline-capture-hint.py` | Exact path absent. | [`.claude/settings.json#L114`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L114) wires it. | [`.claude/hooks/test_baseline_capture_hint_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_baseline_capture_hint_smoke.py) |
|
|
112
|
-
| `.claude/hooks/branch-context.py` | Exact path absent. | [`.claude/settings.json#L13`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L13) wires it. | [`.claude/hooks/test_branch_context_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_branch_context_smoke.py) |
|
|
113
|
-
| `.claude/hooks/convention-drift-hint.py` | Exact path absent. Public `.claude/hooks/skill-drift-hint.py` and `drift-guard.py` are narrower adjacent mechanisms, not proven renames. | [`.claude/settings.json#L33`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L33) and rule `SOURCES.txt` files refer to it. | No dedicated tracked test found. |
|
|
114
|
-
| `.claude/hooks/enforce-worktree.py` | Exact path absent. | [`.claude/settings.json#L109`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L109) wires it. | [`.claude/hooks/test_enforce_worktree.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_enforce_worktree.py) |
|
|
115
|
-
| `.claude/hooks/enforce-worktree-cwd.py` | Exact path absent. | [`.claude/settings.json#L95`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L95) wires it. | [`.claude/hooks/test_enforce_worktree_cwd_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_enforce_worktree_cwd_smoke.py) |
|
|
116
|
-
| `.claude/hooks/enforce-worktree-discipline.py` | Exact path absent. | [`.claude/settings.json#L70`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L70) wires it. | [`.claude/hooks/test_enforce_worktree_discipline_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_enforce_worktree_discipline_smoke.py) |
|
|
117
|
-
| `.claude/hooks/migration-snapshot-reminder.py` | Exact path absent. | [`.claude/settings.json#L166`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L166) wires it. | [`.claude/hooks/test_migration_snapshot_reminder_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_migration_snapshot_reminder_smoke.py) |
|
|
118
|
-
| `.claude/hooks/pre-refactor-sweep.py` | Exact path absent. | [`.claude/settings.json#L23`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L23) wires it. | [`.claude/hooks/test_pre_refactor_sweep.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_pre_refactor_sweep.py) |
|
|
119
|
-
| `.claude/hooks/typecheck-on-stop.sh` | Exact path absent. | [`.claude/settings.json#L145`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L145) wires it. | No dedicated tracked test found. |
|
|
120
|
-
| `.claude/hooks/slice-handoff-hint.py` | Exact path absent. | [`.claude/settings.json#L44`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L44) wires it. | [`.claude/hooks/test_slice_handoff_hint_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_slice_handoff_hint_smoke.py) |
|
|
121
|
-
|
|
122
|
-
## Inputs for the decision grill
|
|
123
|
-
|
|
124
|
-
The crosswalk establishes the decision set but intentionally leaves its verdict
|
|
125
|
-
columns blank. Issue #59 must decide, with the user, each row’s outcome, opt-in,
|
|
126
|
-
profile seam, security and maintenance cost, and ship verdict. In particular,
|
|
127
|
-
the adjacent public primitives identified above must be compared behaviorally
|
|
128
|
-
before any row is called replaced, redundant, or already shipped.
|
package/scripts/build-kit.mjs
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/** Build the distributable kit from this public repository's current SSOT. */
|
|
2
|
-
import { chmod, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { dirname, join, relative } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { collectBundle } from '../src/lib/bundle.mjs';
|
|
6
|
-
import { sha256 } from '../src/lib/hash.mjs';
|
|
7
|
-
import { scrub } from './lib/scrub.mjs';
|
|
8
|
-
import { auditExecRefs, auditModuleImports, auditSkillNameRefs } from './lib/audit-refs.mjs';
|
|
9
|
-
|
|
10
|
-
const ROOT_FILES = ['LICENSE', 'README.md', 'PROVENANCE.md'];
|
|
11
|
-
const DOC_ASSETS = ['index.html', 'methodology.html', 'methodology.svg', 'workflow.png'];
|
|
12
|
-
|
|
13
|
-
const isBinary = (buf) => buf.includes(0);
|
|
14
|
-
|
|
15
|
-
async function walk(dir) {
|
|
16
|
-
const files = [];
|
|
17
|
-
let entries;
|
|
18
|
-
try { entries = await readdir(dir, { withFileTypes: true }); }
|
|
19
|
-
catch (error) { if (error.code === 'ENOENT') return files; throw error; }
|
|
20
|
-
for (const entry of entries) {
|
|
21
|
-
const path = join(dir, entry.name);
|
|
22
|
-
if (entry.isDirectory()) files.push(...await walk(path));
|
|
23
|
-
else if (entry.isFile()) files.push(path);
|
|
24
|
-
}
|
|
25
|
-
return files.sort();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function writeOut(path, content, mode = 0o644) {
|
|
29
|
-
await mkdir(dirname(path), { recursive: true });
|
|
30
|
-
await writeFile(path, content);
|
|
31
|
-
await chmod(path, mode);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function copySource(repoRoot, distDir, source, destination, mode = 0o644, shouldScrub = true) {
|
|
35
|
-
const raw = await readFile(join(repoRoot, source));
|
|
36
|
-
const content = shouldScrub && !isBinary(raw)
|
|
37
|
-
? Buffer.from(scrub(raw.toString('utf8')), 'utf8') : raw;
|
|
38
|
-
await writeOut(join(distDir, destination), content, mode);
|
|
39
|
-
return content;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function shipBundle(repoRoot, distDir, bundleFiles) {
|
|
43
|
-
const entries = [];
|
|
44
|
-
for (const file of bundleFiles) {
|
|
45
|
-
const content = await copySource(repoRoot, distDir, file.src, file.dest, file.mode);
|
|
46
|
-
entries.push({
|
|
47
|
-
path: file.dest, kind: file.kind, ownerSkill: file.ownerSkill,
|
|
48
|
-
surface: file.surface, installRole: file.installRole,
|
|
49
|
-
sha256: sha256(content), mode: file.mode, origin: 'kit',
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
return entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function shipRepositoryFiles(repoRoot, distDir, packageJson) {
|
|
56
|
-
for (const file of ROOT_FILES) await copySource(repoRoot, distDir, file, file, 0o644, false);
|
|
57
|
-
for (const file of DOC_ASSETS) {
|
|
58
|
-
await copySource(repoRoot, distDir, `docs/${file}`, `docs/${file}`);
|
|
59
|
-
}
|
|
60
|
-
for (const absolute of await walk(join(repoRoot, 'src'))) {
|
|
61
|
-
const path = `src/${relative(join(repoRoot, 'src'), absolute)}`;
|
|
62
|
-
await copySource(repoRoot, distDir, path, path);
|
|
63
|
-
}
|
|
64
|
-
const distributable = {
|
|
65
|
-
...packageJson,
|
|
66
|
-
repository: {
|
|
67
|
-
type: 'git', url: 'git+https://github.com/iKon85/agent-workflow-kit.git',
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
await writeOut(join(distDir, 'package.json'), Buffer.from(`${JSON.stringify(distributable, null, 2)}\n`));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async function auditBuild(repoRoot, distDir, manifest, entries) {
|
|
74
|
-
const bodies = new Map();
|
|
75
|
-
for (const entry of entries) {
|
|
76
|
-
if (entry.path.endsWith('.md') || entry.path.endsWith('.py')) {
|
|
77
|
-
bodies.set(entry.path, await readFile(join(distDir, entry.path), 'utf8'));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
const localModules = (await Promise.all(
|
|
81
|
-
['scripts', '.claude/hooks'].map(async (dir) => {
|
|
82
|
-
try { return await readdir(join(repoRoot, dir)); } catch { return []; }
|
|
83
|
-
}),
|
|
84
|
-
)).flat().filter((name) => name.endsWith('.py')).map((name) => name.slice(0, -3));
|
|
85
|
-
const known = Object.keys(manifest.skills);
|
|
86
|
-
const published = known.filter((name) => manifest.skills[name].publish);
|
|
87
|
-
const read = (path) => bodies.get(path) ?? null;
|
|
88
|
-
const failures = [
|
|
89
|
-
...auditExecRefs(entries, read).map((v) => `${v.file} -> ${v.ref}`),
|
|
90
|
-
...auditModuleImports(entries, read, localModules).map((v) => `${v.file} -> ${v.module}`),
|
|
91
|
-
...auditSkillNameRefs(entries, read, { known, published }).map((v) => `${v.file} -> ${v.skill}`),
|
|
92
|
-
];
|
|
93
|
-
if (failures.length) throw new Error(`build-kit: dangling dependencies:\n${failures.join('\n')}`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export async function buildKit({ repoRoot, distDir } = {}) {
|
|
97
|
-
repoRoot ??= join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
98
|
-
distDir ??= join(repoRoot, 'dist-kit');
|
|
99
|
-
const manifest = JSON.parse(await readFile(join(repoRoot, '.claude/skills/skill-manifest.json'), 'utf8'));
|
|
100
|
-
const packageJson = JSON.parse(await readFile(join(repoRoot, 'package.json'), 'utf8'));
|
|
101
|
-
await rm(distDir, { recursive: true, force: true });
|
|
102
|
-
await mkdir(distDir, { recursive: true });
|
|
103
|
-
const { files } = await collectBundle(repoRoot, manifest);
|
|
104
|
-
const entries = await shipBundle(repoRoot, distDir, files);
|
|
105
|
-
await shipRepositoryFiles(repoRoot, distDir, packageJson);
|
|
106
|
-
await writeOut(join(distDir, 'agent-workflow-kit.package.json'), Buffer.from(
|
|
107
|
-
`${JSON.stringify({ kitVersion: packageJson.version, files: entries }, null, 2)}\n`,
|
|
108
|
-
));
|
|
109
|
-
await auditBuild(repoRoot, distDir, manifest, entries);
|
|
110
|
-
return { distDir, kitVersion: packageJson.version, fileCount: entries.length };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
114
|
-
buildKit().then(({ distDir, kitVersion, fileCount }) => {
|
|
115
|
-
console.log(`built ${distDir} · kitVersion ${kitVersion} · ${fileCount} files`);
|
|
116
|
-
}).catch((error) => { console.error(error.message); process.exitCode = 1; });
|
|
117
|
-
}
|