Skip to content

P6.x: correct the ast_importers completion criterion to its reachable floor - #1210

Open
accuser wants to merge 3 commits into
mainfrom
p6-ast-importer-exceptions
Open

P6.x: correct the ast_importers completion criterion to its reachable floor#1210
accuser wants to merge 3 commits into
mainfrom
p6-ast-importer-exceptions

Conversation

@accuser

@accuser accuser commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Summary

#1187 slice 6 — correcting the track's own stated completion criterion (ast_importers = 0), which #1187's own scoping work found was never actually reachable for three files.

AST_IMPORTER_EXCEPTIONS now names emitter.rs, emitter/lower.rs, and project/tests_emit.rs, alongside the existing ir.rs/ir/lower.rs pair.

emitter.rs/emitter/lower.rs: design/tracks/the-ir.md's own Q7 (§3.7) already settled that these files keep hand-writing TypeScript source text after this track's cutover — the printer that would let them stop reading raw Handler/ServiceDecl/AgentDecl parameters for header/body-rendering surface is phase 7's, explicitly out of this track's own scope. ast_importers = 0 was therefore never reachable for either file — the same structural reason it's unreachable for ir.rs/ir/lower.rs, just the opposite half of the Ast ⇄ Ir boundary (a lowering pass whose whole job is reading the AST, vs. a still-string-writing pass whose whole remaining job, past this track's scope, is reading it too).

project/tests_emit.rs was deliberately left out of the original exclusion — a test (ast_importer_exclusion_is_named_not_prefixed) used to assert exactly that, on the reasoning that its AST coupling was still-open, real work. This PR corrects that on new evidence, not a silent reversal: its test/suite case bodies call emitter::lower_block_to_async_body/lower_test_case_body/lower_integration_case_body directly (the same Q7-settled body-rendering pass), and its own driver_param_ty/strip_effect_httpresult read a handler's declared param/return TypeRef with no corresponding TyId available at that call site — the same caller-reads-callee's-declared-shape pattern #661 established for cross-context codec generation. project.rs, which prompted the original "must stay counted" stance, shares neither reason and stays counted.

ast_importers moves from its stale committed 8 to its corrected, reachable floor of 5 (runtime_use.rs, emitter/workers.rs, emitter/serialisation.rs, emitter/workers_entry.rs, project.rs remain — all genuinely open R6.13 surface).

design/tracks/the-ir.md §5/§6 record the correction and the full #1187 slice history since the doc was last updated, including slice 4 (serialisation.rs's codec-name mangling to TyId), which was scoped in full this session and then explicitly abandoned rather than landed — both of its headline claims (ast_importers 8→6, and a straightforward TypeBodyTypeShape conversion) turned out false once actually investigated. Recorded rather than silently dropped, per the track's own "the evidence ages" discipline.

Test plan

  • cargo build --workspace
  • cargo clippy --workspace --all-targets
  • cargo fmt --all -- --check
  • cargo test -p xtask --lib — all 99 tests pass, including the three ast_importers/exclusion tests updated to match the new list
  • cargo test --workspace — full suite
  • cargo xtask greenfield-status --applydesign/greenfield-status.md updated to the new committed value (8 → 5)

🤖 Generated with Claude Code

… floor

#1187 slice 6. AST_IMPORTER_EXCEPTIONS now also names emitter.rs,
emitter/lower.rs, and project/tests_emit.rs, alongside the existing
ir.rs/ir/lower.rs pair.

emitter.rs/emitter/lower.rs: the-ir.md's own Q7 (§3.7) already settled
that these files keep hand-writing TypeScript source text after this
track's cutover — the printer that would let them stop reading raw
Handler/ServiceDecl/AgentDecl parameters for header/body-rendering
surface is phase 7's, out of this track's own scope. ast_importers = 0
was therefore never reachable for either file, the same structural reason
it's unreachable for ir.rs/ir/lower.rs, just the opposite half of the
Ast <-> Ir boundary.

project/tests_emit.rs was deliberately left out of the original 2024-era
exclusion (a test used to assert exactly that), on the reasoning that its
AST coupling was still-open, real work. This corrects that on new
evidence, not a reversal of the reasoning: its test/suite case bodies
call emitter::lower_block_to_async_body/lower_test_case_body/
lower_integration_case_body directly (the same Q7-settled pass), and its
own driver_param_ty/strip_effect_httpresult read a handler's declared
param/return TypeRef with no corresponding TyId available at that call
site (the same caller-reads-callee's-declared-shape pattern #661
established for cross-context codec generation). project.rs, which
prompted the original "must stay counted" stance, shares neither reason
and stays counted.

