@codyswann/lisa 4.38.7 → 4.39.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.
- package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +23 -1
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +23 -0
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +30 -1
- package/all/deletions.json +136 -1
- package/cdk/deletions.json +8 -1
- package/dist/core/config.d.ts +33 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/deletion-basis.d.ts +107 -0
- package/dist/core/deletion-basis.d.ts.map +1 -0
- package/dist/core/deletion-basis.js +81 -0
- package/dist/core/deletion-basis.js.map +1 -0
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +6 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +18 -0
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +19 -12
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/parity-safety-net.sh +23 -0
- package/expo/deletions.json +37 -1
- package/harper-fabric/deletions.json +6 -1
- package/nestjs/deletions.json +12 -1
- package/package.json +6 -5
- package/phaser/deletions.json +6 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/parity-safety-net.sh +23 -0
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +23 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +23 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +23 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/parity-safety-net.sh +23 -0
- package/rails/deletions.json +18 -1
- package/scripts/check-deletion-basis.mjs +126 -0
- package/typescript/deletions.json +48 -0
|
@@ -901,6 +901,7 @@ follow_scan() {
|
|
|
901
901
|
redirected=""
|
|
902
902
|
heredoc=0
|
|
903
903
|
stdin_mode=0
|
|
904
|
+
noexec=0
|
|
904
905
|
j=$((i + 1))
|
|
905
906
|
while [ "$j" -lt "$n" ]; do
|
|
906
907
|
follow_unwrap "${toks[j]}"
|
|
@@ -931,13 +932,35 @@ follow_scan() {
|
|
|
931
932
|
*) j=$((j + 1)) ;;
|
|
932
933
|
esac
|
|
933
934
|
;;
|
|
935
|
+
# `-n` is NOEXEC: the shell reads and parses its operand, then exits
|
|
936
|
+
# without running a line of it. So a syntax check is the one shape
|
|
937
|
+
# that puts a path at a command position while provably executing
|
|
938
|
+
# nothing, and following it reads a file the command never runs.
|
|
939
|
+
#
|
|
940
|
+
# This guard hit that on ITSELF: its pattern list is destructive
|
|
941
|
+
# command literals living inside the guard, so `bash -n` on its own
|
|
942
|
+
# source was refused by its own patterns — and the same held for any
|
|
943
|
+
# file documenting destructive commands. See CodySwannGT/lisa#3803.
|
|
944
|
+
#
|
|
945
|
+
# `bash <file>` still executes and is still followed. Noexec is the
|
|
946
|
+
# distinction, not the program: this is not a read-only exemption.
|
|
947
|
+
--noexec) noexec=1; break ;;
|
|
934
948
|
--*) j=$((j + 1)) ;;
|
|
935
949
|
-*c*) inline=1; j=$((j + 1)) ;;
|
|
950
|
+
-*n*) noexec=1; break ;;
|
|
936
951
|
-s | -[a-zA-Z]*s[a-zA-Z]*) stdin_mode=1; j=$((j + 1)) ;;
|
|
937
952
|
-*) j=$((j + 1)) ;;
|
|
938
953
|
*) break ;;
|
|
939
954
|
esac
|
|
940
955
|
done
|
|
956
|
+
if [ "$noexec" -eq 1 ]; then
|
|
957
|
+
# Nothing runs, so there is no script to follow and nothing to fail
|
|
958
|
+
# closed about. Checked before the heredoc and dispatcher arms: those
|
|
959
|
+
# decide WHICH text to read, and here there is no execution at all.
|
|
960
|
+
cmd_pos=0
|
|
961
|
+
i=$((j + 1))
|
|
962
|
+
continue
|
|
963
|
+
fi
|
|
941
964
|
if [ "$heredoc" -eq 1 ] && [ "$inline" -eq 0 ]; then
|
|
942
965
|
cmd_pos=0
|
|
943
966
|
i=$((j + 1))
|
package/rails/deletions.json
CHANGED
|
@@ -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
|
+
}
|
|
@@ -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
|
}
|