rulebookguard 0.8.0 → 0.9.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 +158 -57
- package/dist/{anchors-C2j9c5MI.mjs → anchors-DQwbqb7w.mjs} +1 -1
- package/dist/cli.mjs +472 -144
- package/dist/index.d.mts +36 -8
- package/dist/index.mjs +3 -3
- package/dist/{lint-DfibQDW3.mjs → lint-CaJnNLmU.mjs} +199 -9
- package/dist/{site-DmY5YVte.mjs → site-BTCwdt_H.mjs} +15 -1
- 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,44 @@ 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
|
+
| [`impact <id>`](#impact-id) | the files and tests a rule touches |
|
|
243
|
+
| [`new <context>`](#new-context---prefix-p) | scaffolds the next rule of a context |
|
|
244
|
+
| [`lint`](#lint---base-ref---json) | checks the whole catalog, and optionally changes since a ref |
|
|
245
|
+
| [`export gherkin`](#export-gherkin---out-dir) | writes the rules' scenarios as Cucumber `.feature` files |
|
|
246
|
+
| [`export cursor\|copilot\|kiro`](#export-cursorcopilotkiro---out-dir) | writes the active rules as rule files of other AI tools |
|
|
247
|
+
| [`export agents-md`](#export-agents-md---out-dir) | keeps an index of the active rules in `AGENTS.md` |
|
|
248
|
+
| [`hook`](#hook) | Claude Code hook that injects the rules of a file |
|
|
249
|
+
| [`mcp`](#mcp---project-dir) | MCP server for AI agents |
|
|
250
|
+
| [`site:generate`](#sitegenerate---out-dir---base-path) | builds a static site of the rulebook |
|
|
251
|
+
| [`site:run`](#siterun---out-dir---base-path---port-n) | builds the site and serves it locally |
|
|
252
|
+
|
|
253
|
+
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
254
|
|
|
233
255
|
### `init <context> [--prefix <P>] [--language <en|es>] [--ci]`
|
|
234
256
|
|
|
@@ -280,7 +302,18 @@ file: docs/rules/clients/R-CLI-001.md
|
|
|
280
302
|
...
|
|
281
303
|
```
|
|
282
304
|
|
|
283
|
-
Exits 1 for an unknown id.
|
|
305
|
+
`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.
|
|
306
|
+
|
|
307
|
+
### `search <text> [--context <c>] [--json]`
|
|
308
|
+
|
|
309
|
+
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.`
|
|
310
|
+
|
|
311
|
+
```sh
|
|
312
|
+
$ rulebookguard search "document number"
|
|
313
|
+
R-CLI-001 [active] A client document number is unique per country.
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Exits 2 for an empty text and 1 for an unknown context.
|
|
284
317
|
|
|
285
318
|
### `for <path>`
|
|
286
319
|
|
|
@@ -288,10 +321,10 @@ Active rules whose anchors match a path, relative to the current directory. This
|
|
|
288
321
|
|
|
289
322
|
```sh
|
|
290
323
|
$ rulebookguard for src/clients/create.ts
|
|
291
|
-
R-CLI-001 (clients): A client document number is unique per country.
|
|
324
|
+
R-CLI-001 (clients): A client document number is unique per country. (lines 12-30)
|
|
292
325
|
```
|
|
293
326
|
|
|
294
|
-
Exits 1 when the path is outside the rulebook root.
|
|
327
|
+
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.
|
|
295
328
|
|
|
296
329
|
### `impact <id>`
|
|
297
330
|
|
|
@@ -332,23 +365,31 @@ Exits 1, writing nothing, when the context has no free id left, when the name is
|
|
|
332
365
|
|
|
333
366
|
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
367
|
|
|
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
|
-
|
|
|
368
|
+
| Severity | Code | Meaning |
|
|
369
|
+
| -------- | ----------------------------- | ------------------------------------------------------------------ |
|
|
370
|
+
| error | `untested-rule` | an active rule has no test tagging it |
|
|
371
|
+
| error | `unknown-rule-tag` | a test tags a rule id that does not exist |
|
|
372
|
+
| error | `deprecated-rule-tag` | a test tags a deprecated rule |
|
|
373
|
+
| error | `unclosed-rule-tag` | a `@rule` has no matching `@endrule` |
|
|
374
|
+
| error | `unmatched-endrule-tag` | an `@endrule` has no open `@rule` of the same id |
|
|
375
|
+
| error | `unclosed-implements-tag` | an `@implements` has no matching `@endimplements` |
|
|
376
|
+
| error | `unmatched-endimplements-tag` | an `@endimplements` has no open `@implements` of the same id |
|
|
377
|
+
| error | `unknown-implements-tag` | code is marked as implementing a rule id that does not exist |
|
|
378
|
+
| error | `deprecated-implements-tag` | code is marked as implementing a deprecated rule |
|
|
379
|
+
| error | `implements-outside-anchors` | an `@implements` region sits in a file its rule does not anchor |
|
|
380
|
+
| error | `unmatched-anchor` | an anchor glob matches no file |
|
|
381
|
+
| error | `schema` | a config, context or rule file breaks the JSON Schema |
|
|
382
|
+
| error | `duplicate-id` | two rule files share an id |
|
|
383
|
+
| error | `file-name-mismatch` | a rule file is not named `<id>.md` |
|
|
384
|
+
| error | `id-prefix-mismatch` | a rule id does not use its context prefix |
|
|
385
|
+
| error | `context-mismatch` | a `context` field does not match its directory |
|
|
386
|
+
| error | `missing-context-file` | a context directory has no `_context.md` |
|
|
387
|
+
| error | `missing-rules-dir` | `rulesDir` does not exist |
|
|
388
|
+
| error | `pending-implementation` | with `--base`: an active rule changed, but none of its regions did |
|
|
389
|
+
| error | `invalid-rule-reference` | `dependsOn` or `conflictsWith` names an unknown rule or itself |
|
|
390
|
+
| error | `dependency-cycle` | `dependsOn` links form a cycle (reported once, at its lowest id) |
|
|
391
|
+
| error | `active-rule-conflict` | two active rules where one lists the other in `conflictsWith` |
|
|
392
|
+
| warning | `context-over-budget` | a context holds more rules than `contextBudget` |
|
|
352
393
|
|
|
353
394
|
```sh
|
|
354
395
|
$ rulebookguard lint
|
|
@@ -372,6 +413,59 @@ error pending-implementation docs/rules/clients/R-CLI-001.md rule R-CLI-001 chan
|
|
|
372
413
|
|
|
373
414
|
`--json` prints `{ "findings": [{ "severity", "code", "file", "line"?, "message", "hint" }], "errors", "warnings" }`.
|
|
374
415
|
|
|
416
|
+
### `export gherkin [--out <dir>]`
|
|
417
|
+
|
|
418
|
+
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:`.
|
|
419
|
+
|
|
420
|
+
```sh
|
|
421
|
+
$ rulebookguard export gherkin
|
|
422
|
+
features/rules/clients/R-CLI-001.feature
|
|
423
|
+
$ cat features/rules/clients/R-CLI-001.feature
|
|
424
|
+
# Generated by "rulebookguard export gherkin" from docs/rules/clients/R-CLI-001.md; edit the rule instead.
|
|
425
|
+
@R-CLI-001
|
|
426
|
+
Feature: R-CLI-001 A client document number is unique per country.
|
|
427
|
+
|
|
428
|
+
Scenario: Duplicate document in the same country
|
|
429
|
+
Given a client with document "00123" in "VE"
|
|
430
|
+
When another client is created with document "123" in "VE"
|
|
431
|
+
Then the creation is rejected with "document already registered"
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
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.
|
|
435
|
+
|
|
436
|
+
### `export cursor|copilot|kiro [--out <dir>]`
|
|
437
|
+
|
|
438
|
+
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:
|
|
439
|
+
|
|
440
|
+
| Format | File | Scoped with |
|
|
441
|
+
| --------- | --------------------------------------------------------- | --------------------------------------------------- |
|
|
442
|
+
| `cursor` | `.cursor/rules/rulebookguard-<id>.mdc` | `globs`, comma-separated, with `alwaysApply: false` |
|
|
443
|
+
| `copilot` | `.github/instructions/rulebookguard-<id>.instructions.md` | `applyTo`, comma-separated |
|
|
444
|
+
| `kiro` | `.kiro/steering/rulebookguard-<id>.md` | `inclusion: fileMatch` and `fileMatchPattern` |
|
|
445
|
+
|
|
446
|
+
```sh
|
|
447
|
+
$ rulebookguard export kiro
|
|
448
|
+
.kiro/steering/rulebookguard-R-CLI-001.md
|
|
449
|
+
$ cat .kiro/steering/rulebookguard-R-CLI-001.md
|
|
450
|
+
---
|
|
451
|
+
inclusion: fileMatch
|
|
452
|
+
fileMatchPattern: "src/clients/**/*.go"
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
<!-- Generated by "rulebookguard export kiro" from docs/rules/clients/R-CLI-001.md; edit the rule instead. -->
|
|
456
|
+
|
|
457
|
+
**R-CLI-001:** A client document number is unique per country.
|
|
458
|
+
|
|
459
|
+
# Unique document number
|
|
460
|
+
…
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
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.
|
|
464
|
+
|
|
465
|
+
### `export agents-md [--out <dir>]`
|
|
466
|
+
|
|
467
|
+
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. Anything other than one start marker followed by one end marker, or neither, fails with exit code 1 and leaves the file untouched.
|
|
468
|
+
|
|
375
469
|
### `hook`
|
|
376
470
|
|
|
377
471
|
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 +477,25 @@ $ echo '{"hook_event_name":"PostToolUse","tool_name":"Read","tool_input":{"file_
|
|
|
383
477
|
|
|
384
478
|
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
479
|
|
|
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.
|
|
480
|
+
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
481
|
|
|
388
482
|
> [!NOTE]
|
|
389
483
|
> 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
484
|
|
|
391
485
|
### `mcp [--project <dir>]`
|
|
392
486
|
|
|
393
|
-
An [MCP](https://modelcontextprotocol.io) server over stdio for AI agents, with
|
|
487
|
+
An [MCP](https://modelcontextprotocol.io) server over stdio for AI agents, with read-only tools:
|
|
394
488
|
|
|
395
|
-
| Tool
|
|
396
|
-
|
|
|
397
|
-
| `rules_for`
|
|
398
|
-
| `rules_show`
|
|
489
|
+
| Tool | Input | Answers |
|
|
490
|
+
| -------------- | ------------------------------------------------------ | ------------------------------------------------------------- |
|
|
491
|
+
| `rules_for` | `path`: absolute, or relative to the project directory | what `rulebookguard for <path> --json` prints |
|
|
492
|
+
| `rules_show` | `id`: a rule id | what `rulebookguard show <id> --json` prints |
|
|
493
|
+
| `contexts` | none | what `rulebookguard contexts --json` prints |
|
|
494
|
+
| `rules_list` | `context`?, `status`? | what `rulebookguard list --json` prints with those options |
|
|
495
|
+
| `rules_search` | `text`, `context`? | what `rulebookguard search <text> --json` prints |
|
|
496
|
+
| `lint` | `base`?: a git ref | what `rulebookguard lint --json` prints, with `--base` if set |
|
|
399
497
|
|
|
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.`
|
|
498
|
+
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
499
|
|
|
402
500
|
### `site:generate [--out <dir>] [--base <path>]`
|
|
403
501
|
|
|
@@ -434,7 +532,7 @@ The site has:
|
|
|
434
532
|
- **Home:** the contexts map, with how many rules of each status every context holds.
|
|
435
533
|
- **A page per context** with its description and rules.
|
|
436
534
|
- **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.
|
|
535
|
+
- **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
536
|
- **Health:** the `lint` findings when the site was built.
|
|
439
537
|
- Full-text search (Pagefind).
|
|
440
538
|
|
|
@@ -461,7 +559,7 @@ jobs:
|
|
|
461
559
|
- uses: actions/setup-node@v6
|
|
462
560
|
with:
|
|
463
561
|
node-version: 22
|
|
464
|
-
- run: npx --yes rulebookguard@0.
|
|
562
|
+
- run: npx --yes rulebookguard@0.9.0 lint --base origin/${{ github.base_ref }}
|
|
465
563
|
```
|
|
466
564
|
|
|
467
565
|
> [!TIP]
|
|
@@ -472,8 +570,11 @@ jobs:
|
|
|
472
570
|
The plugin in [`plugin/`](plugin) connects the rulebook to Claude Code:
|
|
473
571
|
|
|
474
572
|
- **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.
|
|
573
|
+
- **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.
|
|
574
|
+
- **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.
|
|
575
|
+
- **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.
|
|
576
|
+
- **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".
|
|
577
|
+
- **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
578
|
|
|
478
579
|
Install it from this repository's marketplace:
|
|
479
580
|
|