Skip to content

Session overview with a page for every work item; questions only in Approvals (greenfield 0.0.51) - #206

Merged
tbrownio merged 2 commits into
mainfrom
session-item-pages
Nov 12, 2026
Merged

tbrownio merged 2 commits into
mainfrom
session-item-pages

Conversation

@tbrownio

@tbrownio tbrownio commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Today the orchestrator's status page shows every Session item as a card. A card links to a brief for planned work, or to a hub the orchestrator was supposed to write by hand for anything else, and those hubs were often missing or stale. The page also repeats each open question's full wording, which the person already sees in Pane's Approvals. This PR makes the renderer write the overview and one page per work item in the same run, from the same status JSON. Every card opens its item's page and every item page links back up. Questions show only as a count and their Q-ids.

Builds on #200 (merged, greenfield 0.0.49) and follows #201 (merged, 0.0.50); this branch is rebased onto main after them. The work is commit 0a3488e, at greenfield 0.0.51. A second commit, 9a98790, fixes a CI test that started failing on macOS runners regardless of this change (see the last row of the table below).

Visual Overview

Before: status.json renders one page whose cards lead to briefs or hand-written hubs, and which repeats question text. After: the same run writes the overview and items/<id>.html for every item; cards open item pages, item pages link back, and questions are worded only in Approvals.

This PR's own page (diagram, screenshots, the rendered example and this Session's pages): PR #206 walkthrough

Plan: cover sheet, revision 2, approved as D-33. The design follows the approved mock-ups (D-31). The rule that findings, post-mortem and trace go on the item page only is D-34. D-n ids are entries in the plan's decision log; J1–J8 (journeys) and C1–C7 (checks) are the plan's validation criteria, each restated where it is used below.

Why this change exists

The person running a Session wants to see the whole Session at a glance, click any work item to see everything about it, and come back up. Before this PR, the status page could not do that:

  • Items had no reliable page of their own. A planned item's card opened its brief. A quick fix, tweak or picked-up PR needed a hub written by hand (item-hub.md), which often didn't exist.
  • Questions were shown twice. The page's "Needs you" section printed each question, its options and its reasoning. In Pane the same question is a card in Approvals, so the person read and answered it in two places. Questions should appear only in Approvals, not again on the status page.
  • Counts could disagree with the cards. The running, queued and done counters were filled in by hand (session.counts).

The person asked to try this in greenfield first, before any of it moves into Pane (D-34). So the status JSON stays the single source the pages render from.

Concepts

  • Work item: one piece of work the orchestrator tracks: a planned item (built from an approved plan package), a quick fix or tweak (no plan), or a picked-up PR (an existing PR the Session took over).
  • Status JSON: the file the orchestrator keeps at <Session folder>/.agent/status.json, describing the Session and each work item. The renderer turns it into HTML; nobody writes the HTML by hand.
  • Overview: session/index.html, which Pane shows in the Session's Overview tab.
  • Item page: new. session/items/<id>.html, one per work item, named by the item's stable id.
  • Stretched link: the card's title link is stretched (CSS ::after with inset: 0) to cover the whole card, so a click anywhere on the card opens the item page without any script. The PR and "open ↗" links sit above it and still work.

What changed

