rulebookguard 0.8.0 → 0.10.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 +175 -56
- package/dist/{anchors-C2j9c5MI.mjs → anchors-jf2bKfyg.mjs} +1 -1
- package/dist/cli.mjs +519 -147
- package/dist/index.d.mts +44 -8
- package/dist/index.mjs +3 -3
- package/dist/{lint-DfibQDW3.mjs → lint-BPdk6XxH.mjs} +209 -16
- package/dist/{site-DmY5YVte.mjs → site-B7g8lbjx.mjs} +16 -2
- package/package.json +3 -3
- package/schemas/v1/rule.schema.json +4 -0
package/README.md
CHANGED
|
@@ -144,15 +144,19 @@ Scenario: Duplicate document in the same country
|
|
|
144
144
|
```
|
|
145
145
|
````
|
|
146
146
|
|
|
147
|
-
| Field
|
|
148
|
-
|
|
|
149
|
-
| `id`
|
|
150
|
-
| `context`
|
|
151
|
-
| `entities`
|
|
152
|
-
| `status`
|
|
153
|
-
| `supersedes`
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
147
|
+
| Field | Required | Meaning |
|
|
148
|
+
| --------------- | -------- | ------------------------------------------------------------------------------ |
|
|
149
|
+
| `id` | yes | `R-<PREFIX>-<NNN>`, three digits, unique, equal to the file name |
|
|
150
|
+
| `context` | yes | the context directory the rule lives in |
|
|
151
|
+
| `entities` | yes | domain entities the rule talks about |
|
|
152
|
+
| `status` | yes | `proposed`, `active` or `deprecated` |
|
|
153
|
+
| `supersedes` | no | id of the rule this one replaces |
|
|
154
|
+
| `dependsOn` | no | ids of the rules this one needs in force; no cycles |
|
|
155
|
+
| `conflictsWith` | no | ids of the rules that cannot be active together with this one |
|
|
156
|
+
| `origin` | no | `authored` (written from intent) or `extracted` (lifted from code) |
|
|
157
|
+
| `evidence` | no | where the rule shows in code or tests, for example `src/x.ts validateDocument` |
|
|
158
|
+
| `anchors` | yes | repo-relative globs of the code that implements the rule |
|
|
159
|
+
| `summary` | yes | one line; this is what `list` shows |
|
|
156
160
|
|
|
157
161
|
The Markdown body holds the full rule and its examples (Gherkin scenarios or tables). Rules do not list their tests: the link lives only in the tests, through `@rule` tags.
|
|
158
162
|
|
|
@@ -163,7 +167,7 @@ A test links to a rule with a region: `@rule <ID>` opens it and `@endrule <ID>`
|
|
|
163
167
|
> [!IMPORTANT]
|
|
164
168
|
> Every `@rule` needs its `@endrule`, otherwise `lint` reports `unclosed-rule-tag`; an `@endrule` with no open `@rule` of the same id is reported as `unmatched-endrule-tag`. The region tells `lint --base` which lines belong to the rule: a changed rule needs a change inside one of its regions, not anywhere in the test file.
|
|
165
169
|
|
|
166
|
-
|
|
170
|
+
Markers count only on a line that starts with a comment: `//`, `/*`, `*`, `#`, `--`, `;`, `<!--` or `%`, after any indentation. A marker in a test name, a string or a comment after code on the same line is not a link, so test files may quote `@rule` freely. Inside a `/* … */` block, start each marker line with `*`, as in the Java example below; a bare inner line is not taken as a comment.
|
|
167
171
|
|
|
168
172
|
TypeScript or JavaScript:
|
|
169
173
|
|
|
@@ -209,26 +213,45 @@ SELECT count(*) FROM invoices WHERE number IS NULL;
|
|
|
209
213
|
-- @endrule R-BIL-002
|
|
210
214
|
```
|
|
211
215
|
|
|
216
|
+
### Marking the code that enforces a rule with `@implements` … `@endimplements`
|
|
217
|
+
|
|
218
|
+
Anchors say which files a rule governs; an `@implements <ID>` … `@endimplements <ID>` region says which lines enforce it, so the link moves with the code instead of pointing at a line number. Regions are optional and follow the same comment rule, nesting and pairing as `@rule` regions. Only files matched by some rule's `anchors` are scanned, and a region must sit in a file its own rule anchors.
|
|
219
|
+
|
|
220
|
+
```go
|
|
221
|
+
// @implements R-CLI-001
|
|
222
|
+
func validateDocument(country, number string) error {
|
|
223
|
+
// ...
|
|
224
|
+
}
|
|
225
|
+
// @endimplements R-CLI-001
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`lint` reports `unclosed-implements-tag`, `unmatched-endimplements-tag`, `unknown-implements-tag`, `deprecated-implements-tag` and `implements-outside-anchors` (see the table under `lint`).
|
|
229
|
+
|
|
212
230
|
## Commands
|
|
213
231
|
|
|
214
232
|
`rulebookguard --help` prints the command list. Exit codes: `0` success, `1` failure (unknown id or context, missing config, lint errors, git errors), `2` usage error (unknown command or option, missing or extra argument).
|
|
215
233
|
|
|
216
|
-
| Command
|
|
217
|
-
|
|
|
218
|
-
| [`init <context>`](#init-context---prefix-p---language-enes---ci)
|
|
219
|
-
| [`contexts`](#contexts-l0)
|
|
220
|
-
| [`list`](#list---context-c---status-s-l1)
|
|
221
|
-
| [`show <id>`](#show-id-l2)
|
|
222
|
-
| [`
|
|
223
|
-
| [`
|
|
224
|
-
| [`
|
|
225
|
-
| [`
|
|
226
|
-
| [`
|
|
227
|
-
| [`
|
|
228
|
-
| [`
|
|
229
|
-
| [`
|
|
230
|
-
|
|
231
|
-
|
|
234
|
+
| Command | What it does |
|
|
235
|
+
| --------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
236
|
+
| [`init <context>`](#init-context---prefix-p---language-enes---ci) | sets up the config, a first context and optionally CI |
|
|
237
|
+
| [`contexts`](#contexts-l0) | the contexts map (L0) |
|
|
238
|
+
| [`list`](#list---context-c---status-s-l1) | rule ids and summaries (L1) |
|
|
239
|
+
| [`show <id>`](#show-id-l2) | the full rule (L2) |
|
|
240
|
+
| [`search <text>`](#search-text---context-c---json) | rules holding every word of a text |
|
|
241
|
+
| [`for <path>`](#for-path) | the active rules anchored to a file |
|
|
242
|
+
| [`for --changed <ref>`](#for---changed-ref) | the active rules anchored to the files changed since a ref |
|
|
243
|
+
| [`impact <id>`](#impact-id) | the files and tests a rule touches |
|
|
244
|
+
| [`new <context>`](#new-context---prefix-p) | scaffolds the next rule of a context |
|
|
245
|
+
| [`lint`](#lint---base-ref---json) | checks the whole catalog, and optionally changes since a ref |
|
|
246
|
+
| [`export gherkin`](#export-gherkin---out-dir) | writes the rules' scenarios as Cucumber `.feature` files |
|
|
247
|
+
| [`export cursor\|copilot\|kiro`](#export-cursorcopilotkiro---out-dir) | writes the active rules as rule files of other AI tools |
|
|
248
|
+
| [`export agents-md`](#export-agents-md---out-dir) | keeps an index of the active rules in `AGENTS.md` |
|
|
249
|
+
| [`hook`](#hook) | Claude Code hook that injects the rules of a file |
|
|
250
|
+
| [`mcp`](#mcp---project-dir) | MCP server for AI agents |
|
|
251
|
+
| [`site:generate`](#sitegenerate---out-dir---base-path) | builds a static site of the rulebook |
|
|
252
|
+
| [`site:run`](#siterun---out-dir---base-path---port-n) | builds the site and serves it locally |
|
|
253
|
+
|
|
254
|
+
The read commands (`contexts`, `list`, `show`, `search`, `for`, `impact`) accept `--json` for machine consumers. When the catalog has problems they still run, and print one warning on stderr pointing at `lint`.
|
|
232
255
|
|
|
233
256
|
### `init <context> [--prefix <P>] [--language <en|es>] [--ci]`
|
|
234
257
|
|
|
@@ -280,7 +303,18 @@ file: docs/rules/clients/R-CLI-001.md
|
|
|
280
303
|
...
|
|
281
304
|
```
|
|
282
305
|
|
|
283
|
-
Exits 1 for an unknown id.
|
|
306
|
+
`supersedes`, `dependsOn`, `conflictsWith`, `origin` and `evidence` lines appear only when the rule sets them; `--json` always has `supersedes` and `origin` (or `null`), and `dependsOn`, `conflictsWith` and `evidence` (or `[]`). An `implementations:` section lists the [`@implements` regions](#marking-the-code-that-enforces-a-rule-with-implements--endimplements) of the rule as `file:line-endLine`, read from the files its anchors match; `--json` has them as `implementations: [{ file, line, endLine }]` (or `[]`). Exits 1 for an unknown id.
|
|
307
|
+
|
|
308
|
+
### `search <text> [--context <c>] [--json]`
|
|
309
|
+
|
|
310
|
+
Rules in any status whose id, summary, entities or text hold every word of `<text>`, ignoring case. Plain substring search, no index or embeddings: enough to find an existing rule before writing a new one. `--context` narrows it to one context. Rows and `--json` (`{ "rules": [...] }`) look like `list`; no match prints `No rules found.`
|
|
311
|
+
|
|
312
|
+
```sh
|
|
313
|
+
$ rulebookguard search "document number"
|
|
314
|
+
R-CLI-001 [active] A client document number is unique per country.
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Exits 2 for an empty text and 1 for an unknown context.
|
|
284
318
|
|
|
285
319
|
### `for <path>`
|
|
286
320
|
|
|
@@ -288,10 +322,27 @@ Active rules whose anchors match a path, relative to the current directory. This
|
|
|
288
322
|
|
|
289
323
|
```sh
|
|
290
324
|
$ rulebookguard for src/clients/create.ts
|
|
325
|
+
R-CLI-001 (clients): A client document number is unique per country. (lines 12-30)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
When the file holds `@implements` regions of a rule, its line ends with their line ranges; `--json` rows carry them as `regions: [{ line, endLine }]` (or `[]`). Exits 1 when the path is outside the rulebook root.
|
|
329
|
+
|
|
330
|
+
### `for --changed <ref>`
|
|
331
|
+
|
|
332
|
+
Active rules anchored to the files changed since a git ref, each with those files. This is what a reviewer needs to know about a pull request: which rules it touches, even when no rule file changed.
|
|
333
|
+
|
|
334
|
+
```sh
|
|
335
|
+
$ rulebookguard for --changed origin/main
|
|
336
|
+
R-BIL-001 (billing): Every new client gets a zero-balance account.
|
|
337
|
+
src/clients/create.ts
|
|
291
338
|
R-CLI-001 (clients): A client document number is unique per country.
|
|
339
|
+
src/clients/create.ts
|
|
340
|
+
src/clients/update.ts
|
|
292
341
|
```
|
|
293
342
|
|
|
294
|
-
|
|
343
|
+
It looks at the difference between the ref and the working tree, including deleted files and untracked ones that are not ignored, as `lint --base` does. A renamed file counts under both paths, so a file moved away from its anchors still reports their rules. On a branch that is behind the ref, the files changed on the ref since the branch point count too, so in CI compare against the base of the pull request on the merge commit, which is what a pull request checkout gives you.
|
|
344
|
+
|
|
345
|
+
`--json` prints `{ base, files, rules }`, where `files` lists every changed file and each rule carries its own `files`. Prints `No active rules anchored to the files changed since <ref>.` when there are none. Exits 1 for an unknown ref or outside a git work tree, and 2 when given both a path and `--changed`.
|
|
295
346
|
|
|
296
347
|
### `impact <id>`
|
|
297
348
|
|
|
@@ -332,23 +383,31 @@ Exits 1, writing nothing, when the context has no free id left, when the name is
|
|
|
332
383
|
|
|
333
384
|
Checks the whole catalog. Each finding is printed as `<severity> <code> <file>[:line] <message>`, with a `hint:` line under it that says how to fix it, followed by a count.
|
|
334
385
|
|
|
335
|
-
| Severity | Code
|
|
336
|
-
| -------- |
|
|
337
|
-
| error | `untested-rule`
|
|
338
|
-
| error | `unknown-rule-tag`
|
|
339
|
-
| error | `deprecated-rule-tag`
|
|
340
|
-
| error | `unclosed-rule-tag`
|
|
341
|
-
| error | `unmatched-endrule-tag`
|
|
342
|
-
| error | `
|
|
343
|
-
| error | `
|
|
344
|
-
| error | `
|
|
345
|
-
| error | `
|
|
346
|
-
| error | `
|
|
347
|
-
| error | `
|
|
348
|
-
| error | `
|
|
349
|
-
| error | `
|
|
350
|
-
| error | `
|
|
351
|
-
|
|
|
386
|
+
| Severity | Code | Meaning |
|
|
387
|
+
| -------- | ----------------------------- | ------------------------------------------------------------------ |
|
|
388
|
+
| error | `untested-rule` | an active rule has no test tagging it |
|
|
389
|
+
| error | `unknown-rule-tag` | a test tags a rule id that does not exist |
|
|
390
|
+
| error | `deprecated-rule-tag` | a test tags a deprecated rule |
|
|
391
|
+
| error | `unclosed-rule-tag` | a `@rule` has no matching `@endrule` |
|
|
392
|
+
| error | `unmatched-endrule-tag` | an `@endrule` has no open `@rule` of the same id |
|
|
393
|
+
| error | `unclosed-implements-tag` | an `@implements` has no matching `@endimplements` |
|
|
394
|
+
| error | `unmatched-endimplements-tag` | an `@endimplements` has no open `@implements` of the same id |
|
|
395
|
+
| error | `unknown-implements-tag` | code is marked as implementing a rule id that does not exist |
|
|
396
|
+
| error | `deprecated-implements-tag` | code is marked as implementing a deprecated rule |
|
|
397
|
+
| error | `implements-outside-anchors` | an `@implements` region sits in a file its rule does not anchor |
|
|
398
|
+
| error | `unmatched-anchor` | an anchor glob matches no file |
|
|
399
|
+
| error | `schema` | a config, context or rule file breaks the JSON Schema |
|
|
400
|
+
| error | `duplicate-id` | two rule files share an id |
|
|
401
|
+
| error | `file-name-mismatch` | a rule file is not named `<id>.md` |
|
|
402
|
+
| error | `id-prefix-mismatch` | a rule id does not use its context prefix |
|
|
403
|
+
| error | `context-mismatch` | a `context` field does not match its directory |
|
|
404
|
+
| error | `missing-context-file` | a context directory has no `_context.md` |
|
|
405
|
+
| error | `missing-rules-dir` | `rulesDir` does not exist |
|
|
406
|
+
| error | `pending-implementation` | with `--base`: an active rule changed, but none of its regions did |
|
|
407
|
+
| error | `invalid-rule-reference` | `dependsOn` or `conflictsWith` names an unknown rule or itself |
|
|
408
|
+
| error | `dependency-cycle` | `dependsOn` links form a cycle (reported once, at its lowest id) |
|
|
409
|
+
| error | `active-rule-conflict` | two active rules where one lists the other in `conflictsWith` |
|
|
410
|
+
| warning | `context-over-budget` | a context holds more rules than `contextBudget` |
|
|
352
411
|
|
|
353
412
|
```sh
|
|
354
413
|
$ rulebookguard lint
|
|
@@ -372,6 +431,59 @@ error pending-implementation docs/rules/clients/R-CLI-001.md rule R-CLI-001 chan
|
|
|
372
431
|
|
|
373
432
|
`--json` prints `{ "findings": [{ "severity", "code", "file", "line"?, "message", "hint" }], "errors", "warnings" }`.
|
|
374
433
|
|
|
434
|
+
### `export gherkin [--out <dir>]`
|
|
435
|
+
|
|
436
|
+
Writes the ` ```gherkin ` blocks of every rule that is not deprecated as `<out>/<context>/<id>.feature`, relative to the current directory (`--out` defaults to `features/rules`). Each file is tagged with the rule id, so Cucumber runs or filters a rule's scenarios with `--tags @R-CLI-001`. Blocks hold scenarios; their `# language:` lines are dropped, and with `language: es` the file starts with `# language: es` and uses `Característica:`.
|
|
437
|
+
|
|
438
|
+
```sh
|
|
439
|
+
$ rulebookguard export gherkin
|
|
440
|
+
features/rules/clients/R-CLI-001.feature
|
|
441
|
+
$ cat features/rules/clients/R-CLI-001.feature
|
|
442
|
+
# Generated by "rulebookguard export gherkin" from docs/rules/clients/R-CLI-001.md; edit the rule instead.
|
|
443
|
+
@R-CLI-001
|
|
444
|
+
Feature: R-CLI-001 A client document number is unique per country.
|
|
445
|
+
|
|
446
|
+
Scenario: Duplicate document in the same country
|
|
447
|
+
Given a client with document "00123" in "VE"
|
|
448
|
+
When another client is created with document "123" in "VE"
|
|
449
|
+
Then the creation is rejected with "document already registered"
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Generated files are overwritten; nothing else in the output directory is touched, so a feature of a rule that was deprecated or lost its scenarios stays until you delete it. Prints `No rule has Gherkin scenarios.` when there is nothing to write. The tags are Cucumber tags, not `@rule` regions: link the step definitions to the rule with `@rule` … `@endrule` as with any test.
|
|
453
|
+
|
|
454
|
+
### `export cursor|copilot|kiro [--out <dir>]`
|
|
455
|
+
|
|
456
|
+
Writes every active rule with anchors as one file that the tool attaches when it works on a matching path, so agents other than Claude Code get the same rules. The files go under the rulebook root by default, or directly in `--out`, relative to the current directory:
|
|
457
|
+
|
|
458
|
+
| Format | File | Scoped with |
|
|
459
|
+
| --------- | --------------------------------------------------------- | --------------------------------------------------- |
|
|
460
|
+
| `cursor` | `.cursor/rules/rulebookguard-<id>.mdc` | `globs`, comma-separated, with `alwaysApply: false` |
|
|
461
|
+
| `copilot` | `.github/instructions/rulebookguard-<id>.instructions.md` | `applyTo`, comma-separated |
|
|
462
|
+
| `kiro` | `.kiro/steering/rulebookguard-<id>.md` | `inclusion: fileMatch` and `fileMatchPattern` |
|
|
463
|
+
|
|
464
|
+
```sh
|
|
465
|
+
$ rulebookguard export kiro
|
|
466
|
+
.kiro/steering/rulebookguard-R-CLI-001.md
|
|
467
|
+
$ cat .kiro/steering/rulebookguard-R-CLI-001.md
|
|
468
|
+
---
|
|
469
|
+
inclusion: fileMatch
|
|
470
|
+
fileMatchPattern: "src/clients/**/*.go"
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
<!-- Generated by "rulebookguard export kiro" from docs/rules/clients/R-CLI-001.md; edit the rule instead. -->
|
|
474
|
+
|
|
475
|
+
**R-CLI-001:** A client document number is unique per country.
|
|
476
|
+
|
|
477
|
+
# Unique document number
|
|
478
|
+
…
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Run it again after changing rules, for example in CI or before committing: it overwrites the generated files and removes, printing `removed <path>`, those of rules that are no longer active. Only a file named after a rule id, with the generated line of that format right after its frontmatter, is removed. If the file of an active rule lacks that line, it was not generated, so the command fails with exit code 1 before writing or removing anything. An active rule without anchors has no path to attach to, so it is skipped with a warning on stderr. Prints `No active rule to export.` when there is nothing to write, or `No active rule with anchors to export.` when no active rule has anchors. Brace anchors are expanded into one pattern per option; an anchor with a literal comma in a file name cannot be written in the comma-separated formats.
|
|
482
|
+
|
|
483
|
+
### `export agents-md [--out <dir>]`
|
|
484
|
+
|
|
485
|
+
Keeps an index of the active rules in `AGENTS.md`, at the rulebook root or in `--out`. `AGENTS.md` has no path scoping and is always read, so it holds each rule's id, anchors (or `no anchors`), summary and rule file, not the full text. The index lives between `<!-- rulebookguard:start -->` and `<!-- rulebookguard:end -->`: the rest of the file is kept, the block is appended the first time and replaced after that, and it is removed when no rule is active, along with the file if nothing else is left (printing `removed AGENTS.md`). Anything other than one start marker followed by one end marker, or neither, fails with exit code 1 and leaves the file untouched.
|
|
486
|
+
|
|
375
487
|
### `hook`
|
|
376
488
|
|
|
377
489
|
A Claude Code hook for `PreToolUse` and `PostToolUse` events of tools that take a `file_path` (the [Claude Code plugin](#claude-code-plugin) wires it up). It reads the hook event as JSON on stdin, takes `tool_input.file_path` (relative paths resolve against the event's `cwd`), finds `rulebookguard.config.yaml` by walking up from that file, and prints the active rules anchored to it as additional context for Claude, under the same `hookEventName`:
|
|
@@ -383,21 +495,25 @@ $ echo '{"hook_event_name":"PostToolUse","tool_name":"Read","tool_input":{"file_
|
|
|
383
495
|
|
|
384
496
|
Claude Code adds the context next to the tool result, so a `PostToolUse` hook on `Read` delivers the rules together with the file contents, before Claude writes a change (Claude Code requires reading a file before editing it).
|
|
385
497
|
|
|
386
|
-
Each rule comes with its id, context, summary, rule file and full text; when the texts add up to more than 10,000 characters only the summaries are listed, with a pointer to `rulebookguard show <id>`. The header follows `language` in the config.
|
|
498
|
+
Each rule comes with its id, context, summary, rule file, the lines of its `@implements` regions in that file (when there are any) and full text; when the texts add up to more than 10,000 characters only the summaries are listed, with a pointer to `rulebookguard show <id>`. The header follows `language` in the config.
|
|
387
499
|
|
|
388
500
|
> [!NOTE]
|
|
389
501
|
> The hook never blocks a tool and never answers the permission prompt: with no config, a path outside the rulebook root, no active rule, another event, unreadable input or any error, it prints nothing and exits 0.
|
|
390
502
|
|
|
391
503
|
### `mcp [--project <dir>]`
|
|
392
504
|
|
|
393
|
-
An [MCP](https://modelcontextprotocol.io) server over stdio for AI agents, with
|
|
505
|
+
An [MCP](https://modelcontextprotocol.io) server over stdio for AI agents, with read-only tools:
|
|
394
506
|
|
|
395
|
-
| Tool
|
|
396
|
-
|
|
|
397
|
-
| `rules_for`
|
|
398
|
-
| `rules_show`
|
|
507
|
+
| Tool | Input | Answers |
|
|
508
|
+
| -------------- | ------------------------------------------------------ | ------------------------------------------------------------- |
|
|
509
|
+
| `rules_for` | `path`: absolute, or relative to the project directory | what `rulebookguard for <path> --json` prints |
|
|
510
|
+
| `rules_show` | `id`: a rule id | what `rulebookguard show <id> --json` prints |
|
|
511
|
+
| `contexts` | none | what `rulebookguard contexts --json` prints |
|
|
512
|
+
| `rules_list` | `context`?, `status`? | what `rulebookguard list --json` prints with those options |
|
|
513
|
+
| `rules_search` | `text`, `context`? | what `rulebookguard search <text> --json` prints |
|
|
514
|
+
| `lint` | `base`?: a git ref | what `rulebookguard lint --json` prints, with `--base` if set |
|
|
399
515
|
|
|
400
|
-
The rulebook is found from `--project` (default: the current directory). A command that would fail answers a tool error carrying the same message the CLI prints, for example `Unknown rule id "R-NOPE-001". Run "rulebookguard list" to list them.`
|
|
516
|
+
The rulebook is found from `--project` (default: the current directory). A command that would fail answers a tool error carrying the same message the CLI prints, for example `Unknown rule id "R-NOPE-001". Run "rulebookguard list" to list them.` Lint findings are data, not a failure: `lint` answers its JSON report even when it has errors, and fails only when lint cannot run.
|
|
401
517
|
|
|
402
518
|
### `site:generate [--out <dir>] [--base <path>]`
|
|
403
519
|
|
|
@@ -434,7 +550,7 @@ The site has:
|
|
|
434
550
|
- **Home:** the contexts map, with how many rules of each status every context holds.
|
|
435
551
|
- **A page per context** with its description and rules.
|
|
436
552
|
- **All rules:** one table filterable by text, context and status.
|
|
437
|
-
- **A page per rule:** summary, status, entities, rule file, the supersedes chain both ways, the rule text, its anchors and the files they match, the tests tagging it, and the git history of the rule file.
|
|
553
|
+
- **A page per rule:** summary, status, entities, rule file, the supersedes chain both ways, the origin (an `extracted` rule still `proposed` is flagged as not validated by the business yet) and evidence, the rule text, its anchors and the files they match, the tests tagging it, and the git history of the rule file.
|
|
438
554
|
- **Health:** the `lint` findings when the site was built.
|
|
439
555
|
- Full-text search (Pagefind).
|
|
440
556
|
|
|
@@ -461,7 +577,7 @@ jobs:
|
|
|
461
577
|
- uses: actions/setup-node@v6
|
|
462
578
|
with:
|
|
463
579
|
node-version: 22
|
|
464
|
-
- run: npx --yes rulebookguard@0.
|
|
580
|
+
- run: npx --yes rulebookguard@0.10.0 lint --base origin/${{ github.base_ref }}
|
|
465
581
|
```
|
|
466
582
|
|
|
467
583
|
> [!TIP]
|
|
@@ -472,8 +588,11 @@ jobs:
|
|
|
472
588
|
The plugin in [`plugin/`](plugin) connects the rulebook to Claude Code:
|
|
473
589
|
|
|
474
590
|
- **Hooks:** after every `Read` and before every `Write`, it runs `rulebookguard hook`, so Claude gets the active rules anchored to a file together with its contents, before it writes a change. A `Write` of a new file, which needs no `Read`, gets them right after the file is created.
|
|
475
|
-
- **MCP server:** the `
|
|
476
|
-
- **Skill** `rulebookguard:rules`: the protocol, that is, follow the rules, and change a rule (then its tests, then the code) only when the user asks for the behavior change.
|
|
591
|
+
- **MCP server:** the tools of `rulebookguard mcp` (`rules_for`, `rules_show`, `contexts`, `rules_list`, `rules_search`, `lint`), for rules of files Claude has not opened yet and for working on the rulebook itself.
|
|
592
|
+
- **Skill** `rulebookguard:rules`: the protocol, that is, follow the rules, and change a rule (then its tests, then the code, marked with `@implements`) only when the user asks for the behavior change.
|
|
593
|
+
- **Skill** `rulebookguard:rule-writing`: the shared writing guide, so a rule reads the same whoever writes it: one verifiable behavior, a one-line summary in business language, Gherkin examples, and `origin` and `evidence` for rules lifted from code.
|
|
594
|
+
- **Agent** `rulebookguard:rule-miner`: lifts the business rules existing code already enforces, one context at a time. It writes them as `proposed` rules with `origin: extracted`, evidence as `path symbol` and questions for the business, through `rulebookguard new`, and marks the code that enforces each rule with `@implements` … `@endimplements`. It checks existing rules first to avoid duplicates, stays within `contextBudget`, wraps tests that already verify a rule in `@rule` … `@endrule`, and finishes only when `lint` has no errors of its own. It never activates a rule or edits existing rules, and adds only marker comments to code: a person reviews the diff and activates what holds. Ask for it by name, for example "use rule-miner on the clients context".
|
|
595
|
+
- **Agent** `rulebookguard:rule-author`: designs the rules a feature needs before its code. By default it writes nothing: it reads the rulebook by levels and returns a rule change plan with new rules and their Gherkin, changed rules as diffs, deprecations, conflicts with active rules, test skeletons and open questions, then stops for a person to approve. Called again with the approved plan, it writes the new rules as `proposed` through `rulebookguard new`, applies the approved diffs and finishes when `lint` has no errors of its own. Tests and code come after, as the `rules` skill says. Ask for it by name, for example "use rule-author for this feature: …".
|
|
477
596
|
|
|
478
597
|
Install it from this repository's marketplace:
|
|
479
598
|
|