Skip to content

Regime-2 emission: collapse yaml/gitignore/runner_deploy serializers into one std.layout render fold - #5581

Merged
briansrls merged 9 commits into
mainfrom
session/tidy-crane-536
Jun 23, 2026
Merged

briansrls merged 9 commits into
mainfrom
session/tidy-crane-536

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

Regime-2 emission: one shared fold over a std layout IR

Collapses the three boutique pure-projection (regime-2, emit-only) serializers into one fold over a shared layout IR, per docs/plans/regime2-shared-emission-fold.md. DESIGN refs: §2 (no duplicated layout logic — one concept, every format), §3 (single layout authority in std), §4 (emit = ingestion⁻¹, the forward-only subset), §5 (emit-only → no round-trip oracle; honesty at the boundary), §6 (DFS before minting).

The shape

expected_X = render(project_X_to_doc(authority), X_protocol)

  • dsl/std/layout.dag (new) — the emission model: Doc = DocEmpty | DocText | DocLine | DocConcat | DocNest, LayoutProtocol { indent_unit }, and one render fold. The renderer inserts indentation lazily (before the first text of each line) so it reproduces yaml's line-prefix indentation byte-for-byte with no trailing-space artifacts.
  • The discriminator holds: render has zero format-specific branches (5 structural cases). All format-specifics live in project_X_to_doc (quoting/escaping/comment-prefixes baked into DocText) and the thin LayoutProtocol. Asserted by layout_render_witness_test (one fold drives flat + nested; nest/indent perturbations go RED).

The three projections

  • gitignore → project_gitignore_to_doc (dsl/gunbc/gitignore_emit.dag), indent_unit: "".
  • runner_deploy → project_runner_deploy_to_doc (dsl/gunbc/runner_deploy_emit.dag), indent_unit: "".
  • yaml → project_yaml_to_doc (dsl/extdeps/formats/yaml.dag), indent_unit: " ". Scalar quoting/escaping/flow-seq kept as text builders, baked into DocText; nesting/block-seq/multiline via DocNest+DocLine. The old prefix_block_sequence_mapping empty-line-skip is reproduced by construction (multiline blocks emit no wrapper blank).

Public entry signatures preserved (expected_gitignore / expected_ci_yml / expected_runner_deploy_manifest) — gentle-ibex's universal generated-artifact gate (#5568) is unaffected.

Faithfulness — byte-identical (verified by execution)

  • .gitignore (3280 B) and .github/workflows/ci.yml (11723 B): regenerated output is byte-identical to committed (git diff empty). Runner manifest: no committed file (computed; drift-gated) — its witness passes unchanged.
  • All existing witnesses green: ci_yaml_serializer_keystone_holds, gitignore_witnesses, runner_placement_holds. New: layout_render_keystone_holds, yaml_quoting_keystone_holds (sharpening B — reserved/double-quoted/escaped/empty scalar paths that ci.yml does not exercise).

§3 single-authority cleanup (sharpening A)

Removed the dead flat layout IR so std has one layout authority: std.types Document/DocumentLine/DocumentSection/DocumentFile, the shared.dag_util document builders/render_document, and the seed std_types.rs Document/DocumentLine/DocumentSection/TextFile(wrapping Document) cluster — all verified zero-caller across dsl/, src/v1, src/v2. (The removed seed TextFile is distinct from the live v1.std.core.TextFile = path+content.)

Scaffold honesty + dissolution

std.layout Doc + render are seed-realized scaffold; the dissolution trigger is the v2 TargetModel grammar-row inverse (serialize_target) subsuming them at self-host — the Doc/protocol spellings are a forward-only subset of those rows. (This note lives here, not in-source: .dag comments are banned tree-wide post-#5567 parser-wall flush.) Regime-2 is emit-only — no round-trip oracle is claimed; faithfulness rests on the authored projection (§5).

Out of scope (untouched): std.markdown / roadmap_emit (bright-stag's regime-1 lane).

🤖 Generated with Claude Code

@gunbai-bot gunbai-bot Bot changed the title Regime-2 emission shared fold - collapse boutique yaml gitignore runner_deploy serializers into one render over a shared std layout IR - model-checkpoint-gated to warm-lark-306 Regime-2 emission: collapse yaml/gitignore/runner_deploy serializers into one std.layout render fold Jun 22, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 22, 2026 23:20
@gunbai-bot

gunbai-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Addressing the items:

Stale prose (docs/plans/emission-ingestion-inverse.md:218 names the deleted emit_yaml_value/emit_mapping_body) — valid; non-blocking, and the head is currently frozen for approval accrual (per my manager session), so I'm tracking it as a post-merge follow-up rather than resetting reviews/CI with a doc-only push.

One additional item I found in my own pre-review (disclosing for transparency, also post-merge follow-up): emit_inline_scalar_text dropped the old emit_scalar_string multiline |-block branch, so a multiline YamlString outside mapping-value position (a bare sequence element or top-level scalar) now emits embedded raw newlines instead of a block literal. It is latent / zero-trigger: serialize_yaml's only consumer is ci.yml, whose projection only ever places multiline strings as mapping values (run:/path:/restore-keys:), which take the preserved multiline_entry_doc path. ci.yml + .gitignore stay byte-identical and all witnesses are green. The follow-up will either route those arms through the block-literal too, or fail-closed per §5 rather than emit broken YAML.

— sent from tidy-crane-536

briansrls and others added 2 commits June 22, 2026 23:31
…latent §5 fail-open)

The regime-2 refactor's emit_inline_scalar_text dropped emit_scalar_string's
multiline '|' branch, so a multiline YamlString outside mapping-value position
(top-level scalar, bare sequence element) emitted embedded raw newlines —
broken YAML, a §5 fail-open. Latent (serialize_yaml's only consumer is ci.yml,
which never hits those positions) but a real faithfulness regression vs the old
serialize_yaml.

Fix (behavior parity): route multiline strings through a shared multiline_block_doc('|')
helper in the mapping-value, bare-sequence-element, and top-level-scalar arms;
exclude multiline strings from all_scalars_flowable so they take the block path,
not the (also-broken) flow path. ci.yml + .gitignore stay byte-identical
(mapping-value path unperturbed); new yaml_multiline_block_witness asserts the
block literal in all three positions and goes RED on the embedded-newline form.

Bundled: repoint stale prose in docs/plans/emission-ingestion-inverse.md (named
the deleted emit_yaml_value/emit_mapping_body).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Update — both items fixed in 749fd76 (not post-merge after all):

  1. Multiline |-block regression — serialize_yaml now emits a block literal for multiline strings in all positions (mapping value, bare sequence element, top-level scalar) via a shared multiline_block_doc helper, and all_scalars_flowable now excludes multiline strings so they take the block path rather than a broken flow […]. New yaml_multiline_block_witness_test asserts the block literal in each position and goes RED on the embedded-newline form. ci.yml + .gitignore remain byte-identical (the mapping-value path is unperturbed).
  2. Stale prose — docs/plans/emission-ingestion-inverse.md:217 repointed off the deleted emit_yaml_value/emit_mapping_body; it now describes serialize_yaml rendering project_yaml_to_doc over the shared std.layout Doc fold (the paragraph's round-trip-oracle argument is preserved).

— sent from tidy-crane-536

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.

1 participant