Skip to content

Materialize accepted grants once through owner frames #1756

Description

@pinin4fjords

Parent: #1745

Predecessor: #1755 and its stacked draft PR, which persisted the accepted plan and made re-observation consume it.

Prototype evidence: draft PR #1743 and checkpoint 3f11f175, especially the carried-port reconciliation in svg.py.

Retrieving the prototype: git fetch origin refs/pull/1743/head:pr-1743-checkpoint, then read files with git show 3f11f1758f16341ace6b1409eff53a36a36ec715:<path>. Never check that branch out into your worktree.

Outcome

Project carried-port, header, envelope, and containment translations through the accepted owner frames, and materialize accepted member and convergence grants exactly once, emitting the TYPED_MATERIALIZATION trace event. Publishing and enforcing the cohort-final freeze is the successor's job (#1757); this issue delivers the single typed materialization the freeze will protect.

The chokepoint decision, stated explicitly: after this issue, the carried-port, header, envelope, and containment chokepoints in _settle_render_geometry are owner-frame projections of the persisted plan, not re-routes. #1755 made that possible by making re-observation consume the plan; this issue makes the translations themselves flow through the stored owner frames. If a chokepoint cannot be expressed as a projection of the accepted record, stop: that is evidence the accepted plan or translation basis is incomplete, not permission for a repair pass.

Estimate: 4-6 focused hours, hard maximum one working day. Use a fresh worktree based on the predecessor PR.

Starting reproduction

pytest -q -n 0 tests/test_corridor_cohort_integration.py -k 'materializ' --collect-only -q

Zero collected on the predecessor: the materialization locks named below do not exist yet.

Scope

  • Make the accepted record the sole owner during final materialization.
  • member_geometry.py: project exact persisted member/edge/segment identities through their stored owner frames.
  • convergences.py: project exact persisted plan/trunk recipe identities through their stored owner frames.
  • svg.py: gather the known carried-port/header/envelope/containment translations, materialize once, and emit TYPED_MATERIALIZATION from Trace final settlement and resolve seed-72 routing defects #1746's vocabulary at that point.
  • One focused materialization test module may cover both owner kinds and the four translation sources.
  • Record the displaced re-route forms in the PR body under "Coordinates transferred / setters deleted in this PR" and delete them here.

Test additions

  • test_final_solve_materializes_accepted_grants_before_cohort_final
  • test_owner_frame_translation_is_solver_free

(The third lock, test_post_freeze_stages_are_validation_only, belongs to #1757, which makes the freeze binding.)

Preserve test_after_final_checkpoint_sees_settled_geometry (on main), test_render_consumes_discovery_deferral_at_final_route_guard (ported by #1759), and the opposing-bypass geometry lock test_opposing_bypass_lines_hold_separated_direction_qualified_lanes (landed by #1761).

Non-goals

  • No freeze publication or post-freeze enforcement (that is Publish and enforce the cohort-final freeze #1757).
  • No new planning/render stage, solver call, constraint lowering, clearance publication, proximity search, or direction adjustment.
  • No replay compilation fallback.

Acceptance

  • Stage order through this child is final solve -> typed materialization, trace-asserted.
  • Carried-port, header, envelope, and containment translations preserve exact accepted ordering and grants during the single typed materialization.
  • Materialization is idempotent as a property; production invokes it exactly once, asserted by the Trace final settlement and resolve seed-72 routing defects #1746 trace counter.
  • Only explicitly controlled IDs move, by the stored owner-frame delta.
  • No owner appears, disappears, or changes disposition during materialization.
  • Opposite-running routes are never bundled during translation, and the opposing-bypass geometry lock still passes.
  • The behavior-changing stacked PR runs CI and the authoritative render diff; it remains draft and unmerged until the complete stack is green.

Verification

pytest -q -n 0 tests/test_corridor_cohort_integration.py::test_final_solve_materializes_accepted_grants_before_cohort_final tests/test_corridor_cohort_integration.py::test_owner_frame_translation_is_solver_free
pytest -q -n 0 tests/test_deferred_final_guards.py
pytest -q -n 0 tests/test_convergence_corridor_grants.py
pytest -q -n 0 tests/test_corridor_cohort_integration.py -k 'opposing_bypass'
pytest -q -n 0 tests/test_hash_seed_determinism.py
ruff check src/nf_metro/layout/routing/member_geometry.py src/nf_metro/layout/routing/convergences.py src/nf_metro/render/svg.py
ruff format --check src/nf_metro/layout/routing/member_geometry.py src/nf_metro/layout/routing/convergences.py src/nf_metro/render/svg.py
mypy

Check the collected count on every -k run. Behavioral children also refresh the derived corpora (hash pins, gate coverage, guard goldens) and declare the churn in the PR body.

#1653 guardrail and stop condition

This issue finishes one typed materialization. If a translation changes feasibility, owner membership, or order, stop: that is evidence that the accepted plan or translation basis is incomplete, not permission for a repair. Deletion is part of the ownership transfer: if removing a displaced re-route path exposes missing coverage, stop and repair the earlier owner model; do not retain dual ownership.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions