tui3: tree rails back in the tasks side column - #1665
santoshkumarradha wants to merge 7 commits into
Conversation
A family in the tasks side column hangs off its own connectors again, as issue #1660 asks: a child rides ├ while a sibling follows it and └ where it closes its parent's family, and a grandchild carries the │ stem past every ancestor level that had rows still to come. The lead stays two cells a level, so every row stands in the column the bare indent drew and the width computations reading it keep their shape; the run's own row draws no lead. The plan page draws the same tree through the same helper, with the trunk running through the under-block instead of repeating the elbow. The glyphs come through the vocabulary's tree slots, the same door the tasks place draws its kin through; railEntryRow is untouched and the roster's own node rows stay one flat line per task.
69cc9df to
4c1e1d4
Compare
Assisted-by: CodeAF Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
the rail indentation law test compared only the title columns, so a regression that dropped the pending mark off the lead (a bare '-' before the title) still passed. the child row is now asserted to wear its palette mark glyph between the connector and its title. Assisted-by: CodeAF (glm-5.3-flash) Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
Assisted-by: CodeAF Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
Bar audit — gaps against the new PR bar1. CI + changelog: ❌ CI is red: run 36484928108 failed on check, light gate, and touched packages. Diagnosis and fix are the first gap to close. ✅ changelog entry present (1665-tree-rails-side-column.md). 2. Review passes: ❌ none posted as PR comments. Three review-round notes exist as in-tree files ( 3. Video proof: ❌ absent. User-facing visual change (tree rails in the tasks side column). Needs a Spark tmux capture rendered to GIF/video, embedded in this PR body. 4. Spark: CI diagnosis and fix verification run on the Spark (fleet). Action: stays draft; red CI closes first, then the three passes and the body video. — |
PR Bar Audit — gaps against the new bar1. CI + changelog: ❌ CI red — |
|
PR-bar audit: changelog entry present. Blocking first: CI is red — check, light gate and touched packages all failing; that is gap one. Then: the three review passes, and (TUI surface → user-facing) a Spark tmux capture for the body. Draft stays. |
PR bar audit — directive #17907153588225651241. CI + changelog: ❌ CI failing — light gate FAILURE, touched packages FAILURE, check FAILURE (license/cla passes). ✅ one unreleased changelog entry present (1665-tree-rails-side-column.md). The CI failures must be diagnosed and fixed. 2. Review passes: ❌ Pass 1 — ARCHITECTURE: absent. ❌ Pass 2 — SECURITY: absent. ❌ Pass 3 — CODE EFFICIENCY & DESIGN: absent. 3. Video proof: ❌ no video/GIF embedded in the PR body. This change is user-facing (tree rails in the tasks side column) — the bar requires a capture of the change actually running, embedded in the body. To be captured on Spark. Fixes for the gaps are in flight. This PR stays draft until all four conditions hold. drafted with CodeAF |
Audit against the new PR bar
Stays draft until all four conditions hold; nothing merges until then. drafted with CodeAF |
|
PR-bar audit (team bar, 2026-10-03) - status per category:
Stays draft until all four conditions hold; nothing merged. Fixes incoming: three review passes, then Spark capture. drafted with CodeAF |
PR bar audit — gaps against the new bar1. CI — ❌ failing. 2. Review passes — all three missing (Pass 1 ARCHITECTURE, Pass 2 SECURITY, Pass 3 CODE EFFICIENCY & DESIGN), as separate comments naming what was checked and what was found. 3. Video proof — missing. Tree rails in the tasks side column is a visual change — a Spark tmux capture showing the rails rendering, as GIF/video, must be embedded in the PR body. 4. Runs on Spark — per the fleet skill. Stays draft until all four conditions hold. Nothing merges before that. drafted with CodeAF |
Audit against the PR bar — what is missing1. CI + changelog — ❌ CI is RED: check, light gate and touched packages all failing; ✅ changelog entry present. The failures are the first gap being closed, verified on the fleet before pushing. Also missing: milestone (existing sets only). drafted with CodeAF |
|
Audit against the new PR bar:
Stays draft. drafted with CodeAF |
Bar audit — what is missing (per the new PR bar)Audited at head 1. CI + changelog — light gate ❌ · touched packages ❌ · check ❌ — CI is red. license/cla ⏳ pending. Changelog ✅ — 2. Review passes (three, separate comments) — Pass 1 — ARCHITECTURE ❌ · Pass 2 — SECURITY ❌ · Pass 3 — CODE EFFICIENCY & DESIGN ❌ — 0 of 3 posted. (The 3. Proof on screen — user-facing ✅ (tree rails in the tasks side column). Video/GIF embedded in the body ❌ missing — required before ready. 4. Tags — labels ✅ feature · area:chat; milestone was absent → now Chat & connections. Actions: a Spark task is fixing CI and capturing the rails, and the three review passes are running. Stays draft; nothing merges before all four conditions hold. drafted with CodeAF |
The branch's last commit called a railFigWord that was never written, so nothing at head built; and its own c266 pin expected the row shape that same commit had already changed. This reconciles the whole seam in one pass: - railFigWord lands in taskident.go: a row's number in the form a person can say out loud (#6, the stored row's handle or the node's counter), drawn dim before the state glyph. - The name has first claim on the cells: the number is drawn only where the column has room for it beside the whole name, and the glyph is measured and not assumed, so a held row's two-cell pair cannot overrun the column. - c266's pin now carries connector, number, mark and title together. - A family deeper than the column's levels is named at the boundary by one ellipsis row that is the door onto the branch, instead of drawn flat at the cap's depth or dropped with its subtree without a word; railRowPlace is the one place that is decided, shared by both renderers. - The plan page measures its level budget on the column it draws, min(width, planPageKinWidth), rather than on the page's own width. - The changelog says all of this; its railEntryRow-is-untouched claim no longer held. Resolves the read-only review's P0 (undefined railFigWord), P1 (row-shape pin contradiction) and both P2s (depth clamp flattening and hidden subtrees, plan page cap on the wrong width). Assisted-by: CodeAF (glm-5.3-flash-high) Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
The first pass at this reconciliation landed the task-number word the branch's last commit had called for. It cannot ship: the column's settled laws hold that one state glyph leads every row in the same number of cells (railclick_test.go: the column reads downward as one column of states) and that the roster's rows carry no id (railgroups_test.go), and the branch's own c266 pin held the same shape. A number that varies in width cannot lead rows that must read as one column; weakening those assertions to admit it is out of bounds. The number is unlanded and returned to its author for a surface that can hold it. What stands is the rest of the reconciliation: - The undefined railFigWord call is gone with the fig integration; the build heals the way the laws say it must, and the pinned row shapes hold as committed. - A family deeper than the column's levels is named at the boundary by one ellipsis row that is the door onto the branch (railBoundaryRow), instead of drawn flat at the cap's depth or dropped with its subtree without a word; railRowPlace is the one place a row's place is decided, shared by both renderers. - The plan page measures its level budget on the column it draws, min(width, planPageKinWidth), not on the page's own width. - New law test TestADeeperFamilyIsNamedAtTheBoundaryNotDrawnFlat pins the boundary contract. - The changelog records all of it, including the unlanded number and why. Assisted-by: CodeAF (glm-5.3-flash-high) Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
Captured from the real TUI on the Spark at this head: the seeded auth-flow family draws its connectors in the tasks side column — the nested poem family with its trunk lines, the closing corner on the last child, the running spinners, and names cut clean by the row fitter. Recorded as an asciicast of the live pane and rendered with agg; no simulated frames. Assisted-by: CodeAF (glm-5.3-flash-high) Co-Authored-By: CodeAF <267109073+agentfield-bot@users.noreply.github.com>
Fixes #1660
The tasks side column draws a run's parts hanging bare two spaces a level — the connectors #1494 dropped with the old roster forest. This restores the tree in the lead the caller prepends, built by one helper (
railLead) both renderers share: a child rides├while a sibling follows it and└where it closes its parent's family; a descendant carries│past every ancestor level that had rows still to come, and two spaces where that ancestor was the last child; depth-0 rows draw no lead. The lead stays exactly two cells a level, so every row stands in the column the bare indent drew and every width computation that reads the lead — the room cuts inplanRailLines/planPageLines,programSpelling, the age placement — keeps its shape (the width is measured off the lead, not counted, the same bargain hometree.go strikes). On a task's page the trunk runs through the under-block —│while rows follow below it, air where the branch closed — instead of repeating the elbow.The glyphs come through
pal.glyphon the vocabulary's tree slots (tokens.GTreeBranch/GTreeLast/GTreeVert), the same door the tasks place draws its own kin through.railEntryRowis untouched — the connector lives only in the lead. The roster's own node rows stay one flat line per task as #1494 drew them (railLinescomputes no lead), so the column keeps one tree convention: the families hung under a row, drawn byplanRailLinesandplanPageLines. Rails draw containment only — a dependency never re-parents a row, and a held row keeps itsqueued · waits: <task>wording.Test plan:
TestTheRailDrawsAPlanFamilyOnItsOwnConnectors(internal/tui3/c263_rail_plan_test.go) renders a two-level family in the pane and asserts├/└connectors on the children,│stems for the middle rows past ancestors with rows still to come, and no stem past the last child's own connector — its descendants hang in the air it leaves;go test ./internal/tui3/...green;├─/└─now spell the drawn├/└(reading-a-task-page.md, worker-harness.md).Full
go test ./...(once, on a fleet host — this laptop's own fullgo test ./internal/tui3/...run is green) surfaced pre-existing failures unrelated to this change, all reproduced on a pristine dev checkout on the same host, so left alone here:internal/session:TestJobLogsFollowTheSessionFolder,TestJobLogsKeepTheLegacyPathWithoutAFolder,TestATaskWorkersJobLogLandsWithTheFamilyAndNotInTheRepository— macOS TempDir symlink (/private/varvs/var/folders); they fail on pristine dev on this laptop too.internal/tui3: the ten credit-warning tests (TestLowCreditsWarningFollowsThePaidModelOnBothBoxesand friends) fail on that host's environment — and fail identically on pristine dev there; they pass on this laptop.cmd/codeaf:TestDoOnTheRunEngineNeverCommitsThePersonsOwnWorkwedges on that host (a spawned engine is starved; goroutine dump captured) — it wedges pristine dev there too, and passes on this laptop.Left in draft on purpose: a separate review gate owns marking it ready; CI has its say first.
—
Drafted with CodeAF · reviewed and owned by the author
The rail in the running UI
Captured from the real TUI at this head (
f730ad341), on the Spark, against ademo home seeded through the engine's own writers (
cmd/codeaf-demo-home): theauth-flow family draws its connectors in the tasks side column — a nested
family (the poem) carrying its
│trunk past ancestors with rows still tocome, the last child closing with
└, running tasks wearing their spinners,and every name cut clean by the row fitter. A family deeper than the column's
levels is named at the boundary by one ellipsis row that stays a door onto its
branch, never drawn flat and never hidden.