Skip to content

Pre-#1708 tasks rows are corrupt, indistinguishable, and rendered by the Observatory Sessions tab — accept, caveat, or document #1969

Description

@macanderson

Problem

#1708 (fixed by PR #1967) let sub-session workers upsert their own task boards over the lead session's tasks rows for as long as deck sub-sessions have shipped. PR #1967 stops new corruption; it cannot repair what existing databases already hold, and those rows are user-visible.

Two kinds of residue sit in every .stella/private/store.db whose sessions used task_assign or mid-turn dispatch:

  1. Overwritten lead rows. A worker's task "1" replaced the lead's task "1" — subject, description, status and owner all came from the worker. For a session that is still live these heal on the driver's next board mirror (it upserts the lead's true state back). For a session that has ended they are permanently wrong, because nothing will ever write that key again.
  2. Stray rows above the lead's ordinal range. A worker board longer than the lead's left rows at ordinals the lead never had. Nothing overwrites those and nothing deletes them short of /clear on that session — the same "stale-row half" already documented in crates/stella-store/src/task_board.rs's module docs as the reason /clear deletes rather than supersedes.

Why this is not simply a cleanup migration

The rows are indistinguishable by construction — that is precisely #1708's complaint. tasks records no lane and no provenance, so after the fact there is no predicate separating "the lead's row" from "a worker's row that landed on the lead's key". A migration cannot repair (1) at all, and can only guess at (2) by comparing against a board length the table does not store.

So this is a decision, not a patch.

Where it is visible

Repro

On any store predating PR #1967 that ran a delegated worker with its own task_create calls:

SELECT session_id, task_id, subject, owner FROM tasks ORDER BY session_id, CAST(task_id AS INTEGER);

Rows whose owner names a sub:/req: lane while the subject describes work the lead never planned are the overwritten kind; rows at ordinals beyond what that session's board ever reached are the stray kind. stella observe → Sessions → an affected session renders both.

Definition of done

A maintainer's call between:

  • Accept and say so — a note in crates/stella-store/src/task_board.rs's module docs recording that rows written before PR fix(stella-cli): stop a worker mirroring its private board over the lead's tasks rows (#1708) #1967 may mix lead and worker boards and cannot be told apart, so the Observatory's pre-fix session views are approximate. Cheapest, and arguably right for a local telemetry table.
  • Caveat in the UI — the Observatory marks a session's task list as untrustworthy when the session has any deck-sub execution and predates the fix (executions.started_at vs. the release, joined on session_id). More honest, more code, and needs a version marker the DB does not currently carry.
  • Offer a manual escape hatch — document that /clear on an affected live session deletes its mirror (Store::clear_session_tasks), which is already the only correct repair available. Does nothing for ended sessions.

Whichever is chosen, the outcome belongs in crates/stella-store/src/task_board.rs's module docs, beside the existing /clear rationale, so the next reader of that table learns it from the table.

Refs #1708, #1692, #1876. Follows PR #1967.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:clistella-cli — commands, flags, wiringtriageUntyped request — convert by adding bug / feature / epic

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions