Skip to content

aggregator: Needs-you 'Newest first' sorts tier cards by lastSeenAt while 'Oldest first' sorts by since — the two orders are not reverses, and a 30-day-old card can lead 'Newest first' #1485

Closed

Description

@dezren39

Summary

The Needs-you card order preference (#1456, closed) applies its sorts at render in pm-stack/aggregator/src/render.ts, but the two age orders use different timestamp axes:

  • newest sorts by seenMs — the card's lastSeenAt (render.ts:2303)
  • oldest sorts by sinceMs — the card's since (render.ts:2304)

For session cards both fields are the same value (lastActivityAt, render.ts:2284-2289), so the orders are exact reverses there. For tier-item cards they diverge: sinceMs = Date.parse(item.since) and seenMs = Date.parse(item.lastSeenAt) (render.ts:2295-2296). since is when the item entered the queue; lastSeenAt is refreshed whenever the publisher last saw the underlying item — so under "Newest first", a card that has been waiting 30 days but was seen 5 minutes ago outranks a card that entered the queue 1 hour ago. The two options present as opposite ends of one axis ("Newest first" / "Oldest first", render.ts:2151-2152) but are not reverses of each other.

Verified evidence (this run, main 49e6708)

Probe on the laptop (verbatim pm-stack/aggregator/src tree; render.ts sha256 005acc70… and derive.ts sha256 312ac0fb… identical on sandbox main and the laptop copy; Bun 1.4.2; probe ~/git/fleet/probe-2026-10-27-laneA-needsorder there, log hidden_files/probe-2026-10-27-laneA-needsorder/out.log in the goal workspace). Two tier cards rendered through the real buildAttention + renderAttention with needsOrder set:

  • NEWCARD: since = 1h ago, lastSeenAt = 2h ago
  • OLDCARD: since = 30d ago, lastSeenAt = 5m ago

Result:

newest: [ "OLDCARD", "NEWCARD" ]   ← the 30-day-old card leads "Newest first"
oldest: [ "OLDCARD", "NEWCARD" ]   ← identical order — not a reversal
control newest: [ "NEWCARD", "OLDCARD" ]
control oldest: [ "OLDCARD", "NEWCARD" ]

The control pair (where since and lastSeenAt agree in ordering) reverses correctly, which isolates the defect to the axis mismatch, not the sort machinery. The deadline order also ties/falls back on seenMs (render.ts:2305: a.rank - b.rank || b.seenMs - a.seenMs), so it inherits the same question.

The existing test suite only pins newest with cards that differ solely in lastSeenAt and share one since (test/dashboard-overhaul.test.ts:274-286, BASE since at :29) — oldest has no render test at all.

Why it matters

The Needs-you list is Drew's triage surface; the saved order is a standing preference he set (#1456). "Newest first" that actually sorts by last-seen buries genuinely new arrivals under long-waiting cards that the orchestrator merely re-saw in its latest run — the opposite of what the control promises — and "oldest"/"newest" giving the same list makes the preference look broken.

Acceptance criteria

  • newest and oldest sort tier-item cards on a single, documented axis (the natural reading: the card's queue age, since — matching what oldest already does), so the two orders are exact reverses for the same card set.
  • Session cards keep behaving as today (their since/lastSeenAt are the same instant).
  • The deadline tiebreak is decided consistently with the chosen axis and the choice is noted in a code comment.
  • Regression tests in pm-stack/aggregator/test/dashboard-overhaul.test.ts cover tier cards whose since and lastSeenAt orderings disagree, for both newest and oldest (the divergent case above), plus the agreeing control.
  • Full aggregator test suite passes in CI.

Filed by new-issue-creator-code-a (Lane A), verified this run. Related: #1456 (the feature this fixes), #1474 (sibling card-state derivation bug, different function).

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)
    queue/queuedHas a queued task in the Supabase agent queue
    effort/sSmall: expected under 2 hours of work
    on Oct 27, 2026
  2. developing-today commented on Oct 27, 2026

    @developing-today
    Contributor
  3. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: filed

  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed on Oct 28, 2026
  5. 17 remaining items

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

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  8. added
    queue/claimedQueue worker lifecycle state
    and removed
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    on Oct 28, 2026
  9. added a commit that references this issue on Oct 28, 2026
  10. dezren39 commented on Oct 28, 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

Labels

app/aggregatorPackage/app: aggregator (pm-stack in this repo)effort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobstatus:done

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions