@codyswann/lisa 4.46.0 → 4.48.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 +89 -2
- package/all/copy-overwrite/scripts/lisa-gates.mjs +132 -1
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +68 -4
- package/dist/core/host-rules-pointer.d.ts.map +1 -1
- package/dist/core/host-rules-pointer.js +30 -22
- package/dist/core/host-rules-pointer.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +10 -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 +4 -3
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- 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
|
@@ -58,6 +58,8 @@ export const DIAGNOSIS = Object.freeze({
|
|
|
58
58
|
COMMENT_TERMINATED: "comment-terminated",
|
|
59
59
|
/** A type checker ran and reported errors in named files. */
|
|
60
60
|
TYPE_ERRORS: "type-errors",
|
|
61
|
+
/** The prover printed a failure shape the project declared for its gate. */
|
|
62
|
+
DECLARED_FAILURE: "declared-failure",
|
|
61
63
|
/** Output was read and matched nothing this module knows. */
|
|
62
64
|
UNDIAGNOSED: "undiagnosed",
|
|
63
65
|
/** No output was available to read, so nothing can be said. */
|
|
@@ -1107,7 +1109,11 @@ function classify(output, code, load, read, tempRoot) {
|
|
|
1107
1109
|
|
|
1108
1110
|
return {
|
|
1109
1111
|
kind: DIAGNOSIS.UNDIAGNOSED,
|
|
1110
|
-
summary:
|
|
1112
|
+
summary:
|
|
1113
|
+
"no recognised failure signature: Lisa could not read this tool's " +
|
|
1114
|
+
"output, so nothing here is a verdict about the code. Re-run this one " +
|
|
1115
|
+
"check on its own — the tool names what the classifier could not. The " +
|
|
1116
|
+
"command's last lines follow",
|
|
1111
1117
|
evidence: capped(tailLines(output)),
|
|
1112
1118
|
};
|
|
1113
1119
|
}
|
|
@@ -1381,6 +1387,81 @@ function findTerminatedComments(output, read) {
|
|
|
1381
1387
|
return found;
|
|
1382
1388
|
}
|
|
1383
1389
|
|
|
1390
|
+
/**
|
|
1391
|
+
* The verdict for a transcript carrying a failure shape the project declared.
|
|
1392
|
+
*
|
|
1393
|
+
* ## Why the shapes come from OUTSIDE this module
|
|
1394
|
+
*
|
|
1395
|
+
* Everything above this function recognises a fixed set of transcript forms,
|
|
1396
|
+
* and every content signature among them is a vitest or `tsc` form. A prover
|
|
1397
|
+
* that prints anything else falls into the residual bucket wearing
|
|
1398
|
+
* `UNPROVABLE` — the word this fleet reads as *"the box, re-run it somewhere
|
|
1399
|
+
* quieter"* — so a run that genuinely measured a property and found it wanting
|
|
1400
|
+
* is routed into the re-run path.
|
|
1401
|
+
*
|
|
1402
|
+
* The tempting repair is one more entry in the table. It does not converge:
|
|
1403
|
+
* every project points its gates at provers this module has never seen, so
|
|
1404
|
+
* each new one re-introduces the defect once and the cost is paid by whoever
|
|
1405
|
+
* hits it first. Measured on one repository (CodySwannGT/lisa#3974), four
|
|
1406
|
+
* distinct provers hit it — and a Lisa-repo-specific pattern in a module every
|
|
1407
|
+
* consumer installs is the same objection that keeps a Lisa-repo-specific gate
|
|
1408
|
+
* out of the shipped registry.
|
|
1409
|
+
*
|
|
1410
|
+
* So the project that owns the prover says how its output reads as measured,
|
|
1411
|
+
* and this module carries the MECHANISM and none of the vocabulary. Nothing
|
|
1412
|
+
* below names a tool, a script, or an artifact.
|
|
1413
|
+
*
|
|
1414
|
+
* ## Why the shapes are literal substrings and not patterns
|
|
1415
|
+
*
|
|
1416
|
+
* A declaration is untrusted input compiled from configuration, and this
|
|
1417
|
+
* function parses a multi-megabyte transcript inside a git hook. A regular
|
|
1418
|
+
* expression from config would be an operator-authored ReDoS with a
|
|
1419
|
+
* transcript-sized haystack — see `SCRATCH_REMOVAL_RACE` and `PATH_DELIMITER`
|
|
1420
|
+
* for how carefully this module already avoids that shape in patterns it wrote
|
|
1421
|
+
* itself. A literal substring cannot backtrack, needs no escaping, and is what
|
|
1422
|
+
* an operator copying a line out of a failed transcript would write anyway.
|
|
1423
|
+
*
|
|
1424
|
+
* ## Why this is consulted separately rather than folded into `classify`
|
|
1425
|
+
*
|
|
1426
|
+
* The runner calls it ONLY when the shipped classifier has already returned
|
|
1427
|
+
* `undiagnosed`. That placement is the whole safety argument: a killed,
|
|
1428
|
+
* refused, interfered-with or zero-test run never reaches a content signature
|
|
1429
|
+
* at all, so a declaration cannot promote non-measurement into a failure. The
|
|
1430
|
+
* guarantee is structural rather than a matter of where a line was inserted.
|
|
1431
|
+
* @param {string|null|undefined} output The command's combined output.
|
|
1432
|
+
* @param {Array<{gate: string, shape: string[]}>|null|undefined} declarations
|
|
1433
|
+
* What each gate sharing this prover declared its failure looks like.
|
|
1434
|
+
* @returns {Diagnosis|null} The verdict, or null when nothing declared matched.
|
|
1435
|
+
*/
|
|
1436
|
+
export function declaredFailure(output, declarations) {
|
|
1437
|
+
if (typeof output !== "string" || output.length === 0) return null;
|
|
1438
|
+
if (!Array.isArray(declarations)) return null;
|
|
1439
|
+
|
|
1440
|
+
const lines = output.split("\n");
|
|
1441
|
+
for (const declaration of declarations) {
|
|
1442
|
+
const shapes = declaration?.shape;
|
|
1443
|
+
if (!Array.isArray(shapes)) continue;
|
|
1444
|
+
const matched = lines.filter(line =>
|
|
1445
|
+
shapes.some(
|
|
1446
|
+
shape =>
|
|
1447
|
+
typeof shape === "string" && shape !== "" && line.includes(shape)
|
|
1448
|
+
)
|
|
1449
|
+
);
|
|
1450
|
+
if (matched.length === 0) continue;
|
|
1451
|
+
const gate = declaration.gate ?? null;
|
|
1452
|
+
return {
|
|
1453
|
+
kind: DIAGNOSIS.DECLARED_FAILURE,
|
|
1454
|
+
summary:
|
|
1455
|
+
`the prover printed a failure shape ${gate ?? "this project"} ` +
|
|
1456
|
+
`declared, so it ran and found this property wanting. That is a ` +
|
|
1457
|
+
`verdict about the code, not about the machine`,
|
|
1458
|
+
evidence: capped(matched.map(line => line.trim())),
|
|
1459
|
+
proves: gate,
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
return null;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1384
1465
|
/**
|
|
1385
1466
|
* Classify a failure and say whose property it belongs to.
|
|
1386
1467
|
*
|
|
@@ -1429,5 +1510,11 @@ export function diagnoseFailure(
|
|
|
1429
1510
|
tempRoot
|
|
1430
1511
|
) {
|
|
1431
1512
|
const verdict = classify(output, code, load, read, tempRoot);
|
|
1432
|
-
|
|
1513
|
+
// A verdict that already knows whose property it is keeps that answer. The
|
|
1514
|
+
// static table maps a KIND to a gate, which cannot express a failure whose
|
|
1515
|
+
// owner is whichever gate declared the shape that matched.
|
|
1516
|
+
return {
|
|
1517
|
+
...verdict,
|
|
1518
|
+
proves: verdict.proves ?? ATTRIBUTION[verdict.kind] ?? null,
|
|
1519
|
+
};
|
|
1433
1520
|
}
|
|
@@ -193,6 +193,57 @@ export const STATE_FAMILIES = [CONTINUOUS];
|
|
|
193
193
|
/** Keys on a gate entry that are settings rather than moments. */
|
|
194
194
|
export const GATE_FIELDS = new Set(["run", "needs", "task", "reuse"]);
|
|
195
195
|
|
|
196
|
+
/**
|
|
197
|
+
* The per-moment field saying how this gate's prover prints a MEASURED failure.
|
|
198
|
+
*
|
|
199
|
+
* `gate-failure-diagnosis.mjs` recognises a fixed set of transcript forms, and
|
|
200
|
+
* every content signature among them is a vitest or `tsc` form. A prover that
|
|
201
|
+
* prints anything else lands in the residual bucket wearing `UNPROVABLE` — the
|
|
202
|
+
* word this fleet reads as "the box, re-run it" — so a run that measured a
|
|
203
|
+
* property and found it wanting is routed into the re-run path
|
|
204
|
+
* (CodySwannGT/lisa#3974).
|
|
205
|
+
*
|
|
206
|
+
* Enumerating other tools' output in the shipped module cannot converge: every
|
|
207
|
+
* project points its gates at provers Lisa has never seen. So the project that
|
|
208
|
+
* OWNS the prover declares how its failure reads, beside the `run:` that names
|
|
209
|
+
* the prover.
|
|
210
|
+
*
|
|
211
|
+
* ## Why per MOMENT and not per gate
|
|
212
|
+
*
|
|
213
|
+
* The first draft put it on the gate, reasoning that output shape is a
|
|
214
|
+
* property of the prover. Two facts overruled that, and the second is the one
|
|
215
|
+
* with consequences.
|
|
216
|
+
*
|
|
217
|
+
* **A gate's prover already varies by moment.** `code-style` runs `lint:staged`
|
|
218
|
+
* at commit and `lint` at pull-request here; the first prints lint-staged's
|
|
219
|
+
* `✖ <task>` banner and the second does not. A gate-level shape would assert
|
|
220
|
+
* one prover's vocabulary for both.
|
|
221
|
+
*
|
|
222
|
+
* **The gate level is a CLOSED allowlist and the moment level is open.**
|
|
223
|
+
* `GATE_FIELDS` is exhaustive, so an older Lisa refuses any gate-level key it
|
|
224
|
+
* does not know — and refuses the WHOLE gates block with it. Measured against
|
|
225
|
+
* the packaged resolver this repository's own quality facade resolves first:
|
|
226
|
+
*
|
|
227
|
+
* ```
|
|
228
|
+
* Invalid gates configuration:
|
|
229
|
+
* gates."code-style"."failure_shape" is not a moment Lisa knows.
|
|
230
|
+
* ```
|
|
231
|
+
*
|
|
232
|
+
* Every facade then reads `configured=false` and falls through to built-in
|
|
233
|
+
* behaviour, so declaring a shape would silently un-configure every job in the
|
|
234
|
+
* repository until the pin caught up. A moment entry's extra keys are ignored
|
|
235
|
+
* by an older validator instead, which makes the declaration inert there
|
|
236
|
+
* rather than destructive. Inert-until-upgraded is the safe direction; every
|
|
237
|
+
* other per-moment field (`await`, `posted_by`, `evidence`, `caller_chain`)
|
|
238
|
+
* already lives with the same property.
|
|
239
|
+
*
|
|
240
|
+
* The value is a list of literal substrings, not patterns. A regular
|
|
241
|
+
* expression from configuration would be an operator-authored ReDoS run
|
|
242
|
+
* against a multi-megabyte transcript inside a git hook, and a literal is what
|
|
243
|
+
* somebody copying a line out of a failed transcript writes anyway.
|
|
244
|
+
*/
|
|
245
|
+
export const FAILURE_SHAPE_FIELD = "failure_shape";
|
|
246
|
+
|
|
196
247
|
/**
|
|
197
248
|
* The per-declaration field naming the job chain this gate's prover sits under.
|
|
198
249
|
*
|
|
@@ -4489,6 +4540,22 @@ function validateGate(id, gate) {
|
|
|
4489
4540
|
// as "this is not a moment" and sends the author looking for a moment
|
|
4490
4541
|
// spelling. The mistake is real but different: the field exists, and it
|
|
4491
4542
|
// belongs one level down.
|
|
4543
|
+
if (moment === FAILURE_SHAPE_FIELD) {
|
|
4544
|
+
// Named before the generic typo message for the reason the caller
|
|
4545
|
+
// chain is: "this is not a moment" sends the author looking for a
|
|
4546
|
+
// moment spelling, and the mistake is a level, not a spelling.
|
|
4547
|
+
problems.push(
|
|
4548
|
+
`gates."${id}"."${FAILURE_SHAPE_FIELD}" is declared for the whole ` +
|
|
4549
|
+
`gate, but a gate's prover can differ by moment — this ` +
|
|
4550
|
+
`repository runs code-style through "lint:staged" at commit and ` +
|
|
4551
|
+
`"lint" at pull-request, and only the first prints lint-staged's ` +
|
|
4552
|
+
`own banner. Declare it inside the moment whose prover prints ` +
|
|
4553
|
+
`it, e.g. gates."${id}"."${COMMIT}".${FAILURE_SHAPE_FIELD}. ` +
|
|
4554
|
+
`A gate-level key is also refused outright by any older Lisa, ` +
|
|
4555
|
+
`which refuses the whole gates block with it.`
|
|
4556
|
+
);
|
|
4557
|
+
continue;
|
|
4558
|
+
}
|
|
4492
4559
|
if (moment === CALLER_CHAIN_FIELD) {
|
|
4493
4560
|
problems.push(
|
|
4494
4561
|
`gates."${id}"."${CALLER_CHAIN_FIELD}" is declared for the whole ` +
|
|
@@ -4517,6 +4584,61 @@ function validateGate(id, gate) {
|
|
|
4517
4584
|
return problems;
|
|
4518
4585
|
}
|
|
4519
4586
|
|
|
4587
|
+
/**
|
|
4588
|
+
* Validate a gate's declared failure shape.
|
|
4589
|
+
*
|
|
4590
|
+
* Three refusals, and all three are the same defect wearing different clothes:
|
|
4591
|
+
* a declaration that looks configured and governs nothing.
|
|
4592
|
+
*
|
|
4593
|
+
* - **Not an array.** A bare string is the natural typo, and it would iterate
|
|
4594
|
+
* as characters — every transcript containing the letter `c` would match.
|
|
4595
|
+
* - **Empty array.** Reads as "declared" at a glance and matches nothing ever.
|
|
4596
|
+
* - **Empty string.** The declaration that cannot fail: an empty needle is
|
|
4597
|
+
* contained in every line, so every unrecognised failure would report FAILED
|
|
4598
|
+
* against whichever gate declared it. That is this mechanism's own inverse
|
|
4599
|
+
* defect, and shipping it by accident is one keystroke away.
|
|
4600
|
+
* @param {string} id Gate id.
|
|
4601
|
+
* @param {string} moment Moment key.
|
|
4602
|
+
* @param {*} shape The declared value, if any.
|
|
4603
|
+
* @returns {string[]} Problems.
|
|
4604
|
+
*/
|
|
4605
|
+
function validateFailureShape(id, moment, shape) {
|
|
4606
|
+
if (shape === undefined) return [];
|
|
4607
|
+
const where = `gates."${id}"."${moment}".${FAILURE_SHAPE_FIELD}`;
|
|
4608
|
+
if (!Array.isArray(shape)) {
|
|
4609
|
+
return [
|
|
4610
|
+
`${where} is ${JSON.stringify(shape)}; expected a list of literal ` +
|
|
4611
|
+
`strings this gate's prover prints when it measures the property and ` +
|
|
4612
|
+
`finds it wanting. A bare string would be read one character at a ` +
|
|
4613
|
+
`time, and every transcript contains most characters.`,
|
|
4614
|
+
];
|
|
4615
|
+
}
|
|
4616
|
+
if (shape.length === 0) {
|
|
4617
|
+
return [
|
|
4618
|
+
`${where} is empty, so it declares nothing while looking configured. ` +
|
|
4619
|
+
`Remove it, or name the line the prover actually prints.`,
|
|
4620
|
+
];
|
|
4621
|
+
}
|
|
4622
|
+
const problems = [];
|
|
4623
|
+
for (const [index, entry] of shape.entries()) {
|
|
4624
|
+
if (typeof entry !== "string") {
|
|
4625
|
+
problems.push(
|
|
4626
|
+
`${where}[${index}] is ${JSON.stringify(entry)}; expected a literal ` +
|
|
4627
|
+
`string from the prover's own output.`
|
|
4628
|
+
);
|
|
4629
|
+
continue;
|
|
4630
|
+
}
|
|
4631
|
+
if (entry.trim() === "") {
|
|
4632
|
+
problems.push(
|
|
4633
|
+
`${where}[${index}] is blank. An empty needle is contained in every ` +
|
|
4634
|
+
`line, so this would report a measured failure for any output at ` +
|
|
4635
|
+
`all — the inverse of the defect the field exists to fix.`
|
|
4636
|
+
);
|
|
4637
|
+
}
|
|
4638
|
+
}
|
|
4639
|
+
return problems;
|
|
4640
|
+
}
|
|
4641
|
+
|
|
4520
4642
|
/**
|
|
4521
4643
|
* Validate a gate's reuse declaration (#3013).
|
|
4522
4644
|
*
|
|
@@ -4620,6 +4742,9 @@ function validateMoment(id, moment, value, known, interceptor, gateRun) {
|
|
|
4620
4742
|
`alongside it, or drop the evidence block — it governs nothing here.`
|
|
4621
4743
|
);
|
|
4622
4744
|
}
|
|
4745
|
+
problems.push(
|
|
4746
|
+
...validateFailureShape(id, moment, entry[FAILURE_SHAPE_FIELD])
|
|
4747
|
+
);
|
|
4623
4748
|
problems.push(...validatePostedBy(id, moment, entry));
|
|
4624
4749
|
problems.push(...validateCallerChain(id, moment, entry));
|
|
4625
4750
|
if (!known && !interceptor && !entry.await && !entry.run && !gateRun) {
|
|
@@ -5107,7 +5232,7 @@ export function auditConfigKeys(config) {
|
|
|
5107
5232
|
* UNKNOWN, and an unknown manifest resolves exactly as it did before this
|
|
5108
5233
|
* option existed — a caller that has not been taught to read the manifest
|
|
5109
5234
|
* must not have its answers changed by silence.
|
|
5110
|
-
* @returns {Array<{id: string, level: string, mode: string, awaits: string|null, postedBy: number|null, declared: string|null, task: string|null, command: string|null, label: string, work: string|null, alias: {from: string, to: string}|null, evidence: {proof: string[], no_work: string[], on_hollow: string, wait_minutes: number|null, on_timeout: string}|null}>} Resolved provers, sorted by gate id. `declared` is the project's own `run:` — the PROVENANCE of the command, which `task` alone cannot carry because a project may spell its `run:` exactly as the registry default.
|
|
5235
|
+
* @returns {Array<{id: string, level: string, mode: string, awaits: string|null, postedBy: number|null, declared: string|null, task: string|null, command: string|null, label: string, work: string|null, alias: {from: string, to: string}|null, evidence: {proof: string[], no_work: string[], on_hollow: string, wait_minutes: number|null, on_timeout: string}|null, callerChain: string[]|null, failureShape: string[]|null, mayRewrite: boolean, costly: boolean}>} Resolved provers, sorted by gate id. `declared` is the project's own `run:` — the PROVENANCE of the command, which `task` alone cannot carry because a project may spell its `run:` exactly as the registry default.
|
|
5111
5236
|
*/
|
|
5112
5237
|
export function resolveMoment({
|
|
5113
5238
|
gates,
|
|
@@ -5174,6 +5299,7 @@ export function resolveMoment({
|
|
|
5174
5299
|
alias: null,
|
|
5175
5300
|
evidence: null,
|
|
5176
5301
|
callerChain: null,
|
|
5302
|
+
failureShape: entry[FAILURE_SHAPE_FIELD] ?? null,
|
|
5177
5303
|
mayRewrite: false,
|
|
5178
5304
|
costly: false,
|
|
5179
5305
|
});
|
|
@@ -5265,6 +5391,11 @@ export function resolveMoment({
|
|
|
5265
5391
|
// malformed chain at declaration time; `contextsFor` refuses it again at
|
|
5266
5392
|
// derivation time.
|
|
5267
5393
|
callerChain: entry.await ? null : (entry[CALLER_CHAIN_FIELD] ?? null),
|
|
5394
|
+
// Carried on every resolved entry, including an awaited one. It describes
|
|
5395
|
+
// what the project SAID about this moment's prover, and the project said
|
|
5396
|
+
// it whatever mode the moment resolves to — the same argument `declared`
|
|
5397
|
+
// makes one field up.
|
|
5398
|
+
failureShape: entry[FAILURE_SHAPE_FIELD] ?? null,
|
|
5268
5399
|
mayRewrite: definition?.mayRewrite === true,
|
|
5269
5400
|
costly: definition?.costly === true,
|
|
5270
5401
|
});
|
|
@@ -54,6 +54,7 @@ import { dirname, join, relative } from "node:path";
|
|
|
54
54
|
import { fileURLToPath } from "node:url";
|
|
55
55
|
|
|
56
56
|
import {
|
|
57
|
+
declaredFailure,
|
|
57
58
|
DIAGNOSIS,
|
|
58
59
|
diagnoseFailure,
|
|
59
60
|
ranNoTests,
|
|
@@ -423,7 +424,7 @@ function stateFor(kind) {
|
|
|
423
424
|
return kind === DIAGNOSIS.KILLED ? STATE.KILLED : STATE.UNPROVABLE;
|
|
424
425
|
}
|
|
425
426
|
|
|
426
|
-
function execute(gate, exec) {
|
|
427
|
+
function execute(gate, exec, declarations) {
|
|
427
428
|
const { code, output } = normaliseExec(exec(gate.command, gate));
|
|
428
429
|
if (code === 0) {
|
|
429
430
|
// A zero exit is not by itself a measurement. A runner invoked with
|
|
@@ -466,7 +467,11 @@ function execute(gate, exec) {
|
|
|
466
467
|
// reads exactly like a real gate failure — which is how one `exit 1` came to
|
|
467
468
|
// have three distinct causes with re-running a rational response to all of
|
|
468
469
|
// them (CodySwannGT/lisa#2897).
|
|
469
|
-
const diagnosis =
|
|
470
|
+
const diagnosis = withDeclarations(
|
|
471
|
+
diagnoseFailure(output, code),
|
|
472
|
+
output,
|
|
473
|
+
declarations
|
|
474
|
+
);
|
|
470
475
|
return {
|
|
471
476
|
state: stateFor(diagnosis.kind),
|
|
472
477
|
detail: `${gate.command} (exit ${shown}) — ${diagnosis.summary}`,
|
|
@@ -477,6 +482,53 @@ function execute(gate, exec) {
|
|
|
477
482
|
};
|
|
478
483
|
}
|
|
479
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Give a shape the project declared its say, but only where nothing else did.
|
|
487
|
+
*
|
|
488
|
+
* The shipped classifier knows a fixed set of transcript forms, and every
|
|
489
|
+
* prover outside that set lands in the residual bucket wearing `UNPROVABLE` —
|
|
490
|
+
* the word this fleet reads as "the box, re-run it". Enumerating other tools'
|
|
491
|
+
* output in a module every consumer installs cannot converge, so a project
|
|
492
|
+
* declares its own prover's measured-failure shape instead
|
|
493
|
+
* (CodySwannGT/lisa#3974).
|
|
494
|
+
*
|
|
495
|
+
* **Consulted ONLY on `undiagnosed`, and that is the entire safety argument.**
|
|
496
|
+
* A killed, refused, interfered-with or zero-test run is classified before any
|
|
497
|
+
* content signature is read, so it can never reach this function — a
|
|
498
|
+
* declaration cannot promote non-measurement into a failure. The guarantee is
|
|
499
|
+
* structural rather than a matter of where a line was inserted, which is what
|
|
500
|
+
* the constraint carried in from CodySwannGT/lisa#3946 asks for.
|
|
501
|
+
*
|
|
502
|
+
* **A declaration that matched nothing is REPORTED rather than dropped.** A
|
|
503
|
+
* mechanism wired to a field nothing reads passes exactly the way the current
|
|
504
|
+
* absence passes: silently. A typo'd shape and no shape at all must not look
|
|
505
|
+
* the same to the operator who wrote one.
|
|
506
|
+
* @param {object} diagnosis What the shipped classifier decided.
|
|
507
|
+
* @param {string|null|undefined} output The command's combined output.
|
|
508
|
+
* @param {Array<{gate: string, shape: string[]}>} declarations What the gates
|
|
509
|
+
* sharing this prover declared.
|
|
510
|
+
* @returns {object} The diagnosis as it should read.
|
|
511
|
+
*/
|
|
512
|
+
function withDeclarations(diagnosis, output, declarations) {
|
|
513
|
+
if (diagnosis.kind !== DIAGNOSIS.UNDIAGNOSED) return diagnosis;
|
|
514
|
+
if (!Array.isArray(declarations) || declarations.length === 0) {
|
|
515
|
+
return diagnosis;
|
|
516
|
+
}
|
|
517
|
+
const declared = declaredFailure(output, declarations);
|
|
518
|
+
if (declared) return declared;
|
|
519
|
+
const count = declarations.reduce(
|
|
520
|
+
(total, entry) => total + (entry.shape?.length ?? 0),
|
|
521
|
+
0
|
|
522
|
+
);
|
|
523
|
+
return {
|
|
524
|
+
...diagnosis,
|
|
525
|
+
summary:
|
|
526
|
+
`${diagnosis.summary}. ${count} declared failure shape(s) from ` +
|
|
527
|
+
`${declarations.map(entry => entry.gate).join(", ")} were consulted ` +
|
|
528
|
+
`and none matched, so the declaration did not help here`,
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
|
|
480
532
|
/**
|
|
481
533
|
* Re-attribute one command's failure to the property it actually belongs to.
|
|
482
534
|
*
|
|
@@ -658,7 +710,7 @@ function summarise(result, priorKills = []) {
|
|
|
658
710
|
* @param {{proved: Map<string, object>, blockedBy: string|null, exec: Function}} ctx Run state.
|
|
659
711
|
* @returns {{outcome: object, shared: object|undefined, ran: boolean}} The verdict.
|
|
660
712
|
*/
|
|
661
|
-
function verdictFor(gate, { proved, blockedBy, exec, siblings }) {
|
|
713
|
+
function verdictFor(gate, { proved, blockedBy, exec, siblings, declarations }) {
|
|
662
714
|
const own = classifyStatic(gate);
|
|
663
715
|
if (own) return { outcome: own, shared: undefined, ran: false };
|
|
664
716
|
|
|
@@ -704,7 +756,7 @@ function verdictFor(gate, { proved, blockedBy, exec, siblings }) {
|
|
|
704
756
|
ran: false,
|
|
705
757
|
};
|
|
706
758
|
}
|
|
707
|
-
const raw = execute(gate, exec);
|
|
759
|
+
const raw = execute(gate, exec, declarations);
|
|
708
760
|
return {
|
|
709
761
|
outcome: attributed(gate, raw, siblings),
|
|
710
762
|
raw,
|
|
@@ -768,12 +820,23 @@ export function runGates({
|
|
|
768
820
|
// the failure belongs to — `coverage-adequacy` runs `test:cov` and
|
|
769
821
|
// `test-correctness` is the one the timeout indicts.
|
|
770
822
|
const sharers = new Map();
|
|
823
|
+
// Declared failure shapes, keyed the same way and for the same reason: one
|
|
824
|
+
// command runs once, and the shape that explains its output may have been
|
|
825
|
+
// declared by a gate other than the one that happened to run it.
|
|
826
|
+
const declaredShapes = new Map();
|
|
771
827
|
for (const gate of resolved) {
|
|
772
828
|
if (!gate.command) continue;
|
|
773
829
|
sharers.set(
|
|
774
830
|
gate.command,
|
|
775
831
|
(sharers.get(gate.command) ?? new Set()).add(gate.id)
|
|
776
832
|
);
|
|
833
|
+
if (!Array.isArray(gate.failureShape) || gate.failureShape.length === 0) {
|
|
834
|
+
continue;
|
|
835
|
+
}
|
|
836
|
+
declaredShapes.set(gate.command, [
|
|
837
|
+
...(declaredShapes.get(gate.command) ?? []),
|
|
838
|
+
{ gate: gate.id, shape: gate.failureShape },
|
|
839
|
+
]);
|
|
777
840
|
}
|
|
778
841
|
|
|
779
842
|
// One command proves every gate that names it, so it runs once.
|
|
@@ -796,6 +859,7 @@ export function runGates({
|
|
|
796
859
|
blockedBy,
|
|
797
860
|
exec,
|
|
798
861
|
siblings: sharers.get(gate.command) ?? new Set(),
|
|
862
|
+
declarations: declaredShapes.get(gate.command) ?? [],
|
|
799
863
|
});
|
|
800
864
|
|
|
801
865
|
// Only what this iteration actually executed is shareable, and `ran` says
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-rules-pointer.d.ts","sourceRoot":"","sources":["../../src/core/host-rules-pointer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"host-rules-pointer.d.ts","sourceRoot":"","sources":["../../src/core/host-rules-pointer.ts"],"names":[],"mappings":"AA6BA,8DAA8D;AAC9D,eAAO,MAAM,4BAA4B,mCAAmC,CAAC;AAC7E,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,MAAM,CA6BR;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAStE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO1D"}
|
|
@@ -11,6 +11,18 @@
|
|
|
11
11
|
* Pointer only. Lisa never writes rule bodies into `AGENTS.md` or into
|
|
12
12
|
* `.agents/rules/`; that is what distinguishes this block from the legacy
|
|
13
13
|
* `LISA_RULES_START..END` bake that PR #1150 removed.
|
|
14
|
+
*
|
|
15
|
+
* The block is a plain-prose instruction, and short on purpose. Every line of
|
|
16
|
+
* it is loaded into every agent's context in every session, forever, so it
|
|
17
|
+
* carries the instruction and nothing else: the ownership and transition
|
|
18
|
+
* explanations it used to carry are Lisa internals that no agent acts on, and
|
|
19
|
+
* they live in this file's comments now instead of in every host's `AGENTS.md`.
|
|
20
|
+
*
|
|
21
|
+
* Prose rather than an import directive, because prose is the only form all six
|
|
22
|
+
* agents can act on. `@path` is Claude Code syntax that the other five do not
|
|
23
|
+
* parse, and it resolves files rather than directories even on Claude — an
|
|
24
|
+
* `@.agents/rules/` line was measured to load nothing at all, producing a block
|
|
25
|
+
* that reads as instruction-bearing while instructing no one.
|
|
14
26
|
* @module core/host-rules-pointer
|
|
15
27
|
*/
|
|
16
28
|
import { HOST_RULES_DIR } from "./project-config.js";
|
|
@@ -68,16 +80,8 @@ export function buildHostRulesPointer(legacyRulesFile) {
|
|
|
68
80
|
LISA_HOST_RULES_START_MARKER,
|
|
69
81
|
"## Host Rules",
|
|
70
82
|
"",
|
|
71
|
-
`
|
|
72
|
-
|
|
73
|
-
"injected at session start, so consult them on demand — which also means every",
|
|
74
|
-
"agent reads them through this one pointer and no agent loads them twice.",
|
|
75
|
-
"",
|
|
76
|
-
`**Ownership.** The host owns every file in \`${HOST_RULES_DIR}/\`. Lisa never writes`,
|
|
77
|
-
"rule bodies there; Lisa's own rules ship through its per-agent plugins. This",
|
|
78
|
-
"marked block is the only Lisa-managed content in this file — everything outside",
|
|
79
|
-
"the markers belongs to the host and is never touched.",
|
|
80
|
-
...transitionParagraph(legacyRulesFile),
|
|
83
|
+
`Read every file under \`${HOST_RULES_DIR}/\` for this project's standing rules.`,
|
|
84
|
+
...transitionSentence(legacyRulesFile),
|
|
81
85
|
LISA_HOST_RULES_END_MARKER,
|
|
82
86
|
].join("\n");
|
|
83
87
|
}
|
|
@@ -91,25 +95,29 @@ export function stripHostRulesPointer(body) {
|
|
|
91
95
|
return replaceManagedBlock(body, LISA_HOST_RULES_START_MARKER, LISA_HOST_RULES_END_MARKER, "");
|
|
92
96
|
}
|
|
93
97
|
/**
|
|
94
|
-
*
|
|
95
|
-
* stays reachable while the project transitions. Empty when the project
|
|
96
|
-
* none — the
|
|
98
|
+
* The clause naming a surviving legacy single-file rules document, so its
|
|
99
|
+
* content stays reachable while the project transitions. Empty when the project
|
|
100
|
+
* has none — the sentence then disappears on its own, which is what keeps the
|
|
101
|
+
* block from sending an agent after a path that is not there.
|
|
102
|
+
*
|
|
103
|
+
* The auto-load caveat is the one piece of the retired transition paragraph
|
|
104
|
+
* that has to survive: `.agents/rules/` is not a native auto-load tree for any
|
|
105
|
+
* runtime, but a legacy path can be. Claude Code auto-loads `.claude/rules/`,
|
|
106
|
+
* so an unqualified "also read it" would reintroduce exactly the double-load
|
|
107
|
+
* this block exists to prevent. It is phrased against the runtime rather than
|
|
108
|
+
* against the path because `projectRulesFile` may point somewhere Claude does
|
|
109
|
+
* not auto-load, and naming `.claude/rules/` unconditionally would be false
|
|
110
|
+
* there.
|
|
97
111
|
* @param legacyRulesFile - Project-relative legacy rules path, if any.
|
|
98
112
|
* @returns Zero or more block lines.
|
|
99
113
|
*/
|
|
100
|
-
function
|
|
114
|
+
function transitionSentence(legacyRulesFile) {
|
|
101
115
|
if (legacyRulesFile === undefined) {
|
|
102
116
|
return [];
|
|
103
117
|
}
|
|
104
118
|
return [
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
"They remain authoritative and are left exactly as written — Lisa does not",
|
|
108
|
-
"move, rewrite, or delete them. Agents whose runtime auto-loads that path",
|
|
109
|
-
"(Claude Code auto-loads `.claude/rules/`) already have that content and must",
|
|
110
|
-
"not read it a second time; every other agent should read it alongside",
|
|
111
|
-
`\`${HOST_RULES_DIR}/\`. Reclassifying or relocating it is a human-gated`,
|
|
112
|
-
"decision, never an automated rewrite.",
|
|
119
|
+
`Also read \`${legacyRulesFile}\`, unless your runtime auto-loads it —`,
|
|
120
|
+
"Claude Code auto-loads `.claude/rules/`.",
|
|
113
121
|
];
|
|
114
122
|
}
|
|
115
123
|
//# sourceMappingURL=host-rules-pointer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-rules-pointer.js","sourceRoot":"","sources":["../../src/core/host-rules-pointer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"host-rules-pointer.js","sourceRoot":"","sources":["../../src/core/host-rules-pointer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,4BAA4B,GAAG,gCAAgC,CAAC;AAC7E,8DAA8D;AAC9D,MAAM,CAAC,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,WAAmB,EACnB,SAAiB,EACjB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC;IAC7B,MAAM,iBAAiB,GACrB,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,MAAM,eAAe,GACnB,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,IACE,QAAQ,KAAK,MAAM;QACnB,CAAC,QAAQ,IAAI,MAAM,GAAG,QAAQ,CAAC;QAC/B,iBAAiB;QACjB,eAAe,EACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QACtD,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,WAAW,IAAI,CAAC;IAC/C,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,GAAG,MAAM,GAAG,WAAW,GAAG,KAAK,EAAE,CAAC;IAC/C,+EAA+E;IAC/E,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,eAAwB;IAC5D,OAAO;QACL,4BAA4B;QAC5B,eAAe;QACf,EAAE;QACF,2BAA2B,cAAc,wCAAwC;QACjF,GAAG,kBAAkB,CAAC,eAAe,CAAC;QACtC,0BAA0B;KAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,mBAAmB,CACxB,IAAI,EACJ,4BAA4B,EAC5B,0BAA0B,EAC1B,EAAE,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,kBAAkB,CAAC,eAAmC;IAC7D,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO;QACL,eAAe,eAAe,yCAAyC;QACvE,0CAA0C;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA6mCjC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAghCjC,CAAC"}
|
|
@@ -365,9 +365,11 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
365
365
|
"4503ddbe7bd54cd553db2b5952972d5319d6b6eb39a258b7c58577b61c7e7ce7",
|
|
366
366
|
"45bff9913d5a9e75b712a67cd42fe69bd4620cf4d7807f153ea83ab24319f425",
|
|
367
367
|
"503b51e9239411d07ce6b51dbe2b3079bb12e94bf7c0310e76247af19ff667e6",
|
|
368
|
+
"59cdf9163880189a18e1b9ff6e587048101812f424d219f429189f0978df8a0f",
|
|
368
369
|
"5d0aee00b95dba43cae499f338358ad4b0286f869c993508c1146448e92bd777",
|
|
369
370
|
"6742cc12ea14fc99b7bef31ff03df68d5c4610b56fad43107790372e6d777eb1",
|
|
370
371
|
"6b72a6a71078c838fdb0531e74898a5e36d942cad424b20480e2cd370b5264eb",
|
|
372
|
+
"7f5f40819835d8f7cfc2fd36ce4c377ea9d52cd0d3d69fd8049996e0050e6d38",
|
|
371
373
|
"7ffcd3f6a0595ae26c697bb0f77044b8a100200985774ad7059ebc3dc2e6bedd",
|
|
372
374
|
"9bce79d2cdcf709be40fee1bec469796bee2bb06a4cd38b11905677b97c12bc3",
|
|
373
375
|
"a36a7bd7845878e5f1f991e896739ba4cc468e50f562b71a251ebe193ca151b6",
|
|
@@ -537,6 +539,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
537
539
|
"49f37c7e896df0c43c07827b02bbecc570cccf3c27b2f7741ed53dc139a7824c",
|
|
538
540
|
"4a1dd584267006e0538590ec183d40f90a87a5eea40bf041027920145f4f39d3",
|
|
539
541
|
"4b8236c11146725b2f0ae297c1741193bba2808cfc408336e9741dfa4eb424ad",
|
|
542
|
+
"4bbebb7516227532a13136e34f4ea86e7df3d5bb2524924871fdaab82c7562c8",
|
|
540
543
|
"4e663692d9ae7d4631b6493674aa75e19b74fd35687d4b403a2d57effb877a97",
|
|
541
544
|
"4fe7003d048086a366b9bea1711275c2186e095f4bf976279d1ff825fd4eca1d",
|
|
542
545
|
"50cb619a56ed4c81c078ef4b680f781a6e0d89a606d3c68acab129f25e9aa893",
|
|
@@ -608,6 +611,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
608
611
|
"d93cd07b576ab630a29cb381b9e845042684b6003fde290965bf9c2619d57314",
|
|
609
612
|
"dab7ae5948e26b49eb4caf0ef6be5f3a29b6ed013edef73904a20ba5e06a1b22",
|
|
610
613
|
"dbca450e5a17133841ab015e71808feb028996f8297fda362dbeca4f07af2352",
|
|
614
|
+
"de1bb66dd26e504a98485e090691df43dd22e961929abfc1bf70a32a4fb84959",
|
|
611
615
|
"e13d9c5ee11648cebae22d71890c0b81415c72e5e5b977472bffa810dfe52dd4",
|
|
612
616
|
"e1c5edde3e8ca79f079fe2f350a41c984ecbae152c09db8dde11957c26f9d2ba",
|
|
613
617
|
"e35a175f8f97f841b2b21de7b6e62bc31eb6de2ba2fa502742325a5e95bf05eb",
|
|
@@ -900,6 +904,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
900
904
|
"23574bf396cadfaa1e8f8c59b70bca4ecebd145e23917a90d79ee2ded74f2b69",
|
|
901
905
|
"235c541534fc0eca510135ac39b9fbd196965fbeb54d42a09fbf052da1c925cd",
|
|
902
906
|
"242ac60aa8d77842e3704c5568b426084d9f2643ec9bce2a0601f66497835093",
|
|
907
|
+
"2a961b0ea1a8cbd0311dbb3643b427afdf46157c9372165b1a757ad8efb7062b",
|
|
903
908
|
"2d166a07c9809800771c7f41e515bff8d66c23aeeae2838dd52d5f2547037422",
|
|
904
909
|
"305b0567b309eba1176d3ff003fe32e87731497130cddd1281bdbcd0dd08f733",
|
|
905
910
|
"36f96d5be341004417d005746baeef902b610c5708b75c4a3fbbf84cf05b478c",
|
|
@@ -1488,8 +1493,10 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
1488
1493
|
"4503ddbe7bd54cd553db2b5952972d5319d6b6eb39a258b7c58577b61c7e7ce7",
|
|
1489
1494
|
"45bff9913d5a9e75b712a67cd42fe69bd4620cf4d7807f153ea83ab24319f425",
|
|
1490
1495
|
"503b51e9239411d07ce6b51dbe2b3079bb12e94bf7c0310e76247af19ff667e6",
|
|
1496
|
+
"59cdf9163880189a18e1b9ff6e587048101812f424d219f429189f0978df8a0f",
|
|
1491
1497
|
"5d0aee00b95dba43cae499f338358ad4b0286f869c993508c1146448e92bd777",
|
|
1492
1498
|
"6742cc12ea14fc99b7bef31ff03df68d5c4610b56fad43107790372e6d777eb1",
|
|
1499
|
+
"7f5f40819835d8f7cfc2fd36ce4c377ea9d52cd0d3d69fd8049996e0050e6d38",
|
|
1493
1500
|
"7ffcd3f6a0595ae26c697bb0f77044b8a100200985774ad7059ebc3dc2e6bedd",
|
|
1494
1501
|
"9bce79d2cdcf709be40fee1bec469796bee2bb06a4cd38b11905677b97c12bc3",
|
|
1495
1502
|
"a36a7bd7845878e5f1f991e896739ba4cc468e50f562b71a251ebe193ca151b6",
|
|
@@ -1640,6 +1647,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
1640
1647
|
"49f37c7e896df0c43c07827b02bbecc570cccf3c27b2f7741ed53dc139a7824c",
|
|
1641
1648
|
"4a1dd584267006e0538590ec183d40f90a87a5eea40bf041027920145f4f39d3",
|
|
1642
1649
|
"4b8236c11146725b2f0ae297c1741193bba2808cfc408336e9741dfa4eb424ad",
|
|
1650
|
+
"4bbebb7516227532a13136e34f4ea86e7df3d5bb2524924871fdaab82c7562c8",
|
|
1643
1651
|
"4e663692d9ae7d4631b6493674aa75e19b74fd35687d4b403a2d57effb877a97",
|
|
1644
1652
|
"4fe7003d048086a366b9bea1711275c2186e095f4bf976279d1ff825fd4eca1d",
|
|
1645
1653
|
"50cb619a56ed4c81c078ef4b680f781a6e0d89a606d3c68acab129f25e9aa893",
|
|
@@ -1691,6 +1699,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
1691
1699
|
"d6ce40929ead45c4df1fa79a607bc17b967a88df00833807d1e3b0b727964b1b",
|
|
1692
1700
|
"d93cd07b576ab630a29cb381b9e845042684b6003fde290965bf9c2619d57314",
|
|
1693
1701
|
"dab7ae5948e26b49eb4caf0ef6be5f3a29b6ed013edef73904a20ba5e06a1b22",
|
|
1702
|
+
"de1bb66dd26e504a98485e090691df43dd22e961929abfc1bf70a32a4fb84959",
|
|
1694
1703
|
"e1c5edde3e8ca79f079fe2f350a41c984ecbae152c09db8dde11957c26f9d2ba",
|
|
1695
1704
|
"e35a175f8f97f841b2b21de7b6e62bc31eb6de2ba2fa502742325a5e95bf05eb",
|
|
1696
1705
|
"e3bf3269817b857d20747b2c73c8088d95c281d4cae5e08d47086b7ac0fb23cf",
|
|
@@ -1959,6 +1968,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
1959
1968
|
"23574bf396cadfaa1e8f8c59b70bca4ecebd145e23917a90d79ee2ded74f2b69",
|
|
1960
1969
|
"235c541534fc0eca510135ac39b9fbd196965fbeb54d42a09fbf052da1c925cd",
|
|
1961
1970
|
"242ac60aa8d77842e3704c5568b426084d9f2643ec9bce2a0601f66497835093",
|
|
1971
|
+
"2a961b0ea1a8cbd0311dbb3643b427afdf46157c9372165b1a757ad8efb7062b",
|
|
1962
1972
|
"2d166a07c9809800771c7f41e515bff8d66c23aeeae2838dd52d5f2547037422",
|
|
1963
1973
|
"305b0567b309eba1176d3ff003fe32e87731497130cddd1281bdbcd0dd08f733",
|
|
1964
1974
|
"36f96d5be341004417d005746baeef902b610c5708b75c4a3fbbf84cf05b478c",
|