Skip to content

Record views keep their filters, and every kind can be read in sequence - #34

Merged
illodev merged 1 commit into
mainfrom
feat/t-0207-record-cursor
Aug 7, 2026
Merged

Record views keep their filters, and every kind can be read in sequence#34
illodev merged 1 commit into
mainfrom
feat/t-0207-record-cursor

Conversation

@illodev

@illodev illodev commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Two UI cards from the backlog, both closed with browser evidence.

T-0201 — the record views' filters died on reload

T-0195 moved the three free-text boxes into the address bar and left the five chips beside them in useState: Docs' managed toggle, History's state and visibility, Memory's collection and status. Narrowing Memory to open incidents, opening one to read it and coming back handed you the whole workspace, with nothing in the interface saying the narrowing had ever been there.

They are the shell's state now, serialised by query.ts. The part worth reviewing is the names: they live in one table and every one is prefixed by its view.

That prefix is a rule rather than five separate choices, because the obvious name for Memory's is status — which the card filter already owns. A clash there is not reported, it is quietly resolved: readUrlState validates the card status against STATUSES and answers "" for anything that is not one, so the loser filters by nothing, in silence. The test derives both name sets from what writeUrlState actually emits and fails if they intersect, so a new axis on either side is covered the day it is added.

Verified: 24 checks in Chromium against a live server on this workspace. Memory narrowed 55 → 32 records and kept it across a reload, a switch to Explorer and back; History 171 rows → 2 with both chips restored; the docs indexed group gone with the toggle still pressed after a reload; Back walks the narrowings. Five mutations, five failures with the right message — including the bare status name, which reports the clash rather than the rename it also is.

T-0207 — only cards could be read in sequence

The previous/next cursor the card inspector has carried since the rail became a drawer is one shared control now, rendered by every panel that reads a record. The rule for where previous and next go is recordNeighbours in navigation.ts, beside the other navigation rules and where a test reaches it without a renderer.

The list is whatever the view was showing, in the order it was showing it — Memory lane by lane, History's rail across its section breaks, Docs managed-then-indexed — so it narrows when the filters do. Absent, not guessed, where there is no list: a link inside a body, a related row, the command palette.

The card's scope would have produced a fix that passed review

Worth reading before the diff. T-0207 was filed as ADR-0017's surviving finding. ADR-0018 then superseded ADR-0017 and moved the layout — docs and history became views that own their readers, so the shared drawer stopped opening for either — and the card was never touched. It did not have to be wrong to mislead: every sentence in it was true when written.

Its scope named one file, RecordPanel.tsx. A change touching only that file would have met all five acceptance criteria, passed review, and left serial reading in history — the complaint the whole chain started from — exactly as broken as it was.

Opening the view before writing anything, which is what LRN-0027 asks for, is what caught it. Two premises are corrected on the card, and one thing it promised is deliberately not delivered: the Workflow graph gets no cursor, because a force-directed layout is not an order and the card's own rule forbids an arbitrary one. LRN-0033 records the general lesson — a card outlives the decision it was filed under, and nothing reports the staleness, because nothing is broken.

Verified: 25 checks in Chromium. Lane order, rail order across the section break, a state filter narrowing the cursor with the list, no cursor until Docs' reader is given a choice, none at all on the graph or for a record opened by URL, and the card cursor still walking the visible table. Keyboard: the control takes focus and steps on Enter, Escape still dismisses the drawer and Ctrl-K still opens the palette, so it binds nothing of its own. Four mutations, four failures — including a lookalike pair added back to the inspector.

Not in here

packages/workfile/ui/src/demo-data.json regenerated as a side effect of build:demo (+20k lines) and was reverted. Per LRN-0003 it is a local-development artifact the hosted demo rebuilds on every deploy, so committing it changes nothing and only makes this diff unreadable.


pnpm run check green — 470 + 10 tests, strict ratchet with no regressions. doctor 0 errors 0 warnings, memory verify and changelog verify clean, the demo builds.

🤖 Generated with Claude Code

https://claude.ai/code/session_01D3LTdq3mzMAQ98rwBegGjU

T-0201. T-0195 moved the three free-text boxes into the address bar and left
the five chips beside them in local state, so Docs' managed toggle and the
axis filters in History and Memory died on every reload and every view switch.
They are the shell's state now, serialised by query.ts, with the parameter
names decided in one table and every one of them prefixed by its view. The
prefix is a rule rather than a case-by-case choice: the obvious name for
Memory's is `status`, which the card filter already owns, and the loser of a
clash like that filters by nothing without reporting anything — readUrlState
validates the card status against STATUSES and answers "" for whatever else.
The test derives both name sets from what writeUrlState emits and fails if
they intersect.

T-0207. The previous/next cursor the card inspector has always carried is one
shared control now, rendered by every panel that reads a record, with the rule
for where it goes in navigation.ts beside the other navigation rules. The list
is whatever the view was showing, in the order it was showing it, published by
that view; absent, not guessed, where there is no list behind the record.

Which is more than the card asked for, and the reason is on the card. It was
filed as ADR-0017's surviving finding, ADR-0018 then gave docs and history
their own readers, and the card was never updated — so its scope named one
file, RecordPanel.tsx, and a fix that touched only that file would have met
all five criteria and left serial reading in history exactly as broken as the
complaint that started the chain. Two premises corrected on the record, and
one thing the card promised that is deliberately not delivered: the Workflow
graph gets no cursor, because a force layout is not an order. LRN-0033 is the
general lesson.

Both verified in Chromium against a live server on this workspace — 24 checks
and 25 — and both guards mutation-proven, five ways and four.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D3LTdq3mzMAQ98rwBegGjU
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workfile Ready Ready Preview Aug 7, 2026 7:55pm
workfile-site Ready Ready Preview Aug 7, 2026 7:55pm

@illodev
illodev merged commit 61512e4 into main Aug 7, 2026
14 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