@ikon85/agent-workflow-kit 0.30.0 → 0.32.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/audit-skills/SKILL.md +34 -5
- package/.agents/skills/board-to-waves/SKILL.md +14 -0
- package/.agents/skills/code-review/SKILL.md +22 -3
- package/.agents/skills/git-worktree-recover/SKILL.md +31 -10
- package/.agents/skills/kit-update/SKILL.md +21 -1
- package/.agents/skills/local-ci/SKILL.md +16 -0
- package/.agents/skills/orchestrate-wave/SKILL.md +43 -14
- package/.agents/skills/project-release/SKILL.md +18 -0
- package/.agents/skills/security-audit/SKILL.md +18 -0
- package/.agents/skills/setup-workflow/SKILL.md +39 -2
- package/.agents/skills/spec-self-critique/SKILL.md +16 -7
- package/.agents/skills/to-issues/SKILL.md +13 -1
- package/.agents/skills/to-prd/SKILL.md +14 -0
- package/.agents/skills/to-waves/SKILL.md +16 -2
- package/.agents/skills/triage/SKILL.md +24 -0
- package/.agents/skills/verify-spike/SKILL.md +20 -1
- package/.agents/skills/wrapup/SKILL.md +26 -4
- package/.claude/skills/audit-skills/SKILL.md +34 -5
- package/.claude/skills/board-to-waves/SKILL.md +14 -0
- package/.claude/skills/code-review/SKILL.md +22 -3
- package/.claude/skills/git-worktree-recover/SKILL.md +31 -10
- package/.claude/skills/kit-update/SKILL.md +21 -1
- package/.claude/skills/local-ci/SKILL.md +16 -0
- package/.claude/skills/orchestrate-wave/SKILL.md +43 -14
- package/.claude/skills/project-release/SKILL.md +18 -0
- package/.claude/skills/security-audit/SKILL.md +18 -0
- package/.claude/skills/setup-workflow/SKILL.md +39 -2
- package/.claude/skills/spec-self-critique/SKILL.md +16 -7
- package/.claude/skills/to-issues/SKILL.md +13 -1
- package/.claude/skills/to-prd/SKILL.md +14 -0
- package/.claude/skills/to-waves/SKILL.md +16 -2
- package/.claude/skills/triage/SKILL.md +24 -0
- package/.claude/skills/verify-spike/SKILL.md +20 -1
- package/.claude/skills/wrapup/SKILL.md +26 -4
- package/README.md +41 -0
- package/agent-workflow-kit.package.json +36 -36
- package/package.json +1 -1
- package/scripts/kit-update-pr.mjs +14 -1
- package/scripts/kit-update-pr.test.mjs +21 -0
- package/scripts/test_retro_wrapup_contract.py +17 -0
- package/scripts/test_skill_optional_readiness.py +171 -0
- package/scripts/test_skill_readiness_contract.py +127 -7
- package/scripts/test_skill_readiness_preflight.py +180 -0
- package/scripts/test_skill_required_readiness.py +233 -0
- package/scripts/test_skill_setup_workflow_seeds.py +22 -0
- package/src/cli.mjs +10 -2
- package/src/commands/update.mjs +65 -8
- package/src/lib/updateCandidate.mjs +116 -2
|
@@ -10,6 +10,20 @@ description: "Turn a locked plan (PLAN.md in the worktree, conversation context,
|
|
|
10
10
|
|
|
11
11
|
Takes an **already-locked plan** and publishes it as a **Draft-PRD issue**. **Never invents requirements** — only synthesizes what's already decided. Pipeline: `board-to-waves → grill(-with-docs) → to-prd → to-issues`. The **grill sits upstream**; to-prd writes the PRD after the grill. **Slicing + promotion to an anchor (cluster/Wave, child link) = `to-issues`** (future), not here.
|
|
12
12
|
|
|
13
|
+
<!-- readiness:required-preflight:start -->
|
|
14
|
+
## 0. Required readiness preflight
|
|
15
|
+
|
|
16
|
+
This is the first executable workflow step. From the project root, before any remote write or other `gh`/`board-sync.py` command, run this read-only check:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
node scripts/readiness.mjs check --skill to-prd --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `verdict=ready`: continue with the existing workflow without announcing the check. **Ready is silent.**
|
|
23
|
+
- `verdict=blocked`: `STOP` before any mutation. Report every required capability as `<capability>=<state>` so `missing`, `pending`, and `invalid` remain distinct, then give exactly one recovery path: **Run `/setup-workflow`, then rerun `/to-prd`.** Do not fall back to bare tracker or board commands.
|
|
24
|
+
- `managedBoard=not-applicable`: `STOP` and report that `/to-prd` is **inapplicable** for a project that deliberately has no managed board. This is a terminal project decision, not invalid evidence and not a partially active mode.
|
|
25
|
+
<!-- readiness:required-preflight:end -->
|
|
26
|
+
|
|
13
27
|
Board constants (project node, field/status IDs) + helpers live **consumer-side**: read `docs/agents/board-sync.md` from the project root + use the helper `scripts/board-sync.py` (missing → `/setup-workflow` scaffolds the project layer). Issue body **always** via `--body-file` (inline `--body` with backticks/parens crashes bash).
|
|
14
28
|
|
|
15
29
|
## 1. Input — source-agnostic
|
|
@@ -14,6 +14,20 @@ Takes a **Program-PRD** — the native Sub-Issue anchor over a multi-wave progra
|
|
|
14
14
|
The **grill and to-prd sit upstream**; to-waves runs once the Program-PRD exists.
|
|
15
15
|
It **never invents structure** — it only unfolds what the plan already decided.
|
|
16
16
|
|
|
17
|
+
<!-- readiness:required-preflight:start -->
|
|
18
|
+
## 0. Required readiness preflight
|
|
19
|
+
|
|
20
|
+
This is the first executable workflow step. From the project root, before any remote write or other `gh`/`board-sync.py` command, run this read-only check:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
node scripts/readiness.mjs check --skill to-waves --json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `verdict=ready`: continue with the existing workflow without announcing the check. **Ready is silent.**
|
|
27
|
+
- `verdict=blocked`: `STOP` before any mutation. Report every required capability as `<capability>=<state>` so `issueTracker`, `managedBoard`, and `specCompleteness` failures — including distinct `missing`, `pending`, and `invalid` states — stay visible, then give exactly one recovery path: **Run `/setup-workflow`, then rerun `/to-waves`.** Do not fall back to bare tracker or board commands.
|
|
28
|
+
- `managedBoard=not-applicable`: `STOP` and report that `/to-waves` is **inapplicable** for a project that deliberately has no managed board. This is a terminal project decision, not invalid evidence and not a partially active mode.
|
|
29
|
+
<!-- readiness:required-preflight:end -->
|
|
30
|
+
|
|
17
31
|
Board constants (project node, field/status IDs) + helpers live **consumer-side**:
|
|
18
32
|
read `docs/agents/board-sync.md` from the project root + use the helper
|
|
19
33
|
`scripts/board-sync.py` (missing → `/setup-workflow` scaffolds the project layer).
|
|
@@ -36,8 +50,8 @@ target, an anchor is already a single wave.
|
|
|
36
50
|
|
|
37
51
|
## 2. Parse + validate — the graph preflight
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
mutations):
|
|
53
|
+
After the required readiness preflight, run the graph preflight before preview or
|
|
54
|
+
publication — it is **read-only** (a single board read, zero mutations):
|
|
41
55
|
|
|
42
56
|
```bash
|
|
43
57
|
python3 scripts/board-sync.py validate-graph --issue <prd#>
|
|
@@ -14,6 +14,30 @@ Every comment or issue posted to the issue tracker during triage **must** start
|
|
|
14
14
|
> *This was generated by AI during triage.*
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## Required readiness preflight
|
|
18
|
+
|
|
19
|
+
Before reading from or writing to the issue tracker, labels, or board, run:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
node scripts/readiness.mjs check --skill triage --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Treat the result as authoritative. A `ready` verdict is silent: continue with
|
|
26
|
+
the existing triage flow and all of its confirmation gates. For a `blocked`
|
|
27
|
+
verdict, stop without querying or mutating the issue tracker and report
|
|
28
|
+
`Triage unavailable`, the exact state (`missing`, `pending`, `not-applicable`,
|
|
29
|
+
or `invalid`), and the matching recovery path:
|
|
30
|
+
|
|
31
|
+
- `issueTracker` → run `/setup-workflow`, then fill
|
|
32
|
+
`docs/agents/issue-tracker.md`.
|
|
33
|
+
- `managedBoard` → run `/setup-workflow`, then configure
|
|
34
|
+
`docs/agents/board-sync.md`; `not-applicable` means this board-driven skill is
|
|
35
|
+
unavailable, not partially usable.
|
|
36
|
+
- `triageLabels` → run `/setup-workflow`, then fill
|
|
37
|
+
`docs/agents/triage-labels.md`.
|
|
38
|
+
|
|
39
|
+
Never guess a tracker, label, board, field, status, or fallback workflow.
|
|
40
|
+
|
|
17
41
|
## Reference docs
|
|
18
42
|
|
|
19
43
|
- [AGENT-BRIEF.md](AGENT-BRIEF.md) — how to write durable agent briefs
|
|
@@ -21,10 +21,29 @@ This is the "Verify First" rule with a runnable harness behind it: when you cann
|
|
|
21
21
|
|
|
22
22
|
If the question is really "what should this be", it is not a verify-spike — those are open, not yes/no.
|
|
23
23
|
|
|
24
|
+
## Readiness preflight — first
|
|
25
|
+
|
|
26
|
+
<!-- readiness:optional-preflight:start -->
|
|
27
|
+
Before framing or running the spike, run this once from the project root:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
node scripts/readiness.mjs check --skill verify-spike --json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- `ready`: continue without a readiness message. Ready is silent.
|
|
34
|
+
- `degraded`: keep the generic empirical spike active, omit only the inactive block `projectPlacement`, and emit exactly one concise summary: `Readiness degraded — inactive block projectPlacement (verifySpikeLayer: <state>). Run /setup-workflow, configure docs/agents/skills/verify-spike.md, then rerun this skill.`
|
|
35
|
+
- `blocked`: stop before continuing and report the non-ready required capability plus the exact `/setup-workflow` recovery path.
|
|
36
|
+
- Invalid is always visible: include the `invalid` capability state in the single summary and never treat it as an opt-out. Do not emit separate warnings later in the workflow.
|
|
37
|
+
<!-- readiness:optional-preflight:end -->
|
|
38
|
+
|
|
39
|
+
<!-- readiness:block projectPlacement -->
|
|
40
|
+
When `projectPlacement` is active, read `docs/agents/skills/verify-spike.md` and follow its project-specific harness-placement and import rules.
|
|
41
|
+
<!-- readiness:end -->
|
|
42
|
+
|
|
24
43
|
## Steps
|
|
25
44
|
|
|
26
45
|
1. **Frame one falsifiable question.** Write it down as a single sentence with a yes/no answer and the exact version/context it is scoped to — e.g. "Does `customType.mapFromDriverValue` run on `drizzle-orm@1.0.0-rc.3` + node-postgres?". Name what a YES vs a NO looks like in the output *before* you run anything.
|
|
27
|
-
2. **Build the smallest harness that forces the answer.** Borrow the feedback-loop toolkit from `diagnose` Phase 1 — a one-call throwaway script, a fixture replay, a tiny HTTP/curl probe, a headless-browser assertion. Pick the cheapest one that touches the real thing (real lib version, real runtime, the actual DB read). One command to run; locate it in a clearly-throwaway path (`scratch/`, `*.spike.ts`).
|
|
46
|
+
2. **Build the smallest harness that forces the answer.** Borrow the feedback-loop toolkit from `diagnose` Phase 1 — a one-call throwaway script, a fixture replay, a tiny HTTP/curl probe, a headless-browser assertion. Pick the cheapest one that touches the real thing (real lib version, real runtime, the actual DB read). One command to run; locate it in a clearly-throwaway path (`scratch/`, `*.spike.ts`).
|
|
28
47
|
3. **Run it and capture the proof.** Keep the raw output — the value, the error, the stack, the HTTP status. The verdict is only as good as the evidence pasted under it.
|
|
29
48
|
4. **Record the verdict durably, with its evidence inline.** Yes/No + the proof (output snippet / `file:line` / version) + the date + the scope it was checked at. Sink it where the decision lives: an ADR, the issue body, the plan, or a PR comment. A verdict without inline evidence is just an unverified claim — keep the proof attached so a later reader does not have to re-run the spike to trust it.
|
|
30
49
|
5. **Delete the harness.** The *answer* is the only keeper. Remove the spike code (or fold the proven fact into real code) so nothing throwaway rots in the repo.
|
|
@@ -3,7 +3,7 @@ name: wrapup
|
|
|
3
3
|
disable-model-invocation: true
|
|
4
4
|
description: >-
|
|
5
5
|
Use ONLY when the user types /wrapup. Session-end "land & clean" for a
|
|
6
|
-
finished feature/fix worktree — merges the open PR
|
|
6
|
+
finished feature/fix worktree — merges the open PR,
|
|
7
7
|
kills the worktree dev server, removes the worktree + local branch, and
|
|
8
8
|
fast-forwards the main checkout so main is current again, then sweeps
|
|
9
9
|
merged-branch leftovers (local + stale remote whose PR is merged). If the
|
|
@@ -20,7 +20,11 @@ Trigger: user types `/wrapup` (optionally with a PR number). **Manual only** —
|
|
|
20
20
|
|
|
21
21
|
## ⚠ Spec context
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
The user's `/wrapup` input IS the explicit landing authorization for that run.
|
|
24
|
+
It authorizes the normal merge flow whether Prod readiness is ready or degraded;
|
|
25
|
+
it never authorizes the agent to invent or configure a deploy target. Never call
|
|
26
|
+
this skill from a hook, another skill, or autonomously. There is no second merge
|
|
27
|
+
confirmation; the pre-flight hard stops are non-negotiable.
|
|
24
28
|
|
|
25
29
|
## Execution model — script does mechanics, the agent does judgment
|
|
26
30
|
|
|
@@ -37,6 +41,17 @@ python3 scripts/wrapup-land.py preflight
|
|
|
37
41
|
```
|
|
38
42
|
Hard stop (the only pure precondition): not in a feature worktree / on `main` — the script exits 1. The report carries everything the later steps need: dirty files, `.env` hits, secret-grep hits, issue + parent (leaf vs. anchor slice), existing PR + whether its body has a `**Retro:**` line, parsed `ANNAHMEN.md` drift lines, profile values (`retro_values`, `vor_bau`, remote-sweep switch).
|
|
39
43
|
|
|
44
|
+
Then run:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node scripts/readiness.mjs check --skill wrapup --json
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`prodTarget: ready` activates only `deployReport` below. `pending` or `missing`
|
|
51
|
+
omits that block, emits exactly one concise note — `Prod readiness is pending or missing; deploy reporting omitted.` — and landing continues normally.
|
|
52
|
+
`invalid` means malformed or divergent Prod evidence: STOP and report the
|
|
53
|
+
conflicting instruction surfaces; never choose a target on the user's behalf.
|
|
54
|
+
|
|
40
55
|
### 2 · Retro gate (blocking, optional retro-exit — before anything is committed)
|
|
41
56
|
One reminder, not a merge confirmation:
|
|
42
57
|
> "Already ran a retro? **(a)** yes / continue → landing now. **(b)** you want one first → the retro starts now; afterwards, invoke `/wrapup` again — repo-file patches then travel in this PR."
|
|
@@ -82,10 +97,17 @@ One call covers: push → PR create/reuse (+ drift markers merged into the body)
|
|
|
82
97
|
STOP → diagnose in the main conversation, fix, re-run `land` (an already-merged PR resumes at teardown).
|
|
83
98
|
|
|
84
99
|
### 6 · Post-merge (agent)
|
|
85
|
-
- **Deploy banner**, one line: `⚠ PR #<pr> merged → main deploys (~7 min live).`
|
|
86
100
|
- **Sibling propagation:** for each `drift_markers` entry in the land report, append the note to the target issue's `vor_bau` section + re-stamp its `plan_revision`. Log-based markers → **write directly, then show what was written where** (mandatory report — visibility moved from a pre-gate into the report, decision 2026-07-06); fallback candidates the user hasn't confirmed yet → confirm first. Program context widens the target set to unbuilt wave-stubs/leaves and the Program-PRD itself — same append-only mechanism. **Exception:** appends to the Program-PRD or unbuilt wave-stubs do **not** re-stamp `plan_revision` — that stays reserved for structural wave-plan edits via the `to-waves` escalation path; a mere drift note must not stale-block published stubs.
|
|
87
101
|
- **Anchor close:** report says `anchor_complete: true` → `gh issue close <anchor> -c "Wave complete — all slices merged via PR #<pr>."` and verify board status Done. The guard keeps anchors away from every auto-close — this verified close is the only close path; without it the anchor stays silently open after the last slice. **Then re-run the upward propagation**: the land-time `program-sync` ran BEFORE this close, so on a wave-completing slice the Wellenplan still shows 🔄 and the Phasen-Gate stays unchecked — after the board shows Done, run `python3 scripts/board-sync.py program-sync <program-prd#>` once more (the report's `program_sync.program` names it; skip when the report says the parent is not a program). Board auto-rules can lag the close (Close→Done race) — verify Done first, that's what the token reads.
|
|
88
|
-
- **Report**, concise, from the land JSON: PR merged · issue close (auto/manual) · worktree removed · branch deleted · sweep counts local/remote · anchor synced + complete/pending · program propagation (`program_sync`: Wellenplan refreshed / gates checked / skipped) · propagation writes (what → where) · `main` at `<sha
|
|
102
|
+
- **Report**, concise, from the land JSON: PR merged · issue close (auto/manual) · worktree removed · branch deleted · sweep counts local/remote · anchor synced + complete/pending · program propagation (`program_sync`: Wellenplan refreshed / gates checked / skipped) · propagation writes (what → where) · `main` at `<sha>`.
|
|
103
|
+
|
|
104
|
+
<!-- readiness:block deployReport -->
|
|
105
|
+
- **Deploy-aware report:** read the coherent `## Prod` block; before merging,
|
|
106
|
+
state the configured deploy trigger and expected outcome. After merge, report
|
|
107
|
+
the configured target and its actual known state. Do not claim a deployment
|
|
108
|
+
is running or live unless the configured trigger and observed evidence prove
|
|
109
|
+
it; keep unknown timing explicit.
|
|
110
|
+
<!-- readiness:end -->
|
|
89
111
|
|
|
90
112
|
## Out of scope
|
|
91
113
|
- Live-verify / DoD: must happen **before** `/wrapup` — this skill lands, it does not verify.
|
package/README.md
CHANGED
|
@@ -348,6 +348,47 @@ concurrency-safe. Do not run manifest-mutating commands concurrently. Flags:
|
|
|
348
348
|
|
|
349
349
|
## Release notes
|
|
350
350
|
|
|
351
|
+
### 0.32.0
|
|
352
|
+
|
|
353
|
+
- changed: `.agents/skills/audit-skills/SKILL.md`
|
|
354
|
+
- changed: `.agents/skills/git-worktree-recover/SKILL.md`
|
|
355
|
+
- changed: `.agents/skills/orchestrate-wave/SKILL.md`
|
|
356
|
+
- changed: `.claude/skills/audit-skills/SKILL.md`
|
|
357
|
+
- changed: `.claude/skills/git-worktree-recover/SKILL.md`
|
|
358
|
+
- changed: `.claude/skills/orchestrate-wave/SKILL.md`
|
|
359
|
+
|
|
360
|
+
### 0.31.0
|
|
361
|
+
|
|
362
|
+
- changed: `.agents/skills/board-to-waves/SKILL.md`
|
|
363
|
+
- changed: `.agents/skills/code-review/SKILL.md`
|
|
364
|
+
- changed: `.agents/skills/kit-update/SKILL.md`
|
|
365
|
+
- changed: `.agents/skills/local-ci/SKILL.md`
|
|
366
|
+
- changed: `.agents/skills/project-release/SKILL.md`
|
|
367
|
+
- changed: `.agents/skills/security-audit/SKILL.md`
|
|
368
|
+
- changed: `.agents/skills/setup-workflow/SKILL.md`
|
|
369
|
+
- changed: `.agents/skills/spec-self-critique/SKILL.md`
|
|
370
|
+
- changed: `.agents/skills/to-issues/SKILL.md`
|
|
371
|
+
- changed: `.agents/skills/to-prd/SKILL.md`
|
|
372
|
+
- changed: `.agents/skills/to-waves/SKILL.md`
|
|
373
|
+
- changed: `.agents/skills/triage/SKILL.md`
|
|
374
|
+
- changed: `.agents/skills/verify-spike/SKILL.md`
|
|
375
|
+
- changed: `.agents/skills/wrapup/SKILL.md`
|
|
376
|
+
- changed: `.claude/skills/board-to-waves/SKILL.md`
|
|
377
|
+
- changed: `.claude/skills/code-review/SKILL.md`
|
|
378
|
+
- changed: `.claude/skills/kit-update/SKILL.md`
|
|
379
|
+
- changed: `.claude/skills/local-ci/SKILL.md`
|
|
380
|
+
- changed: `.claude/skills/project-release/SKILL.md`
|
|
381
|
+
- changed: `.claude/skills/security-audit/SKILL.md`
|
|
382
|
+
- changed: `.claude/skills/setup-workflow/SKILL.md`
|
|
383
|
+
- changed: `.claude/skills/spec-self-critique/SKILL.md`
|
|
384
|
+
- changed: `.claude/skills/to-issues/SKILL.md`
|
|
385
|
+
- changed: `.claude/skills/to-prd/SKILL.md`
|
|
386
|
+
- changed: `.claude/skills/to-waves/SKILL.md`
|
|
387
|
+
- changed: `.claude/skills/triage/SKILL.md`
|
|
388
|
+
- changed: `.claude/skills/verify-spike/SKILL.md`
|
|
389
|
+
- changed: `.claude/skills/wrapup/SKILL.md`
|
|
390
|
+
- changed: `scripts/kit-update-pr.mjs`
|
|
391
|
+
|
|
351
392
|
### 0.30.0
|
|
352
393
|
|
|
353
394
|
- added: `.claude/skills/skill-manifest.json`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"kitVersion": "0.
|
|
2
|
+
"kitVersion": "0.32.0",
|
|
3
3
|
"files": [
|
|
4
4
|
{
|
|
5
5
|
"path": ".agents/skills/ask-matt/SKILL.md",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"ownerSkill": "audit-skills",
|
|
28
28
|
"surface": "codex",
|
|
29
29
|
"installRole": "consumer",
|
|
30
|
-
"sha256": "
|
|
30
|
+
"sha256": "662c4dec0c03716c468f202f73f52140ceba84e092873e6619692dde6d7ed0f2",
|
|
31
31
|
"mode": 420,
|
|
32
32
|
"origin": "kit"
|
|
33
33
|
},
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"ownerSkill": "board-to-waves",
|
|
38
38
|
"surface": "codex",
|
|
39
39
|
"installRole": "consumer",
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "203211bc1bd149918783de4ead312d94c4faf1e4ba25d2625ce34f99a0806282",
|
|
41
41
|
"mode": 420,
|
|
42
42
|
"origin": "kit"
|
|
43
43
|
},
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"ownerSkill": "code-review",
|
|
58
58
|
"surface": "codex",
|
|
59
59
|
"installRole": "consumer",
|
|
60
|
-
"sha256": "
|
|
60
|
+
"sha256": "9d0e54bd73bd4cdd810e714f1a5af07a4cd00b7cc07fe360e587abbf3005f2aa",
|
|
61
61
|
"mode": 420,
|
|
62
62
|
"origin": "kit"
|
|
63
63
|
},
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
"ownerSkill": "git-worktree-recover",
|
|
198
198
|
"surface": "codex",
|
|
199
199
|
"installRole": "consumer",
|
|
200
|
-
"sha256": "
|
|
200
|
+
"sha256": "1628f47a5b5f71b7596ec070c8f038a3ce98abe007fce1b7f5c21ea40858124d",
|
|
201
201
|
"mode": 420,
|
|
202
202
|
"origin": "kit"
|
|
203
203
|
},
|
|
@@ -377,7 +377,7 @@
|
|
|
377
377
|
"ownerSkill": "kit-update",
|
|
378
378
|
"surface": "codex",
|
|
379
379
|
"installRole": "consumer",
|
|
380
|
-
"sha256": "
|
|
380
|
+
"sha256": "880766b7aef88760f6d79dd31c3333356eef060623fc053fc61f5d5611765bb8",
|
|
381
381
|
"mode": 420,
|
|
382
382
|
"origin": "kit"
|
|
383
383
|
},
|
|
@@ -387,7 +387,7 @@
|
|
|
387
387
|
"ownerSkill": "local-ci",
|
|
388
388
|
"surface": "codex",
|
|
389
389
|
"installRole": "consumer",
|
|
390
|
-
"sha256": "
|
|
390
|
+
"sha256": "1ebf841e35d0df7e68b2684ba8fd7c674327bcb729a693fd5ed87189ac5e90be",
|
|
391
391
|
"mode": 420,
|
|
392
392
|
"origin": "kit"
|
|
393
393
|
},
|
|
@@ -417,7 +417,7 @@
|
|
|
417
417
|
"ownerSkill": "orchestrate-wave",
|
|
418
418
|
"surface": "codex",
|
|
419
419
|
"installRole": "consumer",
|
|
420
|
-
"sha256": "
|
|
420
|
+
"sha256": "7a94293b7db49f42497d34e6ae0fe9992ab1c770ae0766557618818d6d671c50",
|
|
421
421
|
"mode": 420,
|
|
422
422
|
"origin": "kit"
|
|
423
423
|
},
|
|
@@ -427,7 +427,7 @@
|
|
|
427
427
|
"ownerSkill": "project-release",
|
|
428
428
|
"surface": "codex",
|
|
429
429
|
"installRole": "consumer",
|
|
430
|
-
"sha256": "
|
|
430
|
+
"sha256": "754910dc182b3868f9c0f95b7ddb5665fe955f68bc9bea4e44c7c6f4ef5d8df9",
|
|
431
431
|
"mode": 420,
|
|
432
432
|
"origin": "kit"
|
|
433
433
|
},
|
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
"ownerSkill": "security-audit",
|
|
538
538
|
"surface": "codex",
|
|
539
539
|
"installRole": "consumer",
|
|
540
|
-
"sha256": "
|
|
540
|
+
"sha256": "2e937d1e8c40b20da0c733e1e5c355531b3e777abf6197795186405afb5e009d",
|
|
541
541
|
"mode": 420,
|
|
542
542
|
"origin": "kit"
|
|
543
543
|
},
|
|
@@ -647,7 +647,7 @@
|
|
|
647
647
|
"ownerSkill": "setup-workflow",
|
|
648
648
|
"surface": "codex",
|
|
649
649
|
"installRole": "consumer",
|
|
650
|
-
"sha256": "
|
|
650
|
+
"sha256": "f0d6809b86eec77cf54bccc30e6a7603d831678fcc8b5f52b4e073f9f56a72a8",
|
|
651
651
|
"mode": 420,
|
|
652
652
|
"origin": "kit"
|
|
653
653
|
},
|
|
@@ -737,7 +737,7 @@
|
|
|
737
737
|
"ownerSkill": "spec-self-critique",
|
|
738
738
|
"surface": "codex",
|
|
739
739
|
"installRole": "consumer",
|
|
740
|
-
"sha256": "
|
|
740
|
+
"sha256": "586d49acff382484e7db58719a34d257936ffb8c19c9de1a3322f6b1b5e675ad",
|
|
741
741
|
"mode": 420,
|
|
742
742
|
"origin": "kit"
|
|
743
743
|
},
|
|
@@ -817,7 +817,7 @@
|
|
|
817
817
|
"ownerSkill": "to-issues",
|
|
818
818
|
"surface": "codex",
|
|
819
819
|
"installRole": "consumer",
|
|
820
|
-
"sha256": "
|
|
820
|
+
"sha256": "cae01235d1647e30bf60df93d32cb2f9be1b5dc908429514287aaf648f8094e1",
|
|
821
821
|
"mode": 420,
|
|
822
822
|
"origin": "kit"
|
|
823
823
|
},
|
|
@@ -847,7 +847,7 @@
|
|
|
847
847
|
"ownerSkill": "to-prd",
|
|
848
848
|
"surface": "codex",
|
|
849
849
|
"installRole": "consumer",
|
|
850
|
-
"sha256": "
|
|
850
|
+
"sha256": "dae11a76b317e190f2b10580eda098a3dcf73c0be3806050a7caa1b933107fa6",
|
|
851
851
|
"mode": 420,
|
|
852
852
|
"origin": "kit"
|
|
853
853
|
},
|
|
@@ -867,7 +867,7 @@
|
|
|
867
867
|
"ownerSkill": "to-waves",
|
|
868
868
|
"surface": "codex",
|
|
869
869
|
"installRole": "consumer",
|
|
870
|
-
"sha256": "
|
|
870
|
+
"sha256": "0229b717783054c87c42e088d1323990b6a30ffc80b337b6c14caf5e8f7964d1",
|
|
871
871
|
"mode": 420,
|
|
872
872
|
"origin": "kit"
|
|
873
873
|
},
|
|
@@ -907,7 +907,7 @@
|
|
|
907
907
|
"ownerSkill": "triage",
|
|
908
908
|
"surface": "codex",
|
|
909
909
|
"installRole": "consumer",
|
|
910
|
-
"sha256": "
|
|
910
|
+
"sha256": "dc27da1360edbc8e52a3b2ba67a9bf3d7d15a1a5403204737d7d0d11b7c53e32",
|
|
911
911
|
"mode": 420,
|
|
912
912
|
"origin": "kit"
|
|
913
913
|
},
|
|
@@ -927,7 +927,7 @@
|
|
|
927
927
|
"ownerSkill": "verify-spike",
|
|
928
928
|
"surface": "codex",
|
|
929
929
|
"installRole": "consumer",
|
|
930
|
-
"sha256": "
|
|
930
|
+
"sha256": "a823094a83cdfde40954f581064a5a64b5fcc41a0b5eba2989c9a20ecb39b02b",
|
|
931
931
|
"mode": 420,
|
|
932
932
|
"origin": "kit"
|
|
933
933
|
},
|
|
@@ -957,7 +957,7 @@
|
|
|
957
957
|
"ownerSkill": "wrapup",
|
|
958
958
|
"surface": "codex",
|
|
959
959
|
"installRole": "consumer",
|
|
960
|
-
"sha256": "
|
|
960
|
+
"sha256": "fd4b4abc17cf3d333057d1a25d3689dbab3fe59d08189b6136ac2198cec0abe4",
|
|
961
961
|
"mode": 420,
|
|
962
962
|
"origin": "kit"
|
|
963
963
|
},
|
|
@@ -1189,7 +1189,7 @@
|
|
|
1189
1189
|
"ownerSkill": "audit-skills",
|
|
1190
1190
|
"surface": "claude",
|
|
1191
1191
|
"installRole": "consumer",
|
|
1192
|
-
"sha256": "
|
|
1192
|
+
"sha256": "dce7c13e9b9c2eb6fe9028f69fe2fe2d48ad50546327c9d9c1232191425f1b7c",
|
|
1193
1193
|
"mode": 420,
|
|
1194
1194
|
"origin": "kit"
|
|
1195
1195
|
},
|
|
@@ -1199,7 +1199,7 @@
|
|
|
1199
1199
|
"ownerSkill": "board-to-waves",
|
|
1200
1200
|
"surface": "claude",
|
|
1201
1201
|
"installRole": "consumer",
|
|
1202
|
-
"sha256": "
|
|
1202
|
+
"sha256": "33c897cf670e57b41bf231be7cf1ce3e35634907c94f6b0e037a2eae19adf582",
|
|
1203
1203
|
"mode": 420,
|
|
1204
1204
|
"origin": "kit"
|
|
1205
1205
|
},
|
|
@@ -1219,7 +1219,7 @@
|
|
|
1219
1219
|
"ownerSkill": "code-review",
|
|
1220
1220
|
"surface": "claude",
|
|
1221
1221
|
"installRole": "consumer",
|
|
1222
|
-
"sha256": "
|
|
1222
|
+
"sha256": "9d0e54bd73bd4cdd810e714f1a5af07a4cd00b7cc07fe360e587abbf3005f2aa",
|
|
1223
1223
|
"mode": 420,
|
|
1224
1224
|
"origin": "kit"
|
|
1225
1225
|
},
|
|
@@ -1419,7 +1419,7 @@
|
|
|
1419
1419
|
"ownerSkill": "git-worktree-recover",
|
|
1420
1420
|
"surface": "claude",
|
|
1421
1421
|
"installRole": "consumer",
|
|
1422
|
-
"sha256": "
|
|
1422
|
+
"sha256": "3251c8db671286330e48748719e05ee3fdc0555d93d61d7fee3fc0e0d2868e92",
|
|
1423
1423
|
"mode": 420,
|
|
1424
1424
|
"origin": "kit"
|
|
1425
1425
|
},
|
|
@@ -1659,7 +1659,7 @@
|
|
|
1659
1659
|
"ownerSkill": "kit-update",
|
|
1660
1660
|
"surface": "claude",
|
|
1661
1661
|
"installRole": "consumer",
|
|
1662
|
-
"sha256": "
|
|
1662
|
+
"sha256": "880766b7aef88760f6d79dd31c3333356eef060623fc053fc61f5d5611765bb8",
|
|
1663
1663
|
"mode": 420,
|
|
1664
1664
|
"origin": "kit"
|
|
1665
1665
|
},
|
|
@@ -1669,7 +1669,7 @@
|
|
|
1669
1669
|
"ownerSkill": "local-ci",
|
|
1670
1670
|
"surface": "claude",
|
|
1671
1671
|
"installRole": "consumer",
|
|
1672
|
-
"sha256": "
|
|
1672
|
+
"sha256": "3af9e71a2b65b66cfa2b40d780badd86b925c1d18e0cb16fdd25041db12f2cbc",
|
|
1673
1673
|
"mode": 420,
|
|
1674
1674
|
"origin": "kit"
|
|
1675
1675
|
},
|
|
@@ -1699,7 +1699,7 @@
|
|
|
1699
1699
|
"ownerSkill": "orchestrate-wave",
|
|
1700
1700
|
"surface": "claude",
|
|
1701
1701
|
"installRole": "consumer",
|
|
1702
|
-
"sha256": "
|
|
1702
|
+
"sha256": "9690ec772a99131c225037dd4bca884e899c133a8e460c36b26a25d6c6c797e1",
|
|
1703
1703
|
"mode": 420,
|
|
1704
1704
|
"origin": "kit"
|
|
1705
1705
|
},
|
|
@@ -1709,7 +1709,7 @@
|
|
|
1709
1709
|
"ownerSkill": "project-release",
|
|
1710
1710
|
"surface": "claude",
|
|
1711
1711
|
"installRole": "consumer",
|
|
1712
|
-
"sha256": "
|
|
1712
|
+
"sha256": "754910dc182b3868f9c0f95b7ddb5665fe955f68bc9bea4e44c7c6f4ef5d8df9",
|
|
1713
1713
|
"mode": 420,
|
|
1714
1714
|
"origin": "kit"
|
|
1715
1715
|
},
|
|
@@ -1819,7 +1819,7 @@
|
|
|
1819
1819
|
"ownerSkill": "security-audit",
|
|
1820
1820
|
"surface": "claude",
|
|
1821
1821
|
"installRole": "consumer",
|
|
1822
|
-
"sha256": "
|
|
1822
|
+
"sha256": "4fcd28c4019e84b6ae5307437ecc979a2d6a490a7a379a7e104b3a4974ca877e",
|
|
1823
1823
|
"mode": 420,
|
|
1824
1824
|
"origin": "kit"
|
|
1825
1825
|
},
|
|
@@ -1949,7 +1949,7 @@
|
|
|
1949
1949
|
"ownerSkill": "setup-workflow",
|
|
1950
1950
|
"surface": "claude",
|
|
1951
1951
|
"installRole": "consumer",
|
|
1952
|
-
"sha256": "
|
|
1952
|
+
"sha256": "f0d6809b86eec77cf54bccc30e6a7603d831678fcc8b5f52b4e073f9f56a72a8",
|
|
1953
1953
|
"mode": 420,
|
|
1954
1954
|
"origin": "kit"
|
|
1955
1955
|
},
|
|
@@ -2047,7 +2047,7 @@
|
|
|
2047
2047
|
"ownerSkill": "spec-self-critique",
|
|
2048
2048
|
"surface": "claude",
|
|
2049
2049
|
"installRole": "consumer",
|
|
2050
|
-
"sha256": "
|
|
2050
|
+
"sha256": "0ed723ebad6ceb74defed56a51aa7cee8c343665288e96ff2b06ef214165c7e1",
|
|
2051
2051
|
"mode": 420,
|
|
2052
2052
|
"origin": "kit"
|
|
2053
2053
|
},
|
|
@@ -2127,7 +2127,7 @@
|
|
|
2127
2127
|
"ownerSkill": "to-issues",
|
|
2128
2128
|
"surface": "claude",
|
|
2129
2129
|
"installRole": "consumer",
|
|
2130
|
-
"sha256": "
|
|
2130
|
+
"sha256": "874a636bde53180dab4d69b801c7d3a5c5cbdaf74e1969af56c8d7805163ef24",
|
|
2131
2131
|
"mode": 420,
|
|
2132
2132
|
"origin": "kit"
|
|
2133
2133
|
},
|
|
@@ -2157,7 +2157,7 @@
|
|
|
2157
2157
|
"ownerSkill": "to-prd",
|
|
2158
2158
|
"surface": "claude",
|
|
2159
2159
|
"installRole": "consumer",
|
|
2160
|
-
"sha256": "
|
|
2160
|
+
"sha256": "621644d4de0bdb02d367381c8cf58584c393b9d385f5f2881c00f9d4f70fd834",
|
|
2161
2161
|
"mode": 420,
|
|
2162
2162
|
"origin": "kit"
|
|
2163
2163
|
},
|
|
@@ -2177,7 +2177,7 @@
|
|
|
2177
2177
|
"ownerSkill": "to-waves",
|
|
2178
2178
|
"surface": "claude",
|
|
2179
2179
|
"installRole": "consumer",
|
|
2180
|
-
"sha256": "
|
|
2180
|
+
"sha256": "0229b717783054c87c42e088d1323990b6a30ffc80b337b6c14caf5e8f7964d1",
|
|
2181
2181
|
"mode": 420,
|
|
2182
2182
|
"origin": "kit"
|
|
2183
2183
|
},
|
|
@@ -2217,7 +2217,7 @@
|
|
|
2217
2217
|
"ownerSkill": "triage",
|
|
2218
2218
|
"surface": "claude",
|
|
2219
2219
|
"installRole": "consumer",
|
|
2220
|
-
"sha256": "
|
|
2220
|
+
"sha256": "ea9be39611b3f007edd12089a03f9b4a408e3651765eb104a966cf85c2717496",
|
|
2221
2221
|
"mode": 420,
|
|
2222
2222
|
"origin": "kit"
|
|
2223
2223
|
},
|
|
@@ -2237,7 +2237,7 @@
|
|
|
2237
2237
|
"ownerSkill": "verify-spike",
|
|
2238
2238
|
"surface": "claude",
|
|
2239
2239
|
"installRole": "consumer",
|
|
2240
|
-
"sha256": "
|
|
2240
|
+
"sha256": "ee2258edd8bb9fb03bb1f98926aae20b25147b04aa88af68e06a45a6d75549b5",
|
|
2241
2241
|
"mode": 420,
|
|
2242
2242
|
"origin": "kit"
|
|
2243
2243
|
},
|
|
@@ -2267,7 +2267,7 @@
|
|
|
2267
2267
|
"ownerSkill": "wrapup",
|
|
2268
2268
|
"surface": "claude",
|
|
2269
2269
|
"installRole": "consumer",
|
|
2270
|
-
"sha256": "
|
|
2270
|
+
"sha256": "05a4981b54fb5c4ef1b842bbdd45f6ca91cf0047e38e511feac86e20206c0fe7",
|
|
2271
2271
|
"mode": 420,
|
|
2272
2272
|
"origin": "kit"
|
|
2273
2273
|
},
|
|
@@ -2475,7 +2475,7 @@
|
|
|
2475
2475
|
"path": "scripts/kit-update-pr.mjs",
|
|
2476
2476
|
"kind": "script",
|
|
2477
2477
|
"installRole": "consumer",
|
|
2478
|
-
"sha256": "
|
|
2478
|
+
"sha256": "83f30a4ca938171cfa2f4153917813fae40bf2a906940e047c7066d18284209b",
|
|
2479
2479
|
"mode": 493,
|
|
2480
2480
|
"origin": "kit"
|
|
2481
2481
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikon85/agent-workflow-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
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": {
|
|
@@ -33,7 +33,7 @@ export async function orchestrateUpdatePullRequest(options) {
|
|
|
33
33
|
return { status: 'failed', branch, reason: 'multiple-open-pull-requests' };
|
|
34
34
|
}
|
|
35
35
|
await publishBranch(branch);
|
|
36
|
-
const input = { title: UPDATE_TITLE, body:
|
|
36
|
+
const input = { title: UPDATE_TITLE, body: pullRequestBody(update.stdout), branch };
|
|
37
37
|
if (pulls.length === 1) {
|
|
38
38
|
await updatePullRequest(pulls[0].number, input);
|
|
39
39
|
return { status: 'updated', branch, pullRequest: pulls[0].number };
|
|
@@ -42,6 +42,19 @@ export async function orchestrateUpdatePullRequest(options) {
|
|
|
42
42
|
return { status: 'created', branch };
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function pullRequestBody(stdout = '') {
|
|
46
|
+
const labels = ['newly available:', 'newly degraded:', 'newly blocked:', 'still unresolved:'];
|
|
47
|
+
const clean = stdout.replaceAll(/\x1b\[[0-9;]*m/g, '');
|
|
48
|
+
const summary = clean.split('\n')
|
|
49
|
+
.map((line) => line.trim())
|
|
50
|
+
.filter((line) => labels.some((label) => line.includes(label)))
|
|
51
|
+
.map((line) => line.slice(Math.min(...labels.map((label) => {
|
|
52
|
+
const index = line.indexOf(label);
|
|
53
|
+
return index < 0 ? line.length : index;
|
|
54
|
+
}))));
|
|
55
|
+
return [UPDATE_BODY, '## Availability', summary.join('\n') || 'No readiness availability changes reported.'].join('\n\n');
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
export function createSystemAdapters({
|
|
46
59
|
cwd = process.cwd(), env = process.env, execute = exec,
|
|
47
60
|
} = {}) {
|
|
@@ -28,6 +28,27 @@ test('a successful update creates one stable update pull request', async () => {
|
|
|
28
28
|
]);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
+
test('automated update pull requests carry the behavior availability summary', async () => {
|
|
32
|
+
const h = harness({ update: {
|
|
33
|
+
exitCode: 0,
|
|
34
|
+
stdout: [
|
|
35
|
+
'newly available: orchestrate-wave',
|
|
36
|
+
'newly degraded: orchestrate-wave.projectRecipe',
|
|
37
|
+
'newly blocked: none',
|
|
38
|
+
'still unresolved: orchestrateWaveRecipe:invalid',
|
|
39
|
+
].join('\n'),
|
|
40
|
+
stderr: '',
|
|
41
|
+
} });
|
|
42
|
+
|
|
43
|
+
await orchestrateUpdatePullRequest(h.options);
|
|
44
|
+
|
|
45
|
+
const created = h.calls.find((call) => Array.isArray(call) && call[0] === 'create')[1];
|
|
46
|
+
assert.match(created.body, /## Availability/);
|
|
47
|
+
assert.match(created.body, /newly degraded: orchestrate-wave\.projectRecipe/);
|
|
48
|
+
assert.match(created.body, /still unresolved: orchestrateWaveRecipe:invalid/);
|
|
49
|
+
assert.match(created.body, /never merged automatically/);
|
|
50
|
+
});
|
|
51
|
+
|
|
31
52
|
test('a conflict produces a structured report without touching the stable branch', async () => {
|
|
32
53
|
const h = harness({ update: { exitCode: 2, stdout: 'conflicts: 1', stderr: '' } });
|
|
33
54
|
const report = await orchestrateUpdatePullRequest(h.options);
|
|
@@ -59,6 +59,23 @@ class RetroEnforcementContract(unittest.TestCase):
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
class WrapupChainingContract(unittest.TestCase):
|
|
62
|
+
def test_prod_readiness_degrades_reporting_without_blocking_landing(self):
|
|
63
|
+
required = (
|
|
64
|
+
"readiness.mjs check --skill wrapup --json",
|
|
65
|
+
"Prod readiness is pending or missing; deploy reporting omitted.",
|
|
66
|
+
"landing continues normally",
|
|
67
|
+
"never authorizes the agent to invent or configure a deploy target",
|
|
68
|
+
"<!-- readiness:block deployReport -->",
|
|
69
|
+
"<!-- readiness:end -->",
|
|
70
|
+
)
|
|
71
|
+
for surface in SURFACES:
|
|
72
|
+
with self.subTest(surface=surface):
|
|
73
|
+
text = skill(surface, "wrapup")
|
|
74
|
+
for phrase in required:
|
|
75
|
+
self.assertIn(phrase, text)
|
|
76
|
+
self.assertEqual(text.count("<!-- readiness:block deployReport -->"), 1)
|
|
77
|
+
self.assertEqual(text.count("<!-- readiness:end -->"), 1)
|
|
78
|
+
|
|
62
79
|
def test_retro_is_model_invocable_on_both_surfaces(self):
|
|
63
80
|
for surface in SURFACES:
|
|
64
81
|
with self.subTest(surface=surface):
|