@@ -18,6 +18,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
1919## [ Unreleased]
2020
21+ ## [ 1.17.0] - 2026-05-21
22+
23+ ### Added
24+ - ** Six new ` inline-db-mutation-* ` rules extending the scripts-not-DB
25+ discipline (` feedback_scripts_not_db.md ` ) beyond Moodle/SSH to every DB
26+ CLI.** The pre-existing ` ssh-db-mutation ` rule only caught
27+ ` gcloud compute ssh ... --command= ` with Moodle-flavoured payloads
28+ (` mdl_ ` , ` scorm_ ` , ` php -r ` ). This release blocks inline mutations
29+ across the full surface a developer is likely to reach for:
30+ - ` inline-db-mutation-mysql ` — ` mysql -e "UPDATE/DELETE/..." ` ,
31+ ` mysql ... < file.sql ` , ` mysqldump ... | mysql ... ` .
32+ - ` inline-db-mutation-psql ` — `psql -c "UPDATE/INSERT/ALTER/CREATE/
33+ GRANT/REVOKE/REPLACE/RENAME"` and ` pg_restore`. Complements the
34+ existing ` destructive-db-ops ` rule (which already covers DROP /
35+ TRUNCATE / DELETE FROM via psql).
36+ - ` inline-db-mutation-sqlite ` — ` sqlite3 path "<mutation>" ` .
37+ - ` inline-db-mutation-mongo ` — `mongo|mongosh --eval "db.x.<mutating
38+ method>(...)"` and ` mongorestore`.
39+ - ` inline-db-mutation-redis ` — `redis-cli SET / DEL / FLUSHDB /
40+ FLUSHALL / HSET / HDEL / SADD / SREM / LPUSH / RPUSH / ZADD / ZREM /
41+ EXPIRE / RENAME / MSET / SETEX / SETNX / INCR / DECR / COPY / MOVE /
42+ UNLINK / RESTORE / EVAL`.
43+ - ` inline-db-mutation-gcloud-sql ` — ` gcloud sql import sql|csv|bak ` and
44+ ` gcloud sql export sql|csv|bak ` (export blocked because PII-bearing
45+ prod exports also belong in versioned scripts).
46+ - ** Shared bypass marker ` db-mutation-rule ` ** across all six rules. A single
47+ consistent escape token keeps the muscle memory cheap.
48+ - ** Per-repo escape hatch via ` disable_if_repo_file ` .** New optional rule
49+ schema field: when present, the rule no-ops if a sentinel file with
50+ that exact name exists in the cwd. The inline-DB-mutation family ships
51+ with ` disable_if_repo_file: .no-make-no-mistakes-db-mutation ` , so a
52+ repo whose entire job is inline DB work can opt out with a one-liner
53+ (` touch .no-make-no-mistakes-db-mutation ` ). Hardened path validation
54+ (filename must match ` ^[a-zA-Z0-9._-]+$ ` , cannot be ` . ` / ` .. ` ) prevents
55+ the runtime lookup from escaping the cwd.
56+
57+ ### Changed
58+ - ` hooks/lib/eval-rule.sh ` honours ` disable_if_repo_file ` between the
59+ bypass-marker check and the match-condition loop.
60+ - ` scripts/build-rules.mjs ` validates the new field's shape at build time
61+ (same kebab-validation defense-in-depth as ` bypass_marker ` ).
62+ - ` hooks/rules/README.md ` documents the new field and the per-repo escape
63+ hatch pattern. README.md "Hooks" section now lists the six rules and
64+ the bypass marker.
65+
66+ ### Notes
67+ - 38 rules total (was 32). 262 / 262 tests pass (210 baseline + 52 new).
68+ - SELECT-only reads (` SELECT ` , ` SHOW ` , ` DESCRIBE ` , ` EXPLAIN ` , ` KEYS ` ,
69+ ` GET ` , ` .find ` , ` .aggregate ` , ...) remain allowed inline. The rules
70+ only fire on the mutation keyword set per CLI tool.
71+ - Commands that START with ` ./scripts/ ` , ` bash scripts/ ` , ` ./bin/ ` , or
72+ ` bash bin/ ` are exempted via ` not_pattern ` — the principle is
73+ "versioned scripts: yes; inline one-shots: no". When a wrapper script
74+ is the invocation surface, the sensitive payload lives in git history.
75+ - Memory ref: ` feedback_scripts_not_db.md ` (already existed for the
76+ Moodle-flavoured ` ssh-db-mutation ` rule; this release simply expands
77+ the enforcement surface).
78+
2179## [ 1.16.0] - 2026-05-20
2280
2381### Added
0 commit comments