skilldrop-cli 0.11.4 → 0.11.6
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/README.md +31 -7
- package/contracts/loop.schema.json +87 -0
- package/contracts/terminals.json +33 -0
- package/loops/build/LOOP.md +65 -0
- package/loops/build/loop.json +48 -0
- package/loops/ship-a-draft/LOOP.md +62 -0
- package/loops/ship-a-draft/loop.json +41 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -20,9 +20,18 @@ Every skill is a plain `SKILL.md` folder — the [**Agent Skills open standard**
|
|
|
20
20
|
|
|
21
21
|
## How skilldrop works
|
|
22
22
|
|
|
23
|
-
skilldrop
|
|
23
|
+
skilldrop ships **loops**, not just parts. A loop is a named sequence of stages over existing skills with a gate between them: [`loops/<name>/LOOP.md`](loops/) is what an agent reads, `loop.json` is the machine-readable contract ([RFC-0028](docs/rfcs/0028-loops-as-a-primitive.md)). **Nothing comes out of a loop until it passes that loop's gate.**
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
A loop *sequences* skills — it never contains one. Every skill stays independently installable and runnable on its own, which is what keeps a single-folder copy working in Cursor, Kiro, or Aider.
|
|
26
|
+
|
|
27
|
+
| Loop | Takes | Gate | Produces |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| [`build`](loops/build/LOOP.md) | an agreed requirement or triaged defect | **G2** mechanical — `pre-merge-review`'s gate script decides | merged code |
|
|
30
|
+
| [`ship-a-draft`](loops/ship-a-draft/LOOP.md) | raw notes, a transcript, a ticket | **G4** review — `doc-critique`'s verdict | a stakeholder-ready artifact |
|
|
31
|
+
|
|
32
|
+
Every gate emits a verdict from one shared vocabulary ([`contracts/terminals.json`](contracts/terminals.json)) in five classes — pass, conditional, revise, redirect, blocked — so `READY`, `PROCEED` and `SHIP IT` are recognisably the same kind of answer. Both diagrams render on GitHub; the Mermaid sources live in [`docs/`](docs/) for easy re-rendering.
|
|
33
|
+
|
|
34
|
+
### `ship-a-draft` — the knowledge-work loop
|
|
26
35
|
|
|
27
36
|
Raw input becomes a stakeholder-ready artifact — and loops back through review until it's approved.
|
|
28
37
|
|
|
@@ -45,7 +54,7 @@ flowchart LR
|
|
|
45
54
|
crit == "approved" ==> ART
|
|
46
55
|
```
|
|
47
56
|
|
|
48
|
-
###
|
|
57
|
+
### `build` — code: implement and verify
|
|
49
58
|
|
|
50
59
|
A feature spec becomes shippable code through a self-correcting loop — generate, adversarially challenge, close the gaps, re-check — until the review is clean or a 3-round cap is hit. This is the [`feature-implement-loop`](skills/feature-implement-loop/SKILL.md) skill.
|
|
51
60
|
|
|
@@ -297,14 +306,29 @@ npx skilldrop-cli list --json # machine-readable: lis
|
|
|
297
306
|
|
|
298
307
|
### Or: the Claude Code plugin marketplace
|
|
299
308
|
|
|
300
|
-
skilldrop is also a **Claude Code plugin marketplace** —
|
|
309
|
+
skilldrop is also a **Claude Code plugin marketplace** — one marketplace, seven plugins, no npm step. Add it once:
|
|
301
310
|
|
|
302
311
|
```text
|
|
303
312
|
/plugin marketplace add sananthanarayan/skilldrop
|
|
304
|
-
/plugin install skilldrop@skilldrop
|
|
305
313
|
```
|
|
306
314
|
|
|
307
|
-
|
|
315
|
+
Then take the whole catalogue, or just your role's pack:
|
|
316
|
+
|
|
317
|
+
```text
|
|
318
|
+
/plugin install skilldrop@skilldrop # all 57 skills + 3 reviewer subagents
|
|
319
|
+
/plugin install solution-architect@skilldrop # 17 skills
|
|
320
|
+
/plugin install dev-team@skilldrop # 14 skills + the 3 reviewer subagents
|
|
321
|
+
/plugin install product-manager@skilldrop # 13 skills
|
|
322
|
+
/plugin install ai-engineering@skilldrop # 12 skills
|
|
323
|
+
/plugin install stakeholder-comms@skilldrop # 9 skills
|
|
324
|
+
/plugin install sre-oncall@skilldrop # 5 skills
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Every skill then invokes as `/<plugin>:<name>` (e.g. `/skilldrop:prfaq`). The whole-catalogue plugin ships the flat `skills/` and `agents/` trees at the repo root unchanged — same copy-install premise, expressed in Claude's own plugin format.
|
|
328
|
+
|
|
329
|
+
The six **pack plugins** work differently, because a plugin's skills have to sit in a `skills/` folder inside the plugin. Rather than duplicate every skill into six directories on `main` — physical packs, which [RFC-0001](docs/rfcs/0001-skill-packs.md) rejected — the marketplace entries use Claude's `git-subdir` source to point at `packs/<name>/` on a generated [`plugins`](https://github.com/sananthanarayan/skilldrop/tree/plugins) branch, rebuilt by CI on every push to main. Nothing moves in the source tree, and you still only ever type the one `marketplace add`. A pack carries the reviewer subagents its own skills delegate to, so `dev-team` brings the review panel and `sre-oncall` does not.
|
|
330
|
+
|
|
331
|
+
`.claude-plugin/{marketplace,plugin}.json` are generated from `package.json` + `packs.json` by [`build_marketplace.py`](build_marketplace.py) (`--check` guards drift in CI; `--dist` renders the branch). Use the CLI above when you want per-skill granularity, another IDE, or hooks; use the marketplace when you're in Claude Code. Rationale: [RFC-0027](docs/rfcs/0027-retire-agentbundle-export.md).
|
|
308
332
|
|
|
309
333
|
### Hooks (opt-in) — wire a skill to an event
|
|
310
334
|
|
|
@@ -357,7 +381,7 @@ npx skilldrop-cli install --pack starter --from ../local-catalog
|
|
|
357
381
|
npx skilldrop-cli update # updates bundled and third-party skills side by side — the ledger remembers each skill's source
|
|
358
382
|
```
|
|
359
383
|
|
|
360
|
-
The CLI also reads **agentbundle-shaped catalogs** ([agent-ready-repo](https://github.com/eugenelim/agent-ready-repo)) — `packs/<pack>/.apm/skills/<name>/SKILL.md` with a `pack.toml` per pack — so you can install *its* packs through the same command ([RFC-0014](docs/rfcs/0014-agentbundle-interop.md)). Both shapes share the agentskills.io `SKILL.md`, so the reader just maps his packs onto the accessors above:
|
|
384
|
+
The CLI also reads **agentbundle-shaped catalogs** ([agent-ready-repo](https://github.com/eugenelim/agent-ready-repo)) — `packs/<pack>/.apm/skills/<name>/SKILL.md` with a `pack.toml` per pack — so you can install *its* packs through the same command ([RFC-0014](docs/rfcs/0014-agentbundle-interop.md)). This is one-directional by design: skilldrop reads his shape, and no longer publishes a generated catalogue back into it ([RFC-0027](docs/rfcs/0027-retire-agentbundle-export.md)). Both shapes share the agentskills.io `SKILL.md`, so the reader just maps his packs onto the accessors above:
|
|
361
385
|
|
|
362
386
|
```bash
|
|
363
387
|
npx skilldrop-cli packs --from https://github.com/eugenelim/agent-ready-repo
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/sananthanarayan/skilldrop/contracts/loop.schema.json",
|
|
4
|
+
"title": "skilldrop loop",
|
|
5
|
+
"$comment": "RFC-0028. A loop sequences existing skills; it never contains one. Skills stay in flat skills/<name> folders and stay independently installable — a loop is a named order plus the gates between stages. Enforced by validate.py with hand-rolled stdlib checks: skilldrop ships zero runtime dependencies and this file must not become a reason to add `jsonschema`.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["name", "description", "entrypoint", "kind", "stages"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"$comment": { "type": "string" },
|
|
11
|
+
"name": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
14
|
+
"description": "Kebab-case. Must equal the folder name and the LOOP.md frontmatter name — the same triple-match skills are held to."
|
|
15
|
+
},
|
|
16
|
+
"version": { "type": "string" },
|
|
17
|
+
"description": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Use-case-first. First half says what the loop delivers; second half states the trigger phrases an agent matches on."
|
|
20
|
+
},
|
|
21
|
+
"entrypoint": { "const": "LOOP.md" },
|
|
22
|
+
"kind": {
|
|
23
|
+
"enum": ["loop", "wrapper"],
|
|
24
|
+
"description": "`loop` advances stage to stage toward a terminal. `wrapper` wraps an arbitrary generator skill chosen at run time — its stages are the passes either side of that generator."
|
|
25
|
+
},
|
|
26
|
+
"cap": {
|
|
27
|
+
"type": "integer",
|
|
28
|
+
"minimum": 1,
|
|
29
|
+
"maximum": 10,
|
|
30
|
+
"default": 3,
|
|
31
|
+
"description": "Maximum revision rounds before the loop stops looping and emits its conditional or blocked terminal. Default 3, matching agent-loop-design's revision cap."
|
|
32
|
+
},
|
|
33
|
+
"stages": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"minItems": 1,
|
|
36
|
+
"items": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"additionalProperties": false,
|
|
39
|
+
"required": ["id", "type", "intent", "skills"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
42
|
+
"type": {
|
|
43
|
+
"enum": ["generate", "verify", "gate"],
|
|
44
|
+
"description": "The three state types agent-loop-design mandates: 'Every loop has exactly these three state types.'"
|
|
45
|
+
},
|
|
46
|
+
"intent": { "type": "string", "description": "One line: what this stage is for." },
|
|
47
|
+
"skills": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"minItems": 1,
|
|
50
|
+
"items": { "type": "string" },
|
|
51
|
+
"description": "Skill folder names, in order. Each must be a real skills/<name>. `*` means any generator, and is legal only in a wrapper."
|
|
52
|
+
},
|
|
53
|
+
"gate": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"required": ["id", "kind", "verdicts"],
|
|
57
|
+
"properties": {
|
|
58
|
+
"id": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"pattern": "^G[0-9]+(\\.[0-9]+)?$",
|
|
61
|
+
"description": "Named gate, unique across the repo. A gate is a place a human or a script can point at."
|
|
62
|
+
},
|
|
63
|
+
"kind": {
|
|
64
|
+
"enum": ["mechanical", "review", "human"],
|
|
65
|
+
"description": "mechanical = a script's exit code decides. review = a skill or subagent panel decides. human = a person decides and the agent may not proceed without it."
|
|
66
|
+
},
|
|
67
|
+
"script": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Repo-relative path to the deciding script. Required when kind is mechanical, forbidden otherwise."
|
|
70
|
+
},
|
|
71
|
+
"verdicts": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"minItems": 2,
|
|
74
|
+
"items": { "type": "string" },
|
|
75
|
+
"description": "Every verdict this gate can emit. All must exist in contracts/terminals.json. Must include >=1 pass-class and >=1 non-pass."
|
|
76
|
+
},
|
|
77
|
+
"revise_to": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"description": "Stage id a revise-class verdict returns to. Must be an earlier stage in this loop."
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC-0028 — the shared verdict vocabulary. Before this file, every gating skill invented its own terminal words: feature-implement-loop says VERIFIED, pre-merge-review says READY, council-review says PROCEED, doc-critique says SHIP IT. They mean the same five things. A loop's gate declares which verdicts it can emit, and validate.py checks every one against this file — so a new loop cannot invent a sixth kind of 'yes'.",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"classes": {
|
|
5
|
+
"pass": "The gate is satisfied. The loop advances to the next stage, or terminates successfully.",
|
|
6
|
+
"conditional": "The gate is satisfied, but named open items travel forward with the artifact. Advancing is allowed; forgetting the items is not.",
|
|
7
|
+
"revise": "The gate is not satisfied and the fix is known. Return to the stage named by the loop's revision edge, subject to the cap.",
|
|
8
|
+
"redirect": "The gate is not satisfied and the work is the wrong shape. Do not revise — re-enter a different stage, a different loop, or a different artifact.",
|
|
9
|
+
"blocked": "The gate cannot be evaluated. A required input, decision, or permission is missing. Stop and name what is needed."
|
|
10
|
+
},
|
|
11
|
+
"verdicts": {
|
|
12
|
+
"VERIFIED": { "class": "pass", "origin": "feature-implement-loop" },
|
|
13
|
+
"READY": { "class": "pass", "origin": "pre-merge-review" },
|
|
14
|
+
"PROCEED": { "class": "pass", "origin": "council-review" },
|
|
15
|
+
"SHIP IT": { "class": "pass", "origin": "doc-critique" },
|
|
16
|
+
"VERIFIED WITH OPEN ITEMS": { "class": "conditional", "origin": "feature-implement-loop" },
|
|
17
|
+
"PROCEED WITH CONDITIONS": { "class": "conditional", "origin": "council-review" },
|
|
18
|
+
"SHIP WITH CHANGES": { "class": "conditional", "origin": "doc-critique" },
|
|
19
|
+
"NOT READY": { "class": "revise", "origin": "pre-merge-review" },
|
|
20
|
+
"REVISE": { "class": "revise", "origin": "council-review" },
|
|
21
|
+
"MAJOR REWRITE": { "class": "revise", "origin": "doc-critique" },
|
|
22
|
+
"RECONSIDER": { "class": "redirect", "origin": "council-review" },
|
|
23
|
+
"SPLIT": { "class": "redirect", "origin": "council-review" },
|
|
24
|
+
"WRONG ARTIFACT": { "class": "redirect", "origin": "doc-critique" },
|
|
25
|
+
"BLOCKED": { "class": "blocked", "origin": "feature-implement-loop" }
|
|
26
|
+
},
|
|
27
|
+
"rules": [
|
|
28
|
+
"Every gate declares at least one `pass` verdict and at least one non-pass verdict. A gate that can only succeed is not a gate.",
|
|
29
|
+
"Every gate can emit BLOCKED. A missing input is always possible and must never be fabricated past (AGENTS.md, non-interactive invocation).",
|
|
30
|
+
"A `revise` verdict is subject to the loop's `cap`. On the cap-th revise, the loop emits its conditional or blocked terminal instead of looping again.",
|
|
31
|
+
"A `redirect` verdict leaves the loop. It names where the work goes instead."
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build
|
|
3
|
+
description: Take an agreed requirement to merged code through a capped generate-verify-gate loop, with a mechanical gate that decides and a human who owns the merge. Use when the user wants to implement a story, fix a triaged bug, or ask whether a change is safe to merge.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# build
|
|
7
|
+
|
|
8
|
+
The repo-scope loop: a requirement enters, merged code leaves, and nothing crosses a stage
|
|
9
|
+
boundary without passing that stage's gate. This loop *sequences* skills — it never contains
|
|
10
|
+
one. Every skill named below stays independently installable and runnable on its own.
|
|
11
|
+
|
|
12
|
+
## Stages
|
|
13
|
+
|
|
14
|
+
| # | Stage | Type | Skills | Gate |
|
|
15
|
+
|---|---|---|---|---|
|
|
16
|
+
| 1 | `shape` | generate | [`user-story-splitter`](../../skills/user-story-splitter/SKILL.md), [`bug-triage`](../../skills/bug-triage/SKILL.md) | — |
|
|
17
|
+
| 2 | `implement` | generate | [`feature-implement-loop`](../../skills/feature-implement-loop/SKILL.md) | — |
|
|
18
|
+
| 3 | `verify` | verify | [`pre-merge-review`](../../skills/pre-merge-review/SKILL.md) | **G2** mechanical |
|
|
19
|
+
| 4 | `decide` | gate | [`council-review`](../../skills/council-review/SKILL.md) | **G2.1** human |
|
|
20
|
+
|
|
21
|
+
## How to run this loop
|
|
22
|
+
|
|
23
|
+
1. **Establish the unit of work.** New capability → `user-story-splitter`. Reported defect →
|
|
24
|
+
`bug-triage`. The stage is done when there is one vertical slice with acceptance criteria a
|
|
25
|
+
test can assert. Vague criteria are the single largest cause of a wasted round 3.
|
|
26
|
+
2. **Implement.** Hand the slice to `feature-implement-loop`, which runs its own capped
|
|
27
|
+
generate-challenge-gate cycle internally. Do not re-implement its rounds here — this loop's
|
|
28
|
+
`cap` governs returns from G2, not the inner skill's rounds.
|
|
29
|
+
3. **Verify at G2.** Run `pre-merge-review`. Its script decides and its panel explains:
|
|
30
|
+
`python3 skills/pre-merge-review/scripts/gate.py`. The exit code is the verdict —
|
|
31
|
+
`READY`, `NOT READY`, or `BLOCKED`.
|
|
32
|
+
4. **Honour the gate.** `NOT READY` returns to `implement`, up to `cap` (3) times. On the
|
|
33
|
+
third return, stop looping and emit `BLOCKED` naming what did not converge. Never edit the
|
|
34
|
+
gate to make it pass.
|
|
35
|
+
5. **Decide at G2.1.** The merge is a human's. Escalate design disagreements surfaced at G2 to
|
|
36
|
+
`council-review` rather than arguing them inside the diff; `RECONSIDER` and `SPLIT` both
|
|
37
|
+
leave this loop rather than revising within it.
|
|
38
|
+
|
|
39
|
+
## Verdicts
|
|
40
|
+
|
|
41
|
+
Defined in [`contracts/terminals.json`](../../contracts/terminals.json). G2 emits
|
|
42
|
+
`READY` / `NOT READY` / `BLOCKED`. G2.1 emits the council vocabulary. A `revise`-class verdict
|
|
43
|
+
returns to the stage named in `revise_to`; a `redirect`-class verdict leaves the loop.
|
|
44
|
+
|
|
45
|
+
## When a stage's skill is not installed
|
|
46
|
+
|
|
47
|
+
Skills install à la carte, so a stage may name a skill the target environment does not have.
|
|
48
|
+
Name the missing skill and skilldrop as its source, do the minimal inline version of that
|
|
49
|
+
stage, and record that the stage ran degraded. A missing skill is never a reason to skip a
|
|
50
|
+
**gate** — the gate is the loop's whole value.
|
|
51
|
+
|
|
52
|
+
## Quality bar
|
|
53
|
+
|
|
54
|
+
- **The gate decides, not the agent.** G2's verdict is `gate.py`'s exit code. An agent that reasons its way past a red gate has broken the loop, not passed it.
|
|
55
|
+
- **The cap is honoured.** Three returns to `implement`, then `BLOCKED` with what did not converge. A fourth round is a defect in this loop, not diligence.
|
|
56
|
+
- **Every stage leaves evidence.** Each stage names its skill, its verdict, and its round number, so the run is auditable after the fact rather than asserted.
|
|
57
|
+
- **Acceptance criteria exist before `implement` starts.** A slice whose criteria a test cannot assert is not shaped; return it to `shape`.
|
|
58
|
+
|
|
59
|
+
## Anti-patterns to avoid
|
|
60
|
+
|
|
61
|
+
- ❌ **Calling a skill from inside a skill to "continue the loop."** The loop sequences; skills do not chain. This is what keeps every skill portable to Cursor, Kiro, and Aider.
|
|
62
|
+
- ❌ **Editing `gate.py`, its config, or a test to turn G2 green.** That converts a mechanical gate into a decorative one.
|
|
63
|
+
- ❌ **Treating `PROCEED WITH CONDITIONS` as `PROCEED`.** The conditions travel with the artifact; dropping them is how conditional approvals become unconditional ones.
|
|
64
|
+
- ❌ **Running `decide` for every change.** G2.1 exists for escalated disagreement and the merge itself, not as a ceremony on top of a green gate.
|
|
65
|
+
- ❌ **Starting at `implement` because the story "is obvious."** Unshaped work is what produces a diff nobody can review against anything.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC-0028. This loop is docs/code-implement-verify.mmd promoted from a hand-maintained diagram into the machine-readable source that diagram is now generated from.",
|
|
3
|
+
"name": "build",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Take an agreed requirement to merged code through a capped generate-verify-gate loop, with a mechanical gate that decides and a human who owns the merge. Use when the user wants to implement a story, fix a triaged bug, or ask whether a change is safe to merge.",
|
|
6
|
+
"entrypoint": "LOOP.md",
|
|
7
|
+
"kind": "loop",
|
|
8
|
+
"cap": 3,
|
|
9
|
+
"stages": [
|
|
10
|
+
{
|
|
11
|
+
"id": "shape",
|
|
12
|
+
"type": "generate",
|
|
13
|
+
"intent": "Turn a requirement or defect into one vertically-sliced unit of work with acceptance criteria.",
|
|
14
|
+
"skills": ["user-story-splitter", "bug-triage"]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "implement",
|
|
18
|
+
"type": "generate",
|
|
19
|
+
"intent": "Write the code and its tests against the acceptance criteria, challenging the result each round.",
|
|
20
|
+
"skills": ["feature-implement-loop"]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "verify",
|
|
24
|
+
"type": "verify",
|
|
25
|
+
"intent": "Judge the diff that now exists. The script decides; the panel explains.",
|
|
26
|
+
"skills": ["pre-merge-review"],
|
|
27
|
+
"gate": {
|
|
28
|
+
"id": "G2",
|
|
29
|
+
"kind": "mechanical",
|
|
30
|
+
"script": "skills/pre-merge-review/scripts/gate.py",
|
|
31
|
+
"verdicts": ["READY", "NOT READY", "BLOCKED"],
|
|
32
|
+
"revise_to": "implement"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "decide",
|
|
37
|
+
"type": "gate",
|
|
38
|
+
"intent": "A human merges. Design disagreements surfaced at G2 are adjudicated here, not argued in the diff.",
|
|
39
|
+
"skills": ["council-review"],
|
|
40
|
+
"gate": {
|
|
41
|
+
"id": "G2.1",
|
|
42
|
+
"kind": "human",
|
|
43
|
+
"verdicts": ["PROCEED", "PROCEED WITH CONDITIONS", "REVISE", "RECONSIDER", "SPLIT", "BLOCKED"],
|
|
44
|
+
"revise_to": "shape"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship-a-draft
|
|
3
|
+
description: Take raw mess to a stakeholder-ready artifact by wrapping any skilldrop generator in the two passes either side of it — structured intake before, critique and machine-residue scrub after. Use when the user has notes, a transcript, or a ticket and wants a finished document rather than a first draft.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ship-a-draft
|
|
7
|
+
|
|
8
|
+
A **wrapper**, not a lifecycle loop. Its centre stage is whichever generator the user actually
|
|
9
|
+
needs — an ADR, a design doc, a runbook, a deck, an exec summary. The wrapper contributes the
|
|
10
|
+
two passes every generator otherwise leaves to chance: collect the input properly before, and
|
|
11
|
+
check the argument and the surface after.
|
|
12
|
+
|
|
13
|
+
## Stages
|
|
14
|
+
|
|
15
|
+
| # | Stage | Type | Skills | Gate |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| 1 | `intake` | generate | [`brief-intake`](../../skills/brief-intake/SKILL.md) | — |
|
|
18
|
+
| 2 | `draft` | generate | any generator (`*`) | — |
|
|
19
|
+
| 3 | `critique` | verify | [`doc-critique`](../../skills/doc-critique/SKILL.md) | **G4** review |
|
|
20
|
+
| 4 | `polish` | verify | [`output-hygiene`](../../skills/output-hygiene/SKILL.md) | — |
|
|
21
|
+
|
|
22
|
+
## How to run this wrapper
|
|
23
|
+
|
|
24
|
+
1. **Pick the generator first.** The brief is shaped *for a target*, so `draft` is chosen
|
|
25
|
+
before `intake` runs, not after. `brief-intake`'s own routing table maps trigger phrases to
|
|
26
|
+
targets; use it.
|
|
27
|
+
2. **Collect once.** Run `brief-intake`. Every field is tagged `[explicit]` / `[implied]` /
|
|
28
|
+
`[inferred]` / `[missing]`, and its "Missing for downstream" section predicts what the
|
|
29
|
+
chosen generator will refuse to start without. Resolve those before drafting.
|
|
30
|
+
3. **Draft.** Run the chosen generator on the brief. It is a normal skilldrop skill with its
|
|
31
|
+
own quality bar — this wrapper does not override it.
|
|
32
|
+
4. **Critique at G4.** Run `doc-critique`, which dispatches to the same rubric the generator
|
|
33
|
+
was held to. `MAJOR REWRITE` returns to `intake` (not to `draft` — a rewrite usually means
|
|
34
|
+
the input was wrong, not the prose). `WRONG ARTIFACT` leaves the wrapper entirely.
|
|
35
|
+
5. **Polish last.** Run `output-hygiene` only once the argument is settled. It is a surface
|
|
36
|
+
pass; running it on a draft that is about to be rewritten wastes it.
|
|
37
|
+
|
|
38
|
+
## Verdicts
|
|
39
|
+
|
|
40
|
+
Defined in [`contracts/terminals.json`](../../contracts/terminals.json). G4 emits the critique
|
|
41
|
+
vocabulary. `SHIP WITH CHANGES` carries its changes forward to `polish`; it does not mean the
|
|
42
|
+
changes are optional.
|
|
43
|
+
|
|
44
|
+
## When a stage's skill is not installed
|
|
45
|
+
|
|
46
|
+
Name the missing skill and skilldrop as its source, do the minimal inline version of that
|
|
47
|
+
stage, and say the stage ran degraded. Do not skip G4 — an unreviewed artifact is the failure
|
|
48
|
+
mode this wrapper exists to prevent.
|
|
49
|
+
|
|
50
|
+
## Quality bar
|
|
51
|
+
|
|
52
|
+
- **The generator is chosen before intake runs.** A brief collected for no particular target is a summary, and downstream will reject it for missing fields.
|
|
53
|
+
- **`polish` runs after the argument is settled, never before.** Scrubbing prose that is about to be rewritten is wasted work and hides the rewrite.
|
|
54
|
+
- **A `[missing]` tag is resolved or stated, never silently filled.** Fabricating a goal, an owner, or a decision corrupts every downstream artifact.
|
|
55
|
+
- **Every run ends by naming what was not touched.** `output-hygiene`'s "Not touched" section is part of the deliverable, not an appendix.
|
|
56
|
+
|
|
57
|
+
## Anti-patterns to avoid
|
|
58
|
+
|
|
59
|
+
- ❌ **Running `polish` as the whole review.** Clean prose with a broken argument still fails; that is what G4 is for.
|
|
60
|
+
- ❌ **Skipping `intake` because the input "is already structured."** A Slack thread that looks organized is still untagged — nobody downstream can tell what was inferred.
|
|
61
|
+
- ❌ **Looping `critique` → `draft` instead of `critique` → `intake`.** Re-drafting from the same incomplete brief reproduces the same gaps with new words.
|
|
62
|
+
- ❌ **Treating `WRONG ARTIFACT` as a severe `MAJOR REWRITE`.** It is a redirect: the user wanted a different document, and revising this one cannot get there.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC-0028. This wrapper is docs/knowledge-work-pipeline.mmd promoted from a hand-maintained diagram into the machine-readable source that diagram is now generated from. It is a wrapper, not a loop: the generator at its centre is chosen at run time from whichever artifact the user actually wants.",
|
|
3
|
+
"name": "ship-a-draft",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Take raw mess to a stakeholder-ready artifact by wrapping any skilldrop generator in the two passes either side of it — structured intake before, critique and machine-residue scrub after. Use when the user has notes, a transcript, or a ticket and wants a finished document rather than a first draft.",
|
|
6
|
+
"entrypoint": "LOOP.md",
|
|
7
|
+
"kind": "wrapper",
|
|
8
|
+
"cap": 3,
|
|
9
|
+
"stages": [
|
|
10
|
+
{
|
|
11
|
+
"id": "intake",
|
|
12
|
+
"type": "generate",
|
|
13
|
+
"intent": "Collect the raw input once, into the shape the chosen generator expects, tagging every field explicit / implied / inferred / missing.",
|
|
14
|
+
"skills": ["brief-intake"]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "draft",
|
|
18
|
+
"type": "generate",
|
|
19
|
+
"intent": "Run the generator the brief was shaped for. Any artifact skill is legal here — that choice is the wrapper's whole point.",
|
|
20
|
+
"skills": ["*"]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "critique",
|
|
24
|
+
"type": "verify",
|
|
25
|
+
"intent": "Review the draft against the same rubric the generator was held to.",
|
|
26
|
+
"skills": ["doc-critique"],
|
|
27
|
+
"gate": {
|
|
28
|
+
"id": "G4",
|
|
29
|
+
"kind": "review",
|
|
30
|
+
"verdicts": ["SHIP IT", "SHIP WITH CHANGES", "MAJOR REWRITE", "WRONG ARTIFACT", "BLOCKED"],
|
|
31
|
+
"revise_to": "intake"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "polish",
|
|
36
|
+
"type": "verify",
|
|
37
|
+
"intent": "Strip what the machine left behind before the artifact leaves the building. Surface pass only — never a substitute for the critique above.",
|
|
38
|
+
"skills": ["output-hygiene"]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skilldrop-cli",
|
|
3
|
-
"version": "0.11.
|
|
4
|
-
"description": "Portable AI-agent skills for the deliverables knowledge workers ship
|
|
3
|
+
"version": "0.11.6",
|
|
4
|
+
"description": "Portable AI-agent skills for the deliverables knowledge workers ship \u2014 diagrams, ADRs, PRDs, runbooks, decks, reviews \u2014 installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Sanjay Ananthanarayan",
|
|
7
7
|
"url": "https://github.com/sananthanarayan"
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"bin/",
|
|
14
14
|
"skills/",
|
|
15
15
|
"agents/",
|
|
16
|
+
"loops/",
|
|
17
|
+
"contracts/",
|
|
16
18
|
"packs.json",
|
|
17
19
|
"model-routing.json"
|
|
18
20
|
],
|