feat(v3): D4 Milestone 1 — cross-doc primitives + node-based helpers (v0.14)#83
Open
mbreiser wants to merge 2 commits into
Open
feat(v3): D4 Milestone 1 — cross-doc primitives + node-based helpers (v0.14)#83mbreiser wants to merge 2 commits into
mbreiser wants to merge 2 commits into
Conversation
…findings Bring the D4 cross-library import design from rev 2 to rev 3 ahead of Milestone 1 implementation. Rev-2 -> rev-3 fix list (from v3-d4-design-reviews.md): - plugin merge-by-default when same runtime resource; anchors still namespace - one shared aliasRewriteMap (hasOwnProperty guard); fixed sortedJson recursive sort - per-batch dependency registry; visited-set closure (not depth cap) - topological anchor insert; commit rewrites the cloned name: field - block alias-bound plugin_name; cross-buffer name collision check - broken-alias hard-block at preflight; lock via UI handlers not global pushUndo codex-plan-review (gpt-5.5, rev 3) findings folded in: - cloneNodeAcrossDocs rewrites anchor DEFINITIONS too (inline-anchor hole) - ensureTopLevelSection splices the new section before conditions: (verifyAliasOrder is the stringify default — appending after conditions would throw on commit) - docInsert*Node derive the JS mirror internally via extractCondition/extractPlugin - broaden plugin merge identity (all fields but name, + rig when config-less) - built-in plugin_name: log left unchanged; walk imported plugin config aliases - self-referential anchors handled in topo sort; pre-commit validation + atomic commit (snapshot/restore); expanded import-mode locking; no setDirty on enter Reconciliation report + raw Codex outputs preserved under .codex-review/ (gitignored). Product-shape (snippet vs behavior import) and provenance surfaced as open questions; proceeding on the implementation-handoff defaults. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…(v0.14) First implementation milestone of D4 cross-library import. Pure logic + Node tests; no UI yet (that's Milestone 3). New module js/v3-import.js (dual-export: ES module + CJS + window global): - collectAliasReferences(rootNode) — walk a node subtree for Alias refs - resolveAlias(aliasNode, sourceDoc) — via alias.resolve(doc) (last-wins semantics), NOT name-based lookup; null on broken alias - cloneNodeAcrossDocs(srcNode, targetDoc, aliasRewriteMap) — deep clone + rewrite alias REFERENCES and inline anchor DEFINITIONS via one shared map (hasOwnProperty guard); preserves comments - yamlNodeStructuralEquals + sortedJson (recursive key sort) — plugin merge path New helpers in js/protocol-yaml-v3.js (exported from all surfaces): - ensureTopLevelSection — creates a missing section SPLICED before experiment:/conditions: (appending after them would put an imported *alias before its &anchor; verifyAliasOrder:true would throw on toString) - docInsertConditionNode / docInsertVariableNode / docInsertPluginNode — splice already-cloned nodes and derive the JS mirror INTERNALLY via extractCondition/extractPlugin (no caller-built object that can drift) Tests: suites N1–N6 in tests/test-protocol-roundtrip-v3.js (+43 checks) and a reusable tests/fixtures/v3_sibling_source.yaml (scalar + transitive anchors, plugins, aliasing condition). Covers cross-doc clone+rewrite, inline-anchor rewrite, last-wins resolution, transitive walks, insert into existing/absent variables: with re-parse, internal mirror derivation, round-trip stable. npm test: arena 10/10, v2 137/137, v3 510/510 (was 467). Footer v0.13 -> v0.14. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 this is
Milestone 1 of D4 (cross-library import) for the v3 Experiment Designer — the
substrate for copying conditions (plus the anchors and plugin declarations they
depend on) from a second parsed
YAML.Documentinto the one you're editing.M1 is pure logic + Node tests; no UI (UI is Milestone 3).
Per
docs/development/v3-d4-implementation-handoff.md§5. Stops at M1 — does notstart M2.
Two commits
docs(v3): D4 design rev 3— applies the rev-2 → rev-3 fix list, then foldsin the findings from a fresh
codex-plan-review(gpt-5.5) pass on rev 3.feat(v3): D4 Milestone 1— the code + tests + footer bump.Design: rev 2 → rev 3
Applied the 11-item fix list (
v3-d4-design-reviews.md): plugin merge-by-defaultwhen same runtime resource (anchors still namespace); one shared
aliasRewriteMap;visited-set closure; topological anchor insert; commit rewrites the cloned
name:;alias-bound
plugin_nameblock; cross-buffer collision check; fixedsortedJson;broken-alias hard-block; lock via UI handlers.
Then ran
codex-plan-reviewon rev 3 and addressed the findings (reconciliation +raw outputs under
.codex-review/, gitignored). M1-actionable ones are in thisPR's code; M2/M3 ones are recorded in the design:
cloneNodeAcrossDocsrewrites inline anchor definitions (notjust alias refs);
docInsert*Nodederive the JS mirror internally; and (myfinding Codex missed)
ensureTopLevelSectionsplices a created section beforeconditions:— appending after it would put an imported*aliasbefore its&anchorand, withverifyAliasOrder: true(the stringify default),toString()would throw.
rigguard; built-inplugin_name: logspecial-case; walk imported pluginconfigaliases;planned-name collision blocking (incl. empty prefix); commit atomicity
(snapshot/restore); expanded import-mode locking; no
setDirtyon enter;self-referential-anchor handling in topo sort.
Open questions surfaced (not blocking M1): keep plugin merge-by-default with a
broadened identity vs explicit per-plugin mapping; confirm the "snippet importer"
product contract; import provenance. Proceeding on the handoff's pre-answered
defaults.
Code
New
js/v3-import.js(dual-export: ES module + CommonJS +windowglobal):collectAliasReferences,resolveAlias(viaalias.resolve(doc)— last-wins, notname lookup),
cloneNodeAcrossDocs(one shared rewrite map; rewrites alias refs +inline anchor defs; preserves comments),
yamlNodeStructuralEquals,sortedJson(recursive key sort).
New helpers in
js/protocol-yaml-v3.js(exported fromProtocolV3object +named export):
ensureTopLevelSection,docInsertConditionNode,docInsertVariableNode,docInsertPluginNode— node-based (preserve comments/anchors, unlike the JS-object-building
docInsertCondition), mirror derivedinternally via
extractCondition/extractPlugin.Tests — Milestone 1 gate
Suites N1–N6 (+43 checks) in
tests/test-protocol-roundtrip-v3.js+ a reusabletests/fixtures/v3_sibling_source.yaml(scalar + transitive anchors, plugins, analiasing condition). Cover: cross-doc clone+rewrite, inline-anchor rewrite, last-wins
resolution, transitive walks, insert into existing and absent
variables:(witha re-parse assertion proving the placement fix), internal mirror derivation, plugin
insert, round-trip stable.
Footer bumped v0.13 → v0.14.
Not in scope (later milestones)
M2 staging buffer + commit pipeline; M3 three-pane UI + locking; M4 polish/docs.
🤖 Generated with Claude Code