You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- portal-discovery: a predecessor extension's failure now PROPAGATES (await earlier
without swallowing) so a successor can never confirm coverage over an unscanned
gap (B1/G2 — silent factory-child loss reproduced in review).
- portal.ts: per-fetch RowToken accounting (S1 — a stale evicted fetch can't
register/free rows against its replacement); coveredTo recorded per cache entry;
INV-9 runtime assert at request build; INV-12 stash assert now strict-mode-only
(production keeps pre-refactor overwrite semantics + debug log, S2);
refreshPortalHead retry via client (injectable sleep, S5k).
- portal-client: finalizedHeadRetry; countRows includes headers (S5g); dead
NoProgressError guard removed — progress is by construction (B4c).
- portal-errors: NoProgressError deleted; InvariantViolation message points at
INVARIANTS.md + PORTAL_CHECKS escape hatch (S5b).
- portal/config.ts restored (repo-side compat-harness utility — B2); PUBLISHING.md
stale sentence fixed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
// INV-9: a Portal data request never targets past the known finalized head (an explicit backfill
129
+
// toBlock may exceed it by configuration — the delegation branch already guards served intervals).
130
+
invariant("INV-9",portalHead===undefined||to<=portalHead||spec.backfillEnd!==undefined,"data request targets past the Portal finalized head",()=>({ idx, to, portalHead }));
131
+
consttoken: RowToken={rows: 0,freed: false};
132
+
// G3: register rows as batches ARRIVE. Guarded by the token so a stale stream that outlives its
133
+
// eviction cannot register orphaned rows (S1: accounting is per-fetch, not per-idx).
awaitdiscovery.ensure(to,{ chunkBlocks,endHint: spec.backfillEnd??portalHead??to});// children ≤ this chunk are known
119
137
invariant("INV-3",spec.factories.length===0||discStartIdx===undefined||discovery.through()>=to,"data fetch under a stale discovery watermark",()=>({ idx,through: discovery.through(), to }));
120
138
stats.dataChunks++;
121
139
constcd=createChunkData();
122
140
constneededMissing=newSet<string>();
123
-
constonRows=(n: number): void=>{chunkRows.set(idx,(chunkRows.get(idx)??0)+n);gate.addRows(n);};// G3: register as batches arrive
invariant("INV-12",!stash.has(ikey(interval))&&!delegated.has(ikey(interval)),"stash entry created twice / for a delegated interval",()=>({key: ikey(interval)}));
255
+
// INV-12: a stash entry is created then consumed exactly once. An upstream retry can legitimately
256
+
// re-issue a range, so production (`on`) keeps the pre-refactor OVERWRITE semantics with a debug
257
+
// log; `strict` (tests/CI) makes the double-set loud.
258
+
invariantStrict("INV-12",()=>!stash.has(ikey(interval))&&!delegated.has(ikey(interval)),"stash entry created twice / for a delegated interval",()=>({key: ikey(interval)}));
0 commit comments