@skillsmith/core 0.12.3 → 0.12.4
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/CHANGELOG.md +164 -0
- package/README.md +2 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/config/owned-lock.acquire.d.ts +8 -0
- package/dist/src/config/owned-lock.acquire.d.ts.map +1 -1
- package/dist/src/config/owned-lock.acquire.js +19 -4
- package/dist/src/config/owned-lock.acquire.js.map +1 -1
- package/dist/src/config/owned-lock.claim.d.ts +4 -2
- package/dist/src/config/owned-lock.claim.d.ts.map +1 -1
- package/dist/src/config/owned-lock.claim.js +42 -8
- package/dist/src/config/owned-lock.claim.js.map +1 -1
- package/dist/src/config/owned-lock.d.ts.map +1 -1
- package/dist/src/config/owned-lock.js +1 -0
- package/dist/src/config/owned-lock.js.map +1 -1
- package/dist/src/config/owned-lock.test.js +126 -2
- package/dist/src/config/owned-lock.test.js.map +1 -1
- package/dist/src/config/owned-lock.types.d.ts +9 -0
- package/dist/src/config/owned-lock.types.d.ts.map +1 -1
- package/dist/src/db/createDatabase.d.ts.map +1 -1
- package/dist/src/db/createDatabase.js +0 -2
- package/dist/src/db/createDatabase.js.map +1 -1
- package/dist/src/exports/services.install.d.ts +1 -0
- package/dist/src/exports/services.install.d.ts.map +1 -1
- package/dist/src/exports/services.install.js +5 -0
- package/dist/src/exports/services.install.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/install/fan-out.cleanup.d.ts +37 -0
- package/dist/src/install/fan-out.cleanup.d.ts.map +1 -0
- package/dist/src/install/fan-out.cleanup.js +75 -0
- package/dist/src/install/fan-out.cleanup.js.map +1 -0
- package/dist/src/install/fan-out.d.ts +41 -31
- package/dist/src/install/fan-out.d.ts.map +1 -1
- package/dist/src/install/fan-out.js +213 -112
- package/dist/src/install/fan-out.js.map +1 -1
- package/dist/src/install/fan-out.leftovers.d.ts +60 -0
- package/dist/src/install/fan-out.leftovers.d.ts.map +1 -0
- package/dist/src/install/fan-out.leftovers.js +251 -0
- package/dist/src/install/fan-out.leftovers.js.map +1 -0
- package/dist/src/install/fan-out.locks.d.ts +12 -0
- package/dist/src/install/fan-out.locks.d.ts.map +1 -0
- package/dist/src/install/fan-out.locks.js +114 -0
- package/dist/src/install/fan-out.locks.js.map +1 -0
- package/dist/src/install/fan-out.manifest.d.ts +64 -0
- package/dist/src/install/fan-out.manifest.d.ts.map +1 -0
- package/dist/src/install/fan-out.manifest.js +130 -0
- package/dist/src/install/fan-out.manifest.js.map +1 -0
- package/dist/src/install/fan-out.overwrite.d.ts +51 -0
- package/dist/src/install/fan-out.overwrite.d.ts.map +1 -0
- package/dist/src/install/fan-out.overwrite.js +343 -0
- package/dist/src/install/fan-out.overwrite.js.map +1 -0
- package/dist/src/install/remove-if-same.d.ts +58 -0
- package/dist/src/install/remove-if-same.d.ts.map +1 -0
- package/dist/src/install/remove-if-same.js +222 -0
- package/dist/src/install/remove-if-same.js.map +1 -0
- package/dist/src/provenance/backfill.d.ts.map +1 -1
- package/dist/src/provenance/backfill.js +15 -2
- package/dist/src/provenance/backfill.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +8 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.value-gate.d.ts +22 -2
- package/dist/src/security/scanner/SecurityScanner.value-gate.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.value-gate.js +143 -6
- package/dist/src/security/scanner/SecurityScanner.value-gate.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.d.ts +2 -2
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.js +185 -190
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts +47 -2
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.js +48 -3
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/patterns.sensitive-path.d.ts +31 -3
- package/dist/src/security/scanner/patterns.sensitive-path.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.sensitive-path.js +59 -4
- package/dist/src/security/scanner/patterns.sensitive-path.js.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.js +3 -2
- package/dist/src/services/agent-pack/prompt-source.js.map +1 -1
- package/dist/src/services/skill-installation.content.d.ts +7 -2
- package/dist/src/services/skill-installation.content.d.ts.map +1 -1
- package/dist/src/services/skill-installation.content.js +75 -28
- package/dist/src/services/skill-installation.content.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +8 -0
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.io.d.ts +1 -29
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.dirs.d.ts +15 -0
- package/dist/src/services/skill-installation.io.dirs.d.ts.map +1 -0
- package/dist/src/services/skill-installation.io.dirs.js +84 -0
- package/dist/src/services/skill-installation.io.dirs.js.map +1 -0
- package/dist/src/services/skill-installation.io.js +6 -176
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.io.rollback.d.ts +138 -0
- package/dist/src/services/skill-installation.io.rollback.d.ts.map +1 -0
- package/dist/src/services/skill-installation.io.rollback.js +218 -0
- package/dist/src/services/skill-installation.io.rollback.js.map +1 -0
- package/dist/src/services/skill-installation.io.write.d.ts +69 -0
- package/dist/src/services/skill-installation.io.write.d.ts.map +1 -0
- package/dist/src/services/skill-installation.io.write.js +417 -0
- package/dist/src/services/skill-installation.io.write.js.map +1 -0
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.finalize.d.ts +62 -0
- package/dist/src/services/skill-installation.service.finalize.d.ts.map +1 -0
- package/dist/src/services/skill-installation.service.finalize.js +136 -0
- package/dist/src/services/skill-installation.service.finalize.js.map +1 -0
- package/dist/src/services/skill-installation.service.js +66 -80
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.target-guard.d.ts +82 -0
- package/dist/src/services/skill-installation.target-guard.d.ts.map +1 -0
- package/dist/src/services/skill-installation.target-guard.js +410 -0
- package/dist/src/services/skill-installation.target-guard.js.map +1 -0
- package/dist/src/services/skill-installation.types.d.ts +13 -1
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-installation.uninstall.d.ts +3 -1
- package/dist/src/services/skill-installation.uninstall.d.ts.map +1 -1
- package/dist/src/services/skill-installation.uninstall.helpers.d.ts +59 -0
- package/dist/src/services/skill-installation.uninstall.helpers.d.ts.map +1 -0
- package/dist/src/services/skill-installation.uninstall.helpers.js +124 -0
- package/dist/src/services/skill-installation.uninstall.helpers.js.map +1 -0
- package/dist/src/services/skill-installation.uninstall.js +148 -25
- package/dist/src/services/skill-installation.uninstall.js.map +1 -1
- package/dist/src/utils/safe-fs.d.ts +69 -0
- package/dist/src/utils/safe-fs.d.ts.map +1 -1
- package/dist/src/utils/safe-fs.js +113 -2
- package/dist/src/utils/safe-fs.js.map +1 -1
- package/dist/tests/install/fan-out.test.js +1951 -13
- package/dist/tests/install/fan-out.test.js.map +1 -1
- package/dist/tests/install/remove-if-same.test.d.ts +2 -0
- package/dist/tests/install/remove-if-same.test.d.ts.map +1 -0
- package/dist/tests/install/remove-if-same.test.js +298 -0
- package/dist/tests/install/remove-if-same.test.js.map +1 -0
- package/dist/tests/integration/fan-out-lock-contention.test.d.ts +11 -0
- package/dist/tests/integration/fan-out-lock-contention.test.d.ts.map +1 -0
- package/dist/tests/integration/fan-out-lock-contention.test.js +53 -0
- package/dist/tests/integration/fan-out-lock-contention.test.js.map +1 -0
- package/dist/tests/provenance/backfill.test.js +43 -0
- package/dist/tests/provenance/backfill.test.js.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +33 -5
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-adversarial-review.test.js +120 -0
- package/dist/tests/security/sensitive-path-adversarial-review.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-boolean-flag.test.d.ts +2 -0
- package/dist/tests/security/sensitive-path-boolean-flag.test.d.ts.map +1 -0
- package/dist/tests/security/sensitive-path-boolean-flag.test.js +151 -0
- package/dist/tests/security/sensitive-path-boolean-flag.test.js.map +1 -0
- package/dist/tests/security/sensitive-path-fp.test.js +71 -5
- package/dist/tests/security/sensitive-path-fp.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.d.ts +2 -0
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.d.ts.map +1 -0
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.js +176 -0
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.js.map +1 -0
- package/dist/tests/security/weak-password-lexicon.test.js +14 -4
- package/dist/tests/security/weak-password-lexicon.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.content.test.js +23 -0
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js +35 -14
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.io.rollback.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.test.js +984 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.js +148 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +19 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.finalize.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.service.finalize.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.finalize.test.js +147 -0
- package/dist/tests/unit/services/skill-installation.service.finalize.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.test.js +43 -0
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.target-guard.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.target-guard.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.target-guard.test.js +590 -0
- package/dist/tests/unit/services/skill-installation.target-guard.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.js +473 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.js.map +1 -0
- package/dist/tests/utils/safe-fs.test.js +129 -2
- package/dist/tests/utils/safe-fs.test.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,170 @@ All notable changes to `@skillsmith/core` are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## v0.12.4
|
|
8
|
+
|
|
9
|
+
- **Fix**: SMI-6507 + SMI-6496 -- remediation strings that actually work (#2803)
|
|
10
|
+
- **Fix**: SMI-6508 -- move MF-5 last; it was suppressing HIGH findings (#2808)
|
|
11
|
+
- **Fix**: SMI-6508 — detect prefixed secrets assignments at MEDIUM (MF-5) (#2806)
|
|
12
|
+
- **Fix**: SMI-6530 -- stop recommending bulk `skillsmith update` until the safety gate ships (#2801)
|
|
13
|
+
- **Fix**: SMI-6505 -- stop scoring an embedded key assigned a boolean as a credential (#2793)
|
|
14
|
+
- **Feature**: SMI-6441 -- MF-4b common-password veto (Wave 2) (#2786)
|
|
15
|
+
- **Fix (data loss)**: install and update no longer destroy a skill directory that already
|
|
16
|
+
existed. A failed write restores every overwritten file to its original bytes and removes only
|
|
17
|
+
files and directories the install created; a directory that existed is never deleted (it was
|
|
18
|
+
removed recursively, `.git` included). A new pre-write check, `checkInstallTarget`, refuses to
|
|
19
|
+
write into a git working tree (or a directory inside one, symlinks resolved), a directory
|
|
20
|
+
Skillsmith didn't install (no matching manifest entry, or a row marked local or adopted), and a
|
|
21
|
+
target that differs from the directory `update` compared (`expectedInstallPath`); `force` does
|
|
22
|
+
not override these. A restore that itself fails now raises `InstallRestoreError` naming the
|
|
23
|
+
unrestored files instead of a generic internal error. Private-registry content keys can no
|
|
24
|
+
longer create a `.git` path, and `--also-link --force` replaces a symlink or a fan-out copy
|
|
25
|
+
Skillsmith itself recorded (the new copy is written to a hidden staging folder and swapped into
|
|
26
|
+
place under a per-destination lock, so a failed or concurrent refresh never loses the existing
|
|
27
|
+
copy; the new copy is published by claiming its name with a primitive that refuses to replace —
|
|
28
|
+
`mkdir` for a directory, `symlink` for a link — and the copy it replaces is moved aside only
|
|
29
|
+
while it is still the one that was checked; a published link is recorded only while it is still
|
|
30
|
+
the link this call wrote; an empty destination is refused with an explanation of what it probably is, on the plain and the `--force` path alike, and a hidden folder an interrupted refresh left behind is described without claiming Skillsmith owns it) but still refuses a real directory Skillsmith never created, or a recorded copy that has
|
|
31
|
+
since grown a `.git` directory; uninstall's own cleanup applies the same `.git` refusal to a
|
|
32
|
+
recorded copy instead of deleting it. A copy an interrupted refresh left behind is reported as
|
|
33
|
+
a warning, and is never restored over a skill uninstalled since. The fan-out link manifest is
|
|
34
|
+
changed under its own lock (concurrent fan-outs of different skills lost records and could
|
|
35
|
+
corrupt it), and a corrupt one is moved aside with a warning rather than replaced by an empty
|
|
36
|
+
one that dropped every other skill's record; a manifest written by a newer version is left
|
|
37
|
+
untouched. An uninstall racing a re-link or a refresh leaves the records matching what is on
|
|
38
|
+
disk, and an uninstall that can't read the manifest says so. The per-target write queue now
|
|
39
|
+
classifies and snapshots every write independently (not just the first for a given path), so two
|
|
40
|
+
differently-cased files on a case-sensitive filesystem restore correctly, a short write is
|
|
41
|
+
retried until complete or reported as a restore failure, and a 0-byte file orphaned by a failed
|
|
42
|
+
create is still cleaned up. Rollback and fan-out cleanup never recursively delete a folder that
|
|
43
|
+
something else put at its path after Skillsmith created it, and a cleanup step that fails is
|
|
44
|
+
reported rather than silently ignored. A crashed refresh's staging folder is reported, never
|
|
45
|
+
deleted, and an uninstall re-checks a fan-out copy just before removing it. Each of these
|
|
46
|
+
deletes now checks the entry, moves it to a hidden name and checks it again there before
|
|
47
|
+
removing it, so a folder another program swaps in at that moment is never the one deleted.
|
|
48
|
+
Nothing is ever renamed back over whatever has taken a path — a rename replaces an empty
|
|
49
|
+
directory, a file or a symlink — so anything a call moved aside is reported with its exact path
|
|
50
|
+
instead. A regular file is the one exception: it goes back atomically, since `link`
|
|
51
|
+
fails rather than replacing. What a failed removal leaves behind is reported by the next
|
|
52
|
+
uninstall of that skill, as well as next to a fan-out destination, and a refresh now says why it
|
|
53
|
+
kept the copy it replaced, removes only the symlink it checked when replacing one, and puts a
|
|
54
|
+
copy back only while that path is still free. Uninstall refuses a skill folder that is a git working tree (`.git` at its root), even
|
|
55
|
+
with force and before adopting an untracked one; it removes only the folder it checked, and
|
|
56
|
+
keeps the manifest entry when it removes nothing. It also drops a skill's record only while every
|
|
57
|
+
field of that record still matches the one it removed, so an install claiming the same name
|
|
58
|
+
meanwhile keeps its own record — at the same path, or written in the same millisecond. A manifest
|
|
59
|
+
write that fails after the folder is gone now says so, and what to do about it, instead of
|
|
60
|
+
surfacing as a bare lock error, and a progress listener that throws can no longer stop an
|
|
61
|
+
uninstall from reporting what it removed and what it left behind. A warning about something left
|
|
62
|
+
behind no longer claims Skillsmith owns it: in a race it can be an entry another program put at
|
|
63
|
+
that path. Backfill never modifies a
|
|
64
|
+
`provenance: 'local'` row (SMI-6529, ADR-155).
|
|
65
|
+
|
|
66
|
+
- **Docs**: recorded the two missing `SCANNER_RULESET_VERSION` history entries for
|
|
67
|
+
`2026-09-11.1` and `2026-09-11.2`. Both bumps shipped correctly — the `comparable` gate does
|
|
68
|
+
re-scan — but the constant had moved twice past the end of its own documented history, so the
|
|
69
|
+
*direction* and the consequence-if-omitted were unrecorded for both. `.1` is
|
|
70
|
+
previously-clean-now-flagged (MF-5 delivers new detection). `.2` is the same direction for a
|
|
71
|
+
sharper reason: it invalidates verdicts `.1` computed wrongly under the array-position
|
|
72
|
+
suppression, so omitting it would have left the evasion alive in stored data even after the code
|
|
73
|
+
fix. Raised by another session (SMI-6554) after a downstream stale-dist failure. (SMI-6508)
|
|
74
|
+
- **Fix (security regression, same-day)**: the MF-5 prefixed-secrets entry added below was
|
|
75
|
+
positioned at index 4 of `SENSITIVE_PATH_PATTERNS`, and `scanSensitivePaths` `break`s on the
|
|
76
|
+
**first** entry that matches, in array order. An always-MEDIUM entry ahead of a HIGH-capable one
|
|
77
|
+
therefore **suppressed** it: 11 of the 16 patterns sat after MF-5, so any line where a
|
|
78
|
+
prefixed-`secrets` token co-occurred with one of them reported MEDIUM instead of that entry's
|
|
79
|
+
HIGH, and `passed` flipped from `false` to `true` — the install block disappeared. Appending the
|
|
80
|
+
12-character comment `# a_secrets:` was sufficient to turn `cat ~/.ssh/id_rsa` and
|
|
81
|
+
`curl -F f=@/etc/passwd …` from blocking to passing, making this an attacker-controlled
|
|
82
|
+
suppression token rather than a theoretical ordering nit. **Fixed by moving the entry to LAST**,
|
|
83
|
+
after every HIGH-capable pattern. Realized blast radius was zero — of 636 skills carrying a
|
|
84
|
+
stored HIGH `sensitive_path` finding, none had a `location` matching the prefixed form — so no
|
|
85
|
+
stored verdict was wrongly cleared; the exposure was latent and adversarial. `SCANNER_RULESET_VERSION`
|
|
86
|
+
re-bumps to `2026-09-11.2` so verdicts stored under `.1` are not reused. A new
|
|
87
|
+
**ordering invariant** in `scanner-regression-guard.test.ts` now asserts that no always-MEDIUM
|
|
88
|
+
pattern precedes any HIGH-capable one, which generalises to the next such class; the eight
|
|
89
|
+
suppression cases are pinned in both the core and core↔edge suites. Caught by the post-merge
|
|
90
|
+
governance retro — a cross-family pre-merge gate, 3,175 passing tests and a 9-case manual
|
|
91
|
+
verification were all green over it, because every ordering test compared MF-5 only against the
|
|
92
|
+
one entry that precedes it. (SMI-6508)
|
|
93
|
+
- **Fix**: `sensitive_path` now detects a secret assigned to a **prefixed** key —
|
|
94
|
+
`API_SECRETS`, `app_secrets`, `mySecrets`, and the singular `API_SECRET`. `SECRETS_ASSIGN_PATTERN`
|
|
95
|
+
carries `\b`, and `_` is a word character, so that boundary could never match after an underscore
|
|
96
|
+
or a camelCase hump; SCREAMING_SNAKE and snake_case are the dominant conventions for
|
|
97
|
+
secret-bearing environment variables, so this missed the most likely real shape. The sibling
|
|
98
|
+
`credentials` and `password` patterns carry no boundary and were never affected. Fixed by a
|
|
99
|
+
**complementary** pattern matching exactly what the boundary excludes, rather than by removing it
|
|
100
|
+
— the two never match the same occurrence, and `MY-SECRETS=` / `my.secrets=` stay with the bare
|
|
101
|
+
pattern since `-` and `.` are non-word characters its `\b` already accepts.
|
|
102
|
+
- **Added**: a fifth `sensitive_path` severity class, **MF-5 (`OBSERVE_ONLY_MEDIUM_PATTERNS`)** —
|
|
103
|
+
always MEDIUM, never value-gated and never escalated. The prefixed form is classified here rather
|
|
104
|
+
than into MF-4 because MF-4 is HIGH by default, and a HIGH `sensitive_path` makes
|
|
105
|
+
`SecurityScanner` compute `passed = false`, which blocks installation with no allowlist in that
|
|
106
|
+
path. Measured against 66,495 real skill bodies in production: routing the prefixed form through
|
|
107
|
+
MF-4 would newly block 132 skills (0.20% of that corpus, ~975 extrapolated to the full registry),
|
|
108
|
+
and shape analysis put roughly 46% of those in false-positive-looking shapes. Shipping at MEDIUM
|
|
109
|
+
makes the detection visible at zero install cost and turns the open question into one the
|
|
110
|
+
accumulated findings can answer; promoting it later is a one-line move into the MF-4 set. The
|
|
111
|
+
severity-gate partition grows 4 classes → 5 and 15 patterns → 16, both guarded by the existing
|
|
112
|
+
regression test's totality check. **Deliberate asymmetry**: prefixed `password` / `credentials`
|
|
113
|
+
keys still reach HIGH, grandfathered rather than endorsed — their prefixed-form false-positive
|
|
114
|
+
rate has never been measured, and levelling in either direction without measuring would be the
|
|
115
|
+
wrong fix. `SCANNER_RULESET_VERSION` bumps to `2026-09-11.1` — *previously-clean-now-fires*, the
|
|
116
|
+
opposite direction from SMI-6505's bump and load-bearing for the same reason: without it the
|
|
117
|
+
`comparable` gate reuses the stored verdict and the new finding never reaches an already-scanned
|
|
118
|
+
skill. (SMI-6508)
|
|
119
|
+
- **Fix**: `createDatabaseSync`/`createDatabaseAsync`'s native-module error messages no longer
|
|
120
|
+
recommend `docker compose --profile dev up -d`. `@skillsmith/core` ships under Elastic License
|
|
121
|
+
2.0 to external npm consumers (`@skillsmith/cli`, both MCP servers) who have no worktree tooling
|
|
122
|
+
and no `skillsmith-dev-1` container, so the Docker line was actively misleading for most of its
|
|
123
|
+
readers. The two remaining solutions (`npm rebuild better-sqlite3`, and `createDatabaseAsync()`'s
|
|
124
|
+
automatic WASM fallback) are correct in any environment. (SMI-6507)
|
|
125
|
+
|
|
126
|
+
- **Changed**: the agent pack's CLI fallback commands (`CLI_FALLBACK_COMMANDS` in
|
|
127
|
+
`services/agent-pack/prompt-source.ts`) now lead with `skillsmith update --all --dry-run` and
|
|
128
|
+
then per-skill updates, instead of recommending `skillsmith update --all` directly. Containment
|
|
129
|
+
for SMI-6528: `update --all` in CLI 0.8.8-0.8.10 can overwrite local edits in skill directories
|
|
130
|
+
that are git clones and can write into the wrong directory (SMI-6530).
|
|
131
|
+
|
|
132
|
+
- **Fix**: `sensitive_path` MF-4 no longer scores an **embedded** assignment key assigned a bare
|
|
133
|
+
boolean as a real credential. `allow_credentials=True` — the standard FastAPI/Starlette CORS
|
|
134
|
+
middleware flag — was scoring HIGH, which makes `SecurityScanner` compute `passed = false`, which
|
|
135
|
+
makes the install service reject the install. With no allowlist anywhere in the
|
|
136
|
+
`skill-installation.*` family, that made **any skill documenting FastAPI CORS setup uninstallable**
|
|
137
|
+
at a risk score of 1/100. The discriminator is the key, not the value: `credentials` matched inside
|
|
138
|
+
`allow_credentials` only because `CREDENTIALS_ASSIGN_PATTERN` carries no left boundary, so the fix
|
|
139
|
+
keys on the keyword being a *suffix of a longer identifier*. Bare `credentials:` / `secrets:` /
|
|
140
|
+
`password:` keys are untouched, and `AWS_CREDENTIALS=hunter2` still scores HIGH — deliberately
|
|
141
|
+
**not** fixed by adding `\b` to the pattern, which would have traded this false positive for that
|
|
142
|
+
false negative (tracked separately as SMI-6508, which documents the same missed-detection class
|
|
143
|
+
already live for `secrets`). `SCANNER_RULESET_VERSION` bumps to `2026-09-10.1` —
|
|
144
|
+
*previously-flagged-now-clean*, the same direction as SMI-5207's bump and the opposite of
|
|
145
|
+
SMI-6441's, and load-bearing for the same reason: without it the `comparable` gate keeps reusing
|
|
146
|
+
the stored pre-fix verdict and an already-scanned skill stays blocked. Two formatting variants are
|
|
147
|
+
accepted residuals and stay HIGH — a single-line multi-argument call, and a trailing inline comment
|
|
148
|
+
— because the relaxations that would fix them each leave part of the value span unexamined, which
|
|
149
|
+
measurably lets a real credential hide behind a boolean (both bypass shapes are pinned as
|
|
150
|
+
must-stay-HIGH tests). Adds a core↔edge behavioural parity test, which did not previously exist:
|
|
151
|
+
the existing twin guard only asserts the two `_shared` copies are byte-identical to each other, not
|
|
152
|
+
that they agree with `@skillsmith/core`.
|
|
153
|
+
- **Fix**: `sensitive_path` MF-4 no longer reads a two-word all-lowercase value as a harmless
|
|
154
|
+
documentation label when **every** one of its words is a known common password — `password: monkey
|
|
155
|
+
dragon` now scores HIGH, while `credentials: rotation policy` and ordinary documentation labels are
|
|
156
|
+
untouched. Closes SMI-5207's residual R-2 for the two-common-password case only; a value pairing
|
|
157
|
+
one common password with an ordinary word (`password: horse staple`) deliberately stays MEDIUM,
|
|
158
|
+
because it is not distinguishable from a documentation label at a false-positive rate this gate can
|
|
159
|
+
afford. This is the first `sensitive_path` change that can RAISE severity, so SMI-5207's
|
|
160
|
+
monotonic-non-increase safety argument no longer applies — see
|
|
161
|
+
[ADR-149](../../docs/internal/adr/149-generated-scanner-data-veto-severity-model.md) for the
|
|
162
|
+
severity-raising exception and its § *Revision, 2026-09-09* for why the predicate is `every` and
|
|
163
|
+
not `some` (55% of the emitted lexicon is ordinary English dictionary words, so a `some` predicate
|
|
164
|
+
reopens the documentation false-positive class unboundedly). `SCANNER_RULESET_VERSION` bumps to
|
|
165
|
+
`2026-09-09.1` — *previously-clean-now-flagged*, the opposite direction from SMI-5207's bump, so
|
|
166
|
+
without it an already-scanned skill keeps its stored clean verdict and never sees the tightened
|
|
167
|
+
rule. `assignmentHasRealValue()` gains an optional `{ weakPasswordVeto }` parameter (default on) —
|
|
168
|
+
a pure per-call parameter used only by the blast-radius verification harness, never module state
|
|
169
|
+
(SMI-6441 Wave 2)
|
|
170
|
+
|
|
7
171
|
## v0.12.3
|
|
8
172
|
|
|
9
173
|
- **Add**: `SecurityScanner.weak-passwords.ts` — a generated, versioned list of common weak passwords (vendored from SecLists, hash-pinned, capped to the top 5,000 by frequency rank), built by the new `scripts/gen-weak-password-lexicon.mjs` generator and mirrored byte-identically into the Node and Deno/Supabase edge scanner twins. This wave ships the data pipeline only — no scanner behavior changes; the `sensitive_path` detection change that consumes this data is a separate, follow-on change (SMI-6441 Wave 1)
|
package/README.md
CHANGED
|
@@ -6,13 +6,13 @@ Part of Skillsmith: a registry for sharing, scanning, and tracking agent skills
|
|
|
6
6
|
|
|
7
7
|
## Contents
|
|
8
8
|
|
|
9
|
-
- [What's New](#whats-new-in-
|
|
9
|
+
- [What's New](#whats-new-in-v0124)
|
|
10
10
|
- [Installation](#installation)
|
|
11
11
|
- [Quick Start](#quick-start)
|
|
12
12
|
- [Features](#features)
|
|
13
13
|
- [Exports](#exports)
|
|
14
14
|
|
|
15
|
-
## What's New in v0.12.
|
|
15
|
+
## What's New in v0.12.4
|
|
16
16
|
|
|
17
17
|
- **New `resolveSessionTier` client** (`sync/license-status-client.ts`): authenticates a stored `skillsmith login` session against `/license-status` so the MCP server can resolve a real subscription tier without a separately-configured `SKILLSMITH_API_KEY`, instead of silently falling back to `community`.
|
|
18
18
|
- **Scanner: bundled-file scan expanded to operational code** (Gap 8 of the ClawHavoc remediation): the indexer now reads `scripts/`, `src/`, and `bin/` alongside `SKILL.md`, closing a blind spot where a backdoor buried mid-function in working operational code was structurally invisible.
|