@codyswann/lisa 4.38.8 → 4.40.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.
Files changed (82) hide show
  1. package/all/copy-overwrite/scripts/lisa-cross-worktree-guard.mjs +276 -0
  2. package/all/deletions.json +136 -1
  3. package/cdk/deletions.json +8 -1
  4. package/dist/core/config.d.ts +33 -0
  5. package/dist/core/config.d.ts.map +1 -1
  6. package/dist/core/config.js.map +1 -1
  7. package/dist/core/deletion-basis.d.ts +107 -0
  8. package/dist/core/deletion-basis.d.ts.map +1 -0
  9. package/dist/core/deletion-basis.js +81 -0
  10. package/dist/core/deletion-basis.js.map +1 -0
  11. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  12. package/dist/core/lisa-owned-hash-ledger.js +10 -0
  13. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  14. package/dist/core/lisa.d.ts.map +1 -1
  15. package/dist/core/lisa.js +18 -0
  16. package/dist/core/lisa.js.map +1 -1
  17. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  18. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  19. package/dist/core/upstream-evidence-manifest.js +22 -12
  20. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  21. package/expo/deletions.json +37 -1
  22. package/harper-fabric/deletions.json +6 -1
  23. package/nestjs/deletions.json +12 -1
  24. package/npm-package/create-only/.github/workflows/publish-to-npm.yml +48 -19
  25. package/package.json +6 -5
  26. package/phaser/deletions.json +6 -1
  27. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  29. package/plugins/lisa-agy/plugin.json +1 -1
  30. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  33. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-expo-agy/plugin.json +1 -1
  40. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  45. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  50. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  55. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  59. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  60. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails-agy/plugin.json +1 -1
  65. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  70. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  75. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  77. package/rails/deletions.json +18 -1
  78. package/scripts/check-deletion-basis.mjs +126 -0
  79. package/scripts/two-channel-couplings.json +1 -1
  80. package/typescript/copy-contents/.husky/pre-commit +40 -0
  81. package/typescript/copy-overwrite/.prettierignore +1 -0
  82. package/typescript/deletions.json +48 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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": "4.38.8",
3
+ "version": "4.40.0",
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"
@@ -15,5 +15,22 @@
15
15
  ".github/workflows/claude-nightly-test-coverage.yml",
16
16
  ".github/workflows/claude-nightly-test-improvement.yml",
17
17
  ".github/workflows/claude-sync-down-branches.yml"
