@ikon85/agent-workflow-kit 0.35.0 → 0.36.1

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.
@@ -54,6 +54,10 @@ release contain the same artifact.
54
54
  data, infer an external fact, or manufacture `pending`/`not-applicable` to
55
55
  make a capability appear ready.
56
56
 
57
+ File identity includes the package-declared mode as well as bytes. A
58
+ mode-only Core delta is an update and must be applied transactionally; it
59
+ must not survive preview as `unchanged` only to fail candidate verification.
60
+
57
61
  Readiness-schema adoption also keeps the Claude and Codex instruction
58
62
  surfaces compatible. When exactly one applicable instruction surface has a
59
63
  non-empty `## Prod` section and another has no such section, the staged
@@ -103,16 +107,25 @@ release contain the same artifact.
103
107
 
104
108
  For each conflicted kit-shipped file, always ask the user whether the local
105
109
  edit is a generic improvement or project-specific; never decide or act
106
- automatically. For a generic improvement, offer to file an issue in the
107
- public kit repository and keep the local edit in place as a bridge until a
108
- kit release containing the improvement lands. Before running
109
- `gh issue create --repo <owner>/agent-workflow-kit`, show a sanitized preview
110
- of the exact title and body with consumer identifiers and secrets stripped,
111
- then require the user's explicit approval. The consumer user does not need
112
- to be a kit maintainer. For a project-specific edit, recommend
110
+ automatically. For a generic improvement retained as a bridge, run
111
+ `contribute status <path> --surface=pre-update` and follow only its
112
+ repository-capability routes. Missing, disabled, invalid, or unverifiable
113
+ configuration is a generic Consumer and receives preserve/Explicit-fork
114
+ guidance, never maintainer language or an inferred upstream target. A valid
115
+ capability may add local preparation and may describe an upstream pull
116
+ request, but the latter still needs a sanitized exact preview and separate
117
+ explicit approval before any remote command. For a project-specific edit, recommend
113
118
  `npx @ikon85/agent-workflow-kit@latest own <path> --as=explicit-fork` so
114
- future updates treat that path as an independent fork. A generic experiment
115
- retained only until it returns upstream uses `--as=contribution-bridge`.
119
+ future updates treat that path as an independent fork. `own` snapshots the
120
+ path's current local bytes as the explicit-fork ledger identity, including
121
+ when it follows an already-detected local edit. A generic experiment
122
+ retained only until it returns upstream uses
123
+ `npx @ikon85/agent-workflow-kit@latest contribute start <path>`. Prepare its
124
+ bounded local artifact, when the route report permits it, with `contribute prepare <path>
125
+ --output=.agent-workflow-kit/contributions/<name>.json`. Both commands are
126
+ local-only; opening an issue/PR or pushing remains a separate explicit
127
+ approval. A matching released Core version retires the bridge during
128
+ reimport.
116
129
 
117
130
  4. If a candidate is interrupted, discard its reported stage directory or
118
131
  resume the transaction through the update API's `resumeFrom` option. Do not
@@ -164,9 +164,17 @@ Before formulating a patch in step 4, place **every** friction point on the thre
164
164
 
165
165
  **A GitHub issue is NOT a weight tier.** A real follow-up = work to track → `python3 scripts/board-sync.py create` (step-4 table), **orthogonal** to the ladder; its "weight" follows the follow-up scope. The ladder classifies **config patches**, not "turn it into a ticket".
166
166
 
167
- **Kit-repo routing target (always ask; never automatic).** When a finding lands on a kit-shipped file (a consumer-manifest entry with kit origin), ask whether the improvement is generic or project-specific. For a generic improvement, offer to file a lightweight issue against the public kit repo: a title plus a short body that states the finding, affected file, and why it is generic. For a project-specific improvement, recommend `own` (keep it consumer-owned). The consumer user does not need to be the kit maintainer.
168
-
169
- Before any `gh issue create --repo <owner>/agent-workflow-kit` runs, show the user a **sanitized preview** of the exact title and body with consumer identifiers and secrets stripped. Create the issue only after the user explicitly approves that exact text; if the title or body changes, show the revised preview and ask again. This approval is additional to the per-patch approval in step 5.
167
+ **Kit-repo routing target (capability-driven; never automatic).** When a finding
168
+ lands on a kit-shipped file (a consumer-manifest entry with kit origin), ask
169
+ whether the improvement is generic or project-specific. If it enters a
170
+ Contribution Bridge, run `agent-workflow-kit contribute status <path>
171
+ --surface=retro` and use only the reported repository-capability routes.
172
+ Missing, disabled, invalid, or unverifiable configuration is a generic Consumer:
173
+ offer preserve or Explicit fork, never infer maintainer status or an upstream
174
+ target from identity. A valid capability may offer local preparation. Before
175
+ any reported remote route runs, show the **sanitized exact preview** and require
176
+ separate explicit approval; changing the preview requires approval again. For a
177
+ project-specific improvement, recommend `own` (keep it consumer-owned).
170
178
 
171
179
  **Target missing in the project — separate two cases cleanly:**
172
180
  - **(a) Tier skill missing entirely** (e.g. a foreign project without `spec-self-critique`): no durable spec-time gate exists. **Memory is NOT a substitute** — passive recall doesn't catch a recurring spec defect before building. Report honestly: *"this project has no durable target for this tier"* + propose a `/setup-workflow` follow-up. **No fake guard via memory.**
@@ -293,7 +293,8 @@ decisions without repository evidence and user confirmation.
293
293
  > manifest. It is advisory only: it never blocks, reads the manifest once, uses
294
294
  > no network, and silently fails open when the manifest cannot be read. Shell
295
295
  > redirection, formatters, and IDE edits are knowingly outside its coverage; the
296
- > skills remain the rule's primary carrier.
296
+ > skills remain the rule's primary carrier. Its Contribution Bridge follow-up
297
+ > calls the same read-only route resolver with `--surface=guard`.
297
298
 
298
299
  Activate the shipped hook by reconciling this exact entry into
299
300
  `.claude/settings.json`:
@@ -357,6 +358,26 @@ unaffected surfaces, autonomy, and advanced values. Re-read the profile before
357
358
  activation and use its fingerprint plus the exclusive profile lock; a
358
359
  concurrent user-local change blocks activation and remains byte-preserved.
359
360
 
361
+ ### 2i. Section A10 — Optional contribution return routing
362
+
363
+ > Contribution return routing lets a repository advertise a verifiable Kit
364
+ > upstream without guessing who the user is. It controls offered routes, never
365
+ > remote authorization.
366
+
367
+ Read [contribution-routing.md](./contribution-routing.md) in full. If
368
+ `contributionRouting` is absent, ask whether this repository should advertise
369
+ an upstream contribution route. **Yes** records only the user-confirmed
370
+ owner/repository and local Git remote after verifying that the remote URL
371
+ matches. **Later / No** leaves the section absent or records `enabled: false`
372
+ only when the user requests a durable opt-out. Adopt an existing valid section
373
+ without normalization and preserve every other profile section and unknown key.
374
+
375
+ Missing, disabled, contradictory, or unverifiable configuration must keep the
376
+ generic preserve/Explicit-fork routes. Never infer capability from username,
377
+ machine, checkout path, repository name, credentials, or current GitHub login.
378
+ Even a valid capability authorizes local preparation only; a pull request,
379
+ push, publish, or merge remains a separate explicit approval.
380
+
360
381
  ### 3. Section B — Triage labels
361
382
 