Area Before → after
Overview header Counters and a state bar ("2 need you · 1 blocked") → a one-to-three-sentence summary, Next step:, one pointer ("2 questions wait for you in Approvals: Q-7 (#1014) and Q-8 (#1241). Questions live only there." with an Open Approvals → button), then tiles (work items, done, in progress, waiting on you, blocked, plus queued when any) and a progress bar. The renderer counts tiles from item states; session.counts is no longer read.
Needs you section Removed. needs[] keeps only id, item (the item's id) and link; any q, options or why is ignored and never printed. Outside Pane (no links) the pointer says the questions wait "in the orchestrator's chat". A Notify question without a Q-n yet shows as "a new question".
Cards Each card's title is a stretched link to items/<id>.html, plus a Details → link.
Item pages (new) Breadcrumb → kind and group → title → Asked for / What changes / Where it stands → the item's card with its rail → Everything for this item → sibling chips → ← prev, ↑ Back to overview, next →.
Everything table Fixed rows (D-L6): Plan (planned items) or Task, Pull request, QA, Review, Worker, Trace, Post-mortem always show. Each has a link, a short reason ("none: D-30", "not yet"), or "Not recorded" when the JSON leaves it empty, so a gap looks like a gap. Decisions (from decisions[].item), Depends on and Evidence appear when present. An item a question blocks gets a Waiting row first: "Q-7 waits in Approvals", linked, never the wording.
Item ids Every item needs an id (lower-case letters, digits, hyphens), unique across items and done. A missing, repeated or unsafe id stops the renderer with a message naming the item, before anything is written.
Relative links Links in refs are written relative to the overview. On item pages, one folder down, the renderer prefixes relative links with ../.
Done Finished items keep their id and page. An old done entry without an id still renders, linking its link.
Hardening from Pane's copy script-src 'none' CSP on every page, every link through href() (unsafe schemes become #), numeric counts, item state allow-listed. Pane's next refresh can be a straight copy.
Instructions status-board.md documents the contract above. item-hub.md now describes the generated item page ("never hand-write it"). SKILL.md says every item's front page is its generated page, the overview and item pages render together, findings, post-mortem and trace go on the item page and not the brief (D-34), and questions appear only in Approvals or the chat. ledger.md adds page_id. relay.md, page/references/bundle.md, customer-insights-loop/references/handoff.md and the plugin README drop their "Needs you row", hand-written hub and brief-backfill wording.
CI fix (separate commit) tests/machine-security.test.mjs failed on test (macos-latest), both on the first run and on a rerun: its baseline test scans twice and expects no change, but it read the runner's own Software Update cache (/Library/Preferences/com.apple.SoftwareUpdate.plist), which Software Update rewrote between the two scans (a pending macOS 26.7.3 appeared). check.sh now honours MSC_SUPDATE_PLIST, a test hook like MSC_STATE_DIR, and the test points it at a fixed plist. Nothing changes for people running the check.
Example and tests example-status.json now shows every item kind (planned, quick fix, tweak, picked-up PR, an item waiting on a question, a finished item with a page, and a legacy done entry). Tests cover C2–C5 and C7. Older renderer tests now give their items ids.

Example: an item in the status JSON, and what the renderer writes for it.

{ "id": "env-vars", "group": "Env vars", "kind": "planned", "short": "#1014",
  "name": "Per-project env vars (keychain)", "state": "need", "stateLabel": "Waits on Q-7",
  "asked": "“Let each project keep its own env vars, stored in the keychain.”",
  "refs": { "plan": { "label": "Cover sheet, revision 2", "link": "per-project-env-vars/cover-sheet.html" },
            "review": { "note": "not yet: at the plan's end" } } }
session/index.html           card "Per-project env vars (keychain)" → items/env-vars.html
session/items/env-vars.html  Waiting: Q-7 waits in Approvals · Plan: ../per-project-env-vars/cover-sheet.html
                             Review: not yet: at the plan's end · QA: Not recorded · ↑ Back to overview → ../index.html

Upgrade path. A status JSON written before this PR has no ids, so its first render fails with a message naming each item. The orchestrator rewrites the JSON from its ledger on its next turn (no migration, as the plan says). Existing Session pages aren't regenerated by this PR; each refreshes on its orchestrator's next change.

Validation and limitations

Validation level: full. No agent review: this PR changes only instructions, the renderer, its example and tests (D-30). The plan asks for human review.

  • C1 (checks): pnpm typecheck and pnpm test pass on 9a98790 (347 pass, 9 skipped, 0 fail), and every GitHub check is green on that head (ubuntu, macOS, Windows, windows-link-fallback, check). node scripts/sync-bigbrain-from-greenfield.mjs --check reports no new problems.
  • C2 links, C3 no question text, C4 bad ids, C5 escaping, C6 size, C7 wording: new tests in tests/greenfield.test.mjs, passing. The example's overview is 140 KB (limit 200 KB); each item page is about 90 KB (limit 120 KB).
  • J1–J4 (overview order, card to item and back, every item kind, waiting item): checked on the rendered example (screenshots on the PR page).
  • J5 (this Session's own data): this Session's status JSON, extended to the new contract, renders 10 cards and 16 item pages (10 in flight, 6 done). Every card opens an existing page, every page links back, and no question wording appears on any page. Its structure and order match the approved mock-ups, with the two intended differences: no running/queued/done counters, and the Waiting row of P5 (a setup-fixes package blocked on question Q-120) shows only "Q-120 waits in Approvals". This Session's overview is 185 KB.
  • J6 (light, dark, phone width): overview and an item page in light and dark at 1280 px and 360 px wide. No horizontal scroll; rails switch to their narrow form and tiles wrap.
  • J7 (in Pane) and J8 (a live orchestrated Session on the released plugin): undetermined. They need a Pane build with these pages, and a released plugin.
  • Independent QA (qa-and-verify, on b598d0b, the same feature commit before the rebase onto main): J1–J6 and C1–C6 pass, with real browser clicks. A click on a card body opens its item page, Details → does too, the PR link still opens the PR, and breadcrumb, Back and prev/next work on all 22 item pages. Ten bad-id cases exit 1 and leave earlier files untouched. No defects. J7 and J8 remain undetermined. Noted, not a defect: a needs[].item that names no item renders without a warning.

Not in this PR: Pane's bundled copy of the renderer and skill (refreshed separately once this merges), a grid layout for long Sessions, and bigbrain's orchestrator (a separate Agent Farm plugin that keeps its own status map and copies none of these files).

🤖 Generated with Claude Code

Tyler Brown and others added 2 commits November 11, 2026 16:36
…ls (0.0.51)

The status-page renderer now writes the overview and items/<id>.html for every
item in one run, from the same status JSON. The overview leads with a summary,
the next step, one Approvals pointer (count and Q-ids, no question wording) and
tiles with a progress bar counted from the items; each card opens its item page
through a stretched link, with no script. Item pages show Asked for, What
changes, Where it stands, the card and rail, a fixed Everything table, siblings
and prev/next. Bad item ids stop the renderer before it writes anything.

Folds in Pane's hardening (script-src 'none' CSP, every link through href(),
numeric counts, allow-listed item state) so Pane's next refresh is a copy.

The orchestrator's instructions describe the new contract; findings,
post-mortem and trace go on the item page, not the brief (D-34).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… test

The baseline/--diff test read the machine's own
/Library/Preferences/com.apple.SoftwareUpdate.plist. On GitHub's macOS
runners Software Update rewrites it mid-test (a pending 26.7.3 update and a
27.2 -> 27.2.1 notice appeared between scans), so the second scan reported a
new FAIL and the test failed. check.sh now honours MSC_SUPDATE_PLIST, a test
hook like MSC_STATE_DIR, and the test points it at a fixed plist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tbrownio
tbrownio merged commit e0e45e7 into main Nov 12, 2026
7 checks passed
@tbrownio tbrownio changed the title Session overview with a page for every work item; questions only in Approvals (greenfield 0.0.50) Session overview with a page for every work item; questions only in Approvals (greenfield 0.0.51) Nov 12, 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.

1 participant