Repository navigation
#105 — explore external-drive contract: host bridge (postMessage + DOM attr), focusModel/setView, payload file paths - #225
Conversation
The schema-properties YAML path joins the domain Node as an additive ADR-5-tolerant field. Both engines serialize the wire patch_path as a package URI (<package>://models/schema.yml — fusion normalize_manifest_patch_path / package_uri_path, dbt-schemas manifest/manifest.rs @ 9977b6cb, mirroring dbt-core); the manifest adapter strips the scheme on ingestion so the domain carries a plain relative path. Verified against BOTH real committed fixtures (jaffle-shop = dbt-core 1.11, playground = fusion 2.0-preview), plus the null-fill / omitted-key / scheme-less tolerance shapes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nding, focusModel/setView, payload paths (#105) The explorer's host-facing surface, versioned as contract "1": - window.focusModel(id): highlight + center ONLY — no data-selected-model write, no bridge event (the no-echo rule; a host pushing editor-sync focus never hears its own push back). - window.setView(kind): programmatic lineage <-> cte switch, rebound by the CTE engine (the view-state owner); inert fail-open default. - Dual-bound Space commit: the data-selected-model attribute always writes (the standalone file:// binding) AND, iff a host bridge registered at boot, a versioned commit event posts via postMessage ({type: cute-dbt/commit, contractVersion, modelId, view, paths}). Detection-based registration (acquireVsCodeApi presence or an injected window.cuteDbtHostBridge), presence checks only — inert standalone, zero-egress unaffected. - Per-node paths block on the lineage payload (sql / schema_yaml / unit_tests[].{name,yaml,fixtures}) — all project-relative manifest facts; absence explicit (null/[]), fixture refs verbatim. Surfaced read-only in the detail card's files section. - The version is server-rendered as <body data-cute-dbt-contract> (for attribute-only observers); window.cuteDbtContract reads it back — one source, no drift. asset_embed pins: still exactly one selectedModel write site, exactly one hostBridge.postMessage site, hooks present, CTE engine posts nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e-count mirrors 20 -> 21 (#105) - features/explore_js_contract.feature + step module: the server-rendered halves through the real explore subprocess — the contract-version body attribute and the payload-paths carrier (package-URI strip exercised via a verbatim wire splice; external fixture refs verbatim incl. the bare dbt-core name; explicit-empty paths). - headless (CDP, ignored suite): injected fake host bridge planted via Page.addScriptToEvaluateOnNewDocument BEFORE page scripts parse — focusModel highlights/centers with NO attr write and ZERO bridge events (no echo) and returns false on unknown ids; setView round-trips lineage <-> cte and rejects bogus kinds; search-select + real pointer click never commit on either binding; Space dual-binds (attr + exactly one versioned event carrying modelId/view/paths); a CTE-view commit carries view: cte; a second uninjected tab proves the standalone attr-only path; console-clean throughout. - feature-count mirrors bumped 20 -> 21 in BOTH ci.yml and lefthook.yml (verified: find features -maxdepth 1 = 21 in-tree). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…se-discipline SemVer policy (#105) New Reference page documenting the full surface: the contract version (DOM attribute + JS global, one source), both forward hooks with the no-echo rule, the dual-bound commit signal + host-bridge registration, and the payload-paths shape with the engines' path-derivability notes. release-discipline.md folds the contract into the existing CLI-surface SemVer policy prose — a contract break is a v0.x minor (v1.0+ major) event; no new versioning system. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… surface playground-rendered: the contract-version body attribute, the per-node paths blocks on the carrier, the files card section + engine JS. Double-render byte-identity verified; zero /Users|/home|root_path matches; tests.html and all report goldens zero-diff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR implements the external-drive JavaScript contract for the explorer DAG page. It adds server-rendered contract versioning, per-model file path metadata in lineage payloads, host-bridge integration with forward hooks (focusModel/setView) and dual-bound commit signals, comprehensive test coverage, and contract documentation. ChangesExplorer External-Drive Contract
Sequence DiagramsequenceDiagram
participant Host
participant EmbedPage as explorer page
participant HostBridge as host bridge<br/>(optional)
Host->>EmbedPage: page load (injected window.cuteDbtHostBridge)
activate EmbedPage
EmbedPage->>EmbedPage: init: read data-cute-dbt-contract<br/>mirror to window.cuteDbtContract<br/>detect host bridge
EmbedPage->>Host: expose window.focusModel(id)<br/>expose window.setView(kind)
Note over EmbedPage,Host: forward hooks (no-echo)<br/>return boolean, fail-open
Host->>EmbedPage: call window.focusModel(modelId)
activate EmbedPage
EmbedPage->>EmbedPage: highlight + center node<br/>NO dataset write<br/>NO bridge event
EmbedPage->>Host: return true/false
deactivate EmbedPage
Host->>EmbedPage: user presses Space
activate EmbedPage
EmbedPage->>EmbedPage: commitFocus()
EmbedPage->>EmbedPage: write document.body.dataset.selectedModel
EmbedPage->>EmbedPage: center highlight
opt hostBridge available
EmbedPage->>HostBridge: postMessage({<br/>type: 'cute-dbt/commit',<br/>contractVersion: '1',<br/>modelId, view, paths<br/>})
end
deactivate EmbedPage
Host->>EmbedPage: call window.setView(kind)
activate EmbedPage
EmbedPage->>EmbedPage: toggle view<br/>(if kind valid)
EmbedPage->>Host: return kind===activeView
deactivate EmbedPage
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Ready to review this PR? Stage has broken it down into 7 individual chapters for you: Chapters generated by Stage for commit cb654a9 on Jun 11, 2026 7:34am UTC. |
📄 Rendered report previewAll golden examples regenerated cleanly. 🟡 Golden examplesCommitted to
🐶 Live dogfood previewThis PR doesn't touch ▶ Open ↗ opens the report in your browser in one click — The Pages preview may take ~1 min to update after this comment Alternative: GitHub CLI# gh CLI >= 2.63 extracts into ./report-preview-playground/.
gh run download 27331330386 -R breezy-bays-labs/cute-dbt -n report-preview-playground
open report-preview-playground/playground-report.htmlPosted by |
There was a problem hiding this comment.
Code Review
This pull request implements the explorer's external-drive contract (cute-dbt#105), enabling external tools to drive and observe the lineage view in dag.html. It introduces a versioned contract attribute on the body, forward hooks (window.focusModel and window.setView), a dual-bound commit signal, and project-relative file paths in the lineage payload. On the backend, manifest ingestion is updated to extract and strip the package URI scheme from patch_path. Feedback on the changes suggests optimizing the strip_package_uri_scheme helper function in src/adapters/manifest.rs to accept and return borrowed &str slices instead of owned Strings to eliminate redundant heap allocations.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary
Implements the explorer's external-drive contract (epic #99 V6, founder respec 2026-06-10 — IDE-arc alignment): the host bridge with dual binding (postMessage + the commit-only
data-selected-modelDOM attribute), thefocusModel/setViewforward hooks with the no-echo rule, per-node file paths in the explore payload, and a readable contract version — the seam the in-tree VS Code extension (epic #210) consumes.Closes #105
The commit-event schema (contract version
1)Posted via
postMessageiff a host bridge registered at boot (detection-based:acquireVsCodeApipresence, or an injectedwindow.cuteDbtHostBridge— presence checks only, inert standalone):Fires ONLY on the Space focus commit — never hover/click/search/
focusModel. The DOM attribute (data-selected-model) always writes on commit (the standalonefile:/// cmux binding); the bridge event rides alongside when a host is present. Beyond the AC minimum (id + view + version), the event carries the committed node'spathsso a host can open files without re-parsing the payload carrier.Discovery answers
Paths derivability (verified against the REAL committed fixtures, fusion pinned @
9977b6cb):nodes.<id>.original_file_path(project-relative; the #179 — design integration PR-3: full model path + column-test display alignment #189 precedent, already ingested).nodes.<id>.patch_path, newly ingested. Both engines serialize it as a package URI (<package>://models/schema.yml— fusionnormalize_manifest_patch_path/package_uri_path,dbt-schemasmanifest/manifest.rs@9977b6cb…, mirroring dbt-core; byte-verified on jaffle-shop = dbt-core 1.11 AND playground = fusion 2.0-preview). The adapter strips the scheme on ingestion.original_file_path(the renderer: surface raw unit_test YAML block (+ leading/trailing comments) in test details #69 plumbing), NOTpatch_path: fusion serializes nopatch_pathkey onunit_testsentries (verified on the playground fixture).given[i].fixture/expect.fixture(the renderer: read external unit-test fixture files (csv/sql) for cell-level diffing #126 plumbing), carried verbatim: fusion emits resolved project-relativetests/fixtures/<name>.csv(verified on the playground fixture); dbt-core MAY emit a bare name, which hosts resolve via the same documentedtests/fixtures/<name>.csvconvention the report's renderer: read external unit-test fixture files (csv/sql) for cell-level diffing #126 reader applies. Not derivable statically: whether a bare-name fixture is.csvvs.sqlon disk — hence verbatim, never a guessed path.root_pathleak class); regenerated pages grep clean for/Users|/home|root_path.Version-string surface (the justified choice): BOTH a server-rendered DOM attribute (
<body data-cute-dbt-contract="1">— readable by attribute-only observers with zero JS execution, the same observation channel asdata-selected-model) AND thewindow.cuteDbtContractJS global for script hosts. The attribute is the single source — the global reads it back at boot, so the two surfaces cannot drift.Contract-doc location: a book page (
book/src/explore-contract.md, wired into SUMMARY) — it is a consumer-facing integration contract, not internal code doc — folded into the existing release-discipline CLI-surface SemVer policy (amended prose: a contract break is a v0.x minor / v1.0+ major event; no new versioning system).What changed
feat(domain):Node.patch_path(additive, ADR-5-tolerant; scheme-stripped at the adapter).feat(adapters):NodePathsPayload/UnitTestPathsPayloadon the lineage carrier (explicitnull/[], never omitted keys; unit tests name-ordered, resolution via the sameresolve_target_modelbridge as the badges);EXPLORE_CONTRACT_VERSION+ body attribute; detail-card files section (createElement/textContent only).templates/explore-lineage.js: contract global + bridge detection at boot (inert standalone),window.focusModel(highlight + center, NO attr write, NO bridge event — the no-echo rule; unknown id ⇒falsefail-open), the dual-boundcommitFocus. Still exactly ONEselectedModelwrite site and exactly ONEpostMessagesite (asset_embed pins).templates/explore-cte.js: rebindswindow.setView(the view-state owner; same gates as the toggle; bogus kind ⇒false); pinned to never post bridge events.features/explore_js_contract.feature+ step module (5 scenarios; the patch-path strip exercised via a verbatim scheme'd wire splice through the real subprocess). Feature-count mirrors 20 → 21 in BOTHci.ymlandlefthook.yml(verified in-tree: 21 files).Page.addScriptToEvaluateOnNewDocumentBEFORE page scripts parse; focusModel no-echo (zero events, no attr, with a live bridge present); setView round-trip; search-select + real pointer click never commit; Space dual-binds with the full schema asserted; CTE-view commit carriesview: "cte"; a second uninjected tab proves the standalone attr-only path; console-clean throughout. Pinned single-write-site, badges, card/tooltip tests untouched and green.book/src/explore-contract.md+ SUMMARY + release-discipline fold.examples/explore/dag.htmlregenerated (the only example diff — report goldens +tests.htmlzero-diff).Gate evidence (run directly in the worktree)
cargo fmt --checkcargo clippy --all-targets --locked -- -D warningscb654a9)cargo nextest run --all-targets --lockedcargo test --test bddcargo test --test headless_zero_egress -- --ignoredcargo test --test headless_toggle -- --ignoredRUSTDOCFLAGS="-D warnings" cargo doc --no-deps --lockedcargo deny checkmdbook build bookcargo llvm-cov nextest --locked --fail-under-lines 85crap4rs --config crap4rs.toml --coverage lcov.info(CI-pinned v0.4.0)dag.html+tests.htmlbyte-identicalgit diff --text -U0 -- examples/auditexamples/explore/dag.html(+135/−2); report goldens zero-diff.snap.newexpected=21in both mirrorsInvariants held
Zero-egress per-page gates green (bridge detection is presence-checks only;
postMessageto a host is in-process, not network); domain purity (std + serde only); synthetic-only fixtures;PreflightErrorstays 4 variants; explore stays fail-open; single crate; thedocument.body.dataset.selectedModelsingle write site stays pinned.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation