feat(canvas): IM-0b-2 — canvasStore is the rich-map authoring authority#251
Merged
Conversation
IM-0b-2 (ADR-087 §5): make canvasStore the single authoring authority for the rich-map fields previously mutated by ProcessMapBase -> onChange. Adds 6 method-only actions (not in the CanvasAction union, mirroring addStepsFromColumn), each via applyUndoable: setStepCtq / addTributary / removeTributary (with the subgroupAxes + pinned- hunches cascade) / toggleSubgroupAxis / addHunch / removeHunch Ids are minted from deterministic monotonic sequences (nextTributaryId / nextHunchId), reset by resetCanvasLocalState() like generatedStepSequence — no Date.now() / Math.random() / crypto.randomUUID(), so undo snapshots and tests stay reproducible. addHunch trims + guards empty (defense-in-depth mirroring the HunchList UI guard) and preserves the step / tributary pin. 20 new store tests (RED -> GREEN); 59/59 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IM-0b-2 (ADR-087 §5): retire the second persistence path. ProcessMapBase's ctqColumn / tributary / subgroupAxis / hunch mutators now DISPATCH new optional props (onSetStepCtq / onAddTributary / onRemoveTributary / onToggleSubgroupAxis / onAddHunch / onRemoveHunch) when provided, instead of building a next: ProcessMap and calling onChange directly. The onChange map-build stays as the fallback when a prop is absent (back-compat; the only production caller wires every prop). Canvas/index.tsx forwards the six props (extending the onAddStep / onRenameStep wiring). CanvasWorkspace adds the canvasStore-backed handlers — each dispatches the store action then mirrors persistCanvasStoreMap() exactly like handleAddStep, so edits land on processContext.processMap via the SAME persist path as every step-structure edit. persistCanvasStoreMap sets lastHydratedMapSignature to the post-edit map BEFORE handleChange, so the controlled-prop round-trip does NOT re-trigger the hydration effect (no re-hydrate / clobber loop). After this, canvasStore owns every rich-map authoring mutation. Per-step specs editor routing to setMeasureSpec (measureSpecs) is UNCHANGED. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on-loop guard IM-0b-2 (ADR-087 §5): CanvasProcessMap.test.tsx — re-point the ctqColumn / tributary / subgroupAxis / hunch cases to assert the new dispatch props are CALLED (with onChange NOT called) when wired, and keep a legacy onChange map-build fallback case per group for back-compat. Specs-editor cases keep asserting setMeasureSpec routing (unchanged); step-structure cases unchanged. CanvasWorkspace.test.tsx — add the #1-regression-risk test: a ctqColumn edit dispatches onSetStepCtq -> persistCanvasStoreMap -> setProcessContext (controlled prop round-trip) and MUST NOT re-hydrate / clobber the canvasStore. Asserts the store carries the new ctqColumn (proving the dispatch path, not the onChange fallback) and that hydrateCanvasDocument is NOT called again beyond mount. Verified discriminating: removing the CanvasWorkspace onSetStepCtq wiring fails it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rControlAdd prose IM-0b-2 apply-phase docs: - investigations.md: new "IM-0b-2 deferrals" entry — (1) per-step node.capabilityScope (SpecRule[]) authoring deferred to the IM-5/IM-6 holistic design (specs keep routing to project-wide measureSpecs; no setStepCapabilityScope action added); (2) full visual retirement of ProcessMapBase deferred — verify the real need at IM-4 (it is now a thin dispatcher, harmless). - ADR-087 (§Decision item 5 + §Consequences) + the investigation-surface spec §8: flag the onFactorControlAdd-"currently undefined" prose as STALE (it was already wired in IM-0b) and note the IM-0b-2 capabilityScope + ProcessMapBase- retirement scope cuts. Flag annotations only — the forward-looking design statements are left intact. - `// IM-0b-2 deferral:` code comments at the per-step specs editor seam in ProcessMapBase.tsx + CanvasWorkspace.tsx, where authoring INTENTIONALLY still routes to setMeasureSpec (measureSpecs), not canvasStore / node.capabilityScope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- removeTributary cascade: assert pre-state populated (no vacuous post-assert) - toggleSubgroupAxis: assert version bump + one undo entry (sibling parity) - CanvasWorkspace hydration test: comment names the layered guard accurately Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
IM-0b-2 (ADR-087 §8). Makes
canvasStorethe single authoring authority for rich-map fields and refactorsProcessMapBaseto dispatch through it instead of building anextmap + callingonChange— clearing canvasStore for Wave-3 (IM-4/IM-6).What changed
setStepCtq,addTributary,removeTributary[cascades subgroupAxes + pinned hunches],toggleSubgroupAxis,addHunch,removeHunch) viaapplyUndoablewith deterministic id minters.ProcessMapBasedispatches the 6 new props (one production caller,Canvas/index.tsx);onChangefallback retained.setMeasureSpec(nonode.capabilityScopeauthoring).node.capabilityScopeauthoring → IM-5/IM-6 holistic capability design; full visual retirement of ProcessMapBase → verify need at IM-4.Verification
pr-ready-checkgreen (all packages + both apps tsc/test, lint, PWA build).core/files touched.🤖 Generated with Claude Code