18
- ]
18
+ ],
19
+ "basis": {
20
+ ".overcommit.yml": "needs-review",
21
+ ".claude/skills/action-controller-best-practices": "needs-review",
22
+ ".claude/skills/action-view-best-practices": "needs-review",
23
+ ".claude/skills/active-record-model-best-practices": "needs-review",
24
+ ".claude/skills/plan-add-test-coverage": "needs-review",
25
+ ".claude/skills/plan-fix-linter-error": "needs-review",
26
+ ".claude/skills/plan-lower-code-complexity": "needs-review",
27
+ ".claude/skills/plan-reduce-max-lines": "needs-review",
28
+ ".claude/skills/plan-reduce-max-lines-per-function": "needs-review",
29
+ ".claude/rules/rails-conventions.md": "needs-review",
30
+ ".github/workflows/claude-code-review-response.yml": "needs-review",
31
+ ".github/workflows/claude-nightly-code-complexity.yml": "needs-review",
32
+ ".github/workflows/claude-nightly-test-coverage.yml": "needs-review",
33
+ ".github/workflows/claude-nightly-test-improvement.yml": "needs-review",
34
+ ".github/workflows/claude-sync-down-branches.yml": "needs-review"
35
+ }
19
36
  }
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Refuse a `deletions.json` that declares a path without saying why it may go.
4
+ *
5
+ * This is the AUTHORING gate. `Lisa.processDeletionsFile` has its own runtime
6
+ * fail-safe that keeps an unclassified path in a consumer's repository; the two
7
+ * are deliberately separate mechanisms. The runtime rule protects a consumer
8
+ * whatever manifest they happen to have, including one authored before either
9
+ * existed. This one stops an unclassified path being written here in the first
10
+ * place, so the manifest cannot silently regrow the problem the moment somebody
11
+ * adds entry 256.
12
+ *
13
+ * Without this, the whole change is a one-time sweep. With it, it is a standing
14
+ * property.
15
+ *
16
+ * Also reports the outstanding `needs-review` count, because that number is the
17
+ * debt this change deliberately took on and it should be visible on every run
18
+ * rather than discovered later.
19
+ *
20
+ * Usage: node scripts/check-deletion-basis.mjs
21
+ * @module scripts/check-deletion-basis
22
+ */
23
+ import { readFileSync } from "node:fs";
24
+ import path from "node:path";
25
+ import { fileURLToPath } from "node:url";
26
+
27
+ const REPO_ROOT = path.resolve(
28
+ path.dirname(fileURLToPath(import.meta.url)),
29
+ ".."
30
+ );
31
+
32
+ const MANIFESTS = [
33
+ "all",
34
+ "typescript",
35
+ "expo",
36
+ "rails",
37
+ "nestjs",
38
+ "cdk",
39
+ "phaser",
40
+ "harper-fabric",
41
+ ];
42
+
43
+ const NEEDS_REVIEW = "needs-review";
44
+ const OWNED = "owned";
45
+ const LEGACY_PREFIX = "legacy:";
46
+
47
+ /**
48
+ * Whether one declared path carries a usable basis.
49
+ *
50
+ * Mirrors `resolveDeletionBasis` in `src/core/deletion-basis.ts`. Kept as plain
51
+ * ESM so this check runs with no build step — a gate that needs `dist/` cannot
52
+ * run in a pre-commit hook on a tree that does not compile.
53
+ * @param {object} manifest - Parsed deletions.json.
54
+ * @param {string} declaredPath - The declared path.
55
+ * @returns {boolean} True when the manifest says why the path may be removed.
56
+ */
57
+ function isClassified(manifest, declaredPath) {
58
+ const forced = manifest.force?.[declaredPath];
59
+ if (typeof forced === "string" && forced.trim() !== "") return true;
60
+ const declared = manifest.basis?.[declaredPath];
61
+ if (typeof declared !== "string") return false;
62
+ const value = declared.trim();
63
+ if (value === NEEDS_REVIEW || value === OWNED) return true;
64
+ // A `legacy` basis with no prose is unclassified in substance: the point of
65
+ // the kind is that somebody wrote down WHY.
66
+ if (value.startsWith(LEGACY_PREFIX))
67
+ return value.slice(LEGACY_PREFIX.length).trim() !== "";
68
+ return false;
69
+ }
70
+
71
+ let unclassified = 0;
72
+ let needsReview = 0;
73
+ let classified = 0;
74
+
75
+ for (const stack of MANIFESTS) {
76
+ const file = path.join(REPO_ROOT, stack, "deletions.json");
77
+ let manifest;
78
+ try {
79
+ manifest = JSON.parse(readFileSync(file, "utf8"));
80
+ } catch (error) {
81
+ if (error.code === "ENOENT") continue;
82
+ console.error(
83
+ `${stack}/deletions.json could not be read: ${error.message}`
84
+ );
85
+ process.exitCode = 1;
86
+ continue;
87
+ }
88
+ const keep = new Set(manifest.keep ?? []);
89
+ for (const declaredPath of manifest.paths ?? []) {
90
+ if (keep.has(declaredPath)) continue;
91
+ if (!isClassified(manifest, declaredPath)) {
92
+ if (unclassified === 0)
93
+ console.error(
94
+ "Declared for deletion with no basis — say why each may be removed:\n"
95
+ );
96
+ console.error(` ${stack}/deletions.json ${declaredPath}`);
97
+ unclassified++;
98
+ continue;
99
+ }
100
+ classified++;
101
+ if (manifest.basis?.[declaredPath]?.trim() === NEEDS_REVIEW) needsReview++;
102
+ }
103
+ }
104
+
105
+ if (unclassified > 0) {
106
+ console.error(
107
+ `\n${unclassified} declared path(s) carry no basis.\n\n` +
108
+ "Add one to that manifest's `basis` map:\n" +
109
+ ' "owned" Lisa installs this path today\n' +
110
+ ' "legacy: <reason>" Lisa shipped it once and no longer does\n' +
111
+ ' "needs-review" declared before the basis field; debt, but countable\n' +
112
+ "or a `force` entry when the removal is a ruling that must reach an edited copy.\n\n" +
113
+ "An unclassified path is KEPT at apply time rather than deleted, so leaving\n" +
114
+ "it unclassified does not merely fail this check — it stops the removal\n" +
115
+ "reaching consumers at all."
116
+ );
117
+ process.exitCode = 1;
118
+ } else {
119
+ console.log(
120
+ `deletion basis: ${classified} declared path(s) classified, of which ${needsReview} still carry \`${NEEDS_REVIEW}\`.`
121
+ );
122
+ if (needsReview > 0)
123
+ console.log(
124
+ ` ${needsReview} reason(s) remain unwritten. Each one replaced by \`legacy: <reason>\` is a path whose removal somebody has justified in writing.`
125
+ );
126
+ }
@@ -7,7 +7,7 @@
7
7
  "workflows": 22,
