Skip to content

spaces: reach the whole view block, and export what a board actually holds - #245

Open
nyblnet wants to merge 1 commit into
mainfrom
spaces-view-controls
Open

spaces: reach the whole view block, and export what a board actually holds#245
nyblnet wants to merge 1 commit into
mainfrom
spaces-view-controls

Conversation

@nyblnet

@nyblnet nyblnet commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Two of the gaps from the audit, fixed.

The view controls

layout: 'list' has rendered since the tracker shipped and nothing in the app could produce one — a view could hold a layout you could not undo — and groupBy was reachable only by hand-editing JSON. Board ⇄ List, Group and Sort now sit beside Open only and Filter, all inside the same opts.editable guard, so a reader and a printout still get none of them.

Sort — settling what the decision log deferred

DECISIONS.md said a stored sort and a hand-dragged order contradict each other, and that whoever needed sort had to settle which wins first.

They don't contradict. The hand order is doc.pages; the sort is a key on one block; sorting touches neither. So a sort overrides for as long as it's there, and clearing it returns the exact arrangement. "Manual order" is the first item in the menu — it's the absence of a sort, not a sort called manual.

What sorting does cost is the positional drop. With an order in force, a drop position would write into doc.pages an order the next paint discards — a gesture that appears to do nothing and leaves an undo step behind. The column still highlights and still takes the card; only the insertion point stops being offered.

Ordering rules, each of which is silently wrong the other way:

  • a select sorts by its declared order — alphabetising "Backlog, Todo, In progress, Done" throws away the only thing the list was saying
  • an unset value sorts last in both directions — a blank estimate is not the cheapest issue
  • a value a newer build wrote sorts after everything this build knows, rather than leading a board with a status nobody here can read
  • ties keep the page order, so a hand-arranged board still reads that way within each band
  • an unknown sort key is skipped and the view says so

sort is an array holding one entry — the shape already published — because a second key can be added later, where widening a scalar afterwards could not be done at all.

The export

Every prop block carries a readable Status: In progress. That string is the whole reason the format degrades instead of vanishing for an older build, a thumbnailer or a grep — and the Markdown exporter, its most important consumer, wrote **status:** doing from right beside it, publishing the internal option id to the one audience with no schema to look it up in.

A board exported as its own italic title and nothing else, so a tracker downloaded as Markdown showed a heading where the work was. Boards now export their issues — grouped as the board groups them, in column order, each a link back to its page, carrying the same chips the card shows — with the same filter and sort the screen is using.

toMd's fourth parameter became an MdCtx so a block that describes other content can ask about it, rather than growing a second traversal that drifts from the app.

Measured in the built shell, not asserted

  • the layout button switches, and Group disappears for a list (a list has no columns)
  • sorting by priority gives Urgent → High → Medium → the two with none; clicking the same field reverses it
  • Manual order deletes the key, leaving the block byte-identical to how the starter wrote it
  • a dragover on a sorted column marks the column and no position; the same dragover unsorted marks the position — a negative control that fires
  • the exported Markdown was captured from the real download path

Size

+3.4 KB compressed → 135,134 B, which was 100.0% of the old ceiling. The ceiling moves to 138 KiB in this commit with the reason recorded beside it, per the rule the size gate states.

Rigs

412/412 model (up from 392), 143/143 agent, 18/18 undo, 40/40 release, i18n 234 × 8 complete, splice conformance gate.

One existing assertion was rewritten rather than repaired: it pinned the view controls to the first statement inside the editable guard, so adding a control above it broke the test without breaking anything — and adding one below the guard would have broken the app without breaking the test. It now checks that every control name appears inside the guard and nowhere else.

DECISIONS.md carries the settlement, and the deferral above it is marked settled and points at it. spaces/README.md no longer lists databases as unbuilt.

…holds

THE VIEW CONTROLS WERE TWO BUTTONS FOR A BLOCK WITH FIVE KEYS. `layout:'list'`
has rendered since the tracker shipped and nothing in the app could produce one
— a view could hold a layout you could not undo — and `groupBy` was reachable
only by hand-editing JSON. Board ⇄ List, Group and Sort now sit beside Open only
and Filter, all inside the same `opts.editable` guard, so a reader and a
printout still get none of them.

SORT is the part the decision log deferred. It said a stored sort and a
hand-dragged order contradict each other and whoever needs sort settles which
one wins. They do not contradict: the hand order is `doc.pages`, the sort is a
key on one block, and sorting touches neither. So a sort OVERRIDES for as long
as it is there and clearing it returns the exact arrangement — "Manual order" is
the first item in the menu, and it is the absence of a sort rather than a sort
called manual. What a sort does cost is the positional drop: with an order in
force, a drop position would write into doc.pages an order the next paint
discards, so the column still highlights and still takes the card while the
insertion point stops being offered. dropIssue takes a null aim for that.

Ordering rules, each of which is silently wrong the other way: a select sorts by
its DECLARED order (alphabetising "Backlog, Todo, In progress, Done" throws away
the only thing the list was saying); an unset value sorts last in BOTH
directions (a blank estimate is not the cheapest issue); a value a newer build
wrote sorts after everything this build knows rather than leading the board;
ties keep the page order; an unknown sort key is skipped and the view says so.
`sort` is an array holding one entry — the shape already published — because a
second key can be added later where widening a scalar could not.

THE EXPORT WAS PUBLISHING OPTION IDS AND HIDING BOARDS. Every prop block carries
a readable "Status: In progress", which is the whole reason the format degrades
instead of vanishing for an older build, a thumbnailer or a grep — and the
markdown exporter, its most important consumer, wrote `**status:** doing` from
right beside it. A board exported as its own italic title and nothing else, so a
tracker downloaded as Markdown showed a heading where the work was. Boards now
export their issues, grouped as the board groups them, in column order, each a
link back to its page, with the same filter and sort the screen is using. toMd's
fourth parameter became an MdCtx so a block that describes other content can ask
about it, rather than growing a second traversal that drifts.

Measured in the built shell, not asserted: the layout button switches and the
group control disappears for a list (a list has no columns); sorting by priority
gives Urgent→High→Medium→the two with none; clicking the same field reverses it;
Manual order deletes the key and leaves the block byte-identical to how the
starter wrote it; a dragover on a sorted column marks the column and no
position, and the same dragover unsorted marks the position — a negative control
that fires. The exported Markdown was captured from the real download path.

+3.4 KB compressed (135,134 B local), most of it the sort engine, three popovers
and 13 strings × 8 locales. That is 100.0% of the old ceiling, so the ceiling
moves to 138 KiB in this commit with the reason recorded beside it.

Rigs: 412/412 model (up from 392), 143/143 agent, 18/18 undo, 40/40 release,
i18n 234 × 8 complete, splice gate. One existing assertion was rewritten rather
than repaired: it pinned the view controls to the FIRST statement inside the
editable guard, so adding a control above it broke the test without breaking
anything, and adding one below the guard would have broken the app without
breaking the test. It now checks that every control name appears inside the
guard and nowhere else.

DECISIONS.md carries the settlement; the deferral above it is marked settled and
points at it. spaces/README.md no longer lists databases as unbuilt.
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