@rhize/skill-forge 0.11.3 → 0.12.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 CHANGED
@@ -70,6 +70,9 @@ skill-forge add <source> [options] Quarantine-install a skill and ru
70
70
  skill-forge scan <source> [options] Gate a skill without installing it (always cleans up)
71
71
  skill-forge evolve <skill-dir> [options] Self-evolve an installed skill via SkillOpt-Sleep, re-gate, decide (Pro)
72
72
  skill-forge audit [options] Doctor-style health check over the configured skill/MCP set (alias: doctor)
73
+ skill-forge finding accept <fp-prefix> Acknowledge a LOW/MEDIUM audit finding you've reviewed (human-only, no gate effect)
74
+ skill-forge finding revoke <fp-prefix> Remove a stored acceptance so the finding reports again
75
+ skill-forge finding list [options] List every accepted finding
73
76
  skill-forge organize [options] Set-level capability registry + dependency graph across configured skills roots (Pro)
74
77
  skill-forge find [query] [options] Discover skills via skills.sh and check partner security audits (free)
75
78
  skill-forge watch [options] Drift check across every SOURCES.md provenance ledger (Pro)
@@ -169,6 +172,7 @@ target skills root until you decide.
169
172
  | `-t, --target <dir>` | Skills root to promote into. Defaults to the config's `defaultTarget`, then `skillsRoots[0]`. |
170
173
  | `--json` | Prints the gate result (profile, safety findings, overlap) as JSON instead of the terminal report box. Implies non-interactive: the decision is made the same way `--yes` makes it (verdict decides promote/hold/reject), never an interactive prompt. |
