@codyswann/lisa 2.300.7 → 2.300.8

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.
Files changed (74) hide show
  1. package/dist/core/upstream-evidence-manifest.js +10 -10
  2. package/package.json +1 -1
  3. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  4. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  5. package/plugins/lisa/hooks/threshold-ratchet-compare.mjs +1 -27
  6. package/plugins/lisa/hooks/threshold-ratchet-families.mjs +0 -34
  7. package/plugins/lisa/hooks/threshold-ratchet.mjs +5 -2
  8. package/plugins/lisa/hooks/threshold-ratchet.sh +1 -1
  9. package/plugins/lisa-agy/plugin.json +1 -1
  10. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  11. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  12. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  13. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-copilot/hooks/threshold-ratchet-compare.mjs +1 -27
  17. package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +0 -34
  18. package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +5 -2
  19. package/plugins/lisa-copilot/hooks/threshold-ratchet.sh +1 -1
  20. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cursor/hooks/threshold-ratchet-compare.mjs +1 -27
  22. package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +0 -34
  23. package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +5 -2
  24. package/plugins/lisa-cursor/hooks/threshold-ratchet.sh +1 -1
  25. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo-agy/plugin.json +1 -1
  28. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  48. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-rails-agy/plugin.json +1 -1
  53. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  58. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  63. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/src/base/hooks/threshold-ratchet-compare.mjs +1 -27
  66. package/plugins/src/base/hooks/threshold-ratchet-families.mjs +0 -34
  67. package/plugins/src/base/hooks/threshold-ratchet.mjs +5 -2
  68. package/plugins/src/base/hooks/threshold-ratchet.sh +1 -1
  69. package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +5 -2
  70. package/rails/copy-overwrite/scripts/threshold-ratchet-compare.mjs +1 -27
  71. package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +0 -34
  72. package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +5 -2
  73. package/typescript/copy-overwrite/scripts/threshold-ratchet-compare.mjs +1 -27
  74. package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +0 -34
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.300.7",
3
+ "version": "2.300.8",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import {
10
10
  extractAllowEntries,
11
- extractExemptionEntries,
12
11
  extractK6Constraints,
13
12
  extractNumericLeaves,
14
13
  extractRubocopThresholds,
@@ -20,7 +19,7 @@ import {
20
19
 
21
20
  /** Finding type: a numeric bound or boolean gate moved the weakening way. */
22
21
  const TYPE_WEAKENED = "weakened";
23
- /** Finding type: an exemption entry was added (Tier 3). */
22
+ /** Finding type: a gate-shrinking exemption was added (Tier 3). */
24
23
  const TYPE_EXEMPTION_ADDED = "exemption-added";
25
24
  /** Family kind for .lisa.config.json (the thresholdRatchet.allow carrier). */
26
25
  const KIND_ALLOW_LIST = "allow-list";
@@ -160,29 +159,6 @@ function compareK6(relPath, base, current) {
160
159
  return findings;
161
160
  }
162
161
 
163
- /**
164
- * Compare an exemption-list pair (audit ignore files): report added entries.
165
- * @param {string} relPath Repo-relative path
166
- * @param {unknown} base Parsed baseline list
167
- * @param {unknown} current Parsed current list
168
- * @returns {Finding[]} One finding per newly added ignore entry
169
- */
170
- function compareExemptions(relPath, base, current) {
171
- const baseEntries = extractExemptionEntries(base);
172
- const findings = [];
173
- for (const entry of extractExemptionEntries(current)) {
174
- if (!baseEntries.has(entry)) {
175
- findings.push({
176
- file: relPath,
177
- key: entry,
178
- type: TYPE_EXEMPTION_ADDED,
179
- message: `${relPath}: new security-audit ignore entry "${entry}" — ignoring a finding weakens the gate and needs a human's sign-off.`,
180
- });
181
- }
182
- }
183
- return findings;
184
- }
185
-
186
162
  /**
187
163
  * Compare .lisa.config.json allow lists: report added exception entries so a
188
164
  * change can never grant itself an exception.
@@ -258,8 +234,6 @@ export function compareFile(relPath, baselineText, currentText) {
258
234
  return compareStryker(relPath, base, current);
259
235
  case "k6":
260
236
  return compareK6(relPath, base, current);
261
- case "exemption-list":
262
- return compareExemptions(relPath, base, current);
263
237
  case KIND_ALLOW_LIST:
264
238
  return compareAllowList(relPath, base, current);
265
239
  default:
@@ -48,11 +48,6 @@ export const FAMILIES = [
48
48
  match: /(^|\/)\.github\/k6\/thresholds\/[^/]+\.json$/,
49
49
  kind: "k6",
50
50
  },
51
- {
52
- id: "audit-ignore",
53
- match: /(^|\/)audit\.ignore\.(config|local)\.json$/,
54
- kind: "exemption-list",
55
- },
56
51
  {
57
52
  id: "lisa-config",
58
53
  match: /(^|\/)\.lisa\.config\.json$/,
@@ -251,35 +246,6 @@ export function extractK6Constraints(conf) {
251
246
  return { numeric, booleans };
252
247
  }
253
248
 
254
- /**
255
- * Flatten an exemption file (audit ignore list) into a set of entry tokens.
256
- * Arrays contribute their string items; objects contribute their keys.
257
- * @param {unknown} conf Parsed JSON
258
- * @returns {Set<string>} One token per exemption entry
259
- */
260
- export function extractExemptionEntries(conf) {
261
- const out = new Set();
262
- if (Array.isArray(conf)) {
263
- for (const item of conf) {
264
- if (typeof item === "string") out.add(item);
265
- else if (item && typeof item === "object") out.add(JSON.stringify(item));
266
- }
267
- } else if (conf && typeof conf === "object") {
268
- for (const [key, value] of Object.entries(conf)) {
269
- if (Array.isArray(value)) {
270
- for (const item of value) {
271
- out.add(
272
- `${key}:${typeof item === "string" ? item : JSON.stringify(item)}`
273
- );
274
- }
275
- } else {
276
- out.add(key);
277
- }
278
- }
279
- }
280
- return out;
281
- }
282
-
283
249
  /**
284
250
  * Extract thresholdRatchet.allow entries from parsed .lisa.config.json.
285
251
  * @param {unknown} config Parsed config (may be undefined)
@@ -12,8 +12,11 @@
12
12
  * Tier 1 — designed tunables: vitest/jest/simplecov/e2e thresholds
13
13
  * (minimums) and eslint/rubocop thresholds (maximums). Tier 2 — stryker's
14
14
  * break score and k6 expression bounds. Tier 3 — exemption additions
15
- * (audit-ignore entries, stryker mutate exclusions, thresholdRatchet.allow
16
- * entries) which weaken a gate without touching a number.
15
+ * (stryker mutate exclusions, thresholdRatchet.allow entries) which weaken
16
+ * a gate without touching a number. Audit ignore lists are deliberately NOT
17
+ * watched: the security-audit-handling ladder authorizes agents to add
18
+ * documented entries autonomously, and doctor readiness (B5) audits that
19
+ * every entry carries a written decision.
17
20
  *
18
21
  * Human override: `.lisa.config.json` → `thresholdRatchet.allow` entries
19
22
  * ({ file, key, reason }). Honored ONLY from the baseline side (HEAD /
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # PostToolUse hook for Edit|Write|NotebookEdit|Bash: the threshold ratchet.
3
3
  # Quality thresholds (coverage minimums, complexity maximums, mutation break
4
- # score, e2e route floors, k6 bounds, audit-ignore lists) may tighten but never
4
+ # score, e2e route floors, k6 bounds) may tighten but never
5
5
  # weaken. The deterministic comparator lives in threshold-ratchet.mjs and is
6
6
  # shared with the pre-commit (husky/lefthook --staged) and CI (--base) layers,
7
7
  # so this hook is fast feedback — not the only line of defense.
@@ -12,8 +12,11 @@
12
12
  * Tier 1 — designed tunables: vitest/jest/simplecov/e2e thresholds
13
13
  * (minimums) and eslint/rubocop thresholds (maximums). Tier 2 — stryker's
14
14
  * break score and k6 expression bounds. Tier 3 — exemption additions
15
- * (audit-ignore entries, stryker mutate exclusions, thresholdRatchet.allow
16
- * entries) which weaken a gate without touching a number.
15
+ * (stryker mutate exclusions, thresholdRatchet.allow entries) which weaken
16
+ * a gate without touching a number. Audit ignore lists are deliberately NOT
17
+ * watched: the security-audit-handling ladder authorizes agents to add
18
+ * documented entries autonomously, and doctor readiness (B5) audits that
19
+ * every entry carries a written decision.
17
20
  *
18
21
  * Human override: `.lisa.config.json` → `thresholdRatchet.allow` entries
19
22
  * ({ file, key, reason }). Honored ONLY from the baseline side (HEAD /
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import {
10
10
  extractAllowEntries,
11
- extractExemptionEntries,
12
11
  extractK6Constraints,
13
12
  extractNumericLeaves,
14
13
  extractRubocopThresholds,
@@ -20,7 +19,7 @@ import {
20
19
 
21
20
  /** Finding type: a numeric bound or boolean gate moved the weakening way. */
22
21
  const TYPE_WEAKENED = "weakened";
23
- /** Finding type: an exemption entry was added (Tier 3). */
22
+ /** Finding type: a gate-shrinking exemption was added (Tier 3). */
24
23
  const TYPE_EXEMPTION_ADDED = "exemption-added";
25
24
  /** Family kind for .lisa.config.json (the thresholdRatchet.allow carrier). */
26
25
  const KIND_ALLOW_LIST = "allow-list";
@@ -160,29 +159,6 @@ function compareK6(relPath, base, current) {
160
159
  return findings;
161
160
  }
162
161
 
163
- /**
164
- * Compare an exemption-list pair (audit ignore files): report added entries.
165
- * @param {string} relPath Repo-relative path
166
- * @param {unknown} base Parsed baseline list
167
- * @param {unknown} current Parsed current list
168
- * @returns {Finding[]} One finding per newly added ignore entry
169
- */
170
- function compareExemptions(relPath, base, current) {
171
- const baseEntries = extractExemptionEntries(base);
172
- const findings = [];
173
- for (const entry of extractExemptionEntries(current)) {
174
- if (!baseEntries.has(entry)) {
175
- findings.push({
176
- file: relPath,
177
- key: entry,
178
- type: TYPE_EXEMPTION_ADDED,
179
- message: `${relPath}: new security-audit ignore entry "${entry}" — ignoring a finding weakens the gate and needs a human's sign-off.`,
180
- });
181
- }
182
- }
183
- return findings;
184
- }
185
-
186
162
  /**
187
163
  * Compare .lisa.config.json allow lists: report added exception entries so a
188
164
  * change can never grant itself an exception.
@@ -258,8 +234,6 @@ export function compareFile(relPath, baselineText, currentText) {
258
234
  return compareStryker(relPath, base, current);
259
235
  case "k6":
260
236
  return compareK6(relPath, base, current);
261
- case "exemption-list":
262
- return compareExemptions(relPath, base, current);
263
237
  case KIND_ALLOW_LIST:
264
238
  return compareAllowList(relPath, base, current);
265
239
  default:
@@ -48,11 +48,6 @@ export const FAMILIES = [
48
48
  match: /(^|\/)\.github\/k6\/thresholds\/[^/]+\.json$/,
49
49
  kind: "k6",
50
50
  },
51
- {
52
- id: "audit-ignore",
53
- match: /(^|\/)audit\.ignore\.(config|local)\.json$/,
54
- kind: "exemption-list",
55
- },
56
51
  {
57
52
  id: "lisa-config",
58
53
  match: /(^|\/)\.lisa\.config\.json$/,
@@ -251,35 +246,6 @@ export function extractK6Constraints(conf) {
251
246
  return { numeric, booleans };
252
247
  }
253
248
 
254
- /**
255
- * Flatten an exemption file (audit ignore list) into a set of entry tokens.
256
- * Arrays contribute their string items; objects contribute their keys.
257
- * @param {unknown} conf Parsed JSON
258
- * @returns {Set<string>} One token per exemption entry
259
- */
260
- export function extractExemptionEntries(conf) {
261
- const out = new Set();
262
- if (Array.isArray(conf)) {
263
- for (const item of conf) {
264
- if (typeof item === "string") out.add(item);
265
- else if (item && typeof item === "object") out.add(JSON.stringify(item));
266
- }
267
- } else if (conf && typeof conf === "object") {
268
- for (const [key, value] of Object.entries(conf)) {
269
- if (Array.isArray(value)) {
270
- for (const item of value) {
271
- out.add(
272
- `${key}:${typeof item === "string" ? item : JSON.stringify(item)}`
273
- );
274
- }
275
- } else {
276
- out.add(key);
277
- }
278
- }
279
- }
280
- return out;
281
- }
282
-
283
249
  /**
284
250
  * Extract thresholdRatchet.allow entries from parsed .lisa.config.json.
285
251
  * @param {unknown} config Parsed config (may be undefined)
@@ -12,8 +12,11 @@
12
12
  * Tier 1 — designed tunables: vitest/jest/simplecov/e2e thresholds
13
13
  * (minimums) and eslint/rubocop thresholds (maximums). Tier 2 — stryker's
14
14
  * break score and k6 expression bounds. Tier 3 — exemption additions
15
- * (audit-ignore entries, stryker mutate exclusions, thresholdRatchet.allow
16
- * entries) which weaken a gate without touching a number.
15
+ * (stryker mutate exclusions, thresholdRatchet.allow entries) which weaken
16
+ * a gate without touching a number. Audit ignore lists are deliberately NOT
17
+ * watched: the security-audit-handling ladder authorizes agents to add
18
+ * documented entries autonomously, and doctor readiness (B5) audits that
19
+ * every entry carries a written decision.
17
20
  *
18
21
  * Human override: `.lisa.config.json` → `thresholdRatchet.allow` entries
19
22
  * ({ file, key, reason }). Honored ONLY from the baseline side (HEAD /
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import {
10
10
  extractAllowEntries,
11
- extractExemptionEntries,
12
11
  extractK6Constraints,
13
12
  extractNumericLeaves,
14
13
  extractRubocopThresholds,
@@ -20,7 +19,7 @@ import {
20
19
 
21
20
  /** Finding type: a numeric bound or boolean gate moved the weakening way. */
22
21
  const TYPE_WEAKENED = "weakened";
23
- /** Finding type: an exemption entry was added (Tier 3). */
22
+ /** Finding type: a gate-shrinking exemption was added (Tier 3). */
24
23
  const TYPE_EXEMPTION_ADDED = "exemption-added";
25
24
  /** Family kind for .lisa.config.json (the thresholdRatchet.allow carrier). */
26
25
  const KIND_ALLOW_LIST = "allow-list";
@@ -160,29 +159,6 @@ function compareK6(relPath, base, current) {
160
159
  return findings;
161
160
  }
162
161
 
163
- /**
164
- * Compare an exemption-list pair (audit ignore files): report added entries.
165
- * @param {string} relPath Repo-relative path
166
- * @param {unknown} base Parsed baseline list
167
- * @param {unknown} current Parsed current list
168
- * @returns {Finding[]} One finding per newly added ignore entry
169
- */
170
- function compareExemptions(relPath, base, current) {
171
- const baseEntries = extractExemptionEntries(base);
172
- const findings = [];
173
- for (const entry of extractExemptionEntries(current)) {
174
- if (!baseEntries.has(entry)) {
175
- findings.push({
176
- file: relPath,
177
- key: entry,
178
- type: TYPE_EXEMPTION_ADDED,
179
- message: `${relPath}: new security-audit ignore entry "${entry}" — ignoring a finding weakens the gate and needs a human's sign-off.`,
180
- });
181
- }
182
- }
183
- return findings;
184
- }
185
-
186
162
  /**
187
163
  * Compare .lisa.config.json allow lists: report added exception entries so a
188
164
  * change can never grant itself an exception.
@@ -258,8 +234,6 @@ export function compareFile(relPath, baselineText, currentText) {
258
234
  return compareStryker(relPath, base, current);
259
235
  case "k6":
260
236
  return compareK6(relPath, base, current);
261
- case "exemption-list":
262
- return compareExemptions(relPath, base, current);
263
237
  case KIND_ALLOW_LIST:
264
238
  return compareAllowList(relPath, base, current);
265
239
  default:
@@ -48,11 +48,6 @@ export const FAMILIES = [
48
48
  match: /(^|\/)\.github\/k6\/thresholds\/[^/]+\.json$/,
49
49
  kind: "k6",
50
50
  },
51
- {
52
- id: "audit-ignore",
53
- match: /(^|\/)audit\.ignore\.(config|local)\.json$/,
54
- kind: "exemption-list",
55
- },
56
51
  {
57
52
  id: "lisa-config",
58
53
  match: /(^|\/)\.lisa\.config\.json$/,
@@ -251,35 +246,6 @@ export function extractK6Constraints(conf) {
251
246
  return { numeric, booleans };
252
247
  }
253
248
 
254
- /**
255
- * Flatten an exemption file (audit ignore list) into a set of entry tokens.
256
- * Arrays contribute their string items; objects contribute their keys.
257
- * @param {unknown} conf Parsed JSON
258
- * @returns {Set<string>} One token per exemption entry
259
- */
260
- export function extractExemptionEntries(conf) {
261
- const out = new Set();
262
- if (Array.isArray(conf)) {
263
- for (const item of conf) {
264
- if (typeof item === "string") out.add(item);
265
- else if (item && typeof item === "object") out.add(JSON.stringify(item));
266
- }
267
- } else if (conf && typeof conf === "object") {
268
- for (const [key, value] of Object.entries(conf)) {
269
- if (Array.isArray(value)) {
270
- for (const item of value) {
271
- out.add(
272
- `${key}:${typeof item === "string" ? item : JSON.stringify(item)}`
273
- );
274
- }
275
- } else {
276
- out.add(key);
277
- }
278
- }
279
- }
280
- return out;
281
- }
282
-
283
249
  /**
284
250
  * Extract thresholdRatchet.allow entries from parsed .lisa.config.json.
285
251
  * @param {unknown} config Parsed config (may be undefined)