362
383
  > When `triage` processes an incoming issue it applies labels (or your tracker's equivalent). It needs strings you've actually configured, or it creates duplicates.
@@ -0,0 +1,52 @@
1
+ # Contribution return routing
2
+
3
+ Contribution return is an optional repository capability. It controls which
4
+ routes agents may *offer* for an explicit Contribution Bridge; it never grants
5
+ permission to mutate a remote.
6
+
7
+ The consumer-owned section in `docs/agents/workflow-capabilities.json` is:
8
+
9
+ ```json contribution-routing-capability
10
+ {
11
+ "contributionRouting": {
12
+ "schemaVersion": 1,
13
+ "enabled": true,
14
+ "upstream": {
15
+ "repository": "<owner>/<repository>",
16
+ "remote": "<local-git-remote>"
17
+ },
18
+ "workflows": {
19
+ "prepareLocal": true,
20
+ "upstreamPullRequest": {
21
+ "enabled": true,
22
+ "requiresExplicitApproval": true
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ The resolver accepts the maintainer-capable route only when the configured Git
30
+ remote exists and its GitHub owner/repository matches `upstream.repository`.
31
+ It does not inspect usernames, home paths, machine names, the consumer
32
+ repository name, credentials, or GitHub account identity.
33
+
34
+ - Missing configuration is a generic Consumer: offer preserve or Explicit fork.
35
+ - `enabled: false` is an explicit opt-out with the same generic routes.
36
+ - Invalid, contradictory, or unverifiable configuration fails closed to those
37
+ generic routes and reports one bounded diagnostic.
38
+ - Valid configuration additionally offers local artifact preparation. It may
39
+ describe an upstream pull-request route only with
40
+ `requiresExplicitApproval: true`; this flag documents the gate and does not
41
+ satisfy it.
42
+
43
+ Use the same read-only resolver on every surface:
44
+
45
+ ```sh
46
+ agent-workflow-kit contribute status <path> --surface=retro
47
+ agent-workflow-kit contribute status <path> --surface=pre-update
48
+ agent-workflow-kit contribute status <path> --surface=guard
49
+ ```
50
+
51
+ Only `contribute prepare` writes a local bounded artifact. No contribution
52
+ command opens an issue or pull request, pushes, publishes, or merges.
@@ -12,12 +12,6 @@ from pathlib import Path
12
12
 
13
13
  MANIFEST = "agent-workflow-kit.json"
14
14
  TOOLS = {"Edit", "Write"}
15
- HINT = (
16
- "This file has kit origin. Before editing, ask: should this change go "
17
- "upstream to agent-workflow-kit, or should the consumer own this file?"
18
- )
19
-
20
-
21
15
  def manifest_path(file_path: str, root: Path) -> str | None:
22
16
  try:
23
17
  target = Path(file_path)
@@ -28,31 +22,42 @@ def manifest_path(file_path: str, root: Path) -> str | None:
28
22
  return normalized or None
29
23
 
30
24
 
31
- def is_kit_origin(payload: object, root: Path) -> bool:
25
+ def kit_origin_path(payload: object, root: Path) -> str | None:
32
26
  if not isinstance(payload, dict) or payload.get("tool_name") not in TOOLS:
33
- return False
27
+ return None
34
28
  tool_input = payload.get("tool_input")
35
29
  if not isinstance(tool_input, dict) or not isinstance(tool_input.get("file_path"), str):
36
- return False
30
+ return None
37
31
  path = manifest_path(tool_input["file_path"], root)
38
32
  if path is None:
39
- return False
33
+ return None
40
34
  manifest = json.loads((root / MANIFEST).read_text(encoding="utf-8"))
41
35
  installed = manifest.get("installed", []) if isinstance(manifest, dict) else []
42
- return any(
36
+ return path if any(
43
37
  isinstance(entry, dict) and entry.get("path") == path and entry.get("origin") == "kit"
44
38
  for entry in installed
39
+ ) else None
40
+
41
+
42
+ def hint(path: str) -> str:
43
+ return (
44
+ "This file has kit origin. Before editing, ask whether the change should "
45
+ "stay Consumer-owned or return upstream. If it becomes a Contribution "
46
+ "Bridge, read the repository-scoped route with "
47
+ f"`agent-workflow-kit contribute status {path} --surface=guard`; "
48
+ "missing or invalid capability configuration offers preserve/fork only."
45
49
  )
46
50
 
47
51
 
48
52
  def main() -> int:
49
53
  try:
50
54
  payload = json.load(sys.stdin)
51
- if is_kit_origin(payload, Path.cwd()):
55
+ path = kit_origin_path(payload, Path.cwd())
56
+ if path:
52
57
  print(json.dumps({
53
58
  "hookSpecificOutput": {
54
59
  "hookEventName": "PreToolUse",
55
- "additionalContext": HINT,
60
+ "additionalContext": hint(path),
56
61
  }
57
62
  }))
58
63
  except (OSError, ValueError, TypeError):
@@ -54,6 +54,10 @@ release contain the same artifact.
54
54
  data, infer an external fact, or manufacture `pending`/`not-applicable` to
55
55
  make a capability appear ready.
56
56
 
57
+ File identity includes the package-declared mode as well as bytes. A
58
+ mode-only Core delta is an update and must be applied transactionally; it
59
+ must not survive preview as `unchanged` only to fail candidate verification.
60
+
57
61
  Readiness-schema adoption also keeps the Claude and Codex instruction
58
62
  surfaces compatible. When exactly one applicable instruction surface has a
59
63
  non-empty `## Prod` section and another has no such section, the staged
@@ -103,16 +107,25 @@ release contain the same artifact.
103
107
 
104
108
  For each conflicted kit-shipped file, always ask the user whether the local
105
109
  edit is a generic improvement or project-specific; never decide or act
106
- automatically. For a generic improvement, offer to file an issue in the
107
- public kit repository and keep the local edit in place as a bridge until a
108
- kit release containing the improvement lands. Before running
109
- `gh issue create --repo <owner>/agent-workflow-kit`, show a sanitized preview
110
- of the exact title and body with consumer identifiers and secrets stripped,
111
- then require the user's explicit approval. The consumer user does not need
112
- to be a kit maintainer. For a project-specific edit, recommend
110
+ automatically. For a generic improvement retained as a bridge, run
111
+ `contribute status <path> --surface=pre-update` and follow only its
112
+ repository-capability routes. Missing, disabled, invalid, or unverifiable
113
+ configuration is a generic Consumer and receives preserve/Explicit-fork
114
+ guidance, never maintainer language or an inferred upstream target. A valid
115
+ capability may add local preparation and may describe an upstream pull
116
+ request, but the latter still needs a sanitized exact preview and separate
117
+ explicit approval before any remote command. For a project-specific edit, recommend
113
118
  `npx @ikon85/agent-workflow-kit@latest own <path> --as=explicit-fork` so
114
- future updates treat that path as an independent fork. A generic experiment
115
- retained only until it returns upstream uses `--as=contribution-bridge`.
119
+ future updates treat that path as an independent fork. `own` snapshots the
120
+ path's current local bytes as the explicit-fork ledger identity, including
121
+ when it follows an already-detected local edit. A generic experiment
122
+ retained only until it returns upstream uses
123
+ `npx @ikon85/agent-workflow-kit@latest contribute start <path>`. Prepare its
124
+ bounded local artifact, when the route report permits it, with `contribute prepare <path>
125
+ --output=.agent-workflow-kit/contributions/<name>.json`. Both commands are
126
+ local-only; opening an issue/PR or pushing remains a separate explicit
127
+ approval. A matching released Core version retires the bridge during
128
+ reimport.
116
129
 
117
130
  4. If a candidate is interrupted, discard its reported stage directory or
118
131
  resume the transaction through the update API's `resumeFrom` option. Do not
@@ -164,9 +164,17 @@ Before formulating a patch in step 4, place **every** friction point on the thre
164
164
 
165
165
  **A GitHub issue is NOT a weight tier.** A real follow-up = work to track → `python3 scripts/board-sync.py create` (step-4 table), **orthogonal** to the ladder; its "weight" follows the follow-up scope. The ladder classifies **config patches**, not "turn it into a ticket".
166
166
 
167
- **Kit-repo routing target (always ask; never automatic).** When a finding lands on a kit-shipped file (a consumer-manifest entry with kit origin), ask whether the improvement is generic or project-specific. For a generic improvement, offer to file a lightweight issue against the public kit repo: a title plus a short body that states the finding, affected file, and why it is generic. For a project-specific improvement, recommend `own` (keep it consumer-owned). The consumer user does not need to be the kit maintainer.
168
-
169
- Before any `gh issue create --repo <owner>/agent-workflow-kit` runs, show the user a **sanitized preview** of the exact title and body with consumer identifiers and secrets stripped. Create the issue only after the user explicitly approves that exact text; if the title or body changes, show the revised preview and ask again. This approval is additional to the per-patch approval in step 5.
167
+ **Kit-repo routing target (capability-driven; never automatic).** When a finding
168
+ lands on a kit-shipped file (a consumer-manifest entry with kit origin), ask
169
+ whether the improvement is generic or project-specific. If it enters a
170
+ Contribution Bridge, run `agent-workflow-kit contribute status <path>
171
+ --surface=retro` and use only the reported repository-capability routes.
172
+ Missing, disabled, invalid, or unverifiable configuration is a generic Consumer:
173
+ offer preserve or Explicit fork, never infer maintainer status or an upstream
174
+ target from identity. A valid capability may offer local preparation. Before
175
+ any reported remote route runs, show the **sanitized exact preview** and require
176
+ separate explicit approval; changing the preview requires approval again. For a
177
+ project-specific improvement, recommend `own` (keep it consumer-owned).
170
178
 
171
179
  **Target missing in the project — separate two cases cleanly:**
172
180
  - **(a) Tier skill missing entirely** (e.g. a foreign project without `spec-self-critique`): no durable spec-time gate exists. **Memory is NOT a substitute** — passive recall doesn't catch a recurring spec defect before building. Report honestly: *"this project has no durable target for this tier"* + propose a `/setup-workflow` follow-up. **No fake guard via memory.**
@@ -293,7 +293,8 @@ decisions without repository evidence and user confirmation.
293
293
  > manifest. It is advisory only: it never blocks, reads the manifest once, uses
294
294
  > no network, and silently fails open when the manifest cannot be read. Shell
295
295
  > redirection, formatters, and IDE edits are knowingly outside its coverage; the
296
- > skills remain the rule's primary carrier.
296
+ > skills remain the rule's primary carrier. Its Contribution Bridge follow-up
297
+ > calls the same read-only route resolver with `--surface=guard`.
297
298
 
298
299
  Activate the shipped hook by reconciling this exact entry into
299
300
  `.claude/settings.json`:
@@ -357,6 +358,26 @@ unaffected surfaces, autonomy, and advanced values. Re-read the profile before
357
358
  activation and use its fingerprint plus the exclusive profile lock; a
358
359
  concurrent user-local change blocks activation and remains byte-preserved.
359
360
 
361
+ ### 2i. Section A10 — Optional contribution return routing
362
+
363
+ > Contribution return routing lets a repository advertise a verifiable Kit
364
+ > upstream without guessing who the user is. It controls offered routes, never
365
+ > remote authorization.
366
+
367
+ Read [contribution-routing.md](./contribution-routing.md) in full. If
368
+ `contributionRouting` is absent, ask whether this repository should advertise
369
+ an upstream contribution route. **Yes** records only the user-confirmed
370
+ owner/repository and local Git remote after verifying that the remote URL
371
+ matches. **Later / No** leaves the section absent or records `enabled: false`
372
+ only when the user requests a durable opt-out. Adopt an existing valid section
373
+ without normalization and preserve every other profile section and unknown key.
374
+
375
+ Missing, disabled, contradictory, or unverifiable configuration must keep the
376
+ generic preserve/Explicit-fork routes. Never infer capability from username,
377
+ machine, checkout path, repository name, credentials, or current GitHub login.
378
+ Even a valid capability authorizes local preparation only; a pull request,
379
+ push, publish, or merge remains a separate explicit approval.
380
+
360
381
  ### 3. Section B — Triage labels
361
382
 
362
383
  > When `triage` processes an incoming issue it applies labels (or your tracker's equivalent). It needs strings you've actually configured, or it creates duplicates.
@@ -0,0 +1,52 @@
1
+ # Contribution return routing
2
+
3
+ Contribution return is an optional repository capability. It controls which
4
+ routes agents may *offer* for an explicit Contribution Bridge; it never grants
5
+ permission to mutate a remote.
6
+
7
+ The consumer-owned section in `docs/agents/workflow-capabilities.json` is:
8
+
9
+ ```json contribution-routing-capability
10
+ {
11
+ "contributionRouting": {
12
+ "schemaVersion": 1,
13
+ "enabled": true,
14
+ "upstream": {
15
+ "repository": "<owner>/<repository>",
16
+ "remote": "<local-git-remote>"
17
+ },
18
+ "workflows": {
19
+ "prepareLocal": true,
20
+ "upstreamPullRequest": {
21
+ "enabled": true,
22
+ "requiresExplicitApproval": true
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ The resolver accepts the maintainer-capable route only when the configured Git
30
+ remote exists and its GitHub owner/repository matches `upstream.repository`.
31
+ It does not inspect usernames, home paths, machine names, the consumer
32
+ repository name, credentials, or GitHub account identity.
33
+
34
+ - Missing configuration is a generic Consumer: offer preserve or Explicit fork.
35
+ - `enabled: false` is an explicit opt-out with the same generic routes.
36
+ - Invalid, contradictory, or unverifiable configuration fails closed to those
37
+ generic routes and reports one bounded diagnostic.
38
+ - Valid configuration additionally offers local artifact preparation. It may
39
+ describe an upstream pull-request route only with
40
+ `requiresExplicitApproval: true`; this flag documents the gate and does not
41
+ satisfy it.
42
+
43
+ Use the same read-only resolver on every surface:
44
+
45
+ ```sh
46
+ agent-workflow-kit contribute status <path> --surface=retro
47
+ agent-workflow-kit contribute status <path> --surface=pre-update
48
+ agent-workflow-kit contribute status <path> --surface=guard
49
+ ```
50
+
51
+ Only `contribute prepare` writes a local bounded artifact. No contribution
52
+ command opens an issue or pull request, pushes, publishes, or merges.
package/README.md CHANGED
@@ -331,10 +331,22 @@ npx github:iKon85/agent-workflow-kit uninstall # remove kit-installed files
331
331
  - a file you **did** edit is kept — the incoming version is backed up with a
332
332
  timestamp and a diff is printed, never silently overwritten;
333
333
  - a file you intentionally fork can be detached with
334
- `npx github:iKon85/agent-workflow-kit own <path> --as=explicit-fork`, retained
335
- temporarily with `--as=contribution-bridge`, and returned to kit ownership
336
- with `npx github:iKon85/agent-workflow-kit disown <path>`; owned files are
334
+ `npx github:iKon85/agent-workflow-kit own <path> --as=explicit-fork` and
335
+ returned to kit ownership with
336
+ `npx github:iKon85/agent-workflow-kit disown <path>`; owned files are
337
337
  skipped by updates even after the package stops shipping them;
338
+ - a modified declared Core path enters the temporary Contribution Bridge with
339
+ `contribute start <path>`. `contribute prepare <path>
340
+ --output=.agent-workflow-kit/contributions/<name>.json` writes one local,
341
+ schema-versioned diff/provenance artifact and performs no remote action. A
342
+ release whose Core bytes match the bridged bytes retires the bridge
343
+ automatically on reimport;
344
+ - `contribute status <path> --surface=retro|pre-update|guard` reads the same
345
+ repository-scoped route decision on every workflow surface. Without a valid
346
+ `contributionRouting` section in `docs/agents/workflow-capabilities.json`,
347
+ only preserve/Explicit-fork guidance is available. A configured upstream must
348
+ match its local Git remote; even then, the remote pull-request route requires
349
+ a separate explicit approval;
338
350
  - a file removed upstream is offered for deletion (a hook still referenced by your
339
351
  `settings.json` is kept regardless);
340
352
  - a new Kit path that already exists locally is an `ambiguous-collision` until
@@ -358,7 +370,33 @@ Ownership commands are designed for a single-user CLI workflow and are not
358
370
  concurrency-safe. Do not run manifest-mutating commands concurrently. Flags:
359
371
  `--force` (overwrite pre-existing untracked files on `init`), `--yes` / `-y`
360
372
  (confirm only already-classified safe update actions), and
361
- `--as=contribution-bridge|explicit-fork` for `own`.
373
+ `--as=explicit-fork` for `own`.
374
+
375
+ The optional Contribution Routing capability is consumer-owned:
376
+
377
+ ```json
378
+ {
379
+ "contributionRouting": {
380
+ "schemaVersion": 1,
381
+ "enabled": true,
382
+ "upstream": {
383
+ "repository": "owner/repository",
384
+ "remote": "kit-upstream"
385
+ },
386
+ "workflows": {
387
+ "prepareLocal": true,
388
+ "upstreamPullRequest": {
389
+ "enabled": true,
390
+ "requiresExplicitApproval": true
391
+ }
392
+ }
393
+ }
394
+ }
395
+ ```
396
+
397
+ The resolver verifies the configured remote URL and never infers capability
398
+ from a username, machine, checkout path, consumer repository name, credentials,
399
+ or current GitHub login.
362
400
 
363
401
  ### Project extensions versus forks
364
402
 
@@ -407,6 +445,27 @@ the old way. Decision record:
407
445
 
408
446
  ## Release notes
409
447
 
448
+ ### 0.36.1
449
+
450
+ - changed: `.agents/skills/kit-update/SKILL.md`
451
+ - changed: `.claude/skills/kit-update/SKILL.md`
452
+ - changed: `src/lib/manifest.mjs`
453
+
454
+ ### 0.36.0
455
+
456
+ - added: `.agents/skills/setup-workflow/contribution-routing.md`
457
+ - added: `.claude/skills/setup-workflow/contribution-routing.md`
458
+ - changed: `.agents/skills/kit-update/SKILL.md`
459
+ - changed: `.agents/skills/retro/SKILL.md`
460
+ - changed: `.agents/skills/setup-workflow/SKILL.md`
461
+ - changed: `.claude/hooks/kit-origin-edit-hint.py`
462
+ - changed: `.claude/skills/kit-update/SKILL.md`
463
+ - changed: `.claude/skills/retro/SKILL.md`
464
+ - changed: `.claude/skills/setup-workflow/SKILL.md`
465
+ - changed: `scripts/find-by-marker.py`
466
+ - changed: `src/lib/manifest.mjs`
467
+ - changed: `src/lib/ownershipClassifier.mjs`
468
+
410
469
  ### 0.35.0
411
470
 
412
471
  - added: `scripts/project-skill-extension.mjs`
@@ -1,5 +1,5 @@
1
1
  {
2
- "kitVersion": "0.35.0",
2
+ "kitVersion": "0.36.1",
3
3
  "files": [
4
4
  {
5
5
  "path": ".agents/skills/ask-matt/SKILL.md",
@@ -377,7 +377,7 @@
377
377
  "ownerSkill": "kit-update",
378
378
  "surface": "codex",
379
379
  "installRole": "consumer",
380
- "sha256": "ac067a33cfbc98a6eb520ab2a819d7cc68b78a39201cd719f40a03a59f499814",
380
+ "sha256": "ea34bd16072783325c263b4afc4eefc39f0aabdbb53731b84500b46db69ef2c1",
381
381
  "mode": 420,
382
382
  "origin": "kit"
383
383
  },
@@ -547,7 +547,7 @@
547
547
  "ownerSkill": "retro",
548
548
  "surface": "codex",
549
549
  "installRole": "consumer",
550
- "sha256": "7466183b55696edc5c7da36eba1de3b218da802de5ea622baa4d6d3c12eb5e42",
550
+ "sha256": "adaafe450e014a08318f6676a27cd950bb1d48d3dc85515f0cd79d51d50b195e",
551
551
  "mode": 420,
552
552
  "origin": "kit"
553
553
  },
@@ -611,6 +611,16 @@
611
611
  "mode": 420,
612
612
  "origin": "kit"
613
613
  },
614
+ {
615
+ "path": ".agents/skills/setup-workflow/contribution-routing.md",
616
+ "kind": "skill",
617
+ "ownerSkill": "setup-workflow",
618
+ "surface": "codex",
619
+ "installRole": "consumer",
620
+ "sha256": "1bc224902709868b5e6aa5efa73b48b90a13f956ffe9d8779365f030e6399f67",
621
+ "mode": 420,
622
+ "origin": "kit"
623
+ },
614
624
  {
615
625
  "path": ".agents/skills/setup-workflow/domain.md",
616
626
  "kind": "skill",
@@ -677,7 +687,7 @@
677
687
  "ownerSkill": "setup-workflow",
678
688
  "surface": "codex",
679
689
  "installRole": "consumer",
680
- "sha256": "b74b8662f786a662460fe259379f00440c0ccdc10ddecd8af468ebbc220910b9",
690
+ "sha256": "697ef6f6cdb749bf0646b2add95d4d3246df39c48ca6d9ade063a775690ce462",
681
691
  "mode": 420,
682
692
  "origin": "kit"
683
693
  },
@@ -1117,7 +1127,7 @@
1117
1127
  "path": ".claude/hooks/kit-origin-edit-hint.py",
1118
1128
  "kind": "hook",
1119
1129
  "installRole": "consumer",
1120
- "sha256": "43e9b9597213c03f7da862602f81e6d6addd3a87e7b20cd52a6a2908b3e90f03",
1130
+ "sha256": "d6662eb75ccdd0bad7bea8e41024b8fd865c00c61ddeb81b8cc9d93f813c75e3",
1121
1131
  "mode": 493,
1122
1132
  "origin": "kit"
1123
1133
  },
@@ -1689,7 +1699,7 @@
1689
1699
  "ownerSkill": "kit-update",
1690
1700
  "surface": "claude",
1691
1701
  "installRole": "consumer",
1692
- "sha256": "ac067a33cfbc98a6eb520ab2a819d7cc68b78a39201cd719f40a03a59f499814",
1702
+ "sha256": "ea34bd16072783325c263b4afc4eefc39f0aabdbb53731b84500b46db69ef2c1",
1693
1703
  "mode": 420,
1694
1704
  "origin": "kit"
1695
1705
  },
@@ -1859,7 +1869,7 @@
1859
1869
  "ownerSkill": "retro",
1860
1870
  "surface": "claude",
1861
1871
  "installRole": "consumer",
1862
- "sha256": "290729bb2cb0542fca7aad082e6d0ecc0ab17e377c8ef2723d0597d4f2cefc62",
1872
+ "sha256": "59b31704c9ec7cb25f65efb1c090551a70ebe14b8841be98f87e9e8dfb2dddf2",
1863
1873
  "mode": 420,
1864
1874
  "origin": "kit"
1865
1875
  },
@@ -1943,6 +1953,16 @@
1943
1953
  "mode": 420,
1944
1954
  "origin": "kit"
1945
1955
  },
1956
+ {
1957
+ "path": ".claude/skills/setup-workflow/contribution-routing.md",
1958
+ "kind": "skill",
1959
+ "ownerSkill": "setup-workflow",
1960
+ "surface": "claude",
1961
+ "installRole": "consumer",
1962
+ "sha256": "1bc224902709868b5e6aa5efa73b48b90a13f956ffe9d8779365f030e6399f67",
1963
+ "mode": 420,
1964
+ "origin": "kit"
1965
+ },
1946
1966
  {
1947
1967
  "path": ".claude/skills/setup-workflow/domain.md",
1948
1968
  "kind": "skill",
@@ -2009,7 +2029,7 @@
2009
2029
  "ownerSkill": "setup-workflow",
2010
2030
  "surface": "claude",
2011
2031
  "installRole": "consumer",
2012
- "sha256": "b74b8662f786a662460fe259379f00440c0ccdc10ddecd8af468ebbc220910b9",
2032
+ "sha256": "697ef6f6cdb749bf0646b2add95d4d3246df39c48ca6d9ade063a775690ce462",
2013
2033
  "mode": 420,
2014
2034
  "origin": "kit"
2015
2035
  },
@@ -2511,7 +2531,7 @@
2511
2531
  "path": "scripts/find-by-marker.py",
2512
2532
  "kind": "script",
2513
2533
  "installRole": "consumer",
2514
- "sha256": "afaec50d8214dc3d89d28fbcb20faa9f997fc58158593618fcc80fb800b367ea",
2534
+ "sha256": "5c6c4fae9af11cd1fb25eb5310643961fa8d24b10cb41d013574de78c07e855e",
2515
2535
  "mode": 493,
2516
2536
  "origin": "kit"
2517
2537
  },
@@ -2863,7 +2883,7 @@
2863
2883
  "path": "src/lib/manifest.mjs",
2864
2884
  "kind": "script",
2865
2885
  "installRole": "consumer",
2866
- "sha256": "8696964e50e00eadc5aa3dd1527a8b4fa1b9e5bfe7c061e77fd464ae6843d9a1",
2886
+ "sha256": "f2920f2b25a700be080fbba122a809bf509080673b806aaab2b0c773c8d8267f",
2867
2887
  "mode": 420,
2868
2888
  "origin": "kit"
2869
2889
  },
@@ -2871,7 +2891,7 @@
2871
2891
  "path": "src/lib/ownershipClassifier.mjs",
2872
2892
  "kind": "script",
2873
2893
  "installRole": "consumer",
2874
- "sha256": "acc70a493626542a686df3b0805feae9b36648c8636d3fe8a4c23b092b851bbb",
2894
+ "sha256": "06a8a455752308db63c4b2aa6f360c540c18dfd3d7f153e52706005c1a51f4e9",
2875
2895
  "mode": 420,
2876
2896
  "origin": "kit"
2877
2897
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikon85/agent-workflow-kit",
3
- "version": "0.35.0",
3
+ "version": "0.36.1",
4
4
  "description": "Portable AI-agent workflow skills (plan → execute → land → learn) for Claude Code & Codex — grilling, TDD, diagnosis, two-axis code review, cross-model Codex review, design & domain-modeling, plus a skill router (ask-matt). npx init/update/diff/uninstall.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,6 +29,8 @@ def _gh(args: list[str]) -> str:
29
29
  except subprocess.TimeoutExpired as exc:
30
30
  raise RuntimeError(
31
31
  f"gh api timed out after {GH_TIMEOUT_SECONDS}s") from exc
32
+ except OSError as exc:
33
+ raise RuntimeError(f"gh CLI unavailable: {exc.strerror or exc}") from exc
32
34
  if result.returncode != 0:
33
35
  raise RuntimeError(result.stderr.strip() or "gh api failed")
34
36
  return result.stdout
@@ -149,6 +149,14 @@ class MarkerLookupTest(unittest.TestCase):
149
149
  with self.assertRaisesRegex(RuntimeError, "timed out after 30s"):
150
150
  cli._gh(["api", "--paginate", "repos/example/repo/issues"])
151
151
 
152
+ def test_cli_classifies_a_missing_github_binary(self):
153
+ with patch.object(
154
+ cli.subprocess, "run",
155
+ side_effect=FileNotFoundError(2, "No such file or directory", "gh"),
156
+ ):
157
+ with self.assertRaisesRegex(RuntimeError, "gh CLI unavailable"):
158
+ cli._gh(["api", "--paginate", "repos/example/repo/issues"])
159
+
152
160
 
153
161
  if __name__ == "__main__":
154
162
  unittest.main()