From 2eef9f52d0bee3a6831b881e7711a383a56080bc Mon Sep 17 00:00:00 2001 From: Michael Heller <21163552+mdheller@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:43:57 -0400 Subject: [PATCH 1/3] fix(ci): the required check's PR filter was narrower than its own push filter ts-ci.yml declared ontology/** and scripts/** relevant in on.push.paths, but the PR change-detector matched only ^(package(-lock)?\.json|ts/|\.github/workflows/ts-ci\.yml). The derivation those push paths exist for is real: ontology/kko/kko-2.10.n3 -> scripts/gen-kko.mjs -> ts/src/kko-data.ts ontology/effect-request/*.json -> scripts/gen-effect-request.mjs -> ts/src/* ontology/semantic-action/*.json -> scripts/gen-semantic-action.mjs -> ts/src/semantic-action-data.ts -> ts/dist so a re-vendor touching only ontology/ took the "required check trivially satisfied" branch and build-and-verify-dist -- a REQUIRED check on main, per branches/main/protection: ["build-and-verify-dist","CodeQL"] -- went green having built nothing. Worth stating precisely: the kko-provenance job does cover the FIRST of those three chains, on every PR and with no path filter. But it is not a required check, and nothing covers effect-request or semantic-action at all. The regex moves to a TS_PATHS env var used by the grep, widened with ontology/ and scripts/. A new step then derives on.push.paths from this file and asserts the detector matches every declared family, so widening one filter and forgetting the other fails loudly instead of silently skipping a build. Red-then-green, same probe against both trees: origin/main ontology/kko/kko-2.10.n3 -> skipped (green, built nothing) ontology/effect-request/EffectRequest.json -> skipped scripts/gen-kko.mjs -> skipped assertion: FAILS -- push declares ['ontology/**','scripts/**'], detector does not match fixed all of the above -> BUILDS README.md, rust/src/lib.rs -> still skipped assertion: PASSES -- detector covers all 5 declared push paths --- .github/workflows/ts-ci.yml | 41 ++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ts-ci.yml b/.github/workflows/ts-ci.yml index 0685a8c..bf9f5ad 100644 --- a/.github/workflows/ts-ci.yml +++ b/.github/workflows/ts-ci.yml @@ -38,7 +38,43 @@ jobs: - name: Detect TS/dist-relevant changes id: changed + env: + # Single source of truth for "this change can affect ts/dist". Must stay a superset of + # the `on.push.paths` list above — the step below asserts exactly that, because the two + # drifting apart is what this comment block keeps recording. + TS_PATHS: '^(package(-lock)?\.json|ts/|ontology/|scripts/|\.github/workflows/ts-ci\.yml)' run: | + # The PR detector must not be NARROWER than the workflow's own push filter. It was: + # push declared ontology/** and scripts/** relevant, the detector did not, and the + # derivation is real — + # ontology/kko/kko-2.10.n3 -> scripts/gen-kko.mjs -> ts/src/kko-data.ts + # ontology/effect-request/*.json -> scripts/gen-effect-request.mjs -> ts/src/* + # ontology/semantic-action/*.json -> scripts/gen-semantic-action.mjs -> ts/src/semantic-action-data.ts + # -> ts/dist + # so a re-vendor touching only ontology/ took the "trivially satisfied" branch and + # build-and-verify-dist — a REQUIRED check on main — went green having built nothing. + # The kko-provenance job below covers the FIRST of those three chains, but it is not a + # required check, and nothing covers the other two. + # + # Derive the push filter from this file rather than restating it, so widening one and + # forgetting the other fails here instead of silently skipping a build. + python3 - <<'PY' + import os, re, sys, pathlib + wf = pathlib.Path('.github/workflows/ts-ci.yml').read_text().split('\n') + start = next(i for i, l in enumerate(wf) if l.startswith(' push:')) + end = next(i for i, l in enumerate(wf[start + 1:], start + 1) if re.match(r'^ \S', l)) + declared = re.findall(r'^\s*-\s*"([^"]+)"', '\n'.join(wf[start:end]), re.M) + if not declared: + sys.exit('::error::could not read on.push.paths from ts-ci.yml — this guard has gone blind') + rx = re.compile(os.environ['TS_PATHS']) + # One representative path per declared family; a glob stands for a file beneath it. + bad = [p for p in declared if not rx.match(p.replace('**', 'x').replace('*', 'x'))] + if bad: + sys.exit(f'::error::on.push.paths declares {bad} relevant, but the PR change-detector ' + f'regex does not match them. A PR touching only those paths would report ' + f'build-and-verify-dist green without building anything.') + print(f'detector covers all {len(declared)} declared push paths: {declared}') + PY if [ "${{ github.event_name }}" != "pull_request" ]; then # push is already path-filtered to TS-relevant paths — always build. echo "ts=true" >> "$GITHUB_OUTPUT" @@ -53,8 +89,7 @@ jobs: # defines this gate was the one change the gate never ran on. This PR is that # shape: before this line was widened, the commit adding the Test step below had # it reported as `skipped`. - if git diff --name-only "$base" "$head" \ - | grep -qE '^(package(-lock)?\.json|ts/|\.github/workflows/ts-ci\.yml)'; then + if git diff --name-only "$base" "$head" | grep -qE "$TS_PATHS"; then echo "ts=true" >> "$GITHUB_OUTPUT" else echo "ts=false" >> "$GITHUB_OUTPUT" @@ -99,7 +134,7 @@ jobs: - name: No TS/dist changes — required check trivially satisfied if: steps.changed.outputs.ts != 'true' - run: echo "This PR touches no package.json, package-lock.json, ts/** or ts-ci.yml files; build-and-verify-dist has nothing to verify." + run: echo "This PR touches no package.json, package-lock.json, ts/**, ontology/**, scripts/** or ts-ci.yml files; build-and-verify-dist has nothing to verify." # ── Vendored-ontology provenance (W12) ───────────────────────────────────────────── # ontology/kko/PROVENANCE.md recorded a sha256 that NOTHING verified. Consumers across the From 3c1a8b99e2c90d61fee7ef5461792ec6df5e1333 Mon Sep 17 00:00:00 2001 From: Michael Heller <21163552+mdheller@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:47:57 -0400 Subject: [PATCH 2/3] fix(vendor-graph): consume contractViolations instead of sealing it unread `RevendorProposal.contractViolations` is populated by proposeRevendor and sealed into the analysis, and its own doc comment has always said "Non-empty means the proposal is NOT emitted". Nothing implemented that sentence. Across the repo the field occurs 17 times: 8 in the four compiled ts/dist copies, 4 in vendor-graph.ts (the interface field, the definition, the populate, the return), and 5 in tests. No production reader -- no branch, no `.length`, no throw, no exit code. analyzeVendorFreshness sealed every candidate regardless. Meanwhile the sibling dispositionViolations IS a named top-level field of the sealed analysis, and the validator provably works (vendor-graph.test.ts's TEETH test is a real counter-test). The declared rule is now the actual rule. A candidate whose contractViolations is non-empty is WITHHELD from `proposals`, and its violations are named in a new top-level sealed field `contractViolations`, formatted `${pinKey}: ${violation}` exactly as dispositionViolations is. Both halves are needed. Withholding alone is a silent drop. Naming alone leaves a consumer free to act on a proposal the contract says was never emitted. Reported, not thrown, for three reasons: analyzeVendorFreshness is documented PURE and deterministic; one malformed pin must not destroy the verdicts for every other pin in the run, which is why dispositionViolations is a list and not an exception; and the module's whole doctrine is that the engine proposes while a membrane gate outside it decides -- throwing would be the engine taking an action. proposeRevendor's own signature and behaviour are unchanged, so direct callers see no difference. For a conforming graph the observable output is also unchanged; only the new empty `contractViolations: []` is added, which does change the seal hash. No test pins a literal analysis hash. Red-then-green, ts/src/vendor-graph.test.ts: restored 23 pass / 0 fail withholding reverted 22 / 1 "only the conforming proposal is emitted" reporting reverted (field dropped) 21 / 2 "the withheld proposal is reported, not dropped" both reverted (origin/main behaviour) 21 / 2 Full suite 412 pass / 0 fail; typecheck clean; ts/dist rebuilt. --- ts/dist/index.d.mts | Bin 235834 -> 224189 bytes ts/dist/index.d.ts | Bin 235834 -> 224189 bytes ts/dist/index.js | Bin 432185 -> 424874 bytes ts/dist/index.mjs | Bin 423191 -> 416040 bytes ts/src/vendor-graph.test.ts | 68 ++++++++++++++++++++++++++++++++++++ ts/src/vendor-graph.ts | 37 ++++++++++++++++++-- 6 files changed, 102 insertions(+), 3 deletions(-) diff --git a/ts/dist/index.d.mts b/ts/dist/index.d.mts index 92e64c8dc5930acb9abccb42392ef15337f89b23..9f1e2c824ac8b8df3edc846cabeee1f8b0a42d82 100644 GIT binary patch delta 856 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 diff --git a/ts/dist/index.d.ts b/ts/dist/index.d.ts index 92e64c8dc5930acb9abccb42392ef15337f89b23..9f1e2c824ac8b8df3edc846cabeee1f8b0a42d82 100644 GIT binary patch delta 856 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 diff --git a/ts/dist/index.js b/ts/dist/index.js index 604c6f3b8e13340f66f4ca8b1a3237c57c3d686e..e4fdf7e722646604d87899fcde4736b5ce65e1b7 100644 GIT binary patch delta 2377 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 jaOwq diff --git a/ts/dist/index.mjs b/ts/dist/index.mjs index 135f864dc58f9137c33960e3c90651b365a748c1..2871660915b88858ebc02887ad2d4e1a98a9b3cd 100644 GIT binary patch delta 2408 zcmb7FZERcB8P@UjJvB|!rj662YEw?#klfqYH*QB$NS34(R3eDb1WKdLapP(EgSc9TsK7tVH_)jFDTf`TYJJ2f_pm=8oifv03 zq4|IXmP)24wBYZ=1hFfo3GMGch@<>?2iowJl&@nufDi)7y3OCO9N;)w9(eeu2ZJ2XHb?pPEV&rXcyWqZS+28e>j24p^f@# zJAZEoCAVf*o5={tHap|5an!|Mh@!f9Cy7oB)j#-Sl#gf7`y!^JKgk@;pk7`pp@F93 z5L(O4BI*ed|NIQv&fhGe#V?AvUP4#-f`Oju@k$2Jrn|buQjK?;p7Inm&6Q&)vE??e zb6jJlk)z6PH7!mZLoaU*M6q=NjjriwiXxDu;T{R}K+1*c`?CXugOboanNZDTCsFbWY5SqLSk@1 z{zI6*SCJnS($n&+lr#!NVYw2u^i(S{2HlK}kyynwVx+&H>@e7YEDRpZz+j%x8vbNwNReS2V6MJ@ErHFQZT5QSD2dvE&_8* z4MrsvQ-hV&-idp~JKOO^S$s2rCnXiei&*+G$30Yl`Bkba85<{6jg?KqQ({_7g~1Q< ztD?Re17mm?{{`{ShVeQ+a1UOz7_7IcApc={lDYt4*s%7h)P@zPF~_2cqBk&GA5nCz zN?m3+HdukWWiyD;ruic+S8HoDMb!wIa;h}Xm-gZAVc>Z=%hWx}yyYyi<4Xad^_fxJ zrK~FV%$X)s1Dya%%+pO8BP0ByVZ4nW9K*f6t5PON#&h-D@q}gAj?1-uxIe*4x=Wi# zq_4JI-0dy-abg2S%;V*I0Q&tg9C@(uAEw2mI-`(zTRT3A|@`LJx^7S*R!9;q6N9`LL76_563!c)UmyuSA1OI^ftFV5B*bBP0(eo$w5c5`zV6g&BEDg4hQ4c~aF)17ctm zu}T)M2?F+{OE5@Q>vN=i=`(INWvzEWCVxLdC5) zd=pJH^%vYA4%1B*TyV<~Oe+{BC|yy?4SAQf<)V)m4q$@78DGfY9)8~}?t1+H%F|40 z7rhc0CrMQ+0N9jX{%_yWtiazK-ArGttkFV&=3w)lr~uKLr@P%n>S@53?HRBhTz>?F zRP{3|zi||QKeAl8u;%euByMH!eo0K_@lV5Ir-5fB@huZ4kocvA^GMw1;0u!Y)WxyT FzX73YFj)Wq delta 8897 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 O<4ubfd0u_2>wf`LtTA~2 diff --git a/ts/src/vendor-graph.test.ts b/ts/src/vendor-graph.test.ts index 513d07f..158f743 100644 --- a/ts/src/vendor-graph.test.ts +++ b/ts/src/vendor-graph.test.ts @@ -544,6 +544,74 @@ test('the vendored-contract validator has TEETH — a malformed EffectRequest is }).length > 0, 'nested object properties') }) +/** + * …and the verdict that validator produces must be READ. + * + * `RevendorProposal.contractViolations` has always documented "non-empty means the proposal is NOT + * emitted", and nothing implemented it: `analyzeVendorFreshness` sealed every candidate regardless, + * and across the whole repo the field had no production reader — no branch, no `.length`, no throw, + * only its own definition and these tests. A violation computed, sealed, and never read is worse + * than no check at all, because the receipt then carries evidence that the system looked. + * + * The violation here is driven from the GRAPH, not by mutating a finished request: `policyLabels` + * on the pin is declared `['ops','ops']`, `proposeRevendor` joins and re-splits it, and the + * vendored contract's `uniqueItems` rejects it. Exactly the shape a bad register entry would take. + */ +test('a contract-violating proposal is WITHHELD from the seal and NAMED in it', () => { + const store = new HellGraphStore(new AtomSpace('vendor-graph-violation', false)) + ingestVendorFreshness(store, { + ...REGISTER, + artifacts: [ + REGISTER.artifacts[0], + { ...REGISTER.artifacts[1], policy_labels: ['ops', 'ops'] }, + ], + }) + + // The input really does violate the contract — otherwise the rest of this test proves nothing. + const direct = proposeRevendor(store, WARDEN_PIN, { requestedAt: '2026-07-29T00:00:00Z' }) + assert.ok(direct.contractViolations.length > 0, 'the duplicate policy label is a real violation') + + const a = analyzeVendorFreshness(store, { requestedAt: '2026-07-29T00:00:00Z' }) + + // WITHHELD: both pins are stale, so two candidates were built, but only the conforming one is + // emitted. Sealing the bad one alongside the good one is the defect. + assert.equal(a.pins.filter((p) => p.freshnessState === 'stale').length, 2, 'two stale pins') + assert.equal(a.proposals.length, 1, 'only the conforming proposal is emitted') + assert.equal(a.proposals[0]!.effectRequest.target.identifier, 'hellgraph-engine@hellgraph-service') + assert.ok(a.proposals.every((p) => p.contractViolations.length === 0), + 'nothing carrying a violation rides inside the seal') + + // NAMED: withholding on its own would be a silent drop. + assert.ok(a.contractViolations.length > 0, 'the withheld proposal is reported, not dropped') + assert.ok(a.contractViolations.every((v) => v.startsWith('hellgraph-engine@lifecycle-warden: ')), + 'each violation names the pin it came from, like dispositionViolations does') + assert.ok(a.contractViolations.some((v) => /policyLabels/.test(v)), 'and says what was wrong') + + // Sealed, not merely returned: the field is inside the hashed record. + const clean = analyzeVendorFreshness(fixture(), { requestedAt: '2026-07-29T00:00:00Z' }) + assert.deepEqual(clean.contractViolations, [], 'a conforming graph reports none') + assert.equal(clean.proposals.length, 2, 'and withholds nothing') + assert.notEqual(a.hash, clean.hash, 'the withheld violation changes the seal') +}) + +test('contractViolations participates in the seal rather than sitting beside it', () => { + // Two analyses whose ONLY difference is the violation must not seal identically. If the field + // were dropped from the sealed record, these hashes would collide. + const violating = () => { + const s = new HellGraphStore(new AtomSpace('vendor-graph-seal', false)) + ingestVendorFreshness(s, { + ...REGISTER, + artifacts: [REGISTER.artifacts[0], { ...REGISTER.artifacts[1], policy_labels: ['ops', 'ops'] }], + }) + return analyzeVendorFreshness(s, { requestedAt: '2026-07-29T00:00:00Z' }) + } + const x = violating() + const y = violating() + assert.equal(x.hash, y.hash, 'still deterministic') + assert.ok(x.contractViolations.length > 0) + assert.ok(JSON.stringify(x).includes(x.contractViolations[0]!), 'the violation text is in the record') +}) + /** * CodeQL `js/polynomial-redos` on the pre-fix `slug()` trim (`/^-+|-+$/`). `artifact_id` becomes * `pinKey`, which `slug()` puts into the EffectRequest `id` — so a register value walks straight diff --git a/ts/src/vendor-graph.ts b/ts/src/vendor-graph.ts index a11622a..adc3695 100644 --- a/ts/src/vendor-graph.ts +++ b/ts/src/vendor-graph.ts @@ -1228,9 +1228,19 @@ export interface VendorFreshnessAnalysis { risks: ContractCrossingRisk[] /** Blast radius per producing repository, sorted by repo name. */ blastRadius: BlastRadiusReport[] - /** Pins whose DECLARED disposition contradicts the DERIVED state — the only hard violation. */ + /** Pins whose DECLARED disposition contradicts the DERIVED state. */ dispositionViolations: string[] - /** Re-vendor proposals. Emitted, never executed; empty unless `requestedAt` is supplied. */ + /** + * Proposals WITHHELD because they did not validate against the vendored contract, as + * `${pinKey}: ${violation}`. `RevendorProposal.contractViolations` says a violating proposal is + * not emitted; this is where the ones that were not emitted are named, so the withholding is + * visible in the seal instead of being a silent omission. + */ + contractViolations: string[] + /** + * Re-vendor proposals. Emitted, never executed; empty unless `requestedAt` is supplied. + * Contains only proposals that validated — see `contractViolations` for the rest. + */ proposals: RevendorProposal[] /** sha256 over everything above (proof-carrying). */ hash: string @@ -1286,7 +1296,7 @@ export function analyzeVendorFreshness(store: HellGraphStore, opts: AnalyzeOptio const dispositionViolations = pins.filter((p) => !p.dispositionAgrees) .map((p) => `${p.pinKey}: declared '${p.disposition}' but derived '${p.freshnessState}' (${p.rationale})`) - const proposals = opts.requestedAt === undefined ? [] : pins + const candidates = opts.requestedAt === undefined ? [] : pins .filter((p) => p.freshnessState === 'stale') .map((p) => { const repo = store.out(store.out(p.pinId, VFP_EDGE.pinnedAt)[0]?.id ?? '', VFP_EDGE.producedBy)[0] @@ -1298,6 +1308,26 @@ export function analyzeVendorFreshness(store: HellGraphStore, opts: AnalyzeOptio }) }) + // `RevendorProposal.contractViolations` has always said "non-empty means the proposal is NOT + // emitted". Nothing implemented that sentence: every candidate was sealed regardless, and the + // array had no reader anywhere in the repo — no branch, no `.length`, no throw. A violation + // sealed into a receipt nobody reads is worse than no check, because the receipt then carries + // evidence that the system looked. + // + // So the declared rule is now the actual rule: a violating proposal is WITHHELD, and its + // violations are named at the top level the way `dispositionViolations` already is. Withholding + // alone would be a silent drop, and naming alone would leave a consumer free to act on a + // proposal the contract says was never emitted; it takes both. + // + // Reported, not thrown. `analyzeVendorFreshness` is documented PURE and deterministic, and one + // malformed pin must not destroy the verdicts for every other pin in the run — the same reason + // `dispositionViolations` is a list and not an exception. The engine proposes; a membrane gate + // outside it decides. + const proposals = candidates.filter((p) => p.contractViolations.length === 0) + const contractViolations = candidates + .filter((p) => p.contractViolations.length > 0) + .flatMap((p) => p.contractViolations.map((v) => `${p.effectRequest.target.identifier}: ${v}`)) + return sealed({ method: METHOD, contract: { ...EFFECT_REQUEST_CONTRACT }, @@ -1306,6 +1336,7 @@ export function analyzeVendorFreshness(store: HellGraphStore, opts: AnalyzeOptio risks, blastRadius, dispositionViolations, + contractViolations, proposals, }) } From ce2964ba9c07ba8c344bea27005a1c127a548691 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Jul 2026 21:27:17 -0400 Subject: [PATCH 3/3] build: regenerate dist after rebase onto main --- ts/dist/index.d.mts | Bin 224189 -> 236309 bytes ts/dist/index.d.ts | Bin 224189 -> 236309 bytes ts/dist/index.js | Bin 424874 -> 432473 bytes ts/dist/index.mjs | Bin 416040 -> 423479 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ts/dist/index.d.mts b/ts/dist/index.d.mts index 9f1e2c824ac8b8df3edc846cabeee1f8b0a42d82..066632d450759de812ce24d2d739e774b2d56cc5 100644 GIT binary patch delta 12289 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 F{s)%8hQj~= delta 389 zcmXw!%_{~`6o;F+zKe|_QVu2GWMiY0EYzE_l8wc^X3m()%$;%XnU{Cv-AO5B(pa*$ zQF4`JYb85te}l3%L)Pc{ou23Nq38LdyLs=tf7@EC>)qPzM^`w-;)&Z^Y_vOVw)W(H zyT?4!l0%}R#u5nd5=B~g1RA4;RJ-K?gi0tx4LnG6EQmv#83HdvZyzLe!4%+88c9!5 z)Br(H!r+N00wW1w!XN^#qw*6yyQ@VS&XM8eQy;j-gRTq>p}#_WG9S6=FXA1i!*;&7 zr)1-0Hr!%Q*4P5;n*kZ85yq%W80x5Z1j*Pw*4Uu4YDh!~GAR8O9+sv;lMJc~6AF#y z*C>@rmD5=4C3*%DUGbG^wJ?<5y$%fj&&JIk2EGge)TW9mdx~tGt>@7mwM^Uj gCj0EMBj;?3*|Q5a>)5xP`Ho$=WY^4oU9nO32ON%!HUIzs diff --git a/ts/dist/index.d.ts b/ts/dist/index.d.ts index 9f1e2c824ac8b8df3edc846cabeee1f8b0a42d82..066632d450759de812ce24d2d739e774b2d56cc5 100644 GIT binary patch delta 12289 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 F{s)%8hQj~= delta 389 zcmXw!%_{~`6o;F+zKe|_QVu2GWMiY0EYzE_l8wc^X3m()%$;%XnU{Cv-AO5B(pa*$ zQF4`JYb85te}l3%L)Pc{ou23Nq38LdyLs=tf7@EC>)qPzM^`w-;)&Z^Y_vOVw)W(H zyT?4!l0%}R#u5nd5=B~g1RA4;RJ-K?gi0tx4LnG6EQmv#83HdvZyzLe!4%+88c9!5 z)Br(H!r+N00wW1w!XN^#qw*6yyQ@VS&XM8eQy;j-gRTq>p}#_WG9S6=FXA1i!*;&7 zr)1-0Hr!%Q*4P5;n*kZ85yq%W80x5Z1j*Pw*4Uu4YDh!~GAR8O9+sv;lMJc~6AF#y z*C>@rmD5=4C3*%DUGbG^wJ?<5y$%fj&&JIk2EGge)TW9mdx~tGt>@7mwM^Uj gCj0EMBj;?3*|Q5a>)5xP`Ho$=WY^4oU9nO32ON%!HUIzs diff --git a/ts/dist/index.js b/ts/dist/index.js index e4fdf7e722646604d87899fcde4736b5ce65e1b7..9c827de43c2a0a4949660776e386db77ce3aef80 100644 GIT binary patch delta 9062 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 B%S-?O diff --git a/ts/dist/index.mjs b/ts/dist/index.mjs index 2871660915b88858ebc02887ad2d4e1a98a9b3cd..cc867d96aa91711f589233b73e26b3e4e02ea5e0 100644 GIT binary patch delta 8871 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 delta 2146 zcmah~U2GIp6wck*xm2J~=oU(#cv)&YLwBbIrC@6*jgn9z((>2nc5P>O@9s|7nOWw} zF5t4pY7`|HF`ICGAO>O-4GDn~a>0m{sEIN9;J+^3g<1k^`=&+KkvsT${Da_9Wb zIp6utx#H%MHz$^yeN&VsF8$~$6wjY}`+{##VK#v$Zd=SHj=hickV3J0Ha~gJADElh z9Yc?0C{sy+?;S^h(o2_Hz#i-(`6%frUAerH|Fi?u&jCp{D2gh$l4cY*kKPSPs~qa) z9E%i)rfD(5N*GouL?SMAOwH0w8to!!-AZIADV`s@y3}`m-TSfjdDE>yapsr%YiGzV z{D!)vifn(#i+z9;`PCEBGM@CK0jW@o^6?*h_2L^pI*y=F@iayQXpvHm%xiuX`pk&bAu=6&|| z5-XR<2h`uvbB0S~kbhik)-CWF5L1 zsGZ&vldoRnC;aixq*?q{qaX9L=lt?L(^_L{jJirbM3~oIEV zmGP4tHSiY$s3b0SpuO#->)!?VhEa4)1akode75L*S5c!}8AIVEcWCWB8p{}Qs;pL{V*eO= zWsygUrQ@i3R%3+}9xV-Lx5o#PH7sC*c7*TD? zCk+G~X+evHdjvg!Ib9>)y)tP#M5)YG0T=+Rb7+zjiJc_S=uV zL}BqXHT6ic5^pIfAF@mI}g{&}GUknBhW?+|N@Ry&LmvZT_yl|mz5xuG)ySDd_ zs@9-OVyG4`#{66xVRjj zlEsr@+%KsxUc}VLY-d{%=2yw9q-O)kYb={FTqURlRTzBFKQBtFF(8IJ@lC{k?Zk6= z>v}w4GFWe0J^x4OKI%XS!-BP!rxvV0joBtu6ulg?`V&Rh^3-95ZGjY^n-T*VEt=R} zRaLh}g;Zset#+O!_~bggxD#-m^2+EgW$u(0S@E9%q4dFS+@Q=z_u#=wsB&}yC^1*h z&>-pJH#+e$zNrT{HO+A8C8MsR$M=Ly!?GQ&t-~#0mew6wiA0(UQ_0;~QZYm%lc!%HJ?88LBf1o_CZ}ByqSjQj}E#Cmq}T&*=Qq9=sy7&wzDc{a+%Zlp)VU=^`k46X?R_pN72Er<}O z36iGJA_FdeswY(5_lMlTn+NfGav5{+^B``j6U$?Gqa;jF PkcemT2}v}#IOzKev1idb