Skip to content

Give Inbox rows in Landing, Ready for review and Stopping their state - #1183

Merged
JacobStephens2 merged 4 commits into
mainfrom
issue-1106
Oct 23, 2026
Merged

JacobStephens2 merged 4 commits into
mainfrom
issue-1106

Conversation

@JacobStephens2

@JacobStephens2 JacobStephens2 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

An Inbox row's state word is now computed once, beside the Inbox grouping. The Console row and thirdshift status both show that word:

 InboxItem::state_word()          # src/logs/reading/inbox.rs
   if needs_you_kind  → Silent | Slow | Died | Failed | Triage | Finding   (unchanged)
+  if stopping        → Stopping   # live Command with a Stop request beside its record
+  Ready for review   → Ready
+  Landing            → Landing
   otherwise          → live | ended | died | unknown
 Console row   data-state + <span class="state">   ← state_word()   (was: raw state, or Needs you kind)
 status text   "… · <word> · harness …"            ← state_word()   (was: raw state)
 status --json  state (raw, unchanged), group, needs_you_kind, landing
+               stopping

The existing styles now apply:

  • Landing rows get every Theme's --tag-landing-* colours and keep Working's live-activity marker.
  • Ready rows get --tag-ready-*.
  • Stopping rows get the existing stripe and its drift, which stays still under Pause motion and reduced motion. They keep Working's tag colours instead of falling back to Done's.

Live updates need nothing new: the Stop request file is under logs.dir, so writing it already pushes an Inbox change.

The manual (docs/guide.md, regenerated site/docs/index.html) and console/README.md describe the words and the new stopping field.

CLI and JSON agreement (acceptance criterion 5):

  • thirdshift status text now prints the same word as the Console for every Command record row. That includes Needs you rows, which used to print ended/died/live there.
  • --json keeps state as the Command's own state, so existing readers are unaffected, and adds stopping. With group and needs_you_kind, that gives the word, and the guide documents how.
  • Rows read from Activity logs or Session traces still print start, end and outcome in text, as before. Only the Console gives them a word.

Evidence

  • Before: cargo test --test console inbox::landing_ready_and_stopping_rows_carry_their_state_in_the_console_and_status fails on the base code. The Landing row renders data-state="live" … <span class="state">live</span>.
    After: It passes. In one fixture home, Landing, Working, Stopping, Ready and Failed rows each match on Console data-state, the visible word, their section, status --json group/stopping, and the status text line.
  • Before: The new browser test Landing, Ready and Stopping rows carry their state, Theme tags and still-able motion (console/tests/inbox.test.cjs), built against main's console.css, fails with Landing keeps the live-activity marker.
    After: It passes. The test checks, under focus-light and signal-light:
    • The Landing and Ready label colours equal --tag-landing-*/--tag-ready-*, and under Signal they differ from Done's.
    • The Landing marker spins.
    • A Stop request written while the page is open turns the row into Stopping through the live update. The ::after stripe drifts (activity-drift), and has no running animation under Pause motion or under reduced motion.
    • The Needs you row keeps Failed.
  • Validation on this branch:
    • cargo fmt --check and cargo clippy --all-targets -D warnings: clean.
    • Full Rust suite: unit tests 1262 passed, 3 ignored; cargo test --test '*' all passed. After merging current origin/main, --test console passed again (71).
    • console browser suites: inbox, stop, themes-regressions and notifications 42/42; inbox 24/24 after review fixes.
    • site: npm test 49/49, npm run docs:check passed.
    • Environment note: the unit tests ran with a throwaway GIT_CONFIG_GLOBAL, because this machine's tag.gpgsign = true makes three worktree::synchronization_tests fail at git tag ("no tag message?"). That is unrelated to this change.

Merge Danger

Door: two-way

Blast Radius: small

  • Console: Inbox row tags and markers change for Landing, Ready and Stopping rows only.
  • status text: Readers that parse the state word in status text now see the Console's words. For example, Failed instead of ended on Needs you rows, and Landing instead of live.
  • --json: Additive only (stopping).

Review coverage

The Standards and Spec reviews ran against origin/main (merge-base 399abec; local main was stale).

  • Standards read every changed file.
  • Spec read every changed file except the generated site/docs/index.html. Both reviewers confirmed that exclusion: it comes from docs/guide.md via the unchanged site/generate-docs.mjs, and npm run docs:check exited 0. Standards also inspected its hunks.

No changed file was left unread.

Fixed after review:

  • Standards: named the method state_word(), live_record takes an issue number, use crate::logs::stop.
  • Spec (a)1: the manual no longer claims Activity-log and Session rows carry the word in status text.

Unaddressed findings

Standards

  • Primitive Obsession: state_word() returns &str. Declined. Row.state was already a String that the Askama template writes into data-state, and console.css matches those exact strings (src/console/assets/console.css:69-73). The change extends that existing contract, and a type would only be converted back to the same strings at both edges.
  • Data Clumps: group/needs_you_kind/landing/stopping; serialize the word instead. Declined. status --json reports observations, not presentation words. needs_you_kind is already lowercase while the Console shows titles, and group already says landing/ready for review. stopping is the one fact JSON lacked, and the guide documents the derivation (docs/guide.md, "With group and needs_you_kind, stopping gives the row's state word…").
  • Repeated Switches: :is([data-state="live"], [data-state="Landing"]) in both the marker and animation rules. Declined. It follows the stylesheet's existing pattern: the static rule and its motion inside prefers-reduced-motion: no-preference / :not([data-paused]) must be separate rules, as for Silent and Stopping (console.css:75,86-90).
  • Duplicated Code: the status closure in the new test. Declined. The closure is used twice within one test. The other copies are single inline calls with different assertions.

Spec

  • (b)1 The CLI text for Needs you rows changed (· Failed · instead of · ended ·). Kept on purpose. Acceptance criterion 5 asks the CLI to agree with the Console. "Needs you rows and Working rows are unchanged" holds for the Console, which the other criteria describe. Text output is not the API: the guide names thirdshift status --json "the versioned API", and its state and needs_you_kind are unchanged. Run: cargo test --test console inbox::landing_ready_and_stopping_rows_carry_their_state_in_the_console_and_status asserts the agreed text for the Failed row.
  • (a)2 --json carries no state word. Accepted by the reviewer as documented. See the Data Clumps entry above.
  • (b)2 Stopping rows take Working's tag colours. Kept. Without it a still-ending Command would show Done's colours. Only console.css rules change, not Theme tokens (out of scope per the issue).
  • (b)3 Stopping rows have no spinning marker. No change. The issue asks Stopping rows for "the existing Stopping stripe and its motion", and the marker for Landing only.
  • (c) stopping is recomputed rather than reusing stop::inspect. Declined. inspect judges a selected Command, which may be a child whose owner was stopped (src/logs/stop.rs:126-151). An Inbox row is the owner itself, so state == "live" (process identity alive, no outcome; src/logs/reading.rs:189-195) plus its own Stop request is the same fact. Both use the shared stop::requested.
  • (c) A Silent/Slow live Command given a Stop shows its Needs you kind, not Stopping. By the spec: "Needs you rows keep their Needs-you kind, as now." The peek still shows "still ending".

Security

  • None. The change sets the Inbox row's state only to fixed words (Landing, Ready, Stopping) or the values it already had. Askama HTML-escapes the row template, and live updates re-parse that server-rendered HTML. The new stopping fact reads the existing Stop request file beside the Command record, under logs.dir, through the shared stop::requested. No new input, sink or trust boundary.

Closes #1106

Built with claude · claude-opus-5-5 · high

Security review outcome

No unaddressed introduced findings.

The Inbox row's state word is now computed once, beside the grouping: a
Needs you kind, then Stopping for a live Command given a Stop, Ready and
Landing for those groups, otherwise the Command's own state. The Console
row's data-state and the status text line both use it, so every Theme's
Landing and Ready tag colours and the Stopping stripe apply. status --json
adds stopping beside landing. Landing keeps Working's live-activity
marker and a Stopping row keeps Working's tag colours.
Review follow-ups: InboxItem::state_word names the row's word apart
from the Command's own state, live_record takes its issue number, and
the manual says only Command record rows carry the word in status text.
@JacobStephens2
JacobStephens2 merged commit 2b4f35e into main Oct 23, 2026
18 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-1106 branch October 23, 2026 21:18
@JacobStephens2 JacobStephens2 mentioned this pull request Oct 23, 2026
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.

Inbox rows in Landing and Ready for review, and rows being stopped, never get their state's style

1 participant