rulereceipt 0.1.39 → 0.1.40
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 +1 -1
- package/dist/cli.js +28 -0
- package/dist/guard.js +13 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,7 +184,7 @@ survives that by saying UNCLEAR. A gate cannot — so you mark it:
|
|
|
184
184
|
rulereceipt rules --forbid <handle> --literal "git push --force"
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
Handles come from `rulereceipt
|
|
187
|
+
Handles come from `rulereceipt rules --handles`. The mark is stored
|
|
188
188
|
against the rule's content hash, and the guard blocks on that literal and no
|
|
189
189
|
other. Three things it deliberately will not do:
|
|
190
190
|
|
package/dist/cli.js
CHANGED
|
@@ -535,6 +535,33 @@ async function runRules(opts) {
|
|
|
535
535
|
console.log(`your judgment onto words you never read.`);
|
|
536
536
|
return;
|
|
537
537
|
}
|
|
538
|
+
/**
|
|
539
|
+
* Every rule with its handle.
|
|
540
|
+
*
|
|
541
|
+
* --forbid needs a handle, and before this the only place handles were
|
|
542
|
+
* printed was `check --show-skipped`, which lists the items the classifier
|
|
543
|
+
* DISCARDED. A rule that is actually being checked had no handle anywhere,
|
|
544
|
+
* so the marking feature shipped in 0.1.39 could not be reached for any
|
|
545
|
+
* rule a user would want to mark. Found by trying to use it.
|
|
546
|
+
*/
|
|
547
|
+
if (opts.handles) {
|
|
548
|
+
if (rules.length === 0) {
|
|
549
|
+
console.log("No CLAUDE.md or AGENTS.md rules found in this project.");
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
console.log(`${rules.length} rule${rules.length === 1 ? "" : "s"} in this project:\n`);
|
|
553
|
+
for (const r of rules) {
|
|
554
|
+
const h = ruleFingerprint(r);
|
|
555
|
+
const marked = overrides.get(h)?.forbids;
|
|
556
|
+
console.log(` ${h} ${r.title.replace(/\s+/g, " ").trim().slice(0, 72)}`);
|
|
557
|
+
if (marked?.length)
|
|
558
|
+
console.log(` blocks on: ${marked.map((f) => `\`${f}\``).join(", ")}`);
|
|
559
|
+
}
|
|
560
|
+
console.log(`\nMark which clause of a rule is the prohibition:`);
|
|
561
|
+
console.log(` rulereceipt rules --forbid <handle> --literal "<the banned command>"`);
|
|
562
|
+
console.log(`Only a marked clause can ever refuse a command, and only via \`rulereceipt guard\`.`);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
538
565
|
if (opts.clear) {
|
|
539
566
|
console.log(clearOverride(cwd, opts.clear) ? `Removed the correction for ${opts.clear}.` : `No correction stored for ${opts.clear}.`);
|
|
540
567
|
return;
|
|
@@ -651,6 +678,7 @@ program
|
|
|
651
678
|
.description("correct what the classifier treats as a rule. Handles come from `check --show-skipped`.")
|
|
652
679
|
.option("--include <handle>", "treat this item as a real rule and check it from now on")
|
|
653
680
|
.option("--exclude <handle>", "treat this item as documentation and stop reporting it")
|
|
681
|
+
.option("--handles", "list every rule with its handle, for use with --forbid")
|
|
654
682
|
.option("--forbid <handle>", "mark which clause of this rule is the prohibition, so the guard may block on it")
|
|
655
683
|
.option("--literal <text>", "the exact banned command, used with --forbid; must appear in the rule")
|
|
656
684
|
.option("--clear <handle>", "remove a stored correction")
|
package/dist/guard.js
CHANGED
|
@@ -80,13 +80,22 @@ function structuredBlocks(cwd, event) {
|
|
|
80
80
|
function ratifiedLiteralBlocks(cwd, command) {
|
|
81
81
|
const overrides = loadOverrides(cwd);
|
|
82
82
|
const blocks = [];
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
// Read from the RULES, not from the classification. A human mark
|
|
84
|
+
// supersedes the classifier, including its refusal to classify — and that
|
|
85
|
+
// refusal is the common case here. "Never use `git push --force`; prefer
|
|
86
|
+
// `git push --force-with-lease`" goes to judgment via hasMixedPolarity,
|
|
87
|
+
// for a correct reason: literal matching cannot tell which half owns which
|
|
88
|
+
// token. A rule naming both the ban and the alternative is the canonical
|
|
89
|
+
// reason to have someone say which is which, so gating the mark behind the
|
|
90
|
+
// classifier made the feature unavailable in exactly the case that
|
|
91
|
+
// motivated it. Shipped that way in 0.1.39 and caught by running it.
|
|
92
|
+
for (const rule of loadRules(cwd)) {
|
|
93
|
+
if (overrides.get(ruleFingerprint(rule))?.decision === "notARule")
|
|
85
94
|
continue;
|
|
86
|
-
for (const literal of ratifiedForbids(overrides,
|
|
95
|
+
for (const literal of ratifiedForbids(overrides, rule)) {
|
|
87
96
|
if (!commandRunsLiteral(command, literal))
|
|
88
97
|
continue;
|
|
89
|
-
blocks.push({ rule
|
|
98
|
+
blocks.push({ rule, why: `the command about to run does \`${literal}\`, which this rule forbids (marked by you, not inferred)` });
|
|
90
99
|
break;
|
|
91
100
|
}
|
|
92
101
|
}
|