vigiles 15.0.2 → 15.0.3
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/dist/adapters/claude-code/layout.js +3 -0
- package/dist/adapters/claude-code/run-scripts.d.ts +21 -9
- package/dist/adapters/claude-code/run-scripts.js +33 -22
- package/dist/adapters/codex/driver.js +3 -1
- package/dist/adapters/codex/eval.js +5 -0
- package/dist/audit-score.js +32 -6
- package/dist/check-count.d.ts +62 -3
- package/dist/check-count.js +123 -5
- package/dist/check.d.ts +55 -0
- package/dist/check.js +91 -0
- package/dist/cli.js +456 -54
- package/dist/core/bash-effects.d.ts +41 -0
- package/dist/core/bash-effects.js +278 -0
- package/dist/core/foreign-runner.d.ts +185 -0
- package/dist/core/foreign-runner.js +228 -0
- package/dist/core/harness-driver.d.ts +18 -1
- package/dist/core/hook-program.d.ts +319 -20
- package/dist/core/hook-program.js +743 -49
- package/dist/core/layout.d.ts +13 -0
- package/dist/core/lethal-trifecta.d.ts +93 -0
- package/dist/core/lethal-trifecta.js +409 -65
- package/dist/core/markdown.d.ts +32 -0
- package/dist/core/markdown.js +36 -0
- package/dist/core/merge-conflict.d.ts +50 -0
- package/dist/core/merge-conflict.js +84 -0
- package/dist/core/test-file-ext.d.ts +80 -0
- package/dist/core/test-file-ext.js +90 -0
- package/dist/core/types.d.ts +11 -0
- package/dist/coverage-artifact.d.ts +383 -0
- package/dist/coverage-artifact.js +586 -0
- package/dist/coverage-evidence.d.ts +87 -79
- package/dist/coverage-evidence.js +212 -211
- package/dist/coverage-probe.d.ts +125 -0
- package/dist/coverage-probe.js +700 -0
- package/dist/doc-commands.d.ts +119 -0
- package/dist/doc-commands.js +158 -0
- package/dist/eval-lock.d.ts +9 -0
- package/dist/eval-lock.js +14 -2
- package/dist/eval.js +28 -0
- package/dist/fs-walk.d.ts +80 -0
- package/dist/fs-walk.js +148 -0
- package/dist/harness-assert.js +42 -3
- package/dist/harness-test.js +31 -2
- package/dist/judge.js +4 -0
- package/dist/leaderboard.d.ts +16 -1
- package/dist/leaderboard.js +19 -2
- package/dist/load-hook.js +6 -1
- package/dist/mock-model.d.ts +58 -4
- package/dist/mock-model.js +133 -5
- package/dist/observe.d.ts +1 -1
- package/dist/observe.js +44 -1
- package/dist/plugin-loader.js +52 -13
- package/dist/run-hook.d.ts +58 -0
- package/dist/run-hook.js +70 -0
- package/dist/run-script.js +75 -0
- package/dist/scaffold-test.d.ts +3 -0
- package/dist/scaffold-test.js +10 -5
- package/dist/scan-behavioral.js +4 -0
- package/dist/scan-core.d.ts +22 -0
- package/dist/scan-core.js +46 -14
- package/dist/scan-files.js +19 -2
- package/dist/scan.d.ts +22 -5
- package/dist/scan.js +67 -13
- package/dist/skill-contract.d.ts +46 -0
- package/dist/skill-contract.js +201 -0
- package/dist/skill-refs.d.ts +67 -0
- package/dist/skill-refs.js +117 -0
- package/dist/test-coverage-files.d.ts +7 -1
- package/dist/test-coverage-files.js +66 -55
- package/dist/test-coverage.d.ts +155 -19
- package/dist/test-coverage.js +430 -91
- package/dist/testing.d.ts +8 -2
- package/dist/testing.js +19 -1
- package/dist/trigger-containment.d.ts +85 -0
- package/dist/trigger-containment.js +125 -0
- package/dist/ts-runner-caps.d.ts +16 -0
- package/dist/ts-runner-caps.js +43 -0
- package/dist/unit.d.ts +2 -2
- package/dist/unit.js +2 -1
- package/hooks/eval-lock-nudge.sh +14 -6
- package/package.json +2 -2
- package/skills/test-harness/SKILL.md +68 -2
package/dist/core/layout.d.ts
CHANGED
|
@@ -50,6 +50,19 @@ export interface PluginLayout {
|
|
|
50
50
|
readonly materializeRoot: string;
|
|
51
51
|
/** Env token expanded to the plugin's absolute root in hook commands. */
|
|
52
52
|
readonly pluginRootToken: string;
|
|
53
|
+
/**
|
|
54
|
+
* Tokens that root a path at the PROJECT being scanned, braced form
|
|
55
|
+
* (`${CLAUDE_PROJECT_DIR}`); the unbraced spelling is derived. Optional — a
|
|
56
|
+
* harness with no such variable omits it.
|
|
57
|
+
*
|
|
58
|
+
* 🔴 SEPARATE FROM {@link pluginRootToken}, and its absence made a whole
|
|
59
|
+
* surface kind invisible. `hookScripts` stripped only the plugin token, so a
|
|
60
|
+
* project's own `"$CLAUDE_PROJECT_DIR/.claude/hooks/x.sh"` — Claude Code's
|
|
61
|
+
* DOCUMENTED spelling for a project hook, because hooks do not run with a
|
|
62
|
+
* stable cwd — failed `existsSync` and was dropped. MEASURED on a real
|
|
63
|
+
* consumer repo: `audit` listed sixteen hooks and the SURFACE list held zero.
|
|
64
|
+
*/
|
|
65
|
+
readonly projectRootTokens?: readonly string[];
|
|
53
66
|
/** Standalone MCP config file, e.g. `.mcp.json`. */
|
|
54
67
|
readonly mcpConfigFile: string;
|
|
55
68
|
/** Manifest key declaring MCP servers, e.g. `mcpServers`. */
|
|
@@ -34,6 +34,11 @@
|
|
|
34
34
|
* footgun note, not a hard defect), an inherits-all trifecta is reported as
|
|
35
35
|
* `"advisory"`; an EXPLICIT all-three contract is the `"hard"` flag.
|
|
36
36
|
*
|
|
37
|
+
* 🔴 SUBAGENTS ONLY. Everything above is the SUBAGENT reading, where `tools:` is a
|
|
38
|
+
* documented rail that really does bound the unit. It is NOT how a SKILL works —
|
|
39
|
+
* a skill's `allowed-tools:` is a PRE-APPROVAL, not a fence. See
|
|
40
|
+
* {@link skillTrifectaIssue} for the skill path and the measurement behind it.
|
|
41
|
+
*
|
|
37
42
|
* Pure + ONE detector (one-detector-no-drift) — intended to be reused by `scan`
|
|
38
43
|
* (the read-only audit) and a future `lethal-trifecta` lint rule. The dialect is
|
|
39
44
|
* injected (core ⊄ adapter) so it generalizes across harnesses (Codex's `shell`
|
|
@@ -62,6 +67,19 @@ export interface TrifectaLegs {
|
|
|
62
67
|
* reported as advisory in line with the inherits-all stance.
|
|
63
68
|
*/
|
|
64
69
|
export type TrifectaSeverity = "hard" | "advisory";
|
|
70
|
+
/**
|
|
71
|
+
* How much of a fence a SKILL's `disallowed-tools:` actually is — set only on
|
|
72
|
+
* findings produced by {@link skillTrifectaIssue}, absent on subagent findings.
|
|
73
|
+
*
|
|
74
|
+
* - `"none"` — no `disallowed-tools:` line (or an unreadable block, which yields
|
|
75
|
+
* the same thing): the skill inherits every tool the session grants. This is
|
|
76
|
+
* the DEFAULT state of every skill in the ecosystem, which is why the report
|
|
77
|
+
* aggregates it into one line instead of repeating it per skill.
|
|
78
|
+
* - `"ineffective"` — a `disallowed-tools:` line exists but does not deny every
|
|
79
|
+
* built-in supplier of any one leg, so no leg is closed. That one is per-skill:
|
|
80
|
+
* an author who believed they had fenced and had not.
|
|
81
|
+
*/
|
|
82
|
+
export type SkillFenceState = "none" | "ineffective";
|
|
65
83
|
/**
|
|
66
84
|
* A lethal-trifecta finding — emitted ONLY when all three legs are non-empty (or,
|
|
67
85
|
* for the inherits-all case, when the contract inherits all tools). The `legs`
|
|
@@ -74,7 +92,38 @@ export interface TrifectaFinding {
|
|
|
74
92
|
readonly legs: TrifectaLegs;
|
|
75
93
|
/** A ready-to-show, actionable message. */
|
|
76
94
|
readonly message: string;
|
|
95
|
+
/**
|
|
96
|
+
* SKILLS ONLY — the fence state behind the finding ({@link SkillFenceState}).
|
|
97
|
+
* Absent on subagent findings, whose `tools:` rail is a different mechanism.
|
|
98
|
+
* The report reads it to decide aggregate-vs-per-unit presentation.
|
|
99
|
+
*/
|
|
100
|
+
readonly fence?: SkillFenceState;
|
|
77
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Does a `Bash(...)` grant still supply the shell's legs — reading a secret and
|
|
104
|
+
* curling it out — or has it been narrowed to a command that cannot?
|
|
105
|
+
*
|
|
106
|
+
* Narrowing the grant is a remedy this tool RECOMMENDS, so the reading has to be able
|
|
107
|
+
* to see a narrowed grant as narrowed: `Bash(node ./scripts/log.mjs:*)` was once read
|
|
108
|
+
* as plain `Bash` — the whole shell, in both leg A and leg C — and an author who took
|
|
109
|
+
* the advice saw the score not move. But the fix for that overshot into the opposite
|
|
110
|
+
* error, and the opposite error is the one that matters (see {@link EFFECT_FREE}), so
|
|
111
|
+
* the answer is now: a grant is bounded ONLY when it pins a program from that list.
|
|
112
|
+
*
|
|
113
|
+
* The honest consequence, stated rather than hidden: narrowing `Bash` to a script of
|
|
114
|
+
* your own (`node ./ledger.mjs`) no longer drops a leg, because nothing here has read
|
|
115
|
+
* that script. The remedy that still works is to drop a leg the checker can SEE — fence
|
|
116
|
+
* the tool off, or narrow to a command whose effects are enumerable.
|
|
117
|
+
*
|
|
118
|
+
* Bash no restriction at all
|
|
119
|
+
* Bash(*) Bash(:*) the wildcard forms
|
|
120
|
+
* Bash(node:*) Bash(node x.mjs:*) an interpreter runs whatever it is handed
|
|
121
|
+
* Bash(sh ...) Bash(curl ...) the shell, and the pinned exfiltrator
|
|
122
|
+
* Bash(echo ready:*) bounded — and only this shape is
|
|
123
|
+
*
|
|
124
|
+
* When in doubt it returns true (keeps the legs): a false "you are exposed" costs the
|
|
125
|
+
* author an argument, a false "you are safe" costs them the finding.
|
|
126
|
+
*/
|
|
78
127
|
export declare function bashGrantIsUnbounded(raw: string): boolean;
|
|
79
128
|
/**
|
|
80
129
|
* Classify each tool in a declared contract into the trifecta legs it supplies.
|
|
@@ -127,4 +176,48 @@ export interface TrifectaContext {
|
|
|
127
176
|
* inherits-all, the `"advisory"` finding. Never the other way round.
|
|
128
177
|
*/
|
|
129
178
|
export declare function lethalTrifectaIssues(tools: readonly string[], dialect: HarnessDialect, ctx?: TrifectaContext): TrifectaFinding | null;
|
|
179
|
+
/** The legs a `disallowed-tools:` list leaves standing, naming the suppliers. */
|
|
180
|
+
export declare function skillFenceLegs(disallowed: readonly string[], dialect: HarnessDialect): TrifectaLegs;
|
|
181
|
+
/**
|
|
182
|
+
* Whether THIS harness understands a skill-level `disallowed-tools:` at all.
|
|
183
|
+
*
|
|
184
|
+
* Read off the dialect record that already exists — `skillFrontmatter` is exactly
|
|
185
|
+
* "which SKILL.md keys this harness understands", and `disallowed-tools` is one of
|
|
186
|
+
* the Claude-Code-only ones. No new capability flag: a second field saying the
|
|
187
|
+
* same thing is a second thing to keep true, and the compiler already branches on
|
|
188
|
+
* this one (`renderSkillFrontmatter` emits the tool keys under `"claude-code"` and
|
|
189
|
+
* omits them under `"minimal"`).
|
|
190
|
+
*/
|
|
191
|
+
export declare function dialectSupportsSkillFence(dialect: HarnessDialect): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* The lethal-trifecta finding for a MODEL-INVOCABLE SKILL, computed from its
|
|
194
|
+
* `disallowed-tools:` — the only skill frontmatter field measured to remove a
|
|
195
|
+
* tool. `allowed-tools:` is not an input here, on purpose: it is a pre-approval,
|
|
196
|
+
* and treating it as a bound is the defect this function exists to correct (see
|
|
197
|
+
* the block comment above for the measurement).
|
|
198
|
+
*
|
|
199
|
+
* 🔴 AND IT IS A CLAUDE-CODE MECHANISM, which this applied to every harness. On a
|
|
200
|
+
* Codex repo (`skillFrontmatter: "minimal"` — name + description only, and our own
|
|
201
|
+
* compiler drops the tool keys there) every skill was reported as holding all
|
|
202
|
+
* three legs, scored against Safety, and handed the remedy "add a
|
|
203
|
+
* `disallowed-tools:` line". That line is INERT in Codex: the author does the
|
|
204
|
+
* work, the harness ignores the key, the finding returns, and the score never
|
|
205
|
+
* moves. A remedy the target cannot apply is worse than no finding — it is a floor
|
|
206
|
+
* dressed up as a defect, and it teaches people that the Safety number is fake.
|
|
207
|
+
*
|
|
208
|
+
* So the detector runs only where the fence exists ({@link dialectSupportsSkillFence}).
|
|
209
|
+
* This is a claim about the MECHANISM, not about the risk: a Codex skill really
|
|
210
|
+
* does hold every leg, and bounding it is a session/config-level question that
|
|
211
|
+
* belongs to a Codex-specific detector, not to a Claude Code one applied by
|
|
212
|
+
* default. Subagent findings are unaffected — `tools:` is a different mechanism,
|
|
213
|
+
* with its own dialect handling.
|
|
214
|
+
*
|
|
215
|
+
* @param disallowed `disallowed-tools:` as declared, or `null` when the line is
|
|
216
|
+
* absent — the two are NOT the same: an explicit empty list still denies nothing,
|
|
217
|
+
* but the message should not tell an author who wrote the line that they didn't.
|
|
218
|
+
* @returns `null` once the fence closes at least one leg (Rule of Two satisfied,
|
|
219
|
+
* among the built-ins — see {@link FENCE_SUPPLIERS} for the stated limit), and
|
|
220
|
+
* `null` for any harness with no skill fence to close it with.
|
|
221
|
+
*/
|
|
222
|
+
export declare function skillTrifectaIssue(disallowed: readonly string[] | null, dialect: HarnessDialect, ctx?: TrifectaContext): TrifectaFinding | null;
|
|
130
223
|
//# sourceMappingURL=lethal-trifecta.d.ts.map
|