Skip to content

Render the design lane as /ndd's inbox plus a defect bucket, not one raw label total - #168

Merged
thedavidmeister merged 2 commits into
masterfrom
design-split-panel-240
Aug 9, 2026
Merged

thedavidmeister merged 2 commits into
masterfrom
design-split-panel-240

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Refs rainlanguage/issue-pr-cron#240 (a cross-repo issue cannot be auto-closed reliably, so this is a Refs; the issue closes on its own repo's PR).

Pairs with rainlanguage/issue-pr-cron#243 — the emitter half. The two land together: that PR emits the split, this one draws it. Order does not matter and neither is harmful alone — an old dashboard ignores the new fields, and this page falls back to today's rendering on a snapshot without them — but the number on the panel is only fixed when both are in.

What the panel was saying

site/pipeline.html files the ai:design box under { owner: "human", act: "rule on design Q" }, drawing the raw ai:design label total. On 2026-08-09 that read 6 while /ndd — the command built to rule on those six — had nothing to present, withholding every one as "no trusted comment raises a design question". Draining the queue could not move it, because it was never counting rulable rows.

The invariant, now stated in the code where the human owner's states are defined: every count filed under owner human is a count some human command will present. If no command serves it, it is not an inbox, and displaying it as one manufactures work that cannot be done.

What this renders

  • The ai:design box is now presentable — the number /ndd will serve, which goes to zero when a human drains the queue — with its sparkline drawn from counts.designPresentable (the series measuring that same population) and its click-through listing the presentable rows.
  • The withheld half renders in its own group, outside every actor total (ai:design — withheld from /ndd · not an inbox). No actor's command serves any of it, and inside an owner group it would read as an inbox again — which is the defect being fixed.
    • noQuestion is the headline and carries the leak box's contract: it renders even at zero, has its own series and rising-trend border, and reads as a defect that should trend to zero rather than as work. Its PRs list on click.
    • draft / fetchErrors / unaddressable render only while they hold anything, each with its own count and list.
  • Both halves are cross-checked the way the cell already was: a bucket's stated count against the rows annotated into it (box renders the larger, disagreement named), and each rendered half against the counts key its series draws from — the issue-pr-cron#228 two-numbers check, one level down. The two new keys are claimed by the boxes that draw them, so a clean split draws no defect band and an orphaned key still screams.
  • Backward compatible, by the file's established pattern: a cell with no well-formed breakdown returns null from designSplit and every consumer below falls through to exactly today's rendering. Numbers are validated through the existing posNum (a malformed presentable must not coerce to a fabricated 0 inbox). The frozen STATES table and the pre-lanes legacy branch keep drawing the raw count, with a comment each saying why that is all such a snapshot can say.

Screenshots

All three rendered with nix run .#screenshot (pinned chromium), read before posting. nix run .#roh-scan was NOT run — this is a pure rendering change against committed data.

1. Before / after on LIVE data — byte-identical (cmp reports no difference). The live human-queue.json does not carry the split yet, so the honest state today is no change at all: the design box still reads 6 and no withheld group appears. That is the backward-compat guarantee holding, demonstrated rather than asserted.

2. After, on a fixture snapshot carrying the split at the measured 2026-08-09 shape (presentable: 0, noQuestion: 6, every entry annotated noQuestion, counts.designPresentable: 0 / designNoQuestion: 6): the human row now reads ai:ready 0 · ai:design 0 · close-candidate 0 · leak 0, total 0, and a separate AI:DESIGN — WITHHELD FROM /NDD · not an inbox 6 group carries a single 6 / no trusted question raised / DEFECT — NO COMMAND SERVES IT box. This is the issue's number, fixed: the human inbox and /ndd now agree at 0, and the six are visible as the defect they are.

