@codyswann/lisa 4.60.7 → 4.60.9
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/check-orphaned-branches.mjs +31 -18
- package/all/copy-overwrite/scripts/lisa-gates.mjs +17 -5
- package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +26 -35
- package/all/copy-overwrite/scripts/lisa-reconcile-policy.mjs +31 -8
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +8 -1
- package/all/create-only/.agents/rules/README.md +13 -6
- package/dist/core/host-rules-pointer.js +2 -2
- 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 +11 -9
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/lisa-block-instruction-file-edits.ts +25 -22
- 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-instruction-file-edits.sh +26 -35
- package/plugins/lisa/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa/rules/reference/project-learnings.md +28 -3
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +26 -35
- 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-instruction-file-edits.sh +26 -35
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa-copilot/rules/reference/project-learnings.md +28 -3
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +26 -35
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/project-learnings-reference.mdc +28 -3
- 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-instruction-file-edits.sh +26 -35
- package/plugins/src/base/rules/reference/config-resolution.md +1 -1
- package/plugins/src/base/rules/reference/project-learnings.md +28 -3
|
@@ -200,25 +200,36 @@ export function defaultBranch(remote = "origin") {
|
|
|
200
200
|
*/
|
|
201
201
|
export function branchesWithPullRequests() {
|
|
202
202
|
const json = run("gh", [
|
|
203
|
-
"
|
|
204
|
-
"
|
|
205
|
-
"--
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"
|
|
203
|
+
"api",
|
|
204
|
+
"graphql",
|
|
205
|
+
"--paginate",
|
|
206
|
+
"--slurp",
|
|
207
|
+
"-F",
|
|
208
|
+
"owner={owner}",
|
|
209
|
+
"-F",
|
|
210
|
+
"name={repo}",
|
|
211
|
+
"-f",
|
|
212
|
+
"query=query($owner:String!,$name:String!,$endCursor:String){repository(owner:$owner,name:$name){pullRequests(first:100,after:$endCursor){nodes{headRefName}pageInfo{hasNextPage endCursor}}}}",
|
|
211
213
|
]);
|
|
212
214
|
if (json === undefined) return undefined;
|
|
213
215
|
try {
|
|
214
|
-
const
|
|
215
|
-
return
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
const pages = JSON.parse(json);
|
|
217
|
+
if (!Array.isArray(pages) || pages.length === 0) return undefined;
|
|
218
|
+
const rows = [];
|
|
219
|
+
for (const [index, page] of pages.entries()) {
|
|
220
|
+
const { nodes, pageInfo } = page?.data?.repository?.pullRequests ?? {};
|
|
221
|
+
if (
|
|
222
|
+
!Array.isArray(nodes) ||
|
|
223
|
+
nodes.some(row => typeof row?.headRefName !== "string") ||
|
|
224
|
+
pageInfo?.hasNextPage !== index < pages.length - 1 ||
|
|
225
|
+
(pageInfo.hasNextPage &&
|
|
226
|
+
(typeof pageInfo.endCursor !== "string" || !pageInfo.endCursor))
|
|
227
|
+
) {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
rows.push(...nodes);
|
|
231
|
+
}
|
|
232
|
+
return new Set(rows.map(row => row.headRefName));
|
|
222
233
|
} catch {
|
|
223
234
|
// probe-direction: fail-closed — unparseable output is not an empty pull-
|
|
224
235
|
// request set. `main` turns undefined into EXIT.UNAVAILABLE, so a branch is
|
|
@@ -249,8 +260,10 @@ export function branchesAhead(remote = "origin", base = "main") {
|
|
|
249
260
|
"--count",
|
|
250
261
|
`${remote}/${base}..${remote}/${branch}`,
|
|
251
262
|
]);
|
|
252
|
-
|
|
253
|
-
|
|
263
|
+
if (count === undefined || !/^\d+$/.test(count)) return undefined;
|
|
264
|
+
const ahead = Number(count);
|
|
265
|
+
if (!Number.isSafeInteger(ahead)) return undefined;
|
|
266
|
+
if (ahead > 0) rows.push({ ahead, branch });
|
|
254
267
|
}
|
|
255
268
|
return rows;
|
|
256
269
|
}
|
|
@@ -1619,6 +1619,9 @@ const NO_FALLBACK_PROVER = "(none — the fallback announces the absent adapter)
|
|
|
1619
1619
|
|
|
1620
1620
|
/**
|
|
1621
1621
|
* What each façade job runs when nothing resolves, and under which step names.
|
|
1622
|
+
* `unconditional` is opt-in: only fallbacks that run or fail for missing
|
|
1623
|
+
* prerequisites may own a taskless declaration. Optional service scans and
|
|
1624
|
+
* legacy audit paths that swallow execution failures do not qualify.
|
|
1622
1625
|
*
|
|
1623
1626
|
* Keyed by job id so the gate comes from `QUALITY_JOB_GATES` rather than being
|
|
1624
1627
|
* written twice. `steps` are the exact step names carrying
|
|
@@ -1710,6 +1713,7 @@ const QUALITY_FALLBACKS = Object.freeze({
|
|
|
1710
1713
|
steps: ["🗑️ Run dead code detection (knip)"],
|
|
1711
1714
|
},
|
|
1712
1715
|
learnings_budget: {
|
|
1716
|
+
unconditional: true,
|
|
1713
1717
|
// The built-in runs Lisa's own in-tree checker on the Lisa source repo and
|
|
1714
1718
|
// the published CLI everywhere else, AT THE PROJECT'S OWN VERSION — read
|
|
1715
1719
|
// from its `@codyswann/lisa` dependency range, because the literal that
|
|
@@ -1810,6 +1814,7 @@ const QUALITY_FALLBACKS = Object.freeze({
|
|
|
1810
1814
|
],
|
|
1811
1815
|
},
|
|
1812
1816
|
floor_collisions: {
|
|
1817
|
+
unconditional: true,
|
|
1813
1818
|
// Two candidate paths, and Lisa's own repository ships the script as a
|
|
1814
1819
|
// template rather than installing it — so the built-in chooses between
|
|
1815
1820
|
// them at run time and a single named task cannot reproduce the choice.
|
|
@@ -1936,6 +1941,7 @@ function qualityInvocations() {
|
|
|
1936
1941
|
artifact,
|
|
1937
1942
|
job,
|
|
1938
1943
|
command: entry.command,
|
|
1944
|
+
unconditional: entry.unconditional === true,
|
|
1939
1945
|
steps: Object.freeze([...entry.steps]),
|
|
1940
1946
|
seedRun:
|
|
1941
1947
|
entry.seedRun === undefined ? null : Object.freeze([...entry.seedRun]),
|
|
@@ -1974,12 +1980,14 @@ function prePushInvocation(gate, command, seedRun) {
|
|
|
1974
1980
|
* @param {string} gate Registry gate id.
|
|
1975
1981
|
* @param {string} command What the built-in else-branch runs.
|
|
1976
1982
|
* @param {string[]|null} seedRun Candidate task names, or null for the registry default.
|
|
1983
|
+
* @param {boolean} [unconditional] The fallback fails when its prover cannot run.
|
|
1977
1984
|
* @returns {object} A frozen inventory entry.
|
|
1978
1985
|
*/
|
|
1979
|
-
function preCommitInvocation(gate, command, seedRun) {
|
|
1986
|
+
function preCommitInvocation(gate, command, seedRun, unconditional = false) {
|
|
1980
1987
|
return Object.freeze({
|
|
1981
1988
|
gate,
|
|
1982
1989
|
moment: COMMIT,
|
|
1990
|
+
unconditional,
|
|
1983
1991
|
surface: "pre-commit-hook",
|
|
1984
1992
|
artifact: PRE_COMMIT_HOOK,
|
|
1985
1993
|
job: null,
|
|
@@ -2066,6 +2074,7 @@ function onEditInvocation(gate, artifact, command) {
|
|
|
2066
2074
|
function preToolRefusalInvocation(gate, artifact, command) {
|
|
2067
2075
|
return Object.freeze({
|
|
2068
2076
|
gate,
|
|
2077
|
+
unconditional: true,
|
|
2069
2078
|
moment: PRE_TOOL,
|
|
2070
2079
|
hookEvent: "PreToolUse",
|
|
2071
2080
|
surface: "pre-tool-refusal-hook",
|
|
@@ -2284,8 +2293,9 @@ export const HARDCODED_INVOCATIONS = Object.freeze([
|
|
|
2284
2293
|
"gitleaks protect --staged --redact -v",
|
|
2285
2294
|
// Nothing a project could name reproduces this: the built-in also builds
|
|
2286
2295
|
// a combined ignore file out of .gitleaksignore and .gitleaksignore.local
|
|
2287
|
-
// before scanning, and
|
|
2288
|
-
[]
|
|
2296
|
+
// before scanning, and blocks when gitleaks is absent.
|
|
2297
|
+
[],
|
|
2298
|
+
true
|
|
2289
2299
|
),
|
|
2290
2300
|
// ONE invocation, THREE properties — `lint-staged` runs oxlint/eslint,
|
|
2291
2301
|
// prettier and `ast-grep scan` in a single pass, which is why the hook
|
|
@@ -5414,7 +5424,9 @@ export function resolveMoment({
|
|
|
5414
5424
|
// registry's explicit statement that the default task is descriptive and
|
|
5415
5425
|
// is not shipped. When the matching hard-coded invocation exists, keep the
|
|
5416
5426
|
// declaration visible (so contexts and requiredness still derive from it)
|
|
5417
|
-
// but
|
|
5427
|
+
// but only delegate to an explicitly unconditional prover. A fallback that
|
|
5428
|
+
// skips for missing credentials or files cannot carry a required property.
|
|
5429
|
+
// An explicit
|
|
5418
5430
|
// `run:` still replaces the fallback, and an unexpectedly present default
|
|
5419
5431
|
// script still runs, so this cannot hide a prover the project supplied.
|
|
5420
5432
|
const facadeBuiltIn =
|
|
@@ -5431,7 +5443,7 @@ export function resolveMoment({
|
|
|
5431
5443
|
invocation.gate === id &&
|
|
5432
5444
|
invocation.moment === moment &&
|
|
5433
5445
|
invocation.facade === CONSULTS_THEN_FALLS_BACK &&
|
|
5434
|
-
invocation.
|
|
5446
|
+
invocation.unconditional === true
|
|
5435
5447
|
);
|
|
5436
5448
|
|
|
5437
5449
|
resolved.push({
|
|
@@ -24,11 +24,9 @@
|
|
|
24
24
|
# Reads (`cat AGENTS.md`, `rg pattern AGENTS.md`) never fire.
|
|
25
25
|
#
|
|
26
26
|
# Exemptions (allowed):
|
|
27
|
-
# - `LISA_ALLOW_INSTRUCTION_FILE_WRITE` set
|
|
28
|
-
#
|
|
29
|
-
# -
|
|
30
|
-
# (the agy project-learnings bridge, cross-pollinate's rule section) replace
|
|
31
|
-
# in place on re-run and cannot grow the file;
|
|
27
|
+
# - `LISA_ALLOW_INSTRUCTION_FILE_WRITE` set in the operator's runtime config.
|
|
28
|
+
# This cooperative override does not authenticate conversation approval;
|
|
29
|
+
# - Edit/MultiEdit replacing only bounded `<!-- LISA_` regions on both sides;
|
|
32
30
|
# - paths under `node_modules/` or `dist/` — vendored copies, not the host's.
|
|
33
31
|
set -euo pipefail
|
|
34
32
|
|
|
@@ -58,8 +56,8 @@ fi
|
|
|
58
56
|
|
|
59
57
|
command -v jq >/dev/null 2>&1 || exit 0
|
|
60
58
|
|
|
61
|
-
#
|
|
62
|
-
#
|
|
59
|
+
# Existing operator-configured override. This hook sees tool payloads, not the
|
|
60
|
+
# conversation; the environment variable is not proof of who approved an edit.
|
|
63
61
|
if [ -n "${LISA_ALLOW_INSTRUCTION_FILE_WRITE:-}" ]; then
|
|
64
62
|
exit 0
|
|
65
63
|
fi
|
|
@@ -129,34 +127,27 @@ refuse() {
|
|
|
129
127
|
cat >&2 <<EOF
|
|
130
128
|
BLOCKED: refusing to write \`$target\`.
|
|
131
129
|
|
|
132
|
-
WHY: this
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
4. None of the above — it is background someone may want to look up, not a
|
|
155
|
-
standing instruction. Write it into the project documentation (\`wiki/\` or
|
|
156
|
-
\`docs/\`).
|
|
157
|
-
|
|
158
|
-
If a human explicitly asked for this edit, they can re-run with
|
|
159
|
-
\`LISA_ALLOW_INSTRUCTION_FILE_WRITE=1\` set, which bypasses this guard.
|
|
130
|
+
WHY: this session-instruction file is loaded into future agent sessions.
|
|
131
|
+
Appending incidental findings makes every later session carry those notes.
|
|
132
|
+
This hook checks write patterns; it cannot read or authenticate conversation approval.
|
|
133
|
+
|
|
134
|
+
If an operator already requested a standing-rule edit, that authorization is
|
|
135
|
+
enough for the requested change. Use the relevant topic file in \`.agents/rules/\`
|
|
136
|
+
when no other destination was specified. All six supported agents read that
|
|
137
|
+
directory through the existing \`AGENTS.md\` pointer. Edit it directly; do not
|
|
138
|
+
require learning capture, another ticket, or repeated approval for the same ruling.
|
|
139
|
+
|
|
140
|
+
If the operator explicitly named this guarded file, preserve that target and
|
|
141
|
+
use the runtime's authorized edit path, or report this remaining restriction.
|
|
142
|
+
Do not silently move the edit, switch tools to evade this refusal, or set an
|
|
143
|
+
override yourself. The existing operator-configured
|
|
144
|
+
\`LISA_ALLOW_INSTRUCTION_FILE_WRITE=1\` escape hatch is not proof of consent.
|
|
145
|
+
|
|
146
|
+
For an agent's own finding, first decide whether it is worth maintaining.
|
|
147
|
+
Decline one-off trivia and unnecessary rules. Durable project knowledge can
|
|
148
|
+
use \`/lisa:persist-learning\`; procedural knowledge belongs with its SKILL.md;
|
|
149
|
+
background belongs in existing project documentation. Use
|
|
150
|
+
\`/lisa:cross-pollinate\` only for a material, reusable upstream improvement.
|
|
160
151
|
EOF
|
|
161
152
|
exit 2
|
|
162
153
|
}
|
|
@@ -690,7 +690,6 @@ export function reconcileContexts({
|
|
|
690
690
|
const liveContexts = live ?? [];
|
|
691
691
|
const declaredNames = new Set(declared ?? []);
|
|
692
692
|
const byName = (a, b) => a.localeCompare(b);
|
|
693
|
-
const awaitedDeclarations = awaited ?? [];
|
|
694
693
|
|
|
695
694
|
// The unit of declaration is a (ruleset, context) PAIR, not a name. A name
|
|
696
695
|
// set cannot hold `build` required by both `base` and `release`, so a live
|
|
@@ -707,6 +706,10 @@ export function reconcileContexts({
|
|
|
707
706
|
// chain is not a source of declared policy.
|
|
708
707
|
...(Object.hasOwn(pins, name) ? { integration_id: pins[name] } : {}),
|
|
709
708
|
}));
|
|
709
|
+
const awaitedDeclarations = effectiveAwaitedRecords(
|
|
710
|
+
awaited ?? [],
|
|
711
|
+
supplied ?? reconstituted
|
|
712
|
+
);
|
|
710
713
|
const byContext = new Map();
|
|
711
714
|
for (const record of supplied ?? reconstituted) {
|
|
712
715
|
if (!declaredNames.has(record?.context)) continue;
|
|
@@ -807,6 +810,23 @@ export function reconcileContexts({
|
|
|
807
810
|
};
|
|
808
811
|
}
|
|
809
812
|
|
|
813
|
+
/**
|
|
814
|
+
* Explicit ruleset records override awaited declarations of the same pair.
|
|
815
|
+
* @param {object[]} awaited External check declarations.
|
|
816
|
+
* @param {object[]} records Explicit required-check records.
|
|
817
|
+
* @returns {object[]} Awaited records that still govern a pair.
|
|
818
|
+
*/
|
|
819
|
+
function effectiveAwaitedRecords(awaited, records) {
|
|
820
|
+
return awaited.filter(
|
|
821
|
+
record =>
|
|
822
|
+
!records.some(
|
|
823
|
+
explicit =>
|
|
824
|
+
explicit.context === record.context &&
|
|
825
|
+
explicit.ruleset === record.ruleset
|
|
826
|
+
)
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
|
|
810
830
|
/**
|
|
811
831
|
* Compare the declared `policy` block against observed repository state.
|
|
812
832
|
*
|
|
@@ -1552,13 +1572,16 @@ export function reconcile({
|
|
|
1552
1572
|
// comparison record, that record is what the repair reads its pin off — so
|
|
1553
1573
|
// omitting it here would have the repair write the context unpinned and
|
|
1554
1574
|
// silently discard the one app the project said may post it.
|
|
1555
|
-
const awaitedDeclarations =
|
|
1556
|
-
context
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1575
|
+
const awaitedDeclarations = effectiveAwaitedRecords(
|
|
1576
|
+
awaited.map(context => ({
|
|
1577
|
+
context,
|
|
1578
|
+
...(resolvedAwaitedHome === null ? {} : { ruleset: resolvedAwaitedHome }),
|
|
1579
|
+
...(Object.hasOwn(declaredAwaitedPins, context)
|
|
1580
|
+
? { integration_id: declaredAwaitedPins[context] }
|
|
1581
|
+
: {}),
|
|
1582
|
+
})),
|
|
1583
|
+
configured.records
|
|
1584
|
+
);
|
|
1562
1585
|
const contexts = reconcileContexts({
|
|
1563
1586
|
declared,
|
|
1564
1587
|
live: live.contexts,
|
|
@@ -293,6 +293,9 @@ function skipReason(gate) {
|
|
|
293
293
|
if (gate.mode === "await") {
|
|
294
294
|
return `awaits "${gate.awaits}"; no signal exists locally`;
|
|
295
295
|
}
|
|
296
|
+
if (gate.mode === "builtin") {
|
|
297
|
+
return "delegated to the built-in facade; no local task ran or verdict was proved";
|
|
298
|
+
}
|
|
296
299
|
return null;
|
|
297
300
|
}
|
|
298
301
|
|
|
@@ -1086,9 +1089,13 @@ const UNPROVED_STATES = new Set([
|
|
|
1086
1089
|
export function provenFloor({ gates, moment, wired = [], result = null }) {
|
|
1087
1090
|
const declared = coveredFloor({ gates, moment, wired });
|
|
1088
1091
|
if (!result) return [];
|
|
1092
|
+
// Delegation leaves the built-in responsible for running the check; adding
|
|
1093
|
+
// it to the coverage file would tell that same hook to stand down.
|
|
1089
1094
|
const unproved = new Set(
|
|
1090
1095
|
(result.results ?? [])
|
|
1091
|
-
.filter(
|
|
1096
|
+
.filter(
|
|
1097
|
+
entry => entry.mode === "builtin" || UNPROVED_STATES.has(entry.state)
|
|
1098
|
+
)
|
|
1092
1099
|
.map(entry => entry.id)
|
|
1093
1100
|
);
|
|
1094
1101
|
return declared.filter(id => !unproved.has(id));
|
|
@@ -7,8 +7,11 @@ Antigravity (`agy`) all reach it through the Lisa-managed pointer block in
|
|
|
7
7
|
|
|
8
8
|
## Ownership
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
The host controls this directory. Lisa's installer never overwrites its rules.
|
|
11
|
+
An agent may make a specific edit an operator has requested or approved,
|
|
12
|
+
including simplifying or removing a rule. Honor that existing authorization;
|
|
13
|
+
do not send the same decision through learning capture, another ticket, or a
|
|
14
|
+
second approval. Preserve unrelated rules and the operator's intended meaning.
|
|
12
15
|
|
|
13
16
|
- Lisa's own rules live in its per-agent plugins and arrive by their own route.
|
|
14
17
|
Do not copy them here.
|
|
@@ -17,10 +20,8 @@ never writes rule bodies into it, and never edits or deletes a file in it.
|
|
|
17
20
|
executable contract, and only the gardener (`/lisa:learnings:audit`) ever
|
|
18
21
|
proposes a promotion out of it — as a human-gated tracker ticket, never a
|
|
19
22
|
silent agent rewrite.
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
enforces to earn a promote-and-delete ticket, so this directory shrinks
|
|
23
|
-
instead of growing.
|
|
23
|
+
- An incidental finding is not permission to add or change a standing rule.
|
|
24
|
+
Decline one-off trivia and rules whose maintenance costs exceed their value.
|
|
24
25
|
|
|
25
26
|
## What belongs here
|
|
26
27
|
|
|
@@ -41,5 +42,11 @@ with a heading and a handful of imperative rules. Keep each file short: this
|
|
|
41
42
|
directory is read in full whenever an agent consults it, so length is a real
|
|
42
43
|
cost paid on every consultation.
|
|
43
44
|
|
|
45
|
+
For an approved standing ruling, update the relevant topic file or create one
|
|
46
|
+
here using ordinary editing tools. The existing pointer in `AGENTS.md` makes it
|
|
47
|
+
available to all six supported agents; this directory is not Claude-specific.
|
|
48
|
+
If the operator explicitly named another file, honor that target and any active
|
|
49
|
+
runtime restrictions rather than silently moving the edit here.
|
|
50
|
+
|
|
44
51
|
This README is a Lisa-seeded starter and is never overwritten — edit or delete
|
|
45
52
|
it freely once the directory has real content.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* block in `AGENTS.md` (Claude via the `@AGENTS.md` import in `CLAUDE.md`) — and
|
|
9
9
|
* no agent loads host rules twice.
|
|
10
10
|
*
|
|
11
|
-
* Pointer only. Lisa never writes rule bodies into `AGENTS.md` or into
|
|
11
|
+
* Pointer only. Lisa's installer 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
14
|
*
|
|
@@ -80,7 +80,7 @@ export function buildHostRulesPointer(legacyRulesFile) {
|
|
|
80
80
|
LISA_HOST_RULES_START_MARKER,
|
|
81
81
|
"## Host Rules",
|
|
82
82
|
"",
|
|
83
|
-
`Read every file under \`${HOST_RULES_DIR}
|
|
83
|
+
`Read every file under \`${HOST_RULES_DIR}/\`. Make operator-requested rule edits directly; no learning-promotion step is needed.`,
|
|
84
84
|
...transitionSentence(legacyRulesFile),
|
|
85
85
|
LISA_HOST_RULES_END_MARKER,
|
|
86
86
|
].join("\n");
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,yFAAyF;QAClI,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,CA00CjC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA6uCjC,CAAC"}
|
|
@@ -240,6 +240,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
240
240
|
"e8f70dce15f9dce2b1758fa657d9a279cecc9f8c2a7b69a3bfca86ec37eb2e3f",
|
|
241
241
|
]),
|
|
242
242
|
"scripts/check-orphaned-branches.mjs": Object.freeze([
|
|
243
|
+
"1f450d2492ca0bcdba440f6b403c1deee0f35e749c54d2ed5c5ddc696d5ab896",
|
|
243
244
|
"340618eddcf85909fc1d8274683b3ba75ecff94e7db9e34c3dcb03a6100092d2",
|
|
244
245
|
"42a107a86032a7f72e9d05a74bd9026c20589b87a15148a00802c1c0c0f65c9d",
|
|
245
246
|
"436fb5d8c3b2a686d4e4c350858cee9b4fd7bb6e3d1f6b37496fc345a45618cd",
|
|
@@ -606,6 +607,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
606
607
|
"10b4c60390981d152aa544c014e115cdb5cef28de837d6314f5a4b0df9638e8d",
|
|
607
608
|
"12c09f699414a5fb7577e221ec4291d5897cdf613cf4d8fe410f089b1b34f123",
|
|
608
609
|
"13ac69bf2bbae76bc702506bcef5c8fb2b26befaf1358627f4726c1a8ac5905a",
|
|
610
|
+
"16fa33bfbedb9980526130be5d1ce09159ebe7df918f723b2a9b66164917944b",
|
|
609
611
|
"18496d11521f4f4e66961db6778827d735d0495b92ce2cbbc9f8a49181181c84",
|
|
610
612
|
"186efce62ea9b94db91226587cd5e1d41ecf2cf9d63e2ba56a012dd5a41f362b",
|
|
611
613
|
"18ebb837fdf67b2b5b7bcd8776aaa3993667227a1b00fd9088e69952ab64438e",
|
|
@@ -784,6 +786,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
784
786
|
"3e709e1ec8a5843c00684bc477ad32ddab2c5fdb11f71d5aeec0c49609eaf025",
|
|
785
787
|
"48fe34021b0e91170edf8901d92765cdadf1ade1d22dfc69144559c114f184b6",
|
|
786
788
|
"6f52076e3488821d638b6dd45b5faca527d92b181cc12e6e5033859e0786c8a7",
|
|
789
|
+
"73ac5af581d16992dd9cc273b4e2f6b55bd6a2629abe23b7658563cf433e082c",
|
|
787
790
|
"850cfc23852eb752114ae1e938a1c7bcf34bc50c85d3aaca0c02311cc8c0ef70",
|
|
788
791
|
"8996e0bcbf1db085a5d99734e797c91f5025997bd967bc374efff8348dac14c2",
|
|
789
792
|
"be1e77fb0ddb246eddae71ebac25e972c3c9e8079514e0dc78d0b73df919464c",
|
|
@@ -1035,6 +1038,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
1035
1038
|
"07542e977ed41f094d5a51cae512e4a3246fabe10d0f83676a176abc81d91624",
|
|
1036
1039
|
"1e8053bb51a01fda0e2489de231ea252473991138da150dbdff72c5292e1ce53",
|
|
1037
1040
|
"2512f61074d10216dee0aca748caaebad373e6bba2598bc089f30f977c7a6a83",
|
|
1041
|
+
"263860fba7fadae3c1096973eaf4f25dca1683ef2ce64279dea6845ac90faf6a",
|
|
1038
1042
|
"269241ef59e1a29b7511a096005ea08938408578bf40a4e1acb97d8a632251ad",
|
|
1039
1043
|
"395897d1dc3f0ac92d7c892eaa9b9ddf12078181bb9f5b228965478190b09a91",
|
|
1040
1044
|
"3c062d0b79961a9a93a822507e893dcdaa71d65d735557727d20464c2489d812",
|
|
@@ -1081,6 +1085,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
1081
1085
|
"6e419a489d0605cc0743af207ff4ff3428d8bcdfbabb7207d164593b9644dfa5",
|
|
1082
1086
|
"79055f89eb9c5bf1739867c12dc2d9e30320f86a2a3dd470300ba706c3c9d85e",
|
|
1083
1087
|
"7d91ef0e06c53d9d09ddc0b03a22ddd5933e4001ab759c14a964a463df58e635",
|
|
1088
|
+
"7e04168dffa0caa5d8dfb127a9be462a81f4512e86a57455df5708154bfb19b0",
|
|
1084
1089
|
"853437a0be104fde1eb962f0c5c70b14ea3f4fa8b6973f8d9f6e704a9d3e3611",
|
|
1085
1090
|
"86a84591a81d8b4e92d2d3f4b7bf447230f1bb3a3b6fc9f0604fcff685026f73",
|
|
1086
1091
|
"94453bdae8ab3dd2eba0883c4b278027396090e0bdc8e2f102414abc6415912a",
|
|
@@ -1586,6 +1591,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
1586
1591
|
"e8f70dce15f9dce2b1758fa657d9a279cecc9f8c2a7b69a3bfca86ec37eb2e3f",
|
|
1587
1592
|
]),
|
|
1588
1593
|
"scripts/check-orphaned-branches.mjs": Object.freeze([
|
|
1594
|
+
"1f450d2492ca0bcdba440f6b403c1deee0f35e749c54d2ed5c5ddc696d5ab896",
|
|
1589
1595
|
"340618eddcf85909fc1d8274683b3ba75ecff94e7db9e34c3dcb03a6100092d2",
|
|
1590
1596
|
"42a107a86032a7f72e9d05a74bd9026c20589b87a15148a00802c1c0c0f65c9d",
|
|
1591
1597
|
"436fb5d8c3b2a686d4e4c350858cee9b4fd7bb6e3d1f6b37496fc345a45618cd",
|
|
@@ -1941,6 +1947,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
1941
1947
|
"08a66b2ca128d38735810786fb2be73ed5c6dd71560992ff95ad0a2170428d90",
|
|
1942
1948
|
"091c1198c239f5d49b584a8a296ea9f70ba67b083b36d8742e5a81ff7439b09e",
|
|
1943
1949
|
"0ceb0133be299a3c89bdf736008ee2c5c8ad027c1a4656b9d0fb7c9438a7ed07",
|
|
1950
|
+
"16fa33bfbedb9980526130be5d1ce09159ebe7df918f723b2a9b66164917944b",
|
|
1944
1951
|
"18ebb837fdf67b2b5b7bcd8776aaa3993667227a1b00fd9088e69952ab64438e",
|
|
1945
1952
|
"1a456052254f7c7c8b7c0509fb1e3d8c572891056bc0ef4dd4fbde29b0a54011",
|
|
1946
1953
|
"1ac3180f7a8f777f6be0d90043d4396ec96589168b43fc7128eeec750aa9aef9",
|
|
@@ -2082,6 +2089,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
2082
2089
|
"3e709e1ec8a5843c00684bc477ad32ddab2c5fdb11f71d5aeec0c49609eaf025",
|
|
2083
2090
|
"48fe34021b0e91170edf8901d92765cdadf1ade1d22dfc69144559c114f184b6",
|
|
2084
2091
|
"6f52076e3488821d638b6dd45b5faca527d92b181cc12e6e5033859e0786c8a7",
|
|
2092
|
+
"73ac5af581d16992dd9cc273b4e2f6b55bd6a2629abe23b7658563cf433e082c",
|
|
2085
2093
|
"850cfc23852eb752114ae1e938a1c7bcf34bc50c85d3aaca0c02311cc8c0ef70",
|
|
2086
2094
|
"8996e0bcbf1db085a5d99734e797c91f5025997bd967bc374efff8348dac14c2",
|
|
2087
2095
|
"be1e77fb0ddb246eddae71ebac25e972c3c9e8079514e0dc78d0b73df919464c",
|
|
@@ -2320,6 +2328,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
2320
2328
|
]),
|
|
2321
2329
|
"scripts/lisa-reconcile-policy.mjs": Object.freeze([
|
|
2322
2330
|
"2512f61074d10216dee0aca748caaebad373e6bba2598bc089f30f977c7a6a83",
|
|
2331
|
+
"263860fba7fadae3c1096973eaf4f25dca1683ef2ce64279dea6845ac90faf6a",
|
|
2323
2332
|
"269241ef59e1a29b7511a096005ea08938408578bf40a4e1acb97d8a632251ad",
|
|
2324
2333
|
"395897d1dc3f0ac92d7c892eaa9b9ddf12078181bb9f5b228965478190b09a91",
|
|
2325
2334
|
"3c062d0b79961a9a93a822507e893dcdaa71d65d735557727d20464c2489d812",
|
|
@@ -2361,6 +2370,7 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
2361
2370
|
"6e419a489d0605cc0743af207ff4ff3428d8bcdfbabb7207d164593b9644dfa5",
|
|
2362
2371
|
"79055f89eb9c5bf1739867c12dc2d9e30320f86a2a3dd470300ba706c3c9d85e",
|
|
2363
2372
|
"7d91ef0e06c53d9d09ddc0b03a22ddd5933e4001ab759c14a964a463df58e635",
|
|
2373
|
+
"7e04168dffa0caa5d8dfb127a9be462a81f4512e86a57455df5708154bfb19b0",
|
|
2364
2374
|
"853437a0be104fde1eb962f0c5c70b14ea3f4fa8b6973f8d9f6e704a9d3e3611",
|
|
2365
2375
|
"86a84591a81d8b4e92d2d3f4b7bf447230f1bb3a3b6fc9f0604fcff685026f73",
|
|
2366
2376
|
"94453bdae8ab3dd2eba0883c4b278027396090e0bdc8e2f102414abc6415912a",
|