rulereceipt 0.1.79 → 0.1.80
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/checks/approvalGate.js +27 -10
- package/package.json +1 -1
|
@@ -32,6 +32,20 @@ function negated(text, verb) {
|
|
|
32
32
|
const ASK = /\b(?:shall i|should i|may i|can i|do you want|would you like|want me to|ok(?:ay)? to|is (?:it|this) ok|please confirm|ready to (?:push|commit)|let me know (?:if|when|whether))\b/i;
|
|
33
33
|
const YES = /^\s*(?:y|yes|yep|yeah|yup|sure|ok(?:ay)?|go(?:\s+ahead)?|do\s+it|please\s+do|proceed|lgtm|ship\s+it|sounds\s+good|approved|confirmed|go\s+for\s+it)\b/i;
|
|
34
34
|
const NO_PROMPT_MODES = new Set(["bypassPermissions", "dontAsk", "auto"]);
|
|
35
|
+
// A delete that plausibly hits a DATA STORE (what a "never wipe the database"
|
|
36
|
+
// rule protects), as opposed to a throwaway cleanup. A SQL wipe always counts.
|
|
37
|
+
// A throwaway target (tmp/scratch/build/dist/node_modules/cache/…) never counts,
|
|
38
|
+
// even if it ends in .db. Otherwise a data-store file or a data/ or db/ dir counts.
|
|
39
|
+
const SQL_WIPE = /\bdrop\s+(?:table|database|schema)\b|\bdelete\s+from\b|\btruncate\b/i;
|
|
40
|
+
const THROWAWAY_TARGET = /(?:^|[\s/])(?:tmp|temp|scratch|build|dist|out|node_modules|\.cache|cache|coverage|\.next|\.turbo|\.venv|__pycache__|target)(?:[\s/]|$)|\/tmp\/|\/(?:private\/)?var\/folders\//i;
|
|
41
|
+
const DATA_STORE_TARGET = /\.(?:db|sqlite\d?|mdb|rdb|dump|bak|ldf|mdf|frm|ibd)\b|(?:^|[\s/])(?:data|databases?|db|datastores?|storage|ledger|pgdata|mysql|postgres(?:ql)?|mongo(?:db)?|redis)(?:[\s/-]|$)/i;
|
|
42
|
+
function looksLikeDataStoreDelete(command) {
|
|
43
|
+
if (SQL_WIPE.test(command))
|
|
44
|
+
return true;
|
|
45
|
+
if (THROWAWAY_TARGET.test(command))
|
|
46
|
+
return false;
|
|
47
|
+
return DATA_STORE_TARGET.test(command);
|
|
48
|
+
}
|
|
35
49
|
function commandOf(e) {
|
|
36
50
|
if (e.kind !== "tool_use" || e.toolName !== "Bash")
|
|
37
51
|
return "";
|
|
@@ -166,16 +180,19 @@ export function approvalOccurrences(events, actions, opts = {}) {
|
|
|
166
180
|
const listed = allowListed(command, opts.allow ?? []);
|
|
167
181
|
const noPrompt = (mode && NO_PROMPT_MODES.has(mode)) || listed;
|
|
168
182
|
if (action === "delete") {
|
|
169
|
-
//
|
|
170
|
-
//
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
|
|
183
|
+
// Scope a delete gate to the DATA a data-wipe rule protects. A throwaway
|
|
184
|
+
// `rm -rf /tmp/scratch` (or build/, dist/, node_modules/, .cache/) is not
|
|
185
|
+
// "wiping the database" — it was a real GUARD false alarm (2026-10-02):
|
|
186
|
+
// "Never wipe data storage databases" stopped an unrelated scratch-dir
|
|
187
|
+
// cleanup in auto mode. So an occurrence is produced ONLY when the target
|
|
188
|
+
// looks like a data store (a .db/.sqlite file, a data/ or db/ directory)
|
|
189
|
+
// or the command is SQL (DROP/DELETE FROM/TRUNCATE); anything else yields
|
|
190
|
+
// no occurrence, so the guard never stops a scratch cleanup. A delete
|
|
191
|
+
// gate still NEVER produces a FAIL in `check` (verdict is UNCLEAR) — the
|
|
192
|
+
// transcript can't show a click on the prompt — but the guard may ask.
|
|
193
|
+
if (!looksLikeDataStoreDelete(command))
|
|
194
|
+
continue;
|
|
195
|
+
out.push({ action, command: short, verdict: "unclear", why: "a delete command hit something that looks like a data store; a transcript can't tell whether it was approved" });
|
|
179
196
|
}
|
|
180
197
|
else if (noPrompt) {
|
|
181
198
|
out.push({ action, command: short, verdict: "unapproved", why: listed ? "the command is on the allow list, so no prompt was shown" : `permission mode was ${mode}, so no prompt was shown` });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rulereceipt",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.80",
|
|
4
4
|
"description": "Checks whether your AI coding agent followed your rules, with evidence. Works with Claude Code (Codex in testing); reads CLAUDE.md, AGENTS.md, Cursor, Copilot and Windsurf rules.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|