Skip to content

feat: Debug slots — taxonomy in the UI, session-only semantics, test-pattern proof (P2–P6) - #259

Draft
Yona-Appletree wants to merge 18 commits into
mainfrom
claude/debug-slots-p2-p6
Draft

feat: Debug slots — taxonomy in the UI, session-only semantics, test-pattern proof (P2–P6)#259
Yona-Appletree wants to merge 18 commits into
mainfrom
claude/debug-slots-p2-p6

Conversation

@Yona-Appletree

@Yona-Appletree Yona-Appletree commented Aug 1, 2026

Copy link
Copy Markdown
Member

Plan: lp2025/2026-07-31-1736-ephemeral-slots
Path: /Users/yona/.photomancer/planning/lp2025/2026-07-31-1736-ephemeral-slots/plan.md

P2–P6 of the Debug-slots plan, stacked on PR #254 (P1, SlotRole refactor). Both branches carry a merge of main @ 7a198f40a (2026-08-01). ⚠️ Stacked: no CI here until retargeted to main after #254 merges — merge #254 first, then retarget.

Progress — all phases complete, at G2 final review

  • P2 — Debug leaves dirty/save (D7); Clear at value/node/project scopes (4dc470f8f)
  • P3 — Debug section + treatment (D3/D4/D8/D9); G1 visual gate PASSED after 3 on-gate iterations: softened stripes, collapsed-by-default disclosure w/ zero-reflow rows, actual-state-only chevron (67ae3cb462d72512bb)
  • P4 — Nothing authored (D2): reader warn-and-skip, role-aware schema-gen, 17 clock.json scrubbed, reset = shape default (18ac35b40)
  • P5OutputDef.test_pattern proof case, bypass harvested from 25c3581f3, mutation-checked FakeResolver proof; superseded [HANDOFF] feat: Node action events (SUPERSEDED — harvest + close) #233 commented (already closed) (e684597ad)
  • P6 — ADR docs/adr/2026-08-01-debug-slots-taxonomy.md + glossary Debug entry + pane-grammar debug family; S4/S5/W9 fixed with tests; S6–S9 logged in docs/debt (8ac837aea)

G2 review artifacts

ADR + glossary diff + pane-grammar addition + this PR. Nested-modules session notified for the Debug-vs-Panel boundary review.

🤖 Generated with Claude Code

Yona-Appletree and others added 8 commits August 1, 2026 13:31
…opes

DirtySummary drops its transient bucket (D7): a Debug override is never
dirty, never gates unload, never tints a header, and never appears in
the Save panel — the live-only-never-gates rule is now structural.
UiPendingEditPhase::Live and the Save panel's "Live (transient)"
sections are deleted (retires S1, S2, S10; defuses W8).

Debug values get Clear as their verb: SlotEditOp::Clear (per value),
NodeClearDebugOp (per node), ProjectOp::ClearDebugEdits (project-wide,
consumed by P3's global chip). All three land on RemoveSlotEdit; for a
Debug slot the authored default is the shape default.

Failed Debug edits still count as failed (rejected writes need
attention regardless of target); a test pins this.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P2)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Node cards partition config by SlotRole (D3/D4): Setting/Fixed under a
'Settings' header, Debug fields FLATTENED into a dedicated Debug section
regardless of declaring record — clock's controls.* render as top-level
rows and the old 'Controls' record row disappears. The section comes
from role, not record name.

Treatment is a semantic UiAffordance::Debug in lpa-studio-core, produced
only by from_debug_overrides (never by dirty merging); the web layer
maps it to attention-orange + diagonal hazard stripes in one seam
(app/affordance.rs + one style.css block), so the visual can change
later without hunting call sites (D9).

Three tiers (D8): global 'Debug active · N · Clear all' header chip
(dispatches ProjectOp::ClearDebugEdits), node-card marker while a node
carries an override, and the Debug section striped ALWAYS — even idle —
which is the structural fix for clean-transient invisibility. Per-node
Clear lands in the section header (first UI entry for NodeClearDebugOp).

