Skip to content

pm-stack(aggregator): overview front door throws on a lined-up task with a non-GitHub ref — reconciledInProgress reaches refUrl unguarded #6205

Closed

Description

@dezren39

Problem

The aggregator's overview — the front door at /, served via /frag/overview and /api/overview.json — throws (500 / dead fragment) whenever the orchestration section contains a goal with an in-progress lined-up task whose ref is not a GitHub owner/repo#N ref, or whose title mentions owner/repo#<number> with a number too large to be a safe integer.

Lined-up tasks legitimately carry non-GitHub refs in the real feed (goal ids, bare numbers — the same data reality behind #6174 and #6195), and the feed gate does not check the field: isLinedUpElement (pm-stack/aggregator/src/feed.ts:223-232) validates title/horizon/status/horizonWhy only. LinedUpTask.ref is typed RefKey (pm-stack/aggregator/src/model.ts:640-642) but nothing enforces that promise at the boundary.

Evidence (verified this run, laptop primary @ 36b346f399)

reconciledInProgress (pm-stack/aggregator/src/render.ts:3552, called by deriveOverview at render.ts:3703) walks orchestration.goals[].linedUp:

  • render.ts:3592-3593 — if (task.ref) { signal(task.ref, "active-session", task.title); continue; } — no validity check.
  • signal → ensure (render.ts:3574) falls back to url: project?.issueUrl ?? item?.url ?? url ?? refUrl(ref) whenever the ref is absent from the pool and the items map (always true for a non-GitHub ref). refUrl → parseRef (model.ts:454-460) throws on anything that is not owner/repo#<safe integer>.
  • Second vector, same function: the no-ref title path first routes through refsInText (render.ts:3596), which correctly filters with isValidRef (model.ts:467-484, the shared pm-stack(aggregator): validateNewComment/validateNewAction accept ref keys parseRef rejects (GH_REF number unbounded) #4952 rule) — then the very next loop (render.ts:3597-3599) re-scrapes the title with a raw matchAll(/([\w.-]+\/[\w.-]+)#(\d+)/g) and signals every match without the safe-integer check, re-admitting exactly what refsInText refused.

Call sites have no guard around the throw: server.ts:1329 (/frag/overview), server.ts:1781 (/api/overview.json), and renderOverview (render.ts:3771, the /?full=1 no-JS path).

Probe (bun, real deriveOverview imported from the tree, ~/git/fleet/probe-overview-ref/probe.ts):

case result
no orchestration section OK, inProgress=[]
lined-up in-progress, ref developing-today/code#42 OK, row url https://github.com/developing-today/code/issues/42
lined-up in-progress, ref goal_a243772844c3 THREW not a repo-qualified ref: goal_a243772844c3
lined-up in-progress, ref 812 THREW not a repo-qualified ref: 812
lined-up in-progress, no ref, title Work on developing-today/code#99999999999999999999 next THREW ref number is not a safe integer: developing-today/code#99999999999999999999
lined-up in-progress, no ref, title Work on developing-today/code#42 next OK
lined-up queued (not in-progress), ref goal_a243772844c3 OK (status gate at render.ts:3591 skips it)

Why it matters

The overview is the aggregator's front door — the first page every viewer (and the dashboard's own refresh fragment) loads. One in-progress lined-up task with a goal-id or numeric ref takes the whole overview down for everyone until the orchestrator's next run happens to change the lined-up set; it does not degrade to a missing row. This is a different surface and failure mode from its siblings: #6174 (/today objectives, render.ts:3368), #6195 (board in-flight lane swallowed by a catch, sources/live.ts:634), #4316 (lined-up blockedBy gate → todayFromSection). Same root family: consumers reaching parseRef/refUrl without routing through the shared isValidRef rule (#4952).

Acceptance criteria

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/normalOrdinary priority (the default)
    on Nov 5, 2026
  2. developing-today commented on Nov 5, 2026

    @developing-today
    Contributor
  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    app/pm-stackpm-stack (Pad/Grist) in developing-today/code
    on Nov 5, 2026
  4. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  5. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 5, 2026
  6. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · claimed

  7. 2 remaining items

  8. added
    queue/queuedHas a queued task in the Supabase agent queue
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 5, 2026
  9. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  10. added a commit that references this issue on Nov 5, 2026
  11. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/pm-stackpm-stack (Pad/Grist) in developing-today/codekind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobstatus:donetask/triageQueue packet kind: verify, reproduce, and route this item

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions