vigiles 12.7.0 → 13.0.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 +43 -15
- package/dist/audit-report.d.ts +38 -0
- package/dist/audit-report.js +13 -2
- package/dist/audit-report.template.html +44 -29
- package/dist/audit-score.js +9 -1
- package/dist/audit-verdict.d.ts +89 -0
- package/dist/audit-verdict.js +281 -0
- package/dist/cli.js +162 -13
- package/dist/core/orphans.d.ts +16 -6
- package/dist/core/orphans.js +45 -19
- package/dist/core/rule-meta.js +2 -2
- package/dist/core/types.d.ts +10 -4
- package/dist/eval-cost.d.ts +1 -1
- package/dist/eval.d.ts +2 -2
- package/dist/eval.js +1 -1
- package/dist/leaderboard.js +9 -3
- package/dist/rule-inventory.d.ts +90 -0
- package/dist/rule-inventory.js +327 -0
- package/dist/rule-routing.d.ts +46 -0
- package/dist/rule-routing.js +135 -0
- package/dist/scaffold-test.js +1 -1
- package/dist/segment.d.ts +33 -0
- package/dist/segment.js +454 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,8 +40,10 @@
|
|
|
40
40
|
SPINE = proof/demo-led. Real, screenshotable catches on shipped plugins, THEN
|
|
41
41
|
mechanism. Every proof traces to a real dogfood run (research/dogfood/) — NEVER
|
|
42
42
|
fabricate one. Order = most-RELATABLE first (broken tool ref → skill collision →
|
|
43
|
-
secrets-exfil gotcha
|
|
44
|
-
|
|
43
|
+
rules-not-enforced → secrets-exfil gotcha LAST as the bite). The intro triplet
|
|
44
|
+
maps to the three "vibes break silently" proofs (1, 2, 4); Proof 3 (your rules →
|
|
45
|
+
enforced) pays off the TAGLINE's rule-follows-half-the-time pain. Security is ONE
|
|
46
|
+
dev-native GOTCHA proof, never the brand. Add a repro
|
|
45
47
|
line ("run `npx vigiles audit <any-repo>` for your own") + a one-line note that
|
|
46
48
|
examples use CC subagents but the checks run on Codex too. FALSE CONFIDENCE is
|
|
47
49
|
the coined term (a guard that looks like it works and silently doesn't), defined
|
|
@@ -59,8 +61,11 @@
|
|
|
59
61
|
block; ONE idea per sentence; NO internal vocabulary (moat/flywheel) / NO
|
|
60
62
|
research/ links / NO enterprise/national-interest framing — name the user
|
|
61
63
|
benefit; ~220-line body cap; push depth into docs/ and LINK it. Assets: the hero
|
|
62
|
-
vigiles-audit.png is a
|
|
63
|
-
|
|
64
|
+
vigiles-audit.png is a REPRESENTATIVE report ("my-plugin", C 77) — the verdict-
|
|
65
|
+
led header + ranked fixes + the "Your rules → enforced" section (the new rule-
|
|
66
|
+
compile capability). Re-render via headless Chromium if the UI changes: build
|
|
67
|
+
report/, screenshot report/dist/index.html (falls back to the sample fixture),
|
|
68
|
+
inject the dark :root tokens before </body> for the dark render.
|
|
64
69
|
-->
|
|
65
70
|
|
|
66
71
|
<p align="center">
|
|
@@ -102,10 +107,10 @@ It's free and open-source, runs entirely on your machine, and never bills per to
|
|
|
102
107
|
## What it caught
|
|
103
108
|
|
|
104
109
|
<p align="center">
|
|
105
|
-
<img src="vigiles-audit.png" width="760" alt="vigiles audit report
|
|
110
|
+
<img src="vigiles-audit.png" width="760" alt="vigiles audit report for my-plugin: a verdict header reading 'Two one-line fixes away from a B.' next to a C (77/100) grade, a five-category strip (Truthfulness, Triggering, Structure, Safety, Tested), ranked fix cards with '+N pts' impact badges, and a 'Your rules → enforced' section showing a prose rule the config silently turns off" />
|
|
106
111
|
</p>
|
|
107
112
|
|
|
108
|
-
**Like Google's Lighthouse, but for your agent harness.** One command grades it A–F across five categories, every fix
|
|
113
|
+
**Like Google's Lighthouse, but for your agent harness.** One command grades it A–F across five categories, leads with a plain-English verdict — _"two one-line fixes away from a B"_ — and ranks every fix by the points it buys back:
|
|
109
114
|
|
|
110
115
|
- **Truthfulness** — do the references resolve?
|
|
111
116
|
- **Triggering** — do skills fire, without colliding?
|
|
@@ -113,6 +118,8 @@ It's free and open-source, runs entirely on your machine, and never bills per to
|
|
|
113
118
|
- **Safety** — any way for the agent to leak your data?
|
|
114
119
|
- **Tested** — does the harness ship tests?
|
|
115
120
|
|
|
121
|
+
And it closes the loop from prose to enforcement: **your rules → enforced** maps each rule you wrote to the lint rule that actually enforces it — already on, one config line away, or silently turned off (below).
|
|
122
|
+
|
|
116
123
|
These are real scans of public plugins — run `npx vigiles audit <any-repo>` for your own. The examples below use Claude Code subagents; the same checks run on Codex `AGENTS.md`, skills, and hooks. ↓
|
|
117
124
|
|
|
118
125
|
## Proof 1 — a tool your agent thinks it has and doesn't
|
|
@@ -132,10 +139,23 @@ This subagent — a helper your main agent hands work to — lists a tool that d
|
|
|
132
139
|
apart, so the wrong one fires (e.g. "agent-coder" ↔ "agent-tester", 83% alike)
|
|
133
140
|
```
|
|
134
141
|
|
|
135
|
-
One popular plugin ships **45 pairs of
|
|
142
|
+
One popular plugin ships **45 pairs** of near-identical skill descriptions. Your agent picks a skill by _reading_ them — so when two match, it fires the wrong one. Still perfectly valid markdown.
|
|
136
143
|
**[How triggering works →](docs/measuring-skills.md)**
|
|
137
144
|
|
|
138
|
-
## Proof 3 —
|
|
145
|
+
## Proof 3 — a rule you wrote that nothing enforces
|
|
146
|
+
|
|
147
|
+
Point vigiles at your own repo and the rules section maps each prose rule to the lint rule that enforces it — then checks your config. Representative output:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
Your rules → enforced 1 of 4 enforced · 2 one line away · 1 contradicted by config
|
|
151
|
+
└ "always use ===" → eqeqeq is set to "off" in your ESLint config
|
|
152
|
+
your CLAUDE.md says enforce it; your config quietly turns it off
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
You wrote the rule. Your agent treats it as gospel and follows it — until it doesn't, and nothing tells you which time. vigiles checks each mapped rule three ways: enforced, **one line away**, or — the one people screenshot — documented but silently **turned off**. Deterministic, no model. Want the rest compiled — a custom rule for a rule no linter ships, a hook for `git push`, the judgment calls honestly left alone? That's the opt-in `compile` tier (one model pass, then CI is plain lint).
|
|
156
|
+
**[How enforcement works →](docs/verifying-instruction-files.md)**
|
|
157
|
+
|
|
158
|
+
## Proof 4 — it can quietly read your secrets and send them out
|
|
139
159
|
|
|
140
160
|
```text
|
|
141
161
|
◑ Safety 80 (80/100)
|
|
@@ -144,7 +164,7 @@ One popular plugin ships **45 pairs of skills** with near-identical descriptions
|
|
|
144
164
|
· can send data out (Bash, WebFetch)
|
|
145
165
|
```
|
|
146
166
|
|
|
147
|
-
Hand one subagent all three powers and a poisoned web page can
|
|
167
|
+
Hand one subagent all three powers and a poisoned web page can make it read your `.env` and POST it anywhere — no exploit code, just the tools it was given. The **80 looks like a B** — and that's the trap: a healthy grade hiding a subagent that's a data-leak waiting to happen. vigiles spots it from the tool list alone, free, no model.
|
|
148
168
|
|
|
149
169
|
That's the whole idea: it checks your harness against **reality, not style**. Every tool, hook, file, script, and skill you reference is verified to actually resolve — and where you name a linter rule, it's checked to exist _and_ be enabled (ESLint, Ruff, Clippy, and more).
|
|
150
170
|
**[Everything it catches →](docs/what-vigiles-catches.md)** · point `audit` at a whole marketplace and it ranks every plugin the same way.
|
|
@@ -160,7 +180,7 @@ That's the whole idea: it checks your harness against **reality, not style**. Ev
|
|
|
160
180
|
| `test` | Does the harness behave? | No — a scripted stand-in | Every commit |
|
|
161
181
|
| `eval` | Does a skill actually help? | Yes — your subscription | On demand |
|
|
162
182
|
|
|
163
|
-
`audit`
|
|
183
|
+
**One engine, two doors.** `audit` is the local report; **`lint` is the CI gate** that fails the build on the same deterministic checks — broken refs, bad tool contracts, dead hooks, skill collisions (Proofs 1–2). `test` and `eval` go further: past _does it exist_ to _does it work_. (`init` / `compile` / `eject` manage the spec layer underneath — you rarely run them by hand.)
|
|
164
184
|
|
|
165
185
|
### 🔎 Lint — your instructions stop lying
|
|
166
186
|
|
|
@@ -172,7 +192,7 @@ Every path, script, symbol, and rule verified against reality — plus tool cont
|
|
|
172
192
|
A hook that blocks nothing, a skill that hijacks unrelated prompts, context that never reaches the model — each passes a naive "did it run?" check. That gap is **false confidence**: a guard that looks like it works and silently doesn't. vigiles tests the real thing — hooks block, skills fire, subagents finish what they promised, a stray `git push` is caught before it happens. It drives a scripted stand-in for the model, not a live call, so it needs no key and runs on every commit.
|
|
173
193
|
**[How testing works →](docs/harness-testing.md)**
|
|
174
194
|
|
|
175
|
-
### 📊 Eval —
|
|
195
|
+
### 📊 Eval — the only way to put a real number on cost
|
|
176
196
|
|
|
177
197
|
_"Caveman Mode cuts 65% of your tokens." Says who?_ vigiles A/Bs the claim on real coding tasks and hands you three numbers: the **token bill**, whether it hit its **target**, and whether your code still **works**.
|
|
178
198
|
|
|
@@ -237,18 +257,26 @@ Targets Claude Code and Codex out of the box, or [your own harness](docs/authori
|
|
|
237
257
|
- **Is this a framework I have to build around?** No. It's a tool you run — like ESLint, Lighthouse, or `npm audit`. One command, a report, an optional CI gate. There's a library API for automation, but you never touch it to get value.
|
|
238
258
|
- **Isn't this just a markdown linter?** No — it checks whether your instruction file is _true_ (every path/script/symbol/rule exists and is enabled), then tests and measures your harness. A style linter can't do any of that.
|
|
239
259
|
- **Do I have to write TypeScript?** No — your agent writes the spec (`init` adopts your CLAUDE.md or AGENTS.md into one), or plain markdown lints with zero new files. Compiler-grade guarantees are opt-in, like TS's `strict` ([why?](docs/faq.md#why-are-the-strongest-guarantees-opt-in-not-the-default)).
|
|
240
|
-
- **Is it stable enough to adopt?**
|
|
260
|
+
- **Is it stable enough to adopt?** The CLI you run is small and rarely changes; the library API still moves between releases. The high version number is release automation (a new major per breaking change), not age — see [Stability](STABILITY.md).
|
|
241
261
|
- **Non-JS repo?** `npx vigiles lint` verifies your CLAUDE.md or AGENTS.md with no install (Ruff/Clippy/Pylint/… too).
|
|
242
262
|
|
|
243
263
|
**[Full FAQ →](docs/faq.md)**
|
|
244
264
|
|
|
245
265
|
**Not for you if** you want a model/capability benchmark or runtime guardrails in the request path — vigiles is build-/CI-time.
|
|
246
266
|
|
|
247
|
-
##
|
|
267
|
+
## Docs
|
|
268
|
+
|
|
269
|
+
The **[docs index](docs/README.md)** is the full map, grouped by what you're doing:
|
|
270
|
+
|
|
271
|
+
- **Guides** — [verify instruction files](docs/verifying-instruction-files.md) · [test your harness](docs/harness-testing.md) · [measure a skill](docs/measuring-skills.md) · [ship a plugin](docs/for-plugin-authors.md) · [Codex & other harnesses](docs/harnesses.md)
|
|
272
|
+
- **Reference** — [CLI](docs/cli.md) · [rules matrix](docs/verifying-instruction-files.md#the-validation-rules--the-full-matrix) · [testing API](docs/testing-api.md) · [full API](https://zernie.github.io/vigiles/)
|
|
273
|
+
- **Explanation** — [what it catches](docs/what-vigiles-catches.md) · [how it compares](docs/comparison.md) · [FAQ](docs/faq.md)
|
|
248
274
|
|
|
249
|
-
**
|
|
275
|
+
**Project** — [Stability](STABILITY.md) · [Related tools](docs/comparison.md#what-vigiles-composes-with)
|
|
250
276
|
|
|
251
|
-
|
|
277
|
+
<!-- The "companion to [Feedback Loop Is All You Need](https://zernie.com/blog/feedback-loop-is-all-you-need)"
|
|
278
|
+
link is temporarily removed while AgenticDev paper #1 is under blind review: repo → blog is a
|
|
279
|
+
deanonymization path (the reviewer-offer email links this repo). RESTORE after notification (2026-08-21). -->
|
|
252
280
|
|
|
253
281
|
## License
|
|
254
282
|
|
package/dist/audit-report.d.ts
CHANGED
|
@@ -13,10 +13,13 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { type AuditScore } from "./audit-score.js";
|
|
15
15
|
import { type Recommendation } from "./optimize.js";
|
|
16
|
+
import { type Verdict } from "./audit-verdict.js";
|
|
16
17
|
import type { LedgerSummary } from "./observe.js";
|
|
17
18
|
import type { AdoptabilityResult } from "./adoptability.js";
|
|
18
19
|
import type { ScanReport, MarketplaceInfo } from "./scan.js";
|
|
19
20
|
import type { PluginScore } from "./leaderboard.js";
|
|
21
|
+
import type { RuleInventoryItem } from "./rule-inventory.js";
|
|
22
|
+
import type { RuleRouting } from "./rule-routing.js";
|
|
20
23
|
/** The current schema version. Bump only on a BREAKING change to the shape. */
|
|
21
24
|
export declare const AUDIT_SCHEMA_VERSION = 1;
|
|
22
25
|
export interface AuditReportMeta {
|
|
@@ -80,6 +83,13 @@ export interface AuditReport {
|
|
|
80
83
|
readonly meta: AuditReportMeta;
|
|
81
84
|
/** The five deterministic category rings + the weighted overall + grade. */
|
|
82
85
|
readonly score: AuditScore;
|
|
86
|
+
/**
|
|
87
|
+
* The one-line verdict + per-recommendation `pointsIfFixed`, both derived by
|
|
88
|
+
* RE-SCORING (never a hardcoded number). Drives the report's verdict-led header
|
|
89
|
+
* ("Two one-line fixes away from a B.") and the `+N pts` badges on fix cards.
|
|
90
|
+
* Pure/deterministic — always present.
|
|
91
|
+
*/
|
|
92
|
+
readonly verdict: Verdict;
|
|
83
93
|
/** The deterministic, ranked fixes (the inline recommendations). */
|
|
84
94
|
readonly recommendations: readonly Recommendation[];
|
|
85
95
|
readonly inventory: AuditInventory;
|
|
@@ -104,6 +114,24 @@ export interface AuditReport {
|
|
|
104
114
|
* the pure builder stays fs-free.
|
|
105
115
|
*/
|
|
106
116
|
readonly observations?: LedgerSummary;
|
|
117
|
+
/**
|
|
118
|
+
* The deterministic rule-inventory teaser — prose rules in the harness that
|
|
119
|
+
* map to an off-the-shelf lint rule + whether that rule is already in the
|
|
120
|
+
* config (the one-line-config-fix nudge). No model, no config execution. The
|
|
121
|
+
* CLI computes it (reads the instruction + config text, calls
|
|
122
|
+
* `buildRuleInventory`) and passes it in, so the pure builder stays fs-free.
|
|
123
|
+
* Present only when at least one intent resolves. Additive/optional — schema
|
|
124
|
+
* version unchanged. See `research/audit-rule-compile-tier.md`.
|
|
125
|
+
*/
|
|
126
|
+
readonly rulesInventory?: readonly RuleInventoryItem[];
|
|
127
|
+
/**
|
|
128
|
+
* The deterministic State-B routing PREVIEW — the instruction file segmented
|
|
129
|
+
* into atomic rules, each routed (reuse / hook / semantic / unrouted) to how
|
|
130
|
+
* it would be enforced, with per-category counts. No model, fs-only. Grounds
|
|
131
|
+
* the report's "compile" upsell in real numbers instead of generic copy.
|
|
132
|
+
* Present only when at least one atomic rule was segmented. Additive/optional.
|
|
133
|
+
*/
|
|
134
|
+
readonly ruleRouting?: RuleRouting;
|
|
107
135
|
}
|
|
108
136
|
export interface BuildAuditReportOptions {
|
|
109
137
|
readonly harness: string;
|
|
@@ -117,6 +145,16 @@ export interface BuildAuditReportOptions {
|
|
|
117
145
|
* when there's nothing to adopt.
|
|
118
146
|
*/
|
|
119
147
|
readonly adoptableSurfaces?: readonly string[];
|
|
148
|
+
/**
|
|
149
|
+
* The rule-inventory items the CLI computed via `buildRuleInventory` (reading
|
|
150
|
+
* the instruction + config text). Omit/empty when nothing resolved.
|
|
151
|
+
*/
|
|
152
|
+
readonly rulesInventory?: readonly RuleInventoryItem[];
|
|
153
|
+
/**
|
|
154
|
+
* The State-B routing preview the CLI computed via `routeRules`. Omit when
|
|
155
|
+
* nothing segmented.
|
|
156
|
+
*/
|
|
157
|
+
readonly ruleRouting?: RuleRouting;
|
|
120
158
|
}
|
|
121
159
|
/**
|
|
122
160
|
* Assemble the versioned {@link AuditReport} from a scan report — pure, no clock.
|
package/dist/audit-report.js
CHANGED
|
@@ -19,6 +19,7 @@ exports.buildMarketplaceReport = buildMarketplaceReport;
|
|
|
19
19
|
*/
|
|
20
20
|
const audit_score_js_1 = require("./audit-score.js");
|
|
21
21
|
const optimize_js_1 = require("./optimize.js");
|
|
22
|
+
const audit_verdict_js_1 = require("./audit-verdict.js");
|
|
22
23
|
/** The current schema version. Bump only on a BREAKING change to the shape. */
|
|
23
24
|
exports.AUDIT_SCHEMA_VERSION = 1;
|
|
24
25
|
/** The one command that adopts every un-spec'd surface (bare `init`). */
|
|
@@ -47,6 +48,9 @@ function buildAdoptable(surfaces) {
|
|
|
47
48
|
*/
|
|
48
49
|
function buildAuditReport(report, opts) {
|
|
49
50
|
const adoptable = buildAdoptable(opts.adoptableSurfaces);
|
|
51
|
+
const score = (0, audit_score_js_1.auditScore)(report);
|
|
52
|
+
const recommendations = (0, optimize_js_1.optimize)(report).recommendations;
|
|
53
|
+
const verdict = (0, audit_verdict_js_1.computeVerdict)({ report, score, recommendations });
|
|
50
54
|
return {
|
|
51
55
|
meta: {
|
|
52
56
|
schemaVersion: exports.AUDIT_SCHEMA_VERSION,
|
|
@@ -56,8 +60,9 @@ function buildAuditReport(report, opts) {
|
|
|
56
60
|
harness: opts.harness,
|
|
57
61
|
dir: report.dir,
|
|
58
62
|
},
|
|
59
|
-
score
|
|
60
|
-
|
|
63
|
+
score,
|
|
64
|
+
verdict,
|
|
65
|
+
recommendations,
|
|
61
66
|
inventory: {
|
|
62
67
|
skills: report.skills.length,
|
|
63
68
|
agents: report.agents.length,
|
|
@@ -71,6 +76,12 @@ function buildAuditReport(report, opts) {
|
|
|
71
76
|
},
|
|
72
77
|
...(adoptable ? { adoptable } : {}),
|
|
73
78
|
...(opts.observations ? { observations: opts.observations } : {}),
|
|
79
|
+
...(opts.rulesInventory && opts.rulesInventory.length
|
|
80
|
+
? { rulesInventory: opts.rulesInventory }
|
|
81
|
+
: {}),
|
|
82
|
+
...(opts.ruleRouting && opts.ruleRouting.segmented > 0
|
|
83
|
+
? { ruleRouting: opts.ruleRouting }
|
|
84
|
+
: {}),
|
|
74
85
|
};
|
|
75
86
|
}
|
|
76
87
|
/** Assemble the versioned {@link LeaderboardReport} — pure, no clock. */
|