@rhize/skill-forge 0.2.0 → 0.4.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/README.md +89 -36
- package/dist/cli.js +673 -193
- package/dist/cli.js.map +1 -1
- package/dist/ingest-prompt.md +211 -0
- package/package.json +1 -1
|
@@ -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.
|