Skip to content

The emitted-text attestation reads code outside string literals, not prose - #12203

Merged
gunbai-bot[bot] merged 4 commits into
mainfrom
session/stern-lynx-90-emitted-token-gate
Sep 24, 2026
Merged

gunbai-bot[bot] merged 4 commits into
mainfrom
session/stern-lynx-90-emitted-token-gate

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

The emitted-text attestation reads code outside string literals, not prose

Defect. v1.compiler.emit_rust reference_derived_use_line_plan admits a proposed use-line only when the name appears among the emitted source's identifier tokens. That gate exists to reject misproposed candidates. But the token set was built from the whole emitted text, string-literal contents included. std.content_hash's grounding note mentions v2.std.node.Hash. The emitter proposed Hash for std.content_hash, and v2.std.node declares type Hash = Fnv1a64Structural, an alias of std.content_hash's own type. The prose then let that candidate through, and std_content_hash.rs emitted pub use crate::v2_std_node::{Hash};. Nothing uses it. It is harmless in one crate but is a reverse edge in any partition, because v2.std.node imports std.content_hash.

How it was found. The Pkg7e emitted-workspace plan (v2.workflow.emitted_crate_workspace, on its own branch), once #12190 and #12200 made the two closures agree, refused at the edge merge with the typed EmitterReverseEdge std_content_hash -> v2_std_node. That refusal was added in #12147.

Earliest unjustified link (DESIGN §6b): the gate treating string contents as emitted code. rust_code_outside_string_literals removes escaped backslashes and quotes, splits on the remaining quote characters, and keeps the segments outside literals. The token set is built from that. The candidate producers are untouched, and emit_typed_expr and render_rust_type are untouched, per the operator ruling.

Evidence, by execution.

  • Discriminating specimen: gunbc compile --entry a probe module importing v2.std.node { Node }. std_content_hash.rs carries the v2_std_node use-line before the change (1 line) and not after (0).
  • Whole seed (claim_executor --required-regen):
    • Generation 1, emitted by the old binary, drifts only in the emitter's own mirror.
    • Generation 2, emitted with the fix active, drops eleven use-lines from six mirrors: v1_compiler_emit, emit_rust, infer, trait_derive_emit, gunbc_occurrence_binding_parser_walk, and one claim module. Each is a name that appears in its module only inside a string literal, e.g. AlgebraFieldTemplate and OccurrenceId in v1_compiler_infer.rs.
    • The seed compiles without them, which proves they were dead.
    • Generation 3 is a fixed point (first_generation_equal=true).
  • Failure mode rostered: gunbc.recurring_failure_mode a_string_literal_attests_an_emitted_reference. Rung: mitigatable. Ceiling: structurally guaranteed. Next-rung trigger: use-lines derived from the emitted reference set the renderers return, the capability emitted_inline_crate_path_edges_unreturned_stall names.

Second arm, same gate. Over the full v2.compiler.compile closure, std_content_hash.rs still emitted the Hash use-line. Its code carries #[derive(..., std::hash::Hash)], and the tokenizer splits on :, so a segment inside a qualified path attested the bare name. rust_qualified_segments_marked prefixes every segment after :: with @, so a marked segment never equals a candidate. A path head stays a token, so Parent::Variant still attests Parent. Seed regen: the next generations drop the remaining re-exports whose names occur only as qualified segments (in emit_rust, infer, infer_resolve, parse and trait_derive_emit). The seed compiles, and the third generation is a fixed point.

Limits, stated. The stripper reads quote characters, so a '"' char literal would flip its parity. If that happened, it would drop tokens, and missing imports fail loudly at rustc; it cannot silently add a use-line. The whole-seed fixed point is the measured evidence that no such case exists in the seed today.

v1 admission. This is v2 self-host work under gunbc.v1_maintenance_standing v1_seed_standing: the emitted use-lines are the edges that decide whether the emitted compiler partitions into crates. It adds one function to the emitter .dag and one call-site change. The mirror changes are regenerated, not hand-edited.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 4 commits September 24, 2026 01:58
…prose

reference_derived_use_line_plan admitted a candidate use-line when its name was among the emitted
source's identifier tokens, string literal contents included, so std.content_hash's prose mention of
v2.std.node.Hash emitted pub use crate::v2_std_node::{Hash} -- unused, and a reverse edge the crate
partition refuses. The token set now comes from rust_code_outside_string_literals. Across the seed
eleven dead prose-attested imports drop from six mirrors; the seed compiles and regen is a fixed point.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ates {...}, so {Hash} evaluated Hash

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…no longer emits a Hash use-line

Over the full v2.compiler.compile closure std_content_hash's derive of std::hash::Hash still attested
a proposed Hash through the colon-splitting tokenizer. Segments after :: are marked so they never
equal a candidate; path heads stay tokens. Seed regen reaches a fixed point; the seed compiles.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 24, 2026
Merged via the queue into main with commit b3aa1ba Sep 24, 2026
5 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/stern-lynx-90-emitted-token-gate branch September 24, 2026 13:12
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.

0 participants