@codyswann/lisa 4.70.4 → 4.71.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/automation-provenance-contract.mjs +174 -0
- package/all/copy-overwrite/scripts/lib/automation-provenance-local.mjs +279 -0
- package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +17 -7
- package/all/copy-overwrite/scripts/lib/github-attestation-provider.mjs +241 -0
- package/all/copy-overwrite/scripts/lib/github-attestation-recovery.mjs +283 -0
- package/all/copy-overwrite/scripts/lib/github-attestation-verifier.mjs +244 -0
- package/all/copy-overwrite/scripts/lib/npm-update-allocate.mjs +289 -0
- package/all/copy-overwrite/scripts/lib/npm-update-authorization.mjs +235 -0
- package/all/copy-overwrite/scripts/lib/npm-update-broker-client.mjs +92 -0
- package/all/copy-overwrite/scripts/lib/npm-update-checkpoint.mjs +241 -0
- package/all/copy-overwrite/scripts/lib/npm-update-contract.mjs +278 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-broker.mjs +234 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-factory.mjs +278 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-recipe.mjs +135 -0
- package/all/copy-overwrite/scripts/lib/npm-update-execution-adapter.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-hooks.mjs +214 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-install.mjs +267 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-proof.mjs +99 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate.mjs +300 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-dispatch.mjs +182 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-grants.mjs +156 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-requests.mjs +221 -0
- package/all/copy-overwrite/scripts/lib/npm-update-github.mjs +214 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper-graph.mjs +238 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper-inventory.mjs +126 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-installation.mjs +116 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-preload.mjs +153 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-provider.mjs +207 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-read-client.mjs +164 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hosted-gate.mjs +272 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hosted-hook.mjs +157 -0
- package/all/copy-overwrite/scripts/lib/npm-update-invariants.mjs +28 -0
- package/all/copy-overwrite/scripts/lib/npm-update-isolation.mjs +11 -0
- package/all/copy-overwrite/scripts/lib/npm-update-leaf-contract.mjs +171 -0
- package/all/copy-overwrite/scripts/lib/npm-update-leaf.mjs +194 -0
- package/all/copy-overwrite/scripts/lib/npm-update-native-process.mjs +155 -0
- package/all/copy-overwrite/scripts/lib/npm-update-npm.mjs +190 -0
- package/all/copy-overwrite/scripts/lib/npm-update-object.mjs +112 -0
- package/all/copy-overwrite/scripts/lib/npm-update-orchestrator.mjs +273 -0
- package/all/copy-overwrite/scripts/lib/npm-update-owner.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-prepare.mjs +263 -0
- package/all/copy-overwrite/scripts/lib/npm-update-process-core.mjs +179 -0
- package/all/copy-overwrite/scripts/lib/npm-update-process.mjs +16 -0
- package/all/copy-overwrite/scripts/lib/npm-update-publication.mjs +258 -0
- package/all/copy-overwrite/scripts/lib/npm-update-publish.mjs +258 -0
- package/all/copy-overwrite/scripts/lib/npm-update-quality.mjs +153 -0
- package/all/copy-overwrite/scripts/lib/npm-update-recovery.mjs +264 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-archive.mjs +204 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-graph.mjs +185 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-transport.mjs +221 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime.mjs +284 -0
- package/all/copy-overwrite/scripts/lib/npm-update-tool-launcher.mjs +287 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-environment.mjs +161 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-inspection.mjs +142 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-lifecycle.mjs +256 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-policy.mjs +266 -0
- package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +230 -36
- package/all/copy-overwrite/scripts/lisa-automation-provenance.mjs +161 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +89 -5
- package/all/copy-overwrite/scripts/lisa-npm-updater.mjs +204 -0
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +48 -123
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +107 -41
- package/all/copy-overwrite/scripts/npm-updater-gate-runtime.json +1 -0
- package/all/copy-overwrite/scripts/npm-updater-gate-supervisor.c +121 -0
- package/all/copy-overwrite/scripts/npm-updater-gate.Dockerfile +49 -0
- package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +1085 -0
- package/dist/codex/scripts/block-no-verify.sh +89 -5
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +598 -0
- package/dist/core/lisa-owned-hash-ledger.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 +157 -11
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/block-no-verify.sh +89 -5
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/lisa/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +89 -5
- 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/block-no-verify.sh +89 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +89 -5
- 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/block-no-verify.agy.sh +89 -5
- package/plugins/src/base/hooks/block-no-verify.sh +89 -5
- package/scripts/check-shipped-surface-removals.mjs +96 -24
- package/scripts/generate-npm-updater-helper-graph.mjs +184 -0
- package/scripts/two-channel-couplings.json +31 -7
- package/typescript/copy-contents/.husky/commit-msg +18 -0
- package/typescript/copy-overwrite/.prettierignore +2 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** Reproduce the updater's fixed source graph from actual bounded bytes; this grants no runtime authority. */
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { lstatSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { isBuiltin } from "node:module";
|
|
7
|
+
import { dirname, join, posix, resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { __debug } from "prettier";
|
|
10
|
+
import { invokedAsScript } from "./lib/invoked-as-script.mjs";
|
|
11
|
+
import {
|
|
12
|
+
managedTemplateMembers,
|
|
13
|
+
validateHelperManifest,
|
|
14
|
+
auditControllerClosure,
|
|
15
|
+
helperManifest,
|
|
16
|
+
} from "../all/copy-overwrite/scripts/lib/npm-update-helper-graph.mjs";
|
|
17
|
+
import {
|
|
18
|
+
HELPER_CONTROLS,
|
|
19
|
+
HELPER_PACKAGE_MEMBERS,
|
|
20
|
+
} from "../all/copy-overwrite/scripts/lib/npm-update-helper-inventory.mjs";
|
|
21
|
+
|
|
22
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
23
|
+
const OUTPUT = "all/copy-overwrite/scripts/npm-updater-helper-graph.json";
|
|
24
|
+
|
|
25
|
+
/** Source coordinates bind exceptional nonliteral import handling to exactly the existing canonical expression. */
|
|
26
|
+
function sourceSpan(text, node) {
|
|
27
|
+
assert(
|
|
28
|
+
Number.isSafeInteger(node.start) && Number.isSafeInteger(node.end),
|
|
29
|
+
"genuine AST source coordinates required"
|
|
30
|
+
);
|
|
31
|
+
return text.slice(node.start, node.end).replace(/\s/g, "");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function addEdges(node, member, text, target, result) {
|
|
35
|
+
if (
|
|
36
|
+
[
|
|
37
|
+
"ImportDeclaration",
|
|
38
|
+
"ExportNamedDeclaration",
|
|
39
|
+
"ExportAllDeclaration",
|
|
40
|
+
].includes(node.type) &&
|
|
41
|
+
node.source
|
|
42
|
+
)
|
|
43
|
+
result.staticImports.push(target(node.source.value));
|
|
44
|
+
const dynamic =
|
|
45
|
+
node.type === "ImportExpression"
|
|
46
|
+
? node.source
|
|
47
|
+
: node.type === "CallExpression" && node.callee?.type === "Import"
|
|
48
|
+
? node.arguments?.[0]
|
|
49
|
+
: undefined;
|
|
50
|
+
if (dynamic) {
|
|
51
|
+
if (["StringLiteral", "Literal"].includes(dynamic.type))
|
|
52
|
+
result.dynamicImports.push(target(dynamic.value));
|
|
53
|
+
else {
|
|
54
|
+
assert(
|
|
55
|
+
member === "lib/npm-update-helper.mjs" &&
|
|
56
|
+
sourceSpan(text, node) ===
|
|
57
|
+
"import(pathToFileURL(join(owner.root,MEMBERS[0])).href)",
|
|
58
|
+
"unqualified nonliteral helper import"
|
|
59
|
+
);
|
|
60
|
+
result.dynamicImports.push(
|
|
61
|
+
"package/plugins/lisa/scripts/intake-blocker-reprobe.mjs"
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const child = node.arguments?.[0],
|
|
66
|
+
base = node.arguments?.[1];
|
|
67
|
+
if (
|
|
68
|
+
node.type === "NewExpression" &&
|
|
69
|
+
node.callee?.name === "URL" &&
|
|
70
|
+
["StringLiteral", "Literal"].includes(child?.type) &&
|
|
71
|
+
typeof child.value === "string" &&
|
|
72
|
+
base &&
|
|
73
|
+
sourceSpan(text, base) === "import.meta.url"
|
|
74
|
+
)
|
|
75
|
+
result.children.push(target(child.value));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The genuine parser supplies all imports and canonical URL children without evaluating member code. */
|
|
79
|
+
export async function auditedHelperEdges(member, bytes) {
|
|
80
|
+
const text = new TextDecoder("utf8", { fatal: true }).decode(bytes);
|
|
81
|
+
const result = { staticImports: [], dynamicImports: [], children: [] };
|
|
82
|
+
const target = specifier =>
|
|
83
|
+
isBuiltin(specifier)
|
|
84
|
+
? specifier.startsWith("node:")
|
|
85
|
+
? specifier
|
|
86
|
+
: `node:${specifier}`
|
|
87
|
+
: posix.normalize(posix.join(posix.dirname(member), specifier));
|
|
88
|
+
const visited = new WeakSet();
|
|
89
|
+
const visit = value => {
|
|
90
|
+
if (!value || typeof value !== "object" || visited.has(value)) return;
|
|
91
|
+
visited.add(value);
|
|
92
|
+
addEdges(value, member, text, target, result);
|
|
93
|
+
for (const [key, child] of Object.entries(value))
|
|
94
|
+
if (!["comments", "tokens", "loc", "extra"].includes(key)) {
|
|
95
|
+
if (Array.isArray(child)) child.forEach(visit);
|
|
96
|
+
else visit(child);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
if (member.endsWith(".mjs"))
|
|
100
|
+
visit((await __debug.parse(text, { parser: "babel" })).ast);
|
|
101
|
+
if (member === "lisa-rails-prepush.mjs") {
|
|
102
|
+
assert(
|
|
103
|
+
text.includes('const name = "lisa-work-item.mjs";') &&
|
|
104
|
+
text.includes("[join(scripts, name), ...args]"),
|
|
105
|
+
"canonical Rails child declaration changed"
|
|
106
|
+
);
|
|
107
|
+
result.children.push("lisa-work-item.mjs");
|
|
108
|
+
}
|
|
109
|
+
for (const field of Object.keys(result))
|
|
110
|
+
result[field] = [...new Set(result[field])].sort((a, b) =>
|
|
111
|
+
a.localeCompare(b)
|
|
112
|
+
);
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Read only fixed current source files. Missing packaged members, aliases and oversized files refuse. */
|
|
117
|
+
function sourceBytes(root, file) {
|
|
118
|
+
const path = join(root, file),
|
|
119
|
+
stat = lstatSync(path);
|
|
120
|
+
assert(
|
|
121
|
+
path === realpathSync(path) &&
|
|
122
|
+
stat.isFile() &&
|
|
123
|
+
!stat.isSymbolicLink() &&
|
|
124
|
+
stat.size <= 1_048_576,
|
|
125
|
+
"helper source is missing, aliased or unbounded"
|
|
126
|
+
);
|
|
127
|
+
const bytes = readFileSync(path);
|
|
128
|
+
assert(bytes.length <= 1_048_576, "helper source grew beyond bound");
|
|
129
|
+
return bytes;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Independent controls omit self-inclusive hashes; runtime callers still authenticate them from the pinned owner. */
|
|
133
|
+
export async function generatedHelperGraph(root = ROOT) {
|
|
134
|
+
const inventory = new Map([
|
|
135
|
+
...managedTemplateMembers(),
|
|
136
|
+
...HELPER_PACKAGE_MEMBERS.map(member => [
|
|
137
|
+
member,
|
|
138
|
+
member.slice("package/".length),
|
|
139
|
+
]),
|
|
140
|
+
]);
|
|
141
|
+
const manifest = { version: 1, controls: {}, members: {} },
|
|
142
|
+
authenticated = new Map();
|
|
143
|
+
for (const [member, file] of [...inventory].sort(([a], [b]) =>
|
|
144
|
+
a.localeCompare(b)
|
|
145
|
+
)) {
|
|
146
|
+
const bytes = sourceBytes(root, file),
|
|
147
|
+
edges = await auditedHelperEdges(member, bytes);
|
|
148
|
+
authenticated.set(member, bytes);
|
|
149
|
+
if (HELPER_CONTROLS.includes(member)) manifest.controls[member] = edges;
|
|
150
|
+
else
|
|
151
|
+
manifest.members[member] = {
|
|
152
|
+
sha256: createHash("sha256").update(bytes).digest("hex"),
|
|
153
|
+
...edges,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
validateHelperManifest(manifest);
|
|
157
|
+
auditControllerClosure(manifest, authenticated);
|
|
158
|
+
const bytes = Buffer.from(`${JSON.stringify(manifest, null, 2)}\n`);
|
|
159
|
+
helperManifest(bytes);
|
|
160
|
+
return bytes;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function main() {
|
|
164
|
+
assert(
|
|
165
|
+
process.argv.length <= 3 &&
|
|
166
|
+
(process.argv[2] === undefined || process.argv[2] === "--check"),
|
|
167
|
+
"usage: generate-npm-updater-helper-graph.mjs [--check]"
|
|
168
|
+
);
|
|
169
|
+
const bytes = await generatedHelperGraph();
|
|
170
|
+
if (process.argv[2] === "--check")
|
|
171
|
+
assert(
|
|
172
|
+
readFileSync(join(ROOT, OUTPUT)).equals(bytes),
|
|
173
|
+
"updater helper graph is stale; regenerate it"
|
|
174
|
+
);
|
|
175
|
+
else writeFileSync(join(ROOT, OUTPUT), bytes);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (invokedAsScript(import.meta.url))
|
|
179
|
+
main().catch(error => {
|
|
180
|
+
process.stderr.write(
|
|
181
|
+
`updater helper graph generation failed: ${error.message}\n`
|
|
182
|
+
);
|
|
183
|
+
process.exitCode = 1;
|
|
184
|
+
});
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"quality.yml::scripts/generate-nightly-e2e-guard-certificate.mjs": "Lisa-source-only branch. Both reusable jobs require `github.repository == 'CodySwannGT/lisa'` before the step can start, and the run body repeats that exact repository guard before checking this artifact path. Ordinary and private host callers therefore skip the step without reading or fetching from their own tree. The scoped branch fetches only the immutable refs needed to behavior-test Lisa's own retained certificate inputs. Ratified because the caller-tree read is unreachable outside this repository, not because an undelivered host dependency is tolerated."
|
|
5
5
|
},
|
|
6
6
|
"staleness": {
|
|
7
|
+
"npm-updater.yml::scripts/lisa-npm-updater.mjs": {
|
|
8
|
+
"decision": "warranted",
|
|
9
|
+
"reason": "Verdict-bearing producer delivered through full Lisa apply, while the reusable workflow is independently pinned by its caller. Exact parent checkout, committed policy and authenticated helper hashes bind the installed producer closure, but do not establish agreement between that closure and this workflow's phase/artifact interface. A superseded installed producer can interpret an independently updated workflow differently. A workflow-to-producer contract handshake is warranted; the obligation is recorded without claiming that npm version selection or helper byte authentication already supplies one."
|
|
10
|
+
},
|
|
7
11
|
"history-secrets.yml::scripts/lib/history-secret-policy.mjs": {
|
|
8
12
|
"decision": "warranted",
|
|
9
13
|
"reason": "Verdict-bearing required route delivered through full Lisa apply. An absent policy helper fails its import with static actionable guidance; the existence test chooses the emitted or Lisa-source directory and does not measure age. A successful historyPolicy import and required builtin resolution establish capability only. Neither the reusable workflow's contract major nor the pinned Gitleaks binary checksum/version establishes the installed policy/range helper's contract version. A superseded helper could interpret the declaration or required facade differently, so an artifact version handshake is warranted and remains an open obligation rather than a claimed handshake or exemption."
|
|
@@ -98,14 +102,14 @@
|
|
|
98
102
|
}
|
|
99
103
|
},
|
|
100
104
|
"inspected": {
|
|
101
|
-
"workflows":
|
|
102
|
-
"steps":
|
|
103
|
-
"couplings":
|
|
104
|
-
"inventory":
|
|
105
|
+
"workflows": 25,
|
|
106
|
+
"steps": 797,
|
|
107
|
+
"couplings": 35,
|
|
108
|
+
"inventory": 159
|
|
105
109
|
},
|
|
106
110
|
"counts": {
|
|
107
111
|
"package-backed": 10,
|
|
108
|
-
"apply-lagged":
|
|
112
|
+
"apply-lagged": 23,
|
|
109
113
|
"never-delivered": 0,
|
|
110
114
|
"undelivered": 2
|
|
111
115
|
},
|
|
@@ -113,13 +117,13 @@
|
|
|
113
117
|
"version-handshake": 4,
|
|
114
118
|
"capability-probe": 0,
|
|
115
119
|
"existence-only": 5,
|
|
116
|
-
"no-probe":
|
|
120
|
+
"no-probe": 14,
|
|
117
121
|
"unchecked": 2
|
|
118
122
|
},
|
|
119
123
|
"decisionCounts": {
|
|
120
124
|
"handshake": 4,
|
|
121
125
|
"not-needed": 11,
|
|
122
|
-
"warranted":
|
|
126
|
+
"warranted": 10
|
|
123
127
|
},
|
|
124
128
|
"couplings": [
|
|
125
129
|
{
|
|
@@ -319,6 +323,26 @@
|
|
|
319
323
|
],
|
|
320
324
|
"detail": "`nightly-e2e-tracking.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/reconcile-nightly-e2e-tracking.mjs` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (typescript/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text carries none of the tokens this scan can see (`else-branch`, `exit-zero`, `exit-nonzero`, `error-annotation`, `notice-annotation`, `failure-suppression`), which is a statement about those names and not about the step's behaviour. STALENESS (a separate dimension from the delivery verdict above): `no-probe`. Neither an existence test nor a version probe bears on this read, so nothing here distinguishes a current artifact from an absent or a superseded one. None of the staleness tokens this scan can see (`artifact-declares-version`, `artifact-answers-version`, `step-requests-version`, `workflow-requests-version`) were found."
|
|
321
325
|
},
|
|
326
|
+
{
|
|
327
|
+
"key": "npm-updater.yml::scripts/lisa-npm-updater.mjs",
|
|
328
|
+
"workflow": "npm-updater.yml",
|
|
329
|
+
"path": "scripts/lisa-npm-updater.mjs",
|
|
330
|
+
"channel": "apply",
|
|
331
|
+
"verdict": "apply-lagged",
|
|
332
|
+
"remedy": "run-lisa-apply",
|
|
333
|
+
"guarded": false,
|
|
334
|
+
"handling": [
|
|
335
|
+
"exit-nonzero"
|
|
336
|
+
],
|
|
337
|
+
"detection": "no-probe",
|
|
338
|
+
"stalenessSignals": [],
|
|
339
|
+
"decision": "warranted",
|
|
340
|
+
"reason": "Verdict-bearing producer delivered through full Lisa apply, while the reusable workflow is independently pinned by its caller. Exact parent checkout, committed policy and authenticated helper hashes bind the installed producer closure, but do not establish agreement between that closure and this workflow's phase/artifact interface. A superseded installed producer can interpret an independently updated workflow differently. A workflow-to-producer contract handshake is warranted; the obligation is recorded without claiming that npm version selection or helper byte authentication already supplies one.",
|
|
341
|
+
"lanes": [
|
|
342
|
+
"all/copy-overwrite"
|
|
343
|
+
],
|
|
344
|
+
"detail": "`npm-updater.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/lisa-npm-updater.mjs` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (all/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text does carry `exit-nonzero` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `no-probe`. Neither an existence test nor a version probe bears on this read, so nothing here distinguishes a current artifact from an absent or a superseded one. None of the staleness tokens this scan can see (`artifact-declares-version`, `artifact-answers-version`, `step-requests-version`, `workflow-requests-version`) were found."
|
|
345
|
+
},
|
|
322
346
|
{
|
|
323
347
|
"key": "publish-to-npm.yml::scripts/check-npm-publish-landed.mjs",
|
|
324
348
|
"workflow": "publish-to-npm.yml",
|
|
@@ -119,6 +119,24 @@ if [ $? -ne 0 ]; then
|
|
|
119
119
|
exit 1
|
|
120
120
|
fi
|
|
121
121
|
|
|
122
|
+
# A present automation reference is checked after the ordinary gates. It never
|
|
123
|
+
# waives tracking or commitlint, and malformed proof cannot fall through to AI.
|
|
124
|
+
if grep -qiE '^[[:space:]]*Automation-Provenance[[:space:]]*:' "$COMMIT_MSG_FILE"; then
|
|
125
|
+
AUTOMATION_SCRIPT="node_modules/@codyswann/lisa/all/copy-overwrite/scripts/lisa-automation-provenance.mjs"
|
|
126
|
+
if [ ! -f "$AUTOMATION_SCRIPT" ]; then
|
|
127
|
+
AUTOMATION_SCRIPT="scripts/lisa-automation-provenance.mjs"
|
|
128
|
+
fi
|
|
129
|
+
if [ ! -f "$AUTOMATION_SCRIPT" ]; then
|
|
130
|
+
AUTOMATION_SCRIPT="all/copy-overwrite/scripts/lisa-automation-provenance.mjs"
|
|
131
|
+
fi
|
|
132
|
+
if [ ! -f "$AUTOMATION_SCRIPT" ] || ! node "$AUTOMATION_SCRIPT" "$COMMIT_MSG_FILE"; then
|
|
133
|
+
echo "❌ Commit blocked: invalid automation provenance."
|
|
134
|
+
exit 1
|
|
135
|
+
fi
|
|
136
|
+
echo "Authenticated non-AI automation provenance verified."
|
|
137
|
+
exit 0
|
|
138
|
+
fi
|
|
139
|
+
|
|
122
140
|
# Check for Co-Authored-By line (skip for merge commits)
|
|
123
141
|
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
124
142
|
# `printf '%s\n'`, never `echo "$COMMIT_MSG"`. Under a POSIX/XSI `echo` the
|
|
@@ -89,6 +89,8 @@ scripts/lisa-gates.mjs
|
|
|
89
89
|
scripts/lisa-history-secrets.mjs
|
|
90
90
|
scripts/lisa-lint-staged-preflight.mjs
|
|
91
91
|
scripts/lisa-mutation.mjs
|
|
92
|
+
scripts/lisa-automation-provenance.mjs
|
|
93
|
+
scripts/lisa-npm-updater.mjs
|
|
92
94
|
scripts/lisa-postinstall.mjs
|
|
93
95
|
scripts/lisa-rails-prepush.mjs
|
|
94
96
|
scripts/lisa-reconcile-policy.mjs
|