ast_importers moves from its stale committed 8 to its corrected,
reachable floor of 5 (runtime_use.rs, emitter/workers.rs,
emitter/serialisation.rs, emitter/workers_entry.rs, project.rs remain).
design/tracks/the-ir.md's own §5/§6 record the correction and the full
#1187 slice history since the last update, including slice 4
(serialisation.rs's codec-name mangling), which was scoped in full and
then explicitly abandoned rather than landed once its two headline
claims — ast_importers 8->6, and a straightforward TypeBody->TypeShape
conversion — both turned out false on inspection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions
github-actions Bot marked this pull request as ready for review August 16, 2026 13:39
@claude

claude Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Reviewed the four-file diff. Release discipline is right: exactly one design/pending/p6-ast-importer-exceptions.md with a level and a changelog, and the change is real code (a gated probe's counted value), so an increment is correct. The arithmetic checks out — 10 files in bynk-emit/src match bynk_syntax::ast, minus the five named exclusions leaves the committed 5, and the five survivors are exactly the ones named in the PR body. project/tests_emit.rs's inclusion is well-evidenced.

Three things I'd want resolved before this lands, in priority order.

1. The Q7 justification for emitter.rs/emitter/lower.rs doesn't match what those files actually import the AST for

Q7 (§3.7, as quoted in the-ir.md §5) settles that the string-writing shape survives the cutover — and says the opposite about the imports:

It means the AST-walking decisions those string-writing functions currently re-derive (Callee dispatch, commit shape, store-write target) get replaced by reads off an already-lowered IrExpr/IrItem/CommitShape/StoreFieldIr value; the functions' own Lowered-returning, string-writing shape survives the cutover unchanged.

The live non-test bynk_syntax::ast uses in these two files are the decisions, not header/body-rendering parameters:

  • bynk-emit/src/emitter.rs:1400-1407 — walks commons.commons.items for CommonsItem::Service, then reads svc.protocol / ServiceProtocol::Events. That is verbatim what §6's P6.6 row is for ("closes the emitter reading AST declarations directly"), and P6.6 is in scope for this track.
  • bynk-emit/src/emitter/lower.rs:1147-1153 (cap_op_param_names) — walks commons.items for CommonsItem::Capability. Same AST-declaration read.
  • bynk-emit/src/emitter/lower.rs:4120 / :4172bynk_syntax::ast::queue_variant(&id.name), a name-matched variant dispatch: the exact class P6.2/Callee exists to replace, and a sibling of the block_writes_state name-matched-receiver defect §9 names as this track's live data-loss risk.

None of those need a phase-7 printer to go away; they need P6.2/P6.6, both in this track's own §6 table. Excluding these two files (10.7k lines, the two largest AST-coupled emitter files) means P6.2/P6.5/P6.6 can land in full and move ast_importers by exactly zero — the probe stops measuring the track's headline deliverable, which is the failure mode #1176's own named-not-prefixed argument was written to avoid.

The project/tests_emit.rs half stands on its own evidence (driver_param_ty/strip_effect_httpresult with no TyId at the call site) and looks sound. Suggest landing that one and keeping emitter.rs/emitter/lower.rs counted until the decision-walking above is actually gone — or, if the exclusion is kept, narrowing the stated justification to the surface Q7 really settles and saying plainly that the probe no longer covers P6.2/P6.6.

2. The doc now says two incompatible things about the criterion

design/tracks/the-ir.md:621 calls 5 "the completion probe's own true floor, not a residual number expected to keep falling." But four statements of the criterion are unchanged by this PR:

  • §5:310 — "Here: ast_importers reads 0"
  • §6:415 — "Completion probe: ast_importers = 0 (§5) — live today at 9" (also now stale: live is 5, not 9)
  • §7:632 — phase 7's entry condition, "this track's probe (ast_importers) reads 0 (§5)"
  • §12:715 — "retires when §6's probe (ast_importers) reads its named floor (0, per §5)"

If 5 really is a floor, all four are unsatisfiable and — on this doc's own terms — the track can never retire and phase 7 can never open. Either they move to the new floor, or the claim softens to "reads 5 today." The floor claim also sits badly with the sentence right before it: project.rs is listed as remaining "genuinely open R6.13 surface" and is P6.6's own named target ("EmitProjectCtx's 28 fields"), an in-scope slice. A number with an in-scope slice still pointed at it isn't a floor.

3. ast_importer_exclusion_is_named_not_prefixed no longer tests what it says it does

Both emitter/-prefixed negatives (emitter/lower.rs, project/tests_emit.rs) moved to the positive side, leaving project.rs — which isn't under emitter/ — as the only negative. An emitter/** prefix rule would now pass this test unchanged while wrongly excluding emitter/runtime_use.rs, emitter/workers.rs, emitter/serialisation.rs, emitter/workers_entry.rs. One line restores the invariant:

assert!(!is_named_ast_importer(Path::new("emitter/workers.rs")));

Same gap in ast_importers_excludes_the_named_pairs_but_counts_project_rsassert!(counted.contains("emitter/workers.rs")) keeps the live-tree survivor-set assertion honest.


The honesty of the record is good — writing up abandoned slice 4 rather than dropping it is the right call, and the project/tests_emit.rs correction is properly argued as new evidence rather than a reversal. My concern is narrower: the emitter.rs/emitter/lower.rs half of the exclusion buys a lower number by removing the probe's coverage of the slices that haven't landed yet.

🤖 Generated with Claude Code

accuser and others added 2 commits August 16, 2026 17:42
The review found the PR's exclusion was too broad: emitter.rs/
emitter/lower.rs both still hold live, in-scope AST-declaration reads
(emitter.rs's CommonsItem::Service/svc.protocol walk, emitter/lower.rs's
cap_op_param_names over CommonsItem::Capability) distinct from the
Q7-settled body-rendering surface that motivated excluding them --
exactly the P6.2/P6.6-class conversions design/tracks/the-ir.md's own §6
table still lists as in scope. Excluding either file would have hidden
that real work from the probe the same way a path-prefix rule would --
the failure mode #1176's own named-not-prefixed argument exists to
prevent.

Reverts emitter.rs/emitter/lower.rs from AST_IMPORTER_EXCEPTIONS, keeping
only project/tests_emit.rs (which stands on its own, narrower evidence:
it calls straight into that same body-rendering pass with no declaration-
reading surface of its own). ast_importers moves 8 to 7, not 8 to 5.

Also fixes the "floor" language the review flagged as self-contradicting
four unchanged statements of the completion criterion elsewhere in the
doc: 7 is not a floor, 0 remains the target, and emitter.rs/
emitter/lower.rs's own declaration-reading surface stays real, open work.
Restores the third broken test invariant (emitter/workers.rs as the
prefix-rule counterexample, since emitter/lower.rs moved to the positive
side and back).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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