171
174
  | `--ingest` | Pro (free during the 0.x beta). After a successful promote, hands off to a coding agent — see [Ingestion handoff](#ingestion-handoff---ingest). |
175
+ | `--skill-map <path>` | Path to a generated `rhize-plugins` skill map (Phase 4 of that repo's skill-map-graph-substrate plan). When given, ranks the candidate's name/description against every `skill` node in the map — a near-duplicate of an already-shipped marketplace skill is folded into the safety findings as a `HIGH`-severity finding (escalates the verdict to `block`, so it's held rather than silently promoted); a moderate overlap is `MEDIUM` (`warn`). Free (not Pro-gated) — this enforces the marketplace's own curation rule ("close the gap, don't duplicate"), not a premium ranking feature. Missing/unreadable map: printed to stderr, never fatal. |
172
176
 
173
177
  A promoted skill gets a provenance entry appended to `<target>/SOURCES.md`, and every promote or
174
178
  hold decision is recorded to `~/.skill-forge/queue.json` (or `$SKILL_FORGE_HOME/queue.json`) — see
@@ -190,7 +194,7 @@ skill-forge scan owner/name --json
190
194
  Runs the same gate pipeline as `add` (profile → safety → overlap → report) but never promotes
191
195
  anything — the quarantine sandbox is always cleaned up afterward, on success or failure. Exits
192
196
  nonzero when the safety verdict is `block`. `--json` prints the same gate-result payload shape as
193
- `add`'s.
197
+ `add`'s. Also accepts `--skill-map <path>` — see `add`'s option table above.
194
198
 
195
199
  ### `evolve` (v0.7)
196
200
 
@@ -293,6 +297,13 @@ basename, package spec, arg/env **counts** — never values); TOML targets (e.g.
293
297
  structured TOML enumeration. A per-item failure (unreadable skill, broken symlink, malformed MCP
294
298
  config) becomes a finding — it never aborts the run.
295
299
 
300
+ **Accepted findings (v0.12).** Every finding in the report carries a fingerprint
301
+ (`(fp a1b2c3d4e5f6)`); `Findings` shows **active** findings only, and a separate
302
+ **Accepted findings** section lists whatever you've reviewed and accepted via
303
+ [`skill-forge finding accept`](#finding-v012) — permanently, with reason and date, even after it
304
+ stops matching (see that section for the full contract). `summary.acceptedCount` and each
305
+ finding's `fingerprint` are additive `--json` fields; nothing accepted is ever silently deleted.
306
+
296
307
  **Opportunity pass.** Beyond hygiene, the report surfaces:
297
308
 
298
309
  - **Overlap clusters** (Pro, free during the 0.x beta) — cross-root overlap scoring across every
@@ -331,6 +342,49 @@ in place of `ingest-prompt.md`. `--yes` (and `init --defaults`, which passes it
331
342
  implies either — a non-interactive run writes only the report and, if a profile was already
332
343
  stored, the config; nothing else.
333
344
 
345
+ ### `finding` (v0.12)
346
+
347
+ ```bash
348
+ skill-forge finding accept <fingerprint-prefix> --reason "Funnel genuinely needs root; verified"
349
+ skill-forge finding revoke <fingerprint-prefix>
350
+ skill-forge finding list [--stale] [--json]
351
+ ```
352
+
353
+ Acknowledge an `audit` finding you've reviewed and accepted, so it stops counting against
354
+ `routine --fail-on` and the `add`/`scan` advisory while staying **permanently visible** in its own
355
+ report section — an audit you can't triage decays into noise, and noise is how the one real
356
+ finding gets skimmed. Every finding in an `audit`/`routine` report now carries a 12-char
357
+ fingerprint (`(fp a1b2c3d4e5f6)`) you copy into `accept`/`revoke`.
358
+
359
+ | Command | Effect |
360
+ |---|---|
361
+ | `finding accept <fp-prefix> --reason <text>` | Records an acceptance. Re-runs the read-only audit engine to resolve the prefix against what's **currently active** — you can only accept a finding that exists right now, never from a stale report. `--reason` is mandatory (1-200 chars, no control characters). |
362
+ | `finding revoke <fp-prefix>` | Removes a stored acceptance so the finding reports again. Resolves against the **store**, not a fresh audit run — the target may no longer be producible, which is exactly when you'd want to clean up. |
363
+ | `finding list [--stale] [--json]` | Lists every accepted finding (severity, rule, target, reason, accepted date, fingerprint). `--stale` filters to records whose target no longer exists on disk. |
364
+
365
+ **Identity is content-derived, not a name you pick.** A finding's fingerprint is
366
+ `sha256(severity + rule + target + the offending line's text)` — deliberately excluding the LINE
367
+ NUMBER (drifts on unrelated edits) and deliberately including SEVERITY (so a rule re-tuned to a
368
+ higher severity for the same content can't inherit an ack minted against the lower one). Any change
369
+ to the offending content **fails open to re-reporting** — this is the design, not a bug: the
370
+ alternative (key on rule+path only) is the classic baseline trap, where accepting one benign line
371
+ silently suppresses every future line the same rule matches in that file. Full contract, the
372
+ per-rule `context` table, and fail-open read semantics: see
373
+ [docs/accepted-findings-schema.md](docs/accepted-findings-schema.md).
374
+
375
+ **Severity-capped, human-only, no override.** `finding accept` refuses `HIGH`/`CRITICAL` findings
376
+ outright — there is no `--force`. The precision problem this command exists to solve lives at
377
+ `LOW`/`MEDIUM`; a `HIGH` false positive is a rule bug to fix, not something to baseline. This is a
378
+ human-door CLI (`config set` model), not the agent-facing propose/review queue — both
379
+ `assets/ingest-prompt.md` and `assets/curation-prompt.md` instruct agents to never run
380
+ `finding accept`/`finding revoke` themselves; an agent that judges a finding a false positive says
381
+ so in its summary and lets the user run the command.
382
+
383
+ **Never a gate input.** Acceptances only ever affect `audit`'s own report classification (and,
384
+ downstream, `routine --fail-on` and the `add`/`scan` advisory) — `add`/`scan`/`promote <id>`/
385
+ `evolve`'s re-gate never reads the accepted-findings store. See
386
+ [docs/gate-policy.md](docs/gate-policy.md#accepted-findings-v012).
387
+
334
388
  ### `organize` (v0.9, Pro)
335
389
 
336
390
  ```bash
@@ -404,6 +458,7 @@ shell — you (or your shell's dotenv loader) still need to export it before `fi
404
458
  skill-forge watch
405
459
  skill-forge watch --offline
406
460
  skill-forge watch --json
461
+ skill-forge watch --skill-map generated/skill-map.static.json
407
462
  ```
408
463
 
409
464
  Pro (free during the 0.x beta). TS port of the plugin's `record_provenance.py --check-drift`.
@@ -420,6 +475,15 @@ entry is listed for manual checking regardless.
420
475
  attacker-influenceable data — anyone who can write to a skills root's `SOURCES.md` controls it.
421
476
  It is only ever printed, sanitized, as a suggestion for you (or an agent) to run yourself.
422
477
 
478
+ **`--skill-map <path>` (Phase 4 of `rhize-plugins`' skill-map-graph-substrate plan)** additionally
479
+ drift-checks every `fork-of` edge in a generated skill map: for each edge it resolves the local
480
+ `skill` node's `path`/`contentHash` and the upstream (`external`) node's `url`/`path`, fetches or
481
+ reads the upstream content, and compares content hashes. Each edge reports one of `in-sync`,
482
+ `drifted`, `upstream-unreachable`, or `local-missing`. Same never-execute posture as the ledger
483
+ check above: nothing derived from the map — including a fork-of edge's own `driftCheck`
484
+ metadata — is ever executed; only fetch/read/hash/compare. A missing/unreadable map is a warning,
485
+ never fatal.
486
+
423
487
  ### `ingest` + `queue close` (v0.9, Pro)
424
488
 
425
489
  ```bash
@@ -593,6 +657,13 @@ when the skill it points at no longer exists; a pending entry whose skill is sti
593
657
  undone work, not an orphan. `routine` never installs, promotes, or rejects: no candidate enters a
594
658
  skills root without a human or agent decision, and a cron job is not that.
595
659
 
660
+ **Accepted findings (v0.12)** are honored the same way `audit` honors them: `--fail-on` grades
661
+ **active** findings only, so accepting every remaining finding via `skill-forge finding accept`
662
+ turns a red `--fail-on any` green, and any new or changed finding turns it red again. A
663
+ corrupt/missing accepted-findings store fails open (nothing gets suppressed) and surfaces as a
664
+ report **notice**, never as an "Incomplete step" — see
665
+ [docs/accepted-findings-schema.md](docs/accepted-findings-schema.md).
666
+
596
667
  ```
597
668
  0 9 * * 1 skill-forge routine --offline --fail-on high --housekeeping
598
669
  ```
@@ -720,9 +791,11 @@ guessing between the two).
720
791
 
721
792
  Safety runs the same built-in deny-pattern ruleset used for skills (curl\|bash, credential-file
722
793
  access, etc.) plus MCP-specific rules: inline credential values in config/env (quoted or
723
- unquoted), unpinned `npx -y` launch commands (a moving/dist tag like `@latest` counts as
724
- unpinned, and `npx` is recognized by basename so a full path or `npx.cmd` can't evade it),
725
- `--dangerously-*`/`--no-sandbox` flags, and filesystem-root launch args — see the
794
+ unquoted), unpinned `npx` launch commands — MEDIUM with `-y`/`--yes` (silent install), **LOW
795
+ without it (v0.12)**, since npx still prompts before the first install but the tag floats once
796
+ cached (a moving/dist tag like `@latest` counts as unpinned either way, and `npx` is recognized by
797
+ basename so a full path or `npx.cmd` can't evade it) — `--dangerously-*`/`--no-sandbox` flags, and
798
+ filesystem-root launch args — see the
726
799
  [MCP safety ruleset table](docs/gate-policy.md#mcp-safety-ruleset). Overlap analysis (Pro, free
727
800
  during the 0.x beta) ranks the candidate against the server entries already present in your
728
801
  configured `mcpTargets` files, instead of against a skills root.
@@ -806,6 +879,7 @@ JSON. Detection/overlap is agent-format-agnostic; writing is JSON-only.
806
879
  | `watch` — provenance drift check across every `SOURCES.md` ledger (v0.9) | | ✓ |
807
880
  | `ingest` + `queue close` — pending-queue drain handoff (v0.9) | | ✓ |
808
881
  | `refine` — capture/apply/generalize project-scope skill overrides (v0.10) | | ✓ |
882
+ | `finding accept`/`revoke`/`list` — acknowledge audit findings, never a gate input (v0.12) | ✓ | ✓ |
809
883
 
810
884
  Free is the complete safety gate on its own — quarantine, profile, safety scan, and an explicit
811
885
  promote/reject decision, with nothing held back. Pro is the curation layer on top: whether a new