Also fixes a P2 web test asserting 'Reset' where the code ships 'Clear'
(web tests are outside just check).

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P3)

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

P2/P3 removed the blue live chrome from components; the regenerated
bundle drops the corresponding arbitrary-value utilities (removals only).

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P3)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rows no longer re-stripe on top of the striped section — the stacking
is what made v1 read many times too strong; rows keep only the soft
orange wash. Stripe alpha drops 0.1/0.2 -> 0.03/0.07 with a wider
pitch (4px/14px), and chips/icon chrome move to the faint variant.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P3, G1 iteration)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
G1 feedback round 2. The Debug section becomes a disclosure using the
established card-UI idiom (NodeCardUiState.debug_open, default false,
via NodeUiOp::SetDrawer): the striped DEBUG header stays always visible
with the active count and a working Clear, rows render only when
expanded — most sessions never need them open.

Row geometry is pinned so touching a control moves nothing: debug rows
carry a fixed 44px floor and reserve the trailing verb footprint when
untouched, and the section header holds 28px in every state (count and
Clear appearing measure 0px). Verified via live getBoundingClientRect.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P3, G1 iteration 2)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eedback)

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P3, G1 iteration 3)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dynamic slot reader warns and skips an authored Debug-role field
(single seam, covers host tooling, studio, and firmware parses alike),
so an on-disk value can never become base — reset targets the shape
default structurally (kills W3). Schema-gen omits Debug fields from
authoring schemas while shape dumps keep roles (kills W2); the 17
example clock.json files drop their all-defaults controls stanzas.

The lpa-server fs-refresh test now probes with a Setting-role binding,
since an external controls.rate rewrite is correctly a no-op.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P4)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ypass)

The first Debug bool and first hardware-mode Debug slot. The engine
bypass is harvested from 25c3581 recast onto the effective def: while
test_pattern is true the graph resolve is skipped entirely and the
last-established extent repaints solid white through the shared publish
seam; the frame it flips false the graph renders again — no black
frame. All TTL/press_id/renewal machinery is dropped (a Debug slot has
a durable home); the node accepts no runtime commands and the wire is
untouched (proto stays 4).

The FakeResolver harness counts input resolves and render calls
separately, so 'the graph was skipped' is proved, not inferred; a
studio e2e pins that the output card's Debug section derives entirely
from role + partition with zero output-specific UI code.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P5)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Yona-Appletree and others added 6 commits August 1, 2026 18:49
ADR 2026-08-01-debug-slots-taxonomy records the Settings/Panel/Debug/
State language table, the Panel-vs-Debug boundary (exposure vs
transient-by-nature), and the D1 routing rule (events → command
channel; ephemeral state → Debug slots; produced state →
direction-implied), reconciling — without amending — the 2026-07-27
command-channel ADR and marking its sim-button follow-up obsolete.
Glossary gains a Debug entry; the pane-grammar ADR gains the debug
colour family.

Paydown: stale overlay entries classify by role (S4); both sides share
one persistence classifier incl. the unresolvable→Setting rule (S5);
ProjectRegistry::mutate now validates like the batch path, with the one
legitimate Fixed-map writer isolated as crate-private
stage_dedicated_op (W9). S6/S7/S8/S9 logged in docs/debt/. Stale
SlotPolicy-era prose swept from crate READMEs and module docs.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P6)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three fixes from the panel.md/glossary owner's review (verdict: no
structural collision): latching-vs-momentary panel persistence spelled
out (P14 gestures never persist yet are Panel — fallback is bus
resolution, not a shape default); exposure stated as binding via the
bound channel, control identity (scope, channel); the lease-rejection
scoped to state-with-a-durable-home so P9's momentary wire leases
aren't foreclosed.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P6, G2 review)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The merge of main brought quad-equal100-v3, quad-gamma-full,
quad-gamma-v3, quad-strips-v3 and quad60-v3, whose clock.json files
were authored before D2 landed; all carried identical shape-default
controls values. Schema conformance is green again. Plus rustfmt of a
hand-resolved import.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P6, merge follow-up)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The test (new on main) fabricated an overlay entry through the then-
unvalidated ProjectRegistry::mutate against an unknown artifact; with
mutate now validating like the batch path, the setup loads a real
minimal project root and assigns ProjectDef's one writable field
(name.some) instead. Test intent unchanged: the read reports the
mutation revision.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (P6, merge follow-up)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Yona-Appletree
Yona-Appletree changed the base branch from claude/ephemeral-debug-slots-impl-210c61 to main August 2, 2026 07:32
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

CI refreshed the story baselines on this branch

The validate-stories job detected drift and committed the fresh set: 77 changed
in 1dc05b4.

Review every PNG in the PR's Files changed view (swipe / onion-skin).
Your local branch is now behind — git pull before pushing again.

Story Before After
base__detail-popover__open-sections__lg.png base__detail-popover__open-sections__lg.png@b0a611f185 base__detail-popover__open-sections__lg.png@1dc05b47bd
base__detail-popover__open-sections__md.png base__detail-popover__open-sections__md.png@b0a611f185 base__detail-popover__open-sections__md.png@1dc05b47bd
base__detail-popover__open-sections__sm.png base__detail-popover__open-sections__sm.png@b0a611f185 base__detail-popover__open-sections__sm.png@1dc05b47bd
exploration__node-cards__gallery-drawers-open__lg.png exploration__node-cards__gallery-drawers-open__lg.png@b0a611f185 exploration__node-cards__gallery-drawers-open__lg.png@1dc05b47bd
exploration__node-cards__gallery-drawers-open__md.png exploration__node-cards__gallery-drawers-open__md.png@b0a611f185 exploration__node-cards__gallery-drawers-open__md.png@1dc05b47bd
exploration__node-cards__gallery-drawers-open__sm.png exploration__node-cards__gallery-drawers-open__sm.png@b0a611f185 exploration__node-cards__gallery-drawers-open__sm.png@1dc05b47bd
studio__node__config-slot-row__debug-chrome__lg.png studio__node__config-slot-row__debug-chrome__lg.png@b0a611f185 studio__node__config-slot-row__debug-chrome__lg.png@1dc05b47bd
studio__node__config-slot-row__debug-chrome__md.png studio__node__config-slot-row__debug-chrome__md.png@b0a611f185 studio__node__config-slot-row__debug-chrome__md.png@1dc05b47bd
69 more file(s)
  • studio__node__config-slot-row__debug-chrome__sm.png (changed)
  • studio__node__config-slot-row__debug-detail-popup__lg.png (changed)
  • studio__node__config-slot-row__debug-detail-popup__md.png (changed)
  • studio__node__config-slot-row__debug-detail-popup__sm.png (changed)
  • studio__node__config-slot-row__editable-clean-controls__sm.png (changed)
  • studio__node__config-slot-row__rejected-edit__sm.png (changed)
  • studio__node__fixture-face__advanced-open__lg.png (changed)
  • studio__node__fixture-face__advanced-open__md.png (changed)
  • studio__node__fixture-face__advanced-open__sm.png (changed)
  • studio__node__node__debug-section-active__lg.png (changed)
  • studio__node__node__debug-section-active__md.png (changed)
  • studio__node__node__debug-section-active__sm.png (changed)
  • studio__node__node__debug-section-collapsed-active__lg.png (changed)
  • studio__node__node__debug-section-collapsed-active__md.png (changed)
  • studio__node__node__debug-section-collapsed-active__sm.png (changed)
  • studio__node__node__debug-section-expanded-idle__lg.png (changed)
  • studio__node__node__debug-section-expanded-idle__md.png (changed)
  • studio__node__node__debug-section-expanded-idle__sm.png (changed)
  • studio__node__node__debug-section-idle__lg.png (changed)
  • studio__node__node__debug-section-idle__md.png (changed)
  • studio__node__node__debug-section-idle__sm.png (changed)
  • studio__node__node__debug-section-vs-unsaved__lg.png (changed)
  • studio__node__node__debug-section-vs-unsaved__md.png (changed)
  • studio__node__node__debug-section-vs-unsaved__sm.png (changed)
  • studio__node__node__dirty-failed-header-tint__lg.png (changed)
  • studio__node__node__dirty-failed-header-tint__md.png (changed)
  • studio__node__node__dirty-failed-header-tint__sm.png (changed)
  • studio__node__node__dirty-failed-surface-tint__lg.png (changed)
  • studio__node__node__dirty-failed-surface-tint__md.png (changed)
  • studio__node__node__dirty-failed-surface-tint__sm.png (changed)
  • studio__node__node__dirty-unsaved-header-tint__lg.png (changed)
  • studio__node__node__dirty-unsaved-header-tint__md.png (changed)
  • studio__node__node__dirty-unsaved-header-tint__sm.png (changed)
  • studio__node__node__dirty-unsaved-surface-tint__lg.png (changed)
  • studio__node__node__dirty-unsaved-surface-tint__md.png (changed)
  • studio__node__node__dirty-unsaved-surface-tint__sm.png (changed)
  • studio__node__node__error-node__lg.png (changed)
  • studio__node__node__error-node__md.png (changed)
  • studio__node__node__error-node__sm.png (changed)
  • studio__node__node__header-delete-action__lg.png (changed)
  • studio__node__node__header-delete-action__md.png (changed)
  • studio__node__node__header-delete-action__sm.png (changed)
  • studio__node__node__nested-dirty-children__lg.png (changed)
  • studio__node__node__nested-dirty-children__md.png (changed)
  • studio__node__node__nested-dirty-children__sm.png (changed)
  • studio__node__node__node-pane__lg.png (changed)
  • studio__node__node__node-pane__md.png (changed)
  • studio__node__node__node-pane__sm.png (changed)
  • studio__node__node__output-debug-test-pattern-active__lg.png (changed)
  • studio__node__node__output-debug-test-pattern-active__md.png (changed)
  • studio__node__node__output-debug-test-pattern-active__sm.png (changed)
  • studio__node__node__output-debug-test-pattern-idle__lg.png (changed)
  • studio__node__node__output-debug-test-pattern-idle__md.png (changed)
  • studio__node__node__output-debug-test-pattern-idle__sm.png (changed)
  • studio__node__shader-face__advanced-open__lg.png (changed)
  • studio__node__shader-face__advanced-open__md.png (changed)
  • studio__node__shader-face__advanced-open__sm.png (changed)
  • studio__project__project-pane__debug-absent-from-save-panel__lg.png (changed)
  • studio__project__project-pane__debug-absent-from-save-panel__md.png (changed)
  • studio__project__project-pane__debug-absent-from-save-panel__sm.png (changed)
  • studio__project__project-pane__debug-active-chip__lg.png (changed)
  • studio__project__project-pane__debug-active-chip__md.png (changed)
  • studio__project__project-pane__debug-active-chip__sm.png (changed)
  • studio__project__project-pane__debug-active-with-unsaved__lg.png (changed)
  • studio__project__project-pane__debug-active-with-unsaved__md.png (changed)
  • studio__project__project-pane__debug-active-with-unsaved__sm.png (changed)
  • studio__project__project-workspace__project-ready__lg.png (changed)
  • studio__project__project-workspace__project-ready__md.png (changed)
  • studio__project__project-workspace__project-ready__sm.png (changed)

Yona-Appletree and others added 2 commits August 2, 2026 10:39
…25% (G2)

The style.css merge union dropped one closing brace on
.lpb-ed-hidden-input, which silently killed every rule after it — the
entire debug treatment and the Settings header included. One character.

TEST_PATTERN_RGB drops to [64,64,64] (G2: full white is the
maximum-current case on long strips); the engine tests derive PATTERN16
from the const so a retune can't strand them.

Plan: lp2025/2026-07-31-1736-ephemeral-slots (G2 fixes)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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