@codyswann/lisa 4.57.1 → 4.57.3
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/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +4 -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 +3 -2
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/copy-overwrite/scripts/classify-maestro-failures.mjs +66 -14
- 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-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-cursor/.claude-plugin/plugin.json +1 -1
- 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/scripts/two-channel-couplings.json +7 -5
|
@@ -626,7 +626,7 @@ function countOccurrences(haystack, needle) {
|
|
|
626
626
|
|
|
627
627
|
/**
|
|
628
628
|
* Tally every marker across a run's debug artifacts, per flow.
|
|
629
|
-
* @param {
|
|
629
|
+
* @param {Iterable<{path: string, text: string}>} artifacts - Debug artifacts, iterated once
|
|
630
630
|
* @param {readonly {flow: string, keys: readonly string[]}[]} flowKeys - Flows in the report
|
|
631
631
|
* @param {readonly string[]} markers - Markers to count
|
|
632
632
|
* @returns {{perFlow: Map<string, object>, unattributed: object}} Tallies
|
|
@@ -723,20 +723,72 @@ export function deviceVerdict(tallies, baselines, markers) {
|
|
|
723
723
|
* Absence is normal and silent: a run that crashed before Maestro started, or a
|
|
724
724
|
* caller that has not wired the flag, simply yields no evidence — and with no
|
|
725
725
|
* evidence nothing is ever a device fault.
|
|
726
|
+
*
|
|
727
|
+
* LAZY, and that is load-bearing rather than a micro-optimisation. This used to
|
|
728
|
+
* build an array holding every file's text at once. A real iOS debug tree is
|
|
729
|
+
* 3.5 GB across 540 files — `device-simulator.log` alone reaches 235 MB for a
|
|
730
|
+
* single flow — so the array exhausted the V8 heap and the classifier died with
|
|
731
|
+
* `FATAL ERROR: Reached heap limit` inside `fs.readFileSync`. Measured on a
|
|
732
|
+
* 44-flow iOS leg, 2026-09-11.
|
|
733
|
+
*
|
|
734
|
+
* That crash was invisible: the workflow used `|| true` and `exit 0`
|
|
735
|
+
* so the classifier could never fail the job — deliberately, and the
|
|
736
|
+
* suite beside this file pins that — and the docblock above says absence of
|
|
737
|
+
* evidence is normal. So an OOM produces exactly the observable of a run with
|
|
738
|
+
* nothing to classify. On the measured run, the leg's ONE failure was a
|
|
739
|
+
* simulator launch failure — precisely the device fault this classifier exists
|
|
740
|
+
* to name — and it went unnamed because the classifier had died.
|
|
741
|
+
*
|
|
742
|
+
* Yielding one artifact at a time caps peak memory at the largest single file
|
|
743
|
+
* instead of their sum, and each text becomes garbage as soon as
|
|
744
|
+
* {@link tallyDeviceMarkers} has counted it.
|
|
745
|
+
*
|
|
746
|
+
* The return is a RE-ITERABLE iterable, not a one-shot generator: `run()`
|
|
747
|
+
* computes this once and passes it through `classifyRun` for every report, so a
|
|
748
|
+
* generator would be empty for the second report onward — a silent
|
|
749
|
+
* evidence-loss bug in place of a loud crash, which would be worse than what it
|
|
750
|
+
* replaced.
|
|
726
751
|
* @param {string | null} debugRoot - Absolute path of the debug-output directory
|
|
727
752
|
* @param {{listFiles: Function, readFile: Function}} io - Injected readers
|
|
728
|
-
* @returns {{path: string, text: string}
|
|
753
|
+
* @returns {Iterable<{path: string, text: string}>} Artifacts, read on demand
|
|
729
754
|
*/
|
|
730
755
|
export function readDebugArtifacts(debugRoot, { listFiles, readFile }) {
|
|
731
756
|
if (!debugRoot) return [];
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
757
|
+
return {
|
|
758
|
+
*[Symbol.iterator]() {
|
|
759
|
+
for (const file of listFiles(debugRoot) ?? []) {
|
|
760
|
+
if (isOpaque(file)) continue;
|
|
761
|
+
const text = readFile(file);
|
|
762
|
+
// `readFile` returns null for absent, unreadable AND too-large-to-
|
|
763
|
+
// string files alike. The last is the one that grows back into the bug
|
|
764
|
+
// above — Node refuses a string past its maximum length, and a
|
|
765
|
+
// device log that crosses it would drop out of the evidence silently.
|
|
766
|
+
if (text === null) {
|
|
767
|
+
reportUnreadableArtifact(file);
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
yield { path: file, text };
|
|
771
|
+
}
|
|
772
|
+
},
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Say on stderr that an artifact could not be read.
|
|
778
|
+
*
|
|
779
|
+
* Not a throw: a missing or unreadable artifact must not fail the run, for the
|
|
780
|
+
* same reason the step absorbs a non-zero exit. But it must not be silent
|
|
781
|
+
* either — an artifact that drops out of the evidence takes its markers with
|
|
782
|
+
* it, and a device fault it alone witnessed then reads as a flow failure.
|
|
783
|
+
* stderr rather than the markdown, so it reaches the job log without becoming
|
|
784
|
+
* part of the classification that a consumer parses.
|
|
785
|
+
* @param {string} file - Path of the artifact that could not be read
|
|
786
|
+
*/
|
|
787
|
+
function reportUnreadableArtifact(file) {
|
|
788
|
+
process.stderr.write(
|
|
789
|
+
`classify-maestro-failures: could not read ${path.basename(file)} — ` +
|
|
790
|
+
`its markers are NOT counted in this classification.\n`
|
|
791
|
+
);
|
|
740
792
|
}
|
|
741
793
|
|
|
742
794
|
/**
|
|
@@ -869,7 +921,7 @@ function resolveFlowPath(reported, { projectRoot, maestroRoot, readFile }) {
|
|
|
869
921
|
* @param {readonly string[]} [options.signInMarkers] - Project sign-in markers
|
|
870
922
|
* @param {readonly unknown[]} [options.knownIntermittent] - Raw registry entries
|
|
871
923
|
* @param {string} [options.platform] - Arm the report came from
|
|
872
|
-
* @param {
|
|
924
|
+
* @param {Iterable<{path: string, text: string}>} [options.debugArtifacts] - Run observation
|
|
873
925
|
* @param {readonly string[]} [options.deviceFaultMarkers] - Presence-decided device faults
|
|
874
926
|
* @param {readonly string[]} [options.deviceInstabilityMarkers] - Count-decided device faults
|
|
875
927
|
* @returns {{failures: object[], deviceRunEvidence: object[]}} The report's verdict
|
|
@@ -1115,9 +1167,9 @@ export function loadConfig(projectRoot) {
|
|
|
1115
1167
|
/**
|
|
1116
1168
|
* Classify every named report against one project checkout.
|
|
1117
1169
|
*
|
|
1118
|
-
* The debug-output
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1170
|
+
* The debug-output iterable is shared across the named reports. Each report
|
|
1171
|
+
* reads it lazily so artifact text is not retained between reports.
|
|
1172
|
+
* A retry arm writes into the same tree, which is correct — retries only
|
|
1121
1173
|
* re-run flows that already failed, so its evidence is about those same flows.
|
|
1122
1174
|
* @param {readonly string[]} reportPaths - Report paths
|
|
1123
1175
|
* @param {{projectRoot: string, platform: string | null, debugRoot?: string | null}} context - Run context
|
package/package.json
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
"zod-validation-error": "^4.0.0"
|
|
188
188
|
},
|
|
189
189
|
"name": "@codyswann/lisa",
|
|
190
|
-
"version": "4.57.
|
|
190
|
+
"version": "4.57.3",
|
|
191
191
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
192
192
|
"main": "dist/index.js",
|
|
193
193
|
"exports": {
|
|
@@ -336,7 +336,7 @@
|
|
|
336
336
|
"test": "tests"
|
|
337
337
|
},
|
|
338
338
|
"types": "./dist/index.d.ts",
|
|
339
|
-
"lisaReleaseCommit": "
|
|
340
|
-
"gitHead": "
|
|
341
|
-
"lisaReleaseTag": "v4.57.
|
|
339
|
+
"lisaReleaseCommit": "3fed4f391b9a6f13a80fcd6c11cb5c16837269c9",
|
|
340
|
+
"gitHead": "3fed4f391b9a6f13a80fcd6c11cb5c16837269c9",
|
|
341
|
+
"lisaReleaseTag": "v4.57.3"
|
|
342
342
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.57.
|
|
3
|
+
"version": "4.57.3",
|
|
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": "4.57.
|
|
3
|
+
"version": "4.57.3",
|
|
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": "4.57.
|
|
3
|
+
"version": "4.57.3",
|
|
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": "4.57.
|
|
3
|
+
"version": "4.57.3",
|
|
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": "4.57.
|
|
3
|
+
"version": "4.57.3",
|
|
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"
|