@rhize/skill-forge 0.2.0 → 0.3.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.
@@ -0,0 +1,211 @@
1
+ # Skill Ingestion Pass
2
+
3
+ You are running the deep decide/absorb pass on a skill that has just cleared the
4
+ `skill-forge` quarantine → profile → safety scan → overlap-analysis gate. The gate already
5
+ answered "is this safe to install?" — your job is the harder question: "given everything
6
+ already in this skill set, what should actually be *done* with it?"
7
+
8
+ You may be any coding agent (Claude Code, Codex CLI, Cursor, Windsurf, OpenCode, Gemini
9
+ CLI, or another). Nothing below assumes a specific one. Use whatever file-reading,
10
+ file-editing, and shell-command capabilities you have available.
11
+
12
+ ## 1. Find your target
13
+
14
+ The absolute path to the skill you should evaluate is normally given directly in the
15
+ message that invoked you — look for a path to a directory containing a `SKILL.md`.
16
+
17
+ If no path was given directly, check the pending-ingestion queue instead:
18
+
19
+ ```
20
+ ~/.skill-forge/queue.json # or $SKILL_FORGE_HOME/queue.json if that env var is set
21
+ ```
22
+
23
+ Read it. If it doesn't exist yet, there is nothing queued — stop and say so. Otherwise it
24
+ is a JSON object shaped like:
25
+
26
+ ```json
27
+ {
28
+ "version": 1,
29
+ "entries": [
30
+ {
31
+ "id": "a1b2c3d4",
32
+ "source": "the original slug / git URL / local path the skill was installed from",
33
+ "sourceType": "skills.sh | git | local",
34
+ "installedPath": "final path after promote, or null if only held in quarantine",
35
+ "quarantinePath": "path to the quarantine sandbox this entry was gated from",
36
+ "gate": {
37
+ "license": "detected license string, or null",
38
+ "safetyVerdict": "pass | warn | block",
39
+ "safetyFindings": ["human-readable safety findings, one per string"],
40
+ "overlapTop": [{ "skill": "nearest-existing-skill-name", "score": 0.0 }],
41
+ "suggestedVerb": "DEFER | ABSORB | FORK | REJECT | WATCH | null"
42
+ },
43
+ "status": "pending | ingested | dismissed",
44
+ "createdAt": "ISO-8601 timestamp"
45
+ }
46
+ ]
47
+ }
48
+ ```
49
+
50
+ Pick the entry with `"status": "pending"` whose `installedPath` (or `quarantinePath`, if
51
+ `installedPath` is `null`) matches your target. If several are pending, list them for the
52
+ user and ask which to process, or work through them one at a time — don't silently drain
53
+ the whole queue.
54
+
55
+ If there is no matching queue entry at all (you were pointed straight at a skill directory
56
+ with no CLI queue involved), that's fine — do the same evaluation, just skip the "close the
57
+ entry" step at the end since there's nothing to close.
58
+
59
+ ## 2. Gather context
60
+
61
+ - **Read the candidate skill**: its `SKILL.md` (frontmatter + body) and any scripts,
62
+ references, or templates it ships.
63
+ - **Reuse the gate's findings** if you found a queue entry — `gate.safetyVerdict`,
64
+ `gate.safetyFindings`, `gate.license`, and `gate.overlapTop` were already computed by the
65
+ CLI. Don't re-run a safety or overlap scan on the same source; that's duplicate work the
66
+ gate already did.
67
+ - **Survey the user's existing skill set** for anything that already covers similar ground
68
+ — same domain, same trigger conditions, overlapping capability. If the queue entry has
69
+ `gate.overlapTop`, start there; otherwise search the skill set yourself.
70
+
71
+ ## 3. Decide — pick exactly one verb
72
+
73
+ Every candidate resolves to exactly one of five verbs. Forcing a single choice is
74
+ deliberate: ambiguity is where bloat and licensing risk creep in.
75
+
76
+ Inputs to weigh:
77
+ 1. **Overlap** with the nearest existing skill: low / medium / high.
78
+ 2. **Quality** of the candidate: structure, specificity, whether it explains *why* (not
79
+ just *what*), any test/eval coverage.
80
+ 3. **License** — classify it now, before forming an opinion (see §4).
81
+ 4. **Maintenance** — is the upstream source active, versioned, likely to keep changing?
82
+ 5. **Fit** — does it assume the same stack/conventions as the rest of the skill set, or
83
+ something foreign that would need translation?
84
+
85
+ ```
86
+ LOW overlap MEDIUM overlap HIGH overlap
87
+ HIGH quality ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
88
+ permissive │ DEFER (keep it │ │ FORK (re-skin to │ │ ABSORB (patch the │
89
+ license │ as-is, point the │ │ house conventions)│ │ better parts into │
90
+ │ set at it) │ │ │ │ the near skill) │
91
+ └──────────────────┘ └──────────────────┘ └──────────────────┘
92
+ LOW quality ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
93
+ or │ WATCH (note it, │ │ REJECT (or ABSORB │ │ REJECT (the set │
94
+ poor fit │ revisit later) │ │ one good part only)│ │ already does this │
95
+ │ │ │ │ │ better) │
96
+ └──────────────────┘ └──────────────────┘ └──────────────────┘
97
+ ```
98
+
99
+ **License overrides everything**: none-stated, copyleft entering a permissively-licensed
100
+ set, or restrictive terms → default to REJECT or escalate to the user, regardless of
101
+ quality or overlap. See §4.
102
+
103
+ If the queue entry has a `gate.suggestedVerb`, treat it as a starting hypothesis from the
104
+ overlap heuristic — not a verdict. Confirm or override it based on the fuller read you just
105
+ did.
106
+
107
+ ### Verb definitions
108
+
109
+ - **DEFER** — Adopt the candidate as-is; take nothing out of it into the existing set
110
+ beyond, at most, a one-line pointer from the nearest existing skill ("for X, see
111
+ `<candidate>`"). Best when the candidate is already high quality, actively maintained,
112
+ and re-implementing it would just be re-typing it.
113
+
114
+ - **ABSORB** — Pull specific patterns, scripts, or reference material into an existing
115
+ skill. Use when one existing skill clearly owns this domain and the candidate has a
116
+ handful of genuinely better parts. Never absorb the whole thing wholesale — name the
117
+ exact pieces you took in your record (§6). If it looks like you want to absorb
118
+ everything, that's really a FORK.
119
+
120
+ - **FORK** — Copy the candidate into a new skill of its own and re-skin it to match house
121
+ conventions (frontmatter, description style, stack assumptions, command namespace if
122
+ any). Use when the bones are good but it's a genuinely new capability (low overlap), or
123
+ the house style differs enough that a patch would be messier than a clean rewrite.
124
+ Justify choosing this over the lighter DEFER.
125
+
126
+ - **REJECT** — Take nothing. Record why, so the candidate isn't silently re-evaluated
127
+ later. Common reasons: redundant with something already better, low quality, or a
128
+ license you can't accept.
129
+
130
+ - **WATCH** — Don't adopt now, but don't forget it either. Leave a reference note
131
+ somewhere findable and record a "revisit later" marker. Use for promising-but-immature
132
+ candidates, or things worth citing without adopting.
133
+
134
+ ### Anti-patterns
135
+
136
+ - Absorbing an entire skill "to be safe" — that's FORK with extra steps and no re-skin.
137
+ - Forking when DEFER would do — if you'd copy it nearly verbatim and upstream is well
138
+ maintained, defer instead.
139
+ - Skipping verification (§5) because the candidate "looks obviously fine."
140
+ - Landing on two verbs at once (e.g. "ABSORB and FORK") — that means the overlap read in
141
+ step 2 was incomplete; go back and finish it.
142
+
143
+ ## 4. License triage
144
+
145
+ Classify the detected license (from `gate.license`, a `LICENSE` file, or `SKILL.md`
146
+ frontmatter) before you commit to a verb:
147
+
148
+ | Class | Examples | Action |
149
+ |---|---|---|
150
+ | Permissive | MIT, Apache-2.0, BSD-2/3, ISC, CC0, Unlicense, public domain | OK to ABSORB/FORK. Keep attribution where the license requires it (Apache NOTICE, BSD copyright line). |
151
+ | Attribution-required | CC-BY, MIT with an attribution clause | OK, but you must keep the copyright/attribution notice wherever the content ends up. |
152
+ | Copyleft | GPL, AGPL, CC-BY-SA, MPL | Escalate to the user. Copyleft terms can spread into a permissively-licensed set. Default to DEFER (use without copying) or REJECT — don't ABSORB/FORK without explicit sign-off. |
153
+ | None stated | No LICENSE file, no frontmatter license field | Escalate. Absence of a license means all rights are reserved by default. Default to REJECT or WATCH; ask the user before taking anything. |
154
+ | Restrictive / proprietary | "All rights reserved", a custom EULA, "personal use only" | REJECT. Show the user the exact clause. |
155
+
156
+ **Rule**: never ABSORB or FORK on a copyleft, none-stated, or restrictive license without
157
+ showing the user the exact license text and getting explicit approval first. DEFER is
158
+ usually fine regardless of license, since using an installed skill as-is isn't
159
+ redistributing its source.
160
+
161
+ ## 5. Execute, then verify
162
+
163
+ Carry out the verb from §3:
164
+ - **ABSORB** — write the specific patterns/files/sections you're taking into the target
165
+ skill (patch it, don't replace it wholesale).
166
+ - **FORK** — copy the candidate into a new skill directory and re-skin its frontmatter,
167
+ description, and any stack-specific assumptions to match the rest of the set.
168
+ - **DEFER** — at most, add a one-line pointer from the nearest existing skill's
169
+ description. Nothing else changes.
170
+ - **WATCH / REJECT** — no file changes to the skill set; just the record in §6.
171
+
172
+ For ABSORB and FORK, verify before you call it done: exercise the absorbed/forked skill (or
173
+ its scripts) enough to confirm it actually works in its new home and doesn't regress
174
+ anything nearby it references or depends on. "It looked fine reading it" is not
175
+ verification.
176
+
177
+ ## 6. Record the outcome
178
+
179
+ Write a short record of what you decided and why. At minimum, capture:
180
+
181
+ - Candidate name and source (slug/URL/path).
182
+ - Upstream version or commit ref, if known (or "n/a").
183
+ - License and its class from §4.
184
+ - The verb you chose.
185
+ - Target (which existing skill you patched, or the new skill's name, or "n/a").
186
+ - What was actually taken — specific files/patterns, or "nothing".
187
+ - Verification result, or "n/a" for WATCH/REJECT.
188
+ - Your reasoning in one or two sentences.
189
+
190
+ Where you put this record is up to the conventions of the project you're working in — a
191
+ changelog, a provenance ledger, a commit message, or just a clear message back to the user.
192
+ The one place it's *not* optional is the queue entry, if you found one in step 1.
193
+
194
+ ### Close the queue entry
195
+
196
+ If you located a queue entry in step 1, update its `status` field:
197
+
198
+ - `"ingested"` — once you've recorded the decision above, whatever the verb (including
199
+ REJECT and WATCH — "ingested" means *processed*, not *adopted*).
200
+ - `"dismissed"` — if the user explicitly declined to have this entry processed at all.
201
+
202
+ Never delete entries — the queue is the audit trail. To update it: read
203
+ `~/.skill-forge/queue.json` (or `$SKILL_FORGE_HOME/queue.json`), find the entry by its `id`,
204
+ change only its `status` field, and write the whole file back as JSON with two-space
205
+ indentation and a trailing newline, leaving every other field untouched.
206
+
207
+ ## 7. Report back
208
+
209
+ Close with a short summary for the user: which skill you evaluated, the verb you chose and
210
+ why, what changed (or didn't), and whether the queue entry was closed. Keep it to a few
211
+ sentences — the detailed record from §6 is where the full reasoning lives.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhize/skill-forge",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },