skilldrop-cli 0.11.5 → 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 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 runs two value streams, and **nothing comes out of either until it passes a review gate.** Both diagrams render on GitHub; the Mermaid sources live in [`docs/`](docs/) for easy re-rendering.
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
- ### Knowledge-work pipeline
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
- ### Code: implement and verify
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
 
@@ -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.5",
4
- "description": "Portable AI-agent skills for the deliverables knowledge workers ship — diagrams, ADRs, PRDs, runbooks, decks, reviews — installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
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
  ],