Skip to content

Project board's Task completion median is always —: the metric waits for a status and a stamp the store never writes #1884

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.
Written-by: FlyBot Lead

Defect

The Project board's Task completion median (taskDoneMedianMs, the —/number under "Task completion") is always — on a real deployment, because doneTaskDurations waits for a status and a stamp that no host path ever produces.

  • core/src/host/project-metrics.js:56-70 (on 33e9c6d5) keeps a task only when task.status === 'done' and Number.isFinite(task.completedAt).
  • A card finishes through transition(task, 'accepted') (core/src/host/tasks.js:269-279), which writes only status, updatedAt and an entry on actors ({ status, at }); TRANSITIONS ends at accepted / cancelled / failed, so 'done' is never a record status.
  • completedAt is read in project-metrics.js and written nowhere in the repository — a card that reached the board's Done column has no such field.
  • core/src/shared/task-board.js:8-19 maps accepted / cancelled / failed to the done column; a literal 'done' status is not in that table and would paint as not-started.
  • docs/subsystems/core-host.md:793 promises fields the host never writes (reads createdAt / completedAt from state.tasks).

Existing tests (core/test/project-metrics.test.js:119-121, core/test/project-metrics-scope.test.js:43,46) hand-write status: 'done' plus completedAt, which is exactly the false-green shape: the fixtures assert a record the store cannot produce.

Reproduction (clean 33e9c6d5, sources unchanged, only core/test/project-metrics.test.js taken from the fix)

A card in the shape the store really writes — status: 'accepted', createdAt 10h ago, actors: [open@-10h, claimed@-6h, accepted@-1h], no completedAt — must contribute 9h (32400000). It contributes nothing:

$ TZ=UTC node --test test/project-metrics.test.js
not ok 10 - the task median reads the store stamps only
    null !== 7200000
not ok 13 - a card that finished the way the host finishes cards is a done duration
    null !== 32400000
# tests 14 / # pass 12 / # fail 2

The two null guards pass on the base by design — nothing is counted at all today, so they only start guarding the accepted-only rule once the first line turns green.

Expected behaviour

One rule, read from the board's own column table — no second status table, no invented state, no back-filled completedAt:

  • a card counts when columnOf(task) === 'done' and task.status === 'accepted'; cancelled and failed are in the done column but never completed, so they are skipped (the card's caption is "created to done");
  • its duration is createdAt → the at of the last terminal entry on actors, falling back to completedAt (finite) and then updatedAt for records without actors;
  • the seven-day window still compares that end instant; an empty window or a board whose only done-column cards were cancelled/failed answers null (the client's —), never 0;
  • docs line core-host.md:793 states the real source.

Scope

  • core/src/host/project-metrics.js and its mirror patches/ds-bot/files/src/host/project-metrics.js
  • the red-first cases themselves, inside core/test/project-metrics.test.js (and its mirror)
  • fixture corrections in core/test/project-metrics.test.js and core/test/project-metrics-scope.test.js (the status: 'done' fixtures above, changed to the status the host writes) plus their mirrors
  • docs/subsystems/core-host.md:793, one changelog fragment; generate + check three lines stay green

No client change, no shared/task-board.js change, no state-machine change.

Dedupe

search/issues on live main: taskDoneMedianMs → only #1880 and #1848 (both closed; they scope the same metric to one board), completedAt → 0 hits. This defect is a different one: the metric waits for a status and a stamp the store never writes.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions