Run monitor: show what a submitted job is doing - #9
Conversation
A submitted job disappeared. The designer stayed on the editing view, and the only way to learn whether anything was happening was to reload and read a status string. Every unit already carries a `statusTrack`; nothing read it. - `src/runMonitor.ts` — pure derivation: per-unit rows (status, start, duration) and a run summary. 25 unit tests. - `RunMonitor` — a MetricTile strip over a progress meter, one row per unit with its status chip and duration, and a log tail. - `ResultsTab` gains `showRunMonitor`, opt-in like the rest of the guided designer. It settles rather than switching: when the last unit reaches a terminal status the same rows become the record of the run, so the reader is not moved elsewhere at the moment they most want to look. Judgements worth review: - **A failed run is not 100% complete.** `progressPercent` counts finished units only; showing 100% beside a red unit would be the wrong kind of reassuring. - **A queued unit has not started.** "Started" is the first non-idle entry, so a unit waiting in the queue does not report a duration for work it has not done. - **A retried unit is timed from its current attempt.** Units keep the failed attempt's track too; timing from the original start would report a duration spanning the failure. - **`now` is a prop.** A component reading the clock itself would report a different elapsed time on every unrelated re-render. The demo runs a simulated job — units starting in order, the log growing with them — so the monitor can be reviewed before the webapp feeds the real thing through the same props. That simulation immediately caught a bug: `isRunning` tested the start time for truthiness, so a unit starting at timestamp 0 reported itself as pending while visibly running. Fixed and covered. Also fixes a pre-existing prettier violation in UnitResult.tsx that had `npm run lint` failing before any of this. Needs a @mat3ra/cove release carrying LogViewer, MetricTile and SegmentedMeter. Refs SOF-8023. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DK8KomMescJvMQNSEfeRR8
|
The whole failure is Note the fourth: I'm deliberately not working around it. An ambient module declaration would shadow cove's real types once it does publish, and vendoring the primitives here would duplicate what cove#97 exists to own. Against a local cove build the typecheck is clean, all 25 tests pass, eslint and prettier are clean, and the behaviour in the PR description was measured in the running demo. Sequence: merge and publish cove#97, bump the pin here, re-run. mat3ra/ive#6 is blocked on exactly the same thing. Generated by Claude Code |
Summary
Phase 3.2 of the Job Designer UX update (SOF-8023, plan).
A submitted job disappeared. The designer stayed on the editing view, and the only way to learn whether anything was happening was to reload and read a status string. Every unit already carries a
statusTrackof{ status, trackedAt }— nothing read it.What's here
src/runMonitor.ts— pure derivation: per-unit rows (status, start, duration) and a run summary. 25 unit tests.RunMonitor— aMetricTilestrip over a progress meter, one row per unit with its status chip and duration, and a log tail.ResultsTabgainsshowRunMonitor, opt-in like the rest of the guided designer. It settles rather than switching: when the last unit reaches a terminal status the same rows become the record of the run, so the reader isn't moved elsewhere at the moment they most want to look.Four judgements worth a reviewer's attention
progressPercentcounts finished units only. Showing 100% beside a red unit would be the wrong kind of reassuring.nowis a prop, notDate.now(). A component reading the clock itself would report a different elapsed time on every unrelated re-render — and would be untestable.Verification
npm testgreen (25 tests),tscclean, eslint clean, prettier clean.The demo runs a simulated job — units starting in order, the log growing with them — so the monitor can be reviewed before the webapp feeds the real thing through the same props. Measured in it:
0/5 finished, 1 running1/5 finished, 1 running4s so far · Running12s · Finished4s22s20%That simulation immediately caught a bug worth calling out:
isRunningtested the start time for truthiness, so a unit starting at timestamp0reported itself as pending while visibly running. Real timestamps are never 0, so this would have survived into production and only misbehaved in tests and demos. Fixed, with a test that pins it.Also in here
A pre-existing prettier violation in
UnitResult.tsxthat hadnpm run lintfailing onmainbefore any of this.Still open
The webapp data adapter, which the plan expected to be half of this item. Nothing publishes a log tail yet;
getJobLogTailis read fromsetDependencies(), and without it the monitor says the deployment provides no log feed rather than showing an empty box that reads as a silent job. Unit status tracks come from the job document and need no new endpoint.🤖 Generated with Claude Code
https://claude.ai/code/session_01DK8KomMescJvMQNSEfeRR8
Generated by Claude Code