Skip to content

tui3: tree rails back in the tasks side column - #1665

Draft
santoshkumarradha wants to merge 7 commits into
devfrom
task/restore-tree-rails-in-the-tasks-c2da84
Draft

santoshkumarradha wants to merge 7 commits into
devfrom
task/restore-tree-rails-in-the-tasks-c2da84

Conversation

@santoshkumarradha

@santoshkumarradha santoshkumarradha commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

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 in planRailLines/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.glyph on the vocabulary's tree slots (tokens.GTreeBranch/GTreeLast/GTreeVert), the same door the tasks place draws its own kin through. railEntryRow is untouched — the connector lives only in the lead. The roster's own node rows stay one flat line per task as #1494 drew them (railLines computes no lead), so the column keeps one tree convention: the families hung under a row, drawn by planRailLines and planPageLines. Rails draw containment only — a dependency never re-parents a row, and a held row keeps its queued · waits: <task> wording.

Test plan:

  • new 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;
  • the exact-text candidates named in the issue (railgroups, c246, quicktask, bundle's railHint) assert containment and wording rather than the bare lead, so they needed no change — the one stale comment (c266, "connectors are gone") is updated with the shape;
  • manual pages that spelled the page's connectors ├─/└─ now spell the drawn ├ /└ (reading-a-task-page.md, worker-harness.md).

Full go test ./... (once, on a fleet host — this laptop's own full go 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/var vs /var/folders); they fail on pristine dev on this laptop too.
  • internal/tui3: the ten credit-warning tests (TestLowCreditsWarningFollowsThePaidModelOnBothBoxes and friends) fail on that host's environment — and fail identically on pristine dev there; they pass on this laptop.
  • cmd/codeaf: TestDoOnTheRunEngineNeverCommitsThePersonsOwnWork wedges 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

The tree rails running in the tasks side column

Captured from the real TUI at this head (f730ad341), on the Spark, against a
demo home seeded through the engine's own writers (cmd/codeaf-demo-home): the
auth-flow family draws its connectors in the tasks side column — a nested
family (the poem) carrying its │ trunk past ancestors with rows still to
come, 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.

@santoshkumarradha santoshkumarradha added feature Work that adds a capability; developers break it into tasks area:chat The v3 surface a person sits in front of (internal/tui3) labels Sep 28, 2026
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.
@santoshkumarradha
santoshkumarradha force-pushed the task/restore-tree-rails-in-the-tasks-c2da84 branch from 69cc9df to 4c1e1d4 Compare September 28, 2026 20:17
agentfield-bot and others added 3 commits September 28, 2026 16:52
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>
@santoshkumarradha

Copy link
Copy Markdown
Member Author

Bar audit — gaps against the new PR bar

1. 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 (af-tree-rails-reviews/round0-kimi.md, round1b-quality.md, round1c-render.md) — those are working notes, not the three named passes (ARCHITECTURE, SECURITY, CODE EFFICIENCY & DESIGN); also consider whether review notes should ship inside the repo tree.

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.

—
Drafted with CodeAF · reviewed and owned by the author

@santoshkumarradha

Copy link
Copy Markdown
Member Author

PR Bar Audit — gaps against the new bar

1. CI + changelog: ❌ CI red — check, light gate, and touched packages all fail (license/cla passes). ✅ Changelog present (docs/changes/unreleased/1665-tree-rails-side-column.md).
2. Review passes: ❌ None posted — Pass 1 (ARCHITECTURE), Pass 2 (SECURITY), Pass 3 (CODE EFFICIENCY & DESIGN) all absent. (The af-tree-rails-reviews/round*.md notes in-tree are not PR review passes.)
3. Video proof: ❌ Missing — user-facing change (tree rails in the tasks side column); no video or GIF in the body.
4. Spark runs: CI failures must be reproduced and fixed on the Spark (fleet), captures included.
drafted with CodeAF

@santoshkumarradha

Copy link
Copy Markdown
Member Author

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.
drafted with CodeAF

@santoshkumarradha

Copy link
Copy Markdown
Member Author

PR bar audit — directive #1790715358822565124

1. 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

@santoshkumarradha

Copy link
Copy Markdown
Member Author

Audit against the new PR bar

  • CI + changelog: changelog entry present ✅ — but CI is red: internal/tui3/task.go:4312:11: a.railFigWord undefined breaks the build (light gate, touched packages and check all fail). Fix the compile error first.
  • Review passes: 0 of 3 — ARCHITECTURE, SECURITY, and CODE EFFICIENCY & DESIGN, each as its own comment naming what was checked and what was found.
  • Video proof: missing — the tree rails in the tasks side column are user-facing; a capture must be embedded in the PR body.

Stays draft until all four conditions hold; nothing merges until then.

drafted with CodeAF

@santoshkumarradha

Copy link
Copy Markdown
Member Author

PR-bar audit (team bar, 2026-10-03) - status per category:

  • CI: 1 of 4 checks green, 3 still running, none failing.
  • Changelog: present (1 entry).
  • Review passes: 0 of 3 - the three labeled pass comments are absent; they are being posted.
  • Video proof: required (user-facing TUI: tree rails in the tasks side column) and MISSING.

Stays draft until all four conditions hold; nothing merged. Fixes incoming: three review passes, then Spark capture.

drafted with CodeAF

@santoshkumarradha

Copy link
Copy Markdown
Member Author

PR bar audit — gaps against the new bar

1. CI — ❌ failing. light gate FAILURE, touched packages FAILURE, check FAILURE on the head commit (only license/cla passes). The failures must be diagnosed and fixed, with all runs on the Spark per the fleet skill. ✅ changelog entry present (docs/changes/unreleased/1665-tree-rails-side-column.md).

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

@santoshkumarradha

Copy link
Copy Markdown
Member Author

Audit against the PR bar — what is missing

1. 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.
2. Three review passes — ❌ none posted yet. Pass 1 (ARCHITECTURE), Pass 2 (SECURITY) and Pass 3 (CODE EFFICIENCY & DESIGN) follow as three separate comments, each naming what was checked and what was found.
3. On-screen proof — ❌ user-facing change (tree rails back in the tasks side column): no capture in the body yet.
4. Fleet runs — builds, tests and captures run over ssh on the fleet, never a laptop. Spark is offline at audit time, so the dumb fleet host stands in until it is back.

Also missing: milestone (existing sets only).
Disposition — stays draft; CI red is the first gap to close.

drafted with CodeAF

@santoshkumarradha

Copy link
Copy Markdown
Member Author

Audit against the new PR bar:

  • CI: RED — check, light gate and touched packages are all failing. This is the first gap; nothing else counts until it is green.
  • Changelog: present.
  • Review passes: none posted. Owed: Pass 1 — Architecture, Pass 2 — Security, Pass 3 — Code Efficiency & Design.
  • Video: none; tree rails in the tasks column are visual and user-facing, so a capture is owed.

Stays draft.

drafted with CodeAF

@santoshkumarradha santoshkumarradha added the bug Something the code does that it should not label Oct 3, 2026
@santoshkumarradha santoshkumarradha added this to the Chat & connections milestone Oct 3, 2026
@santoshkumarradha

Copy link
Copy Markdown
Member Author

Bar audit — what is missing (per the new PR bar)

Audited at head 2840fb8d0d495dbc75cd0cadf6eb06651c8913da by @tags.

1. CI + changelog — light gate ❌ · touched packages ❌ · check ❌ — CI is red. license/cla ⏳ pending. Changelog ✅ — docs/changes/unreleased/1665-tree-rails-side-column.md.

2. Review passes (three, separate comments) — Pass 1 — ARCHITECTURE ❌ · Pass 2 — SECURITY ❌ · Pass 3 — CODE EFFICIENCY & DESIGN ❌ — 0 of 3 posted. (The af-tree-rails-reviews/*.md notes are files inside the diff, not the PR comments the bar requires.)

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

agentfield-bot and others added 3 commits October 3, 2026 19:19
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:chat The v3 surface a person sits in front of (internal/tui3) bug Something the code does that it should not feature Work that adds a capability; developers break it into tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tasks side pane: restore tree rail lines (├/└/│) so containment reads

2 participants