Repository navigation
Description
Phase 2 of design #2576 (aggregator ingest, fail-closed). Design doc: files/designs/code-aggregator-ingest-contract.md in the keep-the-four-repos-healthy goal workspace. Gated on Phase 1 (the validate.ts primitives) — status/blocked until it lands.
Scope
Put the feed and snapshot boundaries on the shared primitives from Phase 1 of #2576:
isFleetFeed(src/feed.ts) deep-validates pool, window, and attention elements — a malformed pool element is dropped and counted, never crashes/quota(aggregator(feed): isFleetFeed checks only that quota.pools is an array — burn/choices, pool entries and windows unvalidated, one malformed pool crashes /quota #2429); attention entries without a stringsessionIdare handled per the contract (aggregator(feed): isFleetFeed never checks attention entries — one null entry crashes /attention + /today, entries without a string sessionId silently collapse into one #2427).isAaSection(src/aa.ts) checks thresholds and sources (aggregator(aa): isAaSection never checks thresholds or sources — a section missing them passes the gate and crashes the /aa render instead of degrading #2415);isDnsSection(src/dns.ts) checkstotalAnnualListUsdand entrypriceUsd(aggregator(dns): isDnsSection never checks totalAnnualListUsd or entry priceUsd — a feed section that passes validation crashes /dns and the usage view on .toFixed #2412);isOrchestrationSection(src/feed.ts) checks tier/goal array elements (aggregator(orchestration): section gate never checks tier/goal array elements — a [null] tier item or goal task passes validation and crashes buildAttention/todayFromSection #2417); registrytaskRefselements validated before merge/persist (aggregator(registry): malformed taskRefs elements pass every gate and crash /sessions at render — an array of bad refs merges, persists, then refUrl throws #2485).isSnapshotRecordcheckslimitandresetsAt(aggregator(snapshots): isSnapshotRecord never checks limit/resetsAt — a numeric resetsAt crashes the service history chart, a non-numeric limit NaNs it #2483);SnapshotStorerefuses records it cannot read back (aggregator: SnapshotStore accepts records it can never read back — non-finite estimate pairs and non-ISO timestamps pass validation, append reports success, and dedupe never sees them #1540);freshestDateand the DNS register compare only real calendar dates (aggregator(snapshot-records): shape-only dates win freshestDate — a 2026-13-01 'Last checked' silently drops a pool's snapshot history, 2026-02-30 is stored as a phantom March date #2264, aggregator(dns): parseDnsRegister accepts impossible renewal dates — 2026-02-30 and 2026-13-01 enter the register, count toward the annual total, and string-sort into wrong positions #2199 as it touches this boundary); sectiongeneratedAtstamps validated, future stamps not treated as maximally fresh (aggregator(health): dns/aa section stamps are never validated — a garbage dns generatedAt renders ageMs NaN/null, a future aa generatedAt renders age 0 (maximally fresh) for as long as the skew lasts #2242).
Named scope rule (from the design)
For each of #2412 #2415 #2417 #2427 #2429 #2485 #1540 #2264 #2483 #2242: if still open when this phase starts, this phase closes it with evidence; if already closed per-site, verify its guard uses validate.ts (convert if it hand-rolled) — never re-fix a landed fix.
Acceptance criteria
- Every guard named above is expressed via
validate.tsprimitives; no new private finite/date guards are introduced in the touched files. - A feed document with one malformed pool/session/billing element renders the valid remainder and counts the drop; no ingest path in scope throws across the boundary.
- Snapshot append refuses an unreadable or out-of-range record and reports the refusal.
- Probe-matrix tests cover each converted boundary with its issue's repro shape.
- Verification runs in CI per fleet policy (no builds on the sandbox).
🤖 Design-architect pass 18 — agent note: phase of design #2576; the decisions are recorded there and in the design doc. Do not re-derive them in triage; flag genuine blockers on #2576 instead.
Activity
dezren39 commentedon Oct 30, 2026
🤖 agent-note:v1 — design-architect pass 18 (2026-10-30): Phase 2 of design #2576, gated on Phase 1 (#2577) — status/blocked + queue/queued reflect that gate; when #2577 lands, triage confirms scope against current main (checking each named issue: still open → this phase closes it; already closed per-site → verify/convert its guard), settles what it can, and enqueues the implementation follow-up. Do not implement in the triage task.
dezren39 commentedon Oct 30, 2026
🤖 Agent note · done — triage verdict (queue task 3830)
Gate state: NOT CLEARED. Phase 1 (#2577) is still OPEN (labels at 2026-10-30T22:25Z:
status/needs-triage,queue/queued— its own triage has not run, let alone landed), and currentmain'spm-stack/aggregator/src/listing contains novalidate.ts. This issue correctly keepsstatus/blockeduntil #2577 lands. The implementation packet states the gate as its first acceptance item: a claiming worker revalidates and parks if the gate is still unmet.Scope confirmed against current main (2026-10-30T22:25Z), no rescope needed:
src/feed.ts:244-257—isFleetFeedis still top-level only (version, parseablegeneratedAt, quota object +poolsarray exists,attentionarray exists): no pool/window/attention element validation. aggregator(feed): isFleetFeed checks only that quota.pools is an array — burn/choices, pool entries and windows unvalidated, one malformed pool crashes /quota #2429 and aggregator(feed): isFleetFeed never checks attention entries — one null entry crashes /attention + /today, entries without a string sessionId silently collapse into one #2427 gaps are live as scoped.src/snapshots.ts:295—isSnapshotRecordnever checkslimit/resetsAt(aggregator(snapshots): isSnapshotRecord never checks limit/resetsAt — a numeric resetsAt crashes the service history chart, a non-numeric limit NaNs it #2483 live), and its estimate-pair branch checkstypeof low/high === "number"only, so non-finite pairs pass — the aggregator: SnapshotStore accepts records it can never read back — non-finite estimate pairs and non-ISO timestamps pass validation, append reports success, and dedupe never sees them #1540 readback gap is live as scoped.Follow-up enqueued: implementation packet
repo-health:v1:fix:developing-today/code:issue:2578(kind small_fix, priority 30) with this issue's acceptance criteria intact and the gate as acceptance item 1. Labels left truthful:queue/queued(the follow-up),status/blocked(the gate).79 remaining items
dezren39 commentedon Oct 31, 2026
🤖 Agent note · parked
QuotaView.dropped, projected by /api/quota.json) and in the live source's quota provenance string; (2) retained choices are reconciled to surviving pools with usable windows, mirroring computeChoices(). Threads replied + resolved; re-review requested. Laptop: feed.test.ts 17/17 pass; full aggregator suite 695 pass with only the 7 pre-existing main failures (page-manifest/overview set). Parked 30m on the Codex re-review of the new head.dezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up (resume)
Merge pull request #3070 from developing-today/queue/4006-2578-phase2…
dezren39 commentedon Oct 31, 2026
🤖 Agent note · done