Repository navigation
Description
Bug
pm-stack/aggregator — the fleet feed's top-level gate isFleetFeed checks only that attention is an array, never its entries, and the live source is the one feed consumer that does not element-filter its array before use. One malformed entry therefore takes down the attention and today surfaces instead of being dropped like every sibling section's bad entries are.
Evidence (verified this run, main 5a34fa70)
- Gate:
src/feed.ts:207-219—isFleetFeedrequiresversion === 1, a parseablegeneratedAt, aquotaobject with an arraypools, andArray.isArray(f.attention). Nothing checks that attention entries are objects, or thatsessionId(the field every consumer keys on,src/model.ts:316) is a string. - Unguarded consumer:
src/sources/live.ts:864-896—attention()runsfor (const e of feed.attention) byId.set(e.sessionId, e)(line 873) with no filter and no try/catch around the feed loop (the laptop-sessions half below it is fail-soft). Every other array the live source ingests is element-filtered first: registry records viaisSessionRecord(live.ts:611, 980), project pool items viaisProjectPoolItem(live.ts:703, 742), snapshot records viaisSnapshotRecordinsideSnapshotStore.append(snapshots.ts). Attention is the exception. - No rescue downstream:
server.tsattentionContext()(line 237) andtodayContext()(line 308) awaitsource.attention()with no.catch, andfetchHandler(line 794) has no top-level catch — so the throw surfaces as a failed request on/attention,/today,/frag/attention/*,/api/attention.json, and/api/today.json.
Laptop probe (~/git/fleet/probe-2026-10-29-laneA-feedattn/, real feed.ts + derive.ts from origin/main — md5-identical to the sandbox clone — Bun 1.4.2, live.ts loop reproduced verbatim):
== control: one well-formed entry
isFleetFeed: true
live byId loop: ok, size = 1 keys = [ "s1" ]
buildAttention: ok, all = 1
== attention [null]
isFleetFeed: true
THROWS: TypeError - null is not an object (evaluating 'e.sessionId')
== two entries, both missing sessionId
isFleetFeed: true
live byId loop: ok, size = 1 keys = [ "undefined" ]
buildAttention: ok, all = 1
- Secondary, silent: entries whose
sessionIdis missing or not a string do not crash — they collide on the singleundefinedmap key (probe: two distinct sessions collapse to one; a42/"x"entry is keyedundefinedtoo), so sessions silently vanish from the attention view with no error anywhere.
Why it matters
The feed file is produced by a different job (the collector) and already has a house pattern for exactly this failure class: validate at the gate or filter at the consumer, degrade to the remaining good entries, never let one bad record fail the whole facet (see the dns/aa/orchestration/registry section validators). Attention missed that treatment, so a single corrupt or schema-drifted session entry — e.g. a collector change emitting a null placeholder — blacks out the two most-used pages (/today, /attention) instead of dropping one session, and subtler drift (a renamed/dropped sessionId) silently under-reports live sessions.
Acceptance criteria
- A feed whose
attentionarray contains anull, a non-object, or an entry without a stringsessionIdno longer throws inattention(): the malformed entries are dropped (at theisFleetFeedgate or filtered in the live source, matching the registry/projects pattern — triage pins the layer) and the well-formed entries still render on /attention and /today. - Entries are never silently merged under an
undefined/non-string key: either they are rejected by the same validation, or the dedupe key is only ever a validated string sessionId. - Regression tests (aggregator test suite) cover:
[valid, null]renders just the valid entry; two entries missingsessionIddo not collapse into one rendered session; a fully well-formed feed is unchanged. - The gate/filter choice is consistent for the collector's own use of
isFleetFeed(scripts/collect-fleet-feed.ts imports the same gate) — a stricter gate must not make the collector reject its own emitted feed.
Dedup
gh searches (open + closed) for "isFleetFeed" and "feed attention entries" return only #2242 (health section stamps — different fields/functions) and #1176 (open, a broad contract-test-suite impl request across all publisher→collector→aggregator schemas; it does not name this crash, and every sibling section validator — #2376 registry, #2408 taskRefs, #2415 aa, #2412 dns, #2417 orchestration — was filed individually alongside it). No open or closed issue covers attention-entry validation.
Activity
developing-today commentedon Oct 29, 2026
CODE-1239
dezren39 commentedon Oct 29, 2026
🤖 Agent note · filed
dezren39 commentedon Oct 29, 2026
Cross-link: sibling filed this run — #2429 covers the same gate's quota section (burn/choices, pool entries, windows unvalidated; /quota crash). The two triages should pin a consistent gate-vs-filter layer.
76 remaining items
dezren39 commentedon Nov 2, 2026
agent-note:v1 — parked
Agent: repo-worker-code (OpenChamber scheduled lane)
Task: repo-health-code-pilot task 5324
At: 2026-11-02T10:42:36Z
State: parked
Fresh evidence: #2427 is OPEN and assigned to dezren39 (Drew); canonical PR #4184 is OPEN, non-draft, and authored by dezren39 on queue/5324-2427-feed-attention-filter.
Disposition: parked for 30 minutes at the Drew-owned hard stop. No PR contents, checks, reviews, branch, or saved worktree inspected or touched. Labels reflect parked state; work/assigned remains set.
Resume condition: PR closes or Drew explicitly releases ownership; revalidate fresh before proceeding.
Links: #2427 · #4184 · task 5324
dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
pm-stack/aggregator/src/sources/live.ts+ the new regression test file, all 4 new tests for issue aggregator(feed): isFleetFeed never checks attention entries — one null entry crashes /attention + /today, entries without a string sessionId silently collapse into one #2427 pass in its CI run, and there are no Codex findings on PR fix(aggregator): drop malformed feed attention entries before live dedupe (#2427) #4184. Its CItestcheck fails on exactly two tests (slice-3 routes > dns + sessions + pages routes serve;hub renders > service detail) that fail identically on clean main (run 41403655888) — pre-existing, unrelated to this change.Merge pull request #4184 from developing-today/queue/5324-2427-feed-a…
dezren39 commentedon Nov 2, 2026
🤖 Agent note · done
test/feed-attention-filter-2427.test.tspass in CI run 41391931885 (969 pass overall); no Codex findings on PR fix(aggregator): drop malformed feed attention entries before live dedupe (#2427) #4184. The check's 2 failures (slice-3 routes > dns + sessions + pages routes serve,hub renders > service detail: full metrics, chart, reads, conflicts) fail identically on clean main (run 41403655888) — pre-existing and unrelated to this change; noted in the code backlog.