Skip to content

fix: a status set without a time doesn't keep the old one (MUS-113) - #197

Merged
Castor-o7 merged 2 commits into
mainfrom
mus113/status-time-not-stale
Nov 7, 2026
Merged

Castor-o7 merged 2 commits into
mainfrom
mus113/status-time-not-stale

Conversation

@Castor-o7

Copy link
Copy Markdown
Owner

MUS-113, the follow-up the watchman found while reading MUS-101. This is stacked on #184. Its base is feat/roster-status-age, so the diff shows only this change. Merge it after #184 and retarget it to main.

The gap: the TypeScript plugins set the status with SetSessionCurrentTask alone. That left the current_task_at from an earlier status sitting beside the new one, so a fresh status could read as hours old.

The fix: SetSessionCurrentTask is now written by hand in crates/entities/src/session.rs instead of being generated by #[myko_setter]. It keeps the same command name and the same wire shape ({id, currentTask}), so no client changes.

  • When it sets a status, it stamps current_task_at with the daemon's clock.
  • When it clears the status, it clears current_task_at too.

So every client, the plugins included, gets a true age from that one command. The shim still sends SetSessionCurrentTaskAt afterwards, because an older daemon needs it. On a new daemon that second command only replaces the stamp with the shim's own clock's.

Why stamp rather than only clear: clearing would rely on the shim's two commands being applied in order. If they ran the other way round, the age would vanish. Stamping gives the right answer in either order. It also covers three of the follow-ups listed under MUS-101: the daemon stamps the time, the plugins get ages, and the status and its time are set in one command.

Tests: crates/daemon/tests/status_time.rs sends the plugins' JSON shape over a stale time. It checks that the time is replaced with now, that clearing the status leaves no time and keeps the rest of the row, and that an unknown session is refused. With the old generated setter, the stale time stays and the first test fails.

Local results: fmt, clippy --workspace --all-targets -D warnings and cargo test --workspace are clean. I didn't run the plugin TS tests, because there's no bun here.

🤖 Generated with Claude Code

SetSessionCurrentTask is hand-written in place of the #[myko_setter], under
the same name and wire shape ({id, currentTask}), and stamps current_task_at
with the daemon's clock as it sets the status, or clears it with the status.
A TypeScript plugin sets the status with that command alone, so before this
the time an earlier status left stayed beside the new one and a fresh status
read as hours old. The shim still follows with SetSessionCurrentTaskAt for an
older daemon.

Story: MUS-113
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Castor-o7
Castor-o7 changed the base branch from feat/roster-status-age to main November 7, 2026 03:36
Retargeted to main after #184 landed. The roadmap keeps MUS-113's entry and
main's MUS-104 entry; the changed lines are identical to 529701e's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Castor-o7
Castor-o7 merged commit 95c447c into main Nov 7, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant