Repository navigation
refactor(loom-ui): isolate Builder row-root change workflow into authoring hook [198] - #209
Draft
matthewpeterkort wants to merge 1 commit into
Draft
matthewpeterkort wants to merge 1 commit into
matthewpeterkort wants to merge 1 commit into
Conversation
…[198] BuilderWorkspace owned the assess -> resolve ambiguity -> preview -> apply row-root change lifecycle inline: three request refs, an epoch ref, two state cells, the stale-abort effect, and five action callbacks declared beside unrelated workspace and publishing state (base lines 556-564, 989-1039, 2094-2365). The workflow's only UI is the RowRootPicker / RowChangePreviewPanel composition, and authoring/rootChangeSelection.ts already owns its identity comparison and discriminated UI-state types, so the lifecycle now lives in one feature-owned hook beside those types. - authoring/useRowChangeWorkflow.ts: request lifecycle, epoch/refusal protocol, stale-abort effect, and select/resolve/refresh/cancel/apply actions. Inputs are the typed request identity fields, assess/preview ports, preview limit, and narrow apply/reload/message callbacks; output is the existing discriminated state plus the actions and a render-derived readyRowChangePreview narrowing (same identity predicate as the removed rootChangePreviewReady boolean). - BuilderWorkspace keeps table selection, panel rendering, the workspace refs the actions read, and the assess mutation whose isLoading still gates publishing. No new useEffect: the single stale-abort effect moved with its body, dependency values, and registration order. - Bodies moved verbatim via a checked extraction (documented renames only in the effect/identity render-scope reads); every moved body verified byte-identical against the base blob, including the workspaceAttached.current guard line. Behavior preserved unchanged: preview-before-apply, abort/ignore-after- identity-change, NO_CHANGE/BLOCKED/stale/unavailable/request/ CLIENT_CANCELLED outcomes and messages, ambiguity validation against the current server assessment with route-rebase retention, request dispatch timing, and first-failure precedence. Validation: BuilderWorkspace.reconciliation.unit.test.tsx 92/92; core protocol + operation history + comprehensive formal 42/42; full ExplorerBuilder 79 files 1076/1076; full loom-ui package 97 files 1355/1355, 0 skipped; typecheck:tests and declaration emit clean; check-boundaries passes; no-code-comments gate 0 violations; git diff --check clean. Coordination (outside this ticket's file ownership, flagged not neutered): scripts/lib/formal-source-proofs.mjs Inv_DetachedRootChangeDoesNotPreview still anchors its workspaceAttached mutation at BuilderWorkspace.tsx and now hard-errors "Nonunique mutation anchor"; repointing only the path to authoring/useRowChangeWorkflow.ts (before/after strings unchanged) passes the full positive/broken/restored proof, so the control still detects the fault. docs/ui-contract-inventory needs its BuilderWorkspace.tsx evidence ranges re-anchored (10 distinct ranges shifted by the net -338 lines), plus regenerated watchedFiles hash/file-set. Closes #198
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.
What
Isolates the Builder row-root change workflow (assess → resolve ambiguity → preview → apply) from
BuilderWorkspace.tsxinto one feature-owned hook,authoring/useRowChangeWorkflow.ts, adjacent to therootChangeSelectiontypes it already depends on. Closes #198.Why this reduces reasoning burden (not line count)
Before, understanding "what can abort a row-root request and when" required holding:
table,state.*) with workflow-owned refs;changeTableRoot, far from both the picker state and the panels.After, all of that is one 442-line file whose entire surface is the row-root protocol. A reader answers "when is a late response ignored?" in one screen: epoch bump →
abortRootChangeRequests→isCurrentAttempt→ identity compare, with no unrelated workspace state in scope. What remains inBuilderWorkspace.tsxis selection + composition: a 30-line hook call plus render sites, and the outer workspace keeps deriving table identity and theworkspaceAttached/latestState/serverDraftlifecycle bindings the actions read. The hook adds no abstraction layer: one consumer, no registry, no generic request manager, no new effects — the single pre-existing stale-abort effect moved with identical body, dependency values, and registration order.Equivalence mechanics
Behavior preserved (tests unchanged, expectations untouched)
Boolean(pendingRowChangePreview)action-disabling unchanged.readyRowChangePreviewis the same predicate the oldrootChangePreviewReadyboolean computed, narrowed instead of re-checked at the render site.Validation (matched/passed/skipped recorded)
npm --prefix ui/packages/loom-ui run test -- ...BuilderWorkspace.reconciliation.unit.test.tsxcheck-boundariestypecheck:tests+ declarationtscscripts/check_no_code_comments.py --all-trackedgit diff --checkFollow-ups outside this ticket's file ownership (flagged, not neutered)
scripts/lib/formal-source-proofs.mjsInv_DetachedRootChangeDoesNotPreviewanchors its mutation inBuilderWorkspace.tsxand now hard-errorsNonunique mutation anchor(drift is detected, check not silently weakened). Proven: repointing only the path toauthoring/useRowChangeWorkflow.ts(before/after strings byte-identical) passes the harness's full positive/broken/restored proof — the control still detects the original fault.docs/ui-contract-inventory/ui-supported-affordances.jsonfails--source-onlywith 188 mechanical issues, all from the move:BuilderWorkspace.tsxsha256 + the new watched file, and 10 distinct evidence line-ranges (RowRootPicker/RowChangePreviewPanel composition region) shifted by the net −338 lines. Baseline passes pre-change; needs verifier/tooling-owner regeneration/re-anchoring per batch ownership rules.Not run in this environment: authenticated Builder browser acceptance (
.codex/skills/verify-loom-ui) — no live authenticated stack here; CI browser lane / paired-driver gate remains the authority.Non-goals respected
No behavior/feature changes, no generic async framework, no mass renames, no comment additions, no
useEffect/useLayoutEffectadditions, no test expectation changes.CI observation (run 43495764126 / 43495764254 @ 8dfcc02)
All 8 failing lanes trace to exactly these coordination items; every behavioral lane passes (Go/Postgres/Arango/ClickHouse/contracts/shell all green):
verification/builder-interactions/reviewed-sources.jsonpins the reviewed sha256 ofBuilderWorkspace.tsx;Formal models and generated replaysasserts it and fails withReview required: ...BuilderWorkspace.tsx(3e1691e7...expected vsd4fe5076...actual). This is the same re-pin mechanism as80e88771(125-row disposition): it needs a reviewed-sources re-pin wave recording the new hash + hook file, which is verification-lane ownership per.codex/skills/builder-interaction-formal-verification/SKILL.md(no invented sync commits for unreviewed patches).Tests / Python testsfails ontest_compact_manifest_preserves_pins_and_rejects_fragment_driftwith the same 188 inventory issues — one gate, one fix.Proven locally:
normalize_ui_contract_inventory.pyregenerates hashes/watched-files but does NOT repair the stale anchors — the ~188 stale ranges live in the fragment evidence strings (BuilderWorkspace.tsx:NNNN). Mechanical re-anchor rule that resolves them: map pre-hunk ranges unchanged, ranges inside the 351 extracted lines touseRowChangeWorkflow.tsat the documented region offsets, post-hunk ranges shifted by the per-region net delta (total −338); then rerun the normalizer.