8
8
  "steps": 716,
9
9
  "couplings": 34,
10
- "inventory": 73
10
+ "inventory": 74
11
11
  },
12
12
  "counts": {
13
13
  "package-backed": 10,
@@ -107,6 +107,46 @@ if [ -f ".lintstagedrc.json" ]; then
107
107
  fi
108
108
  fi
109
109
 
110
+ # ---------------------------------------------------------------------------
111
+ # Cross-worktree staged-blob guard.
112
+ #
113
+ # Refuses a commit that stages a NEW file byte-identical to uncommitted work
114
+ # sitting in a different linked worktree. Where several agents share one
115
+ # repository through worktrees, one agent's in-progress file can be committed
116
+ # by another: the file is real, the branch is real, the commit succeeds and
117
+ # every other gate passes, so nothing reports it. Confirmed once — a 284-line
118
+ # test file staged in one worktree, committed an hour later from elsewhere,
119
+ # byte-identical, under a reworded subject.
120
+ #
121
+ # HERE RATHER THAN IN THE GATE REGISTRY, deliberately. This is a property of
122
+ # the machine — which other worktrees exist and what is sitting in them —
123
+ # not of the project, so there is no task a project could declare to prove it.
124
+ # It also has to run on EVERY commit: the whole failure mode is that nobody
125
+ # notices, so a check that waits to be invoked is a check that was not running
126
+ # on the commit where it mattered.
127
+ #
128
+ # Fails OPEN when the script is missing, unlike the lint-staged preflight
129
+ # above. That preflight guards a tool that reports success for work it did not
130
+ # do, so skipping it cannot be read as a pass. This one only ever adds a
131
+ # refusal — a repository without it is exactly as safe as it was before the
132
+ # guard existed, and blocking every commit in a project that has not yet
133
+ # re-applied templates would be a worse trade than the window it closes.
134
+ # ---------------------------------------------------------------------------
135
+ CROSS_WORKTREE_GUARD="node_modules/@codyswann/lisa/all/copy-overwrite/scripts/lisa-cross-worktree-guard.mjs"
136
+ if [ ! -f "$CROSS_WORKTREE_GUARD" ]; then
137
+ CROSS_WORKTREE_GUARD="scripts/lisa-cross-worktree-guard.mjs"
138
+ fi
139
+ if [ ! -f "$CROSS_WORKTREE_GUARD" ]; then
140
+ CROSS_WORKTREE_GUARD="all/copy-overwrite/scripts/lisa-cross-worktree-guard.mjs"
141
+ fi
142
+ if [ -f "$CROSS_WORKTREE_GUARD" ] && command -v node >/dev/null 2>&1; then
143
+ node "$CROSS_WORKTREE_GUARD"
144
+ CROSS_WORKTREE_GUARD_STATUS=$?
145
+ if [ $CROSS_WORKTREE_GUARD_STATUS -ne 0 ]; then
146
+ exit $CROSS_WORKTREE_GUARD_STATUS
147
+ fi
148
+ fi
149
+
110
150
  # ---------------------------------------------------------------------------
111
151
  # Gate-driven checks.
112
152
  #
@@ -80,6 +80,7 @@ scripts/check-verification-coverage.mjs
80
80
  scripts/classify-maestro-failures.mjs
81
81
  scripts/lisa-command-envelope.mjs
82
82
  scripts/lisa-commit-msg-gates.mjs
83
+ scripts/lisa-cross-worktree-guard.mjs
83
84
  scripts/lisa-destructive-guard.mjs
84
85
  scripts/lisa-environment-prepare.mjs
85
86
  scripts/lisa-floor-collisions.mjs
@@ -59,5 +59,53 @@
59
59
  ".github/workflows/reusable-auto-update-pr-branches.yml": "Removed fleet-wide (CodySwannGT/lisa#3590): it force-updated PR branches with the workflow's own github.token, and GitHub will not start runs from such a push, so required checks went ABSENT at head and pull requests silently stopped becoming mergeable. An edited copy does the same damage, so this removal overrides workflow ownership.",
60
60
  ".github/workflows/reusable-auto-update-pr-branches-dispatch.yml": "Removed fleet-wide (CodySwannGT/lisa#3590): it force-updated PR branches with the workflow's own github.token, and GitHub will not start runs from such a push, so required checks went ABSENT at head and pull requests silently stopped becoming mergeable. An edited copy does the same damage, so this removal overrides workflow ownership.",
61
61
  ".github/workflows/required-checks-drift.yml": "Removed fleet-wide (CodySwannGT/lisa#3599): it read the live ruleset over the GitHub API, which needs administration:read and therefore a personal access token held in a permanent repository secret. An edited copy still asks for that token, so this removal overrides workflow ownership."
62
+ },
63
+ "basis": {
64
+ "jest.config.js": "needs-review",
65
+ ".claude/hooks/install_pkgs.sh": "needs-review",
66
+ ".claude/hooks/format-on-edit.sh": "needs-review",
67
+ ".claude/hooks/install-pkgs.sh": "needs-review",
68
+ ".claude/hooks/lint-on-edit.sh": "needs-review",
69
+ ".claude/hooks/sg-scan-on-edit.sh": "needs-review",
70
+ ".claude/skills/jira-add-journey": "needs-review",
71
+ ".claude/skills/jira-create": "needs-review",
72
+ ".claude/skills/jira-evidence": "needs-review",
73
+ ".claude/skills/jira-journey": "needs-review",
74
+ ".claude/skills/jira-verify": "needs-review",
75
+ ".claude/skills/jsdoc-best-practices": "needs-review",
76
+ "eslint-plugin-code-organization": "needs-review",
77
+ "eslint.base.ts": "needs-review",
78
+ "eslint.typescript.ts": "needs-review",
79
+ "jest.base.ts": "needs-review",
80
+ "jest.typescript.ts": "needs-review",
81
+ "tsconfig.base.json": "needs-review",
82
+ "tsconfig.typescript.json": "needs-review",
83
+ ".github/workflows/quality.yml": "needs-review",
84
+ ".github/workflows/release.yml": "needs-review",
85
+ ".github/workflows/create-issue-on-failure.yml": "needs-review",
86
+ ".github/workflows/create-github-issue-on-failure.yml": "needs-review",
87
+ ".github/workflows/create-jira-issue-on-failure.yml": "needs-review",
88
+ ".github/workflows/create-sentry-issue-on-failure.yml": "needs-review",
89
+ ".github/workflows/reusable-claude.yml": "needs-review",
90
+ ".github/workflows/reusable-claude-ci-auto-fix.yml": "needs-review",
91
+ ".github/workflows/reusable-claude-code-review-response.yml": "needs-review",
92
+ ".github/workflows/reusable-claude-deploy-auto-fix.yml": "needs-review",
93
+ ".github/workflows/reusable-claude-nightly-code-complexity.yml": "needs-review",
94
+ ".github/workflows/reusable-claude-nightly-test-coverage.yml": "needs-review",
95
+ ".github/workflows/reusable-claude-nightly-test-improvement.yml": "needs-review",
96
+ ".github/workflows/load-test.yml": "needs-review",
97
+ ".github/workflows/claude-ci-auto-fix.yml": "needs-review",
98
+ ".github/workflows/claude-code-review-response.yml": "needs-review",
99
+ ".github/workflows/claude-deploy-auto-fix.yml": "needs-review",
100
+ ".github/workflows/claude-nightly-code-complexity.yml": "needs-review",
101
+ ".github/workflows/claude-nightly-test-coverage.yml": "needs-review",
102
+ ".github/workflows/claude-nightly-test-improvement.yml": "needs-review",
103
+ ".github/workflows/claude-sync-down-branches.yml": "needs-review",
104
+ ".github/workflows/claude.yml": "needs-review",
105
+ ".github/workflows/reusable-claude-sync-down-branches.yml": "needs-review",
106
+ ".github/workflows/reusable-claude-nightly-code-complexity-rails.yml": "needs-review",
107
+ ".github/workflows/reusable-claude-nightly-jira-triage.yml": "needs-review",
108
+ ".github/workflows/reusable-claude-nightly-test-coverage-rails.yml": "needs-review",
109
+ ".github/workflows/reusable-claude-nightly-test-improvement-rails.yml": "needs-review"
62
110
  }
63
111
  }