Skip to content

aggregator(feed): a goal lined-up task's blockedBy is never gate-checked — a string or [null] blockedBy passes isGoalMeasurement and todayFromSection throws #4316

Open

Description

@dezren39

Finding

The #2417 fix (merged today in PR #4176, main c611bf4) deepened the orchestration section gate for the section's top-level arrays: dependencies elements must now pass isDependencyElement (string task, status in the DependencyRef union, string-typed optional fields), and tier/action elements gained field checks. Inside goals, however, isGoalMeasurement checks linedUp/stalled elements only with isRecord — and a lined-up task's blockedBy field, declared as the very same DependencyRef[] shape, is not checked at all. todayFromSection's blockedText helper calls .map on it, so a gate-passing goal whose lined-up task carries a malformed blockedBy crashes the today view instead of the section being diagnosed invalid and falling back to the derived view.

Scope boundary with #3897 (open): that issue's acceptance criteria enumerate the linedUp element checks as title/horizon/status/horizonWhy and the goal-level fields — blockedBy is not named in it, and a fix implementing those criteria verbatim leaves both crashes below alive. This issue covers only the blockedBy field; everything else in the goal gate stays #3897's.

Evidence (main c611bf4, verified this run)

  • pm-stack/aggregator/src/model.ts:615-623 — LinedUpTask.blockedBy?: DependencyRef[]; DependencyRef is the shape isDependencyElement validates for top-level dependencies.
  • pm-stack/aggregator/src/feed.ts — isGoalMeasurement (:197-212, after aggregator(orchestration): section gate never checks tier/goal array elements — a [null] tier item or goal task passes validation and crashes buildAttention/todayFromSection #2417): g.linedUp.every(isRecord) and g.stalled.every(isRecord) are the only element checks; no clause touches blockedBy. isDependencyElement (:241) shows the house rule for the identical shape one array over.
  • pm-stack/aggregator/src/derive.ts:688-690 — blockedText does deps?.length ? deps.map(...) : undefined; :698 and :714 call it on task.blockedBy unguarded. A string has a truthy .length but no .map; a [null] element reaches d.task on null.
  • Laptop probe (~/git/fleet/probe-2026-11-02-laneA-goalblockedby/, verbatim src/ from main c611bf4 — feed.ts md5 fcfbd045, derive.ts md5 dcdefb5e, both matched to the sandbox clone), importing the real isOrchestrationSection/orchestrationSectionProblem and todayFromSection:
    • Control (blockedBy: [{task, status}]): gate true, today renders blocked by dep-1 (in-progress).
    • blockedBy: "waiting on dep-1" (string): gate true, problem null → todayFromSection throws TypeError: deps.map is not a function.
    • blockedBy: [null]: gate true, problem null → throws TypeError: null is not an object (evaluating 'd.task').
    • blockedBy: [{}]: gate true → renders the falsified text blocked by undefined (undefined).

Why it matters

The orchestration section is machine-published JSON read fail-soft by design: a malformed section is supposed to be diagnosed (goals (per-goal shape)) and demoted to the derived view. #2417 closed that hole for the section's top-level dependencies array; the identical field nested one level deeper in goals still turns one drifted publisher line into an uncaught TypeError on the today path — or, for [{}], silently falsified blocker text presented as measured state.

Acceptance criteria

  • isGoalMeasurement (or a helper it uses) validates each lined-up task's blockedBy when present: an array whose every element passes the same DependencyRef rule the gate applies to top-level dependencies (reuse isDependencyElement rather than duplicating the rule).
  • A section failing only on blockedBy is diagnosed through the existing machinery: orchestrationSectionProblem reports goals (per-goal shape), the section falls back to the derived view, and todayFromSection can no longer be reached with a blockedBy it throws on.
  • Regression tests beside the aggregator(orchestration): section gate never checks tier/goal array elements — a [null] tier item or goal task passes validation and crashes buildAttention/todayFromSection #2417 orchestration gate tests cover at least: blockedBy as a string, blockedBy: [null], blockedBy: [{}] — all rejected — plus the well-formed blockedBy control still passing and rendering.
  • Existing aggregator tests stay green.

Dedup: #3897 (open) covers the goal gate's element/field checks but its enumerated criteria omit blockedBy (see scope boundary above); #2417 (closed, fix merged c611bf4) covered top-level dependencies, tiers, actions, and record-ness of goal elements. No open or closed issue names blockedBy in a goal (title search: no hits).

Filed by new-issue-creator-code-a (Lane A) from a verified laptop probe; filed only, not self-solved — the gate-criteria coordination with #3897 is a triage call.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/aggregatorPackage/app: aggregator (pm-stack in this repo)
    app/pm-stackpm-stack (Pad/Grist) in developing-today/code
    effort/sSmall: expected under 2 hours of work
    on Nov 2, 2026
  2. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    state: filed
    Found via: filed this run (new-issue-creator-code-a, Lane A) — residual of the #2417 gate deepening merged today (c611bf4): top-level dependencies gained isDependencyElement, but a goal lined-up task's blockedBy (same DependencyRef[] shape) has no gate clause, and todayFromSection's blockedText calls .map on it. Verified on the laptop with verbatim sources at c611bf4 (feed.ts md5 fcfbd045, derive.ts md5 dcdefb5e): string and [null] blockedBy pass the gate and throw TypeError; [{}] renders "undefined (undefined)". Probe: ~/git/fleet/probe-2026-11-02-laneA-goalblockedby/. Scope is blockedBy only — the rest of the goal gate remains #3897's. Filed only; enqueued for triage.

  3. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  4. 153 remaining items

  5. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — agent=repo-worker-code state=picked-up task=6396 lane=8ac61616-3815-4e7b-b33d-840a3829154a at=2026-11-04T17:43:43Z
    Claimed this queue task and checkpointed before work. Fresh metadata-only revalidation found issue #4316 open and its exact fix already owned by Drew-authored PR #4581; no PR, branch, or worktree was inspected or changed.

  6. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — agent=repo-worker-code state=parked task=6396 lane=8ac61616-3815-4e7b-b33d-840a3829154a at=2026-11-04T17:45:53Z resume=PR-4581-merged-closed-or-ownership-changes
    Parked for 30 minutes because PR #4581 remains OPEN, authored by Drew/dezren39, and covers this exact fix at queue/6396-4316-gate-blockedby@fafdebb6c2afe112f21531d5c1ff875605ec6a2a. Do not edit, inspect, merge, or duplicate it. Revalidate #4316/#4581 when resuming.

  7. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — agent=repo-worker-code state=picked-up task=6396 lane=8ac61616-3815-4e7b-b33d-840a3829154a at=2026-11-05T01:42:52Z
    Claimed and checkpointed with origin=openchamber-scheduled-lane. Fresh metadata-only revalidation: issue #4316 is OPEN; exact-fix PR #4581 is OPEN, Drew/dezren39-authored on queue/6396-4316-gate-blockedby at fafdebb. I did not inspect or touch the PR contents, branch, or worktree. Active ownership conflict; next action is park for 30 minutes and resume only after #4581 merges/closes or ownership changes.

  8. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — agent=repo-worker-code state=parked task=6396 lane=8ac61616-3815-4e7b-b33d-840a3829154a at=2026-11-05T01:42:52Z resume=PR-4581-merged-closed-or-ownership-changes
    Queue task 6396 parked for 30 minutes after fresh metadata-only verification confirmed issue #4316 OPEN and exact-fix PR #4581 OPEN/Drew-authored on queue/6396-4316-gate-blockedby at fafdebb. No PR contents, branch, or worktree were inspected or changed; no duplicate work was created. Issue labels already reflect parked state (queue/parked, status/parked); work/assigned retained. Revalidate issue, PR state/head/ownership before resuming.

  9. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 5, 2026
  10. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  11. 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
  12. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

    • Agent: fleet monitor
    • Session / ID: task 6396 (repo-fleet-monitor run 2026-11-05T15:39:47Z)
    • Found via: monitor reconciliation (Duty 1 claim/label divergence repair)
    • Task: Claim evaporated: task 6396 is queued and unclaimed in repo-health-code-pilot, but this issue still carried claimed labels. Labels reset to the truth (queue/queued + status/needs-triage). Checkpoint stage at evaporation: handed_off.
    • Expectation: The next lane claim picks task 6396 up from the queued state and posts a fresh pickup note.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/aggregatorPackage/app: aggregator (pm-stack in this repo)app/pm-stackpm-stack (Pad/Grist) in developing-today/codeeffort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)queue/queuedHas a queued task in the Supabase agent queuesource/creatorFiled by the new-issue-creator jobstatus/needs-triageNot yet triaged; needs a first looktask/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