Skip to content

begin: surface forced cells in the UI#35

Merged
sean-parent merged 9 commits into
mainfrom
worktree-forced-to-disabled
Jul 10, 2026
Merged

begin: surface forced cells in the UI#35
sean-parent merged 9 commits into
mainfrom
worktree-forced-to-disabled

Conversation

@sean-parent

@sean-parent sean-parent commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

  • Query property_model::Sheet::is_forced/forced_cells() (already implemented in property-model) after every propagate() in the begin demo app.
  • Disable the Inspector's text field for any cell that's currently forced — its value is always overwritten by an active relationship regardless of what's typed.
  • Highlight forced cells and every constraint edge touching one (both the edge that produces the cell and any outgoing edges carrying its value onward) in the D3 graph, in a distinct purple.
  • Extend the demo source (DEMO_SOURCE) with a new cell g forced by a single-method relationship, gated on the existing p conditional — toggling p between 0 and 1 toggles g between editable and forced/disabled/highlighted.

Notable implementation detail

g's forcing relationship is declared in its own conditional p { 1i32 => { .. } } block rather than folded into the existing 1i32 branch. pm-lang groups every method in one branch into a single relationship, and a relationship's forced outputs are the intersection of its methods' pure outputs — mixing [c] -> [g] in with the existing c/f methods would make that intersection empty, forcing nothing. Two conditionals sharing the same match cell compose independently, so this is a distinct relationship gated on the same p == 1 condition (this also means the graph now renders two diamond nodes for p). See the doc comment on DEMO_SOURCE in begin/src/app.rs and the design spec's superseded-approach note for the full reasoning.

Test plan

  • cargo build --workspace — zero warnings
  • cargo test --workspace / cargo test --doc --workspace — all passing
  • cargo clippy --workspace --exclude begin -- -D warnings — clean
  • cargo clippy -p begin --no-default-features -- -D warnings — clean
  • New unit tests: bridge.rs (GraphData::forced populated/excluded by conditional branch activity), app.rs (g forced/unforced across p toggling, including round-trip back to unforced)
  • Manual: dx serve --platform desktop, toggle p between 0 and 1, confirm g's Inspector field disables/enables and the graph highlights g plus its edges accordingly — not yet run in this environment (no GUI available); recommend a quick pass before merging

Design spec: docs/superpowers/specs/2026-07-09-begin-forced-cells-ui-design.md
Implementation plan: docs/superpowers/plans/2026-07-09-begin-forced-cells-ui.md

🤖 Generated with Claude Code


Note

Low Risk
Demo/UI-only changes in begin using existing property-model APIs; no auth, persistence, or core solver changes.

Overview
The begin demo now surfaces forced cells from Sheet::is_forced / forced_cells: values that an active relationship will always overwrite on propagate(), so editing them in the UI was misleading.

Bridge → D3: GraphData gains a forced list of stable cell node IDs (same pattern as changed). graph.js applies forced / forced-edge classes so those cells and any constraint edge touching them (incoming or outgoing) render in purple.

Inspector: CellRow disables SpTextfield when the cell is forced; SpTextfield adds a disabled prop on <sp-textfield>.

Demo: DEMO_SOURCE adds cell g and a second conditional p { 1i32 => … } with g = c * 10 so forcing works as a single-method relationship (documented in the DEMO_SOURCE comment). Tests in app.rs and bridge.rs cover forced state vs conditional branch activity.

Design/plan docs under docs/superpowers/ were added for this work.

Reviewed by Cursor Bugbot for commit 19ffc25. Bugbot is set up for automated code reviews on this repo. Configure here.

sean-parent and others added 8 commits July 9, 2026 16:20
Spec covers disabling Inspector fields for forced cells, highlighting
forced cells and their producing edge in the D3 graph, and extending
the demo source with a conditional relationship that forces a cell.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
GraphData::forced mirrors the existing changed field, populated from
Sheet::forced_cells(), so graph_view/graph.js can highlight cells (and
their producing edge) that an active relationship guarantees will
always be overwritten by propagate().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A forced cell's value is always overwritten by an active relationship
on the next propagate(), regardless of what the user types, so the
field is disabled rather than silently discarding edits.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…raph

Cells reported by GraphData::forced (see Task 1) get a distinct purple
outline, along with the constraint edge that feeds them, so it's
visible at a glance which cells can never be edited.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DEMO_SOURCE's p == 1 branch now also activates a single-method
relationship g = c * 10, so g is forced (per Sheet::is_forced) only
while that branch is active — exercising the Inspector-disable and
graph-highlight behavior added in prior tasks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ional form

Final whole-branch review flagged that DEMO_SOURCE's doc comment and
the design spec still describe folding g's method into the existing
p == 1 branch, which the planner's forced-output intersection makes a
no-op. Update both to describe and explain the two-conditional form
actually shipped in the prior commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A forced cell's value is just as guaranteed downstream as it is
produced upstream, so the edges carrying it onward to other
relationships should read as forced too, not just the edge that
produces it.

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Surfaces forced cells (as reported by property_model::Sheet::{is_forced, forced_cells}) in the begin demo app so users can see which cell values will be overwritten by active relationships and avoid editing values that cannot “stick”.

Changes:

  • Add GraphData::forced and populate it from Sheet::forced_cells() so the graph UI can style forced cells/edges.
  • Disable the Inspector textfield when Sheet::is_forced(id) is true.
  • Extend the demo pm-lang source with a conditionally-forced cell g and add unit tests covering forced/unforced transitions.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
docs/superpowers/specs/2026-07-09-begin-forced-cells-ui-design.md Design spec for forced-cell Inspector/graph behavior and demo source changes.
docs/superpowers/plans/2026-07-09-begin-forced-cells-ui.md Implementation plan describing how to plumb forced-cell state into UI + demo source.
begin/src/spectrum.rs Add disabled: bool prop to SpTextfield and map it to <sp-textfield disabled>.
begin/src/inspector.rs Compute forced per cell and disable the Inspector input for forced cells.
begin/src/bridge.rs Add GraphData::forced and tests verifying it tracks active conditional forcing.
begin/src/app.rs Update DEMO_SOURCE to include conditionally forced cell g, plus tests for g forced/unforced across p toggles.
begin/assets/graph.js Highlight forced cell nodes and any constraint edge touching a forced cell.
begin/assets/graph.css Add purple styling for forced cells (.node-cell.forced) and forced edges (.link.forced-edge).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/superpowers/specs/2026-07-09-begin-forced-cells-ui-design.md Outdated
Comment thread docs/superpowers/specs/2026-07-09-begin-forced-cells-ui-design.md Outdated
Comment thread docs/superpowers/specs/2026-07-09-begin-forced-cells-ui-design.md Outdated
Comment thread docs/superpowers/plans/2026-07-09-begin-forced-cells-ui.md
Comment thread docs/superpowers/plans/2026-07-09-begin-forced-cells-ui.md
Comment thread docs/superpowers/plans/2026-07-09-begin-forced-cells-ui.md
Comment thread docs/superpowers/specs/2026-07-09-begin-forced-cells-ui-design.md Outdated
…d-cell edges

The design spec still described highlighting only the incoming edge and
still presented the superseded single-conditional demo-source form as
current, contradicting the two-conditional structure and source-or-target
edge highlighting actually shipped. Rewrite the spec's Demo Source/Testing/
Out of Scope sections to match, and mark the plan's now-stale JS/DEMO_SOURCE
snippets as superseded (matching the existing convention) so they don't
mislead readers about the final form.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sean-parent sean-parent merged commit 9ddcee7 into main Jul 10, 2026
2 checks passed
@sean-parent sean-parent deleted the worktree-forced-to-disabled branch July 10, 2026 17:39
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.

2 participants