3. After, on a mixed fixture (presentable: 2, noQuestion: 3, draft: 1): the design box reads 2 under Human action (human total 2, and it takes the group's lead marker as the largest queue), while the withheld group reads 4 across two boxes — 3 / no trusted question raised and 1 / draft — code still forming / PRODUCER FINISHES THE DRAFT. The empty fetchErrors and unaddressable buckets draw nothing.

Fixtures were built by patching the committed human-queue.json (plus two history lines carrying the new keys so the new series draw) and serving it same-origin; the page's fetch URLs were pointed at the local copies for the render only — no committed file was changed.

QA

  • Discriminating tests: pipeline FSM: {the design box is the /ndd inbox — presentable, never the raw label total; presentable rows list under the design box; a drained defect bucket shows its zero; withheld buckets beyond noQuestion render only while they hold anything; a split whose counts mirror disagrees is a loud defect naming both numbers}each verified to FAIL on base by restoring master's site/pipeline.html under the new tests and re-running the suite: FAILED | 242 passed | 4 failed, the four failures being exactly these. Two further new tests (a snapshot without the split renders the design cell exactly as before, split counts keys without a breakdown behind them sweep as unclaimed occupancy) pass on base by design — they are the backward-compat and conservation regression guards, and a guard that failed on base would be asserting the old behaviour was already broken. Full suite on the branch: 246 passed | 0 failed.
  • Mutations applied: the emitter-side mutation pass lives on the paired PR (8/8 killed) since that is where the computation is. On this side the equivalent evidence is the fails-on-base run above — each rendering claim was falsified against the unmodified page — plus two structural mutants of the fixture rather than the code, which is where this page's logic is falsifiable: swapping designPresentable to disagree with the rendered breakdown produces the counted two ways defect (asserted), and removing the breakdown while keeping the counts keys produces claimed by no descriptor (asserted). A code mutant swapping the box's source back to laneCount is killed by the first test in the list (it would render 6).
  • Oracle: the issue's own measurement — dashboard 6 vs /ndd presentable 0, noQuestion 6 at 2026-08-09T08:44Z — used directly as the fixture, so the test asserts the panel now reports what /ndd reports. The bucket vocabulary is the emitter's (DesignBucket), read off the paired PR's schema rather than restated here. Rendering claims are checked against actual screenshots, read, not assumed.
  • Category check: issue asks (a) the human-inbox design count becomes presentable — done; (b) noQuestion as a separate defect bucket with the leak bucket's should-trend-to-zero treatment — done, including always-rendering at zero, its own series and the rising border; (c) its PRs listed under it — done, via the existing click-to-expand registration; (d) backward compat by the file's established fallback pattern — done, and demonstrated by identical before/after renders on live data; (e) the owner-invariant as a code comment where the human owner states are defined — done. The emitter half is the paired PR.

Summary by CodeRabbit

  • New Features
    • Added support for design-state breakdowns in the pipeline dashboard.
    • Presents actionable design work separately from withheld categories.
    • Provides dedicated history details and click-through lists for design items.
  • Bug Fixes
    • Corrected actor totals so withheld work is excluded.
    • Added validation and defect reporting for mismatched counts, lists, and history data.
    • Ensured no-question items are always surfaced as defects.
    • Preserved compatibility with dashboards using legacy snapshot data.

…bucket

The design box told a human there were six design questions to rule on
while /ndd, the command built to rule on them, had nothing to present:
the box drew the raw ai:design label total, and every one of the six was
withheld as 'no trusted comment raises a design question'. A count filed
under owner 'human' that no human command serves is not an inbox.

The tool now attaches next_design's own partition to the ai:design cell
(issue-pr-cron#240), so the panel renders it: the box is the PRESENTABLE
half — the number /ndd serves, which goes to zero when the queue drains —
and the withheld half renders in its own group OUTSIDE every actor total,
led by noQuestion, which carries the leak box's contract of a defect
metric that should read zero, with its own series and rising border. The
other buckets (draft / fetchErrors / unaddressable) surface only while
they hold anything, each with its own click-through list.

Both halves are cross-checked the way the cell already was: a bucket's
stated count against the rows annotated into it, and each rendered half
against the counts key its series is drawn from — the box renders the
larger and the disagreement is named in the defect band.

Backward compatible: a snapshot with no breakdown (every one written
before the tool carried it) renders exactly as today, and the frozen
STATES / pre-lanes tables keep drawing the raw count.

Refs rainlanguage/issue-pr-cron#240

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 49 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fa95bb73-e4bc-4249-81c5-65d1ad1d0a43

📥 Commits

Reviewing files that changed from the base of the PR and between a7796bb and 37db74f.

📒 Files selected for processing (1)
  • test/dashboard.test.js

Walkthrough

The dashboard now supports descriptor-based ai:design breakdowns. It renders presentable work separately from withheld buckets, excludes withheld work from actor totals, validates count conservation, and preserves raw-count rendering for legacy snapshots.

Changes

AI design breakdown

Layer / File(s) Summary
Design split validation
site/pipeline.html, test/dashboard.test.js
The pipeline validates design buckets, annotated rows, count mirrors, and conservation claims. Tests cover valid splits, mismatches, and unclaimed occupancy.
Design bucket rendering
site/pipeline.html, test/dashboard.test.js
Presentable rows populate the design inbox and actor totals. The no-question bucket always renders as a defect. Other withheld buckets render only when non-empty.
Legacy snapshot compatibility
site/pipeline.html, test/dashboard.test.js
Snapshots without a descriptor-based breakdown continue to render the raw counts.design value without withheld groups or split defects.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PipelinePage
  participant designSplit
  participant DescriptorSnapshot
  participant Dashboard
  participant DefectPanel
  PipelinePage->>DescriptorSnapshot: read ai:design breakdown
  PipelinePage->>designSplit: validate bucket counts and rows
  designSplit->>Dashboard: render presentable design rows
  designSplit->>DefectPanel: report count or conservation mismatches
  Dashboard->>Dashboard: render withheld design buckets separately
Loading

Possibly related issues

  • rainlanguage/issue-pr-cron#240: Requests the ai:design split, presentable human work counts, and noQuestion defect reporting.

Possibly related PRs

Suggested labels: ai:ready

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: rendering the design lane as a presentable inbox with separate defect buckets instead of one raw total.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch design-split-panel-240

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Screenshots — read before posting

All rendered with nix run .#screenshot (pinned chromium, 1300x1120). nix run .#roh-scan was not run: this is a pure rendering change and every render is against committed/fixture data.

1. Live data: before and after are byte-identical

The live human-queue.json does not carry the split yet, so the honest state today is no visible change. cmp on the two PNGs reports no difference (135545 bytes each). The design box still reads 6 under Human action and no withheld group appears — the backward-compat fallback, demonstrated rather than asserted.

live, master
live, this branch — byte-identical

2. Fixture at the issue's measured shape (presentable: 0, noQuestion: 6)

This is the 2026-08-09T08:44Z measurement from the issue, fed to the page. The design box now reads 0 and dims, the Human action total drops to 0 — the human inbox and /ndd finally agree — and the six appear below in AI:DESIGN — WITHHELD FROM /NDD · not an inbox 6 as a single no trusted question raised / DEFECT — NO COMMAND SERVES IT box, outside every actor total.

fixture: all six withheld as noQuestion

3. Fixture with a mixed split (presentable: 2, noQuestion: 3, draft: 1)

The design box reads 2 (the rows /ndd would serve) and the Human total is 2; the withheld group reads 4 across two boxes — 3 no trusted question raised and 1 draft — code still forming / PRODUCER FINISHES THE DRAFT. The empty fetchErrors and unaddressable buckets draw nothing, per the render-only-while-occupied rule.

One thing to read correctly in this shot: the design box carries the red border + ▲. That is the pre-existing lead fallback (nothing in the human group is trending, so the largest queue is marked "start here"), not a new bottleneck signal — the same mark ai:design would have carried at 2 before this change.

fixture: mixed split

How the fixtures were built: the committed human-queue.json was copied and patched to carry breakdown + per-entry bucket + the two counts keys, two history lines were appended so the new series have points to draw, and the page's two fetch URLs were pointed at the local copies for the render only. No committed file was modified, and nothing was fetched from the live pipeline for shots 2 and 3.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@site/pipeline.html`:
- Around line 647-672: Move bucket count derivation, row assignment, and
FSM-conformance defect generation out of designSplit and the related dashboard
logic, and have the producer persist verified counts, assignments, and defect
records in human-queue.json. Update the dashboard to fetch and render those
producer-owned fields without recomputing pipeline state, retaining raw-count
fallback only as a display decision.

In `@test/dashboard.test.js`:
- Around line 4268-4294: Extend the dashboard FSM tests around the presentable
design bucket and withheld noQuestion bucket to use HTML- and script-like title
or repository values, then click both rendered boxes. Assert the resulting
payloads are text nodes and no markup elements are created, while preserving the
existing count, grouping, and conservation assertions; apply the same coverage
to the related test block around the second referenced range.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3257c243-955d-4326-beec-d28258450ac2

📥 Commits

Reviewing files that changed from the base of the PR and between fb2de60 and a7796bb.

📒 Files selected for processing (2)
  • site/pipeline.html
  • test/dashboard.test.js

Comment thread site/pipeline.html
Comment thread test/dashboard.test.js
…loads

CodeRabbit on #168: the design split put PR titles and repo names on two
new render paths — the inbox box's presentable rows and the withheld
group's per-bucket rows — and the new tests used only safe values, so
nothing exercised them with the payloads CLAUDE.md requires.

One test, three distinct payloads (one shared string would let a path
that stopped rendering as text pass on another path's copy), opening each
box in turn and asserting through the existing assertInert/markupNodes
helpers that each lands as text and the tree grows no element or handler.

Refs rainlanguage/issue-pr-cron#240

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Reviewed 37db74f: pass — designSplit validates through posNum and returns null on any malformed or absent breakdown, so every pre-split snapshot renders the byte-identical page (confirmed by the live before/after cmp). The split is resolved once per descriptor and stored on it, so the conservation sweep and the render loop cannot read the cell two different ways. shown = max(stated, listed.length) keeps a broken count from hiding inventory the list proves is there, matching laneCount's existing posture, and both halves are claimed as occupancy so a nonzero noQuestion cannot sweep as inventory rendering nowhere. The withheld group sits outside every owner total, which is the substance of issue-pr-cron#240: the human number becomes what /ndd will actually serve. noQuestion renders even at zero under the leak box's defect contract. 4 of 6 new tests verified failing on base.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Reviewed 37db74f: pass

Rulings-conformance: checked the artifact against the rulings section of the issue-pr-cron CLAUDE.md this work is governed by, and against every ruling the human stated for it.

  • "dash should match ndd" (human, 2026-08-09, the ruling that produced Dashboard design-lane count must match /ndd: presentable is the inbox, noQuestion is a defect bucket issue-pr-cron#240). OBEYED, and this is the whole diff: the design box draws presentable — the population /ndd actually serves, which reads zero when a human drains the queue — instead of the raw label total.
  • "every count filed under owner human is a count some human command will present" (the invariant recorded in #240). OBEYED and written into the code as a comment at the STATES human section, which is where a future descriptor would otherwise reintroduce the defect. The withheld rows render in their own group OUTSIDE every actor total, so nothing unservable is counted as an inbox.
  • "data gaps are data entry — the honest empty state is correct, never widen app logic to paper over missing data" (human, standing). OBEYED: a snapshot without the split returns null from designSplit and the page renders exactly as before rather than fabricating a zero inbox; the live before/after screenshots are byte-identical for precisely that reason, and that was reported as the honest current state rather than dressed up as a visible win.
  • "screenshot every visual PR, and READ the diff rather than re-blessing it" (human, standing). OBEYED: before/after plus two fixture shapes posted at Render the design lane as /ndd's inbox plus a defect bucket, not one raw label total #168 (comment), read before posting, with the red border on the mixed shot explicitly identified as the pre-existing lead-fallback mark and not a new signal.
  • "human decisions are transitions to a state, not a separate state" (human, this session). NOT ENGAGED: this diff renders an existing partition and adds no state. The human:design descriptor it leaves untouched is separate and is being filed on its own.
  • Formatter discipline (removal is semantic, not grep, and do not commit churn): the 2176-line deno fmt rewrap that appeared mid-work was confirmed spurious — master is not clean under it and the repo hook excludes .js — and was reverted before any commit carried it.

Merging with --merge --admin per the standing no-squash rule; all checks green, no red to account for.

@thedavidmeister
thedavidmeister merged commit f8726ea into master Aug 9, 2026
9 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