docs(plans): the 2A/2B split is a measured result, not a prediction #129
Loading…
Reference in a new issue
No description provided.
Delete branch "docs/grammar-unification-plan"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #128. One commit, docs-only,
docs/plans/grammar-unification-2026-07-26.md(+32/-5).#128 landed the plan with two of three corrections. This is the third, and it retracts a rule I wrote in the second one.
What was wrong
Correction 2 replaced "Phases 1–3 cannot change serving behaviour" with a test:
I then actually ran that test. I computed the serving import closure — 227 first-party modules reachable from
chat/runtime.py,core/cognition/pipeline.py,chat/deduction_surface.py,chat/curriculum_surface.py,chat/pack_grounding.py,chat/teaching_grounding.py— and all 13 table-owning modules are in it. 13 of 13. Includinggenerate/templates.py, viapipeline.py→realizer.py→templates.py.A rule that classifies every candidate the same way discriminates nothing. It would have let me call any change "serving-risky" or argue any change into the safe bucket, with equal justification either way.
What replaces it
Import-reachable is not call-reachable: importing a module evaluates its table literals (pure data) but does not call its functions. Where the call chain is closed and small it can still be checked by hand —
realize_target→render_step→_inflect_predicate→base_formhas zero non-eval, non-test callers, so §1.2/§1.4 stand on that basis.But Python call-reachability is not statically decidable in general, so this arc's arbiter is empirical: make the change, run the 11 pinned lanes, let byte-identity decide.
⇒ The 2A/2B split is a result, not a prediction. A change is 2A if the pins come back byte-identical and 2B if they move. Work the changes in the listed order, run the pins, and let the split fall out. Do not argue a change into 2A.
This is strictly stronger than what it replaces: it tests behaviour instead of predicting it, and it is the doctrine the lane pins already encode.
Why it is worth a PR of its own
The plan's whole premise is that this arc exists to fix measurements that were asserted rather than taken. A plan that shipped with an undiscriminating classification rule at its Phase 2 gate would be the same defect one level up.
[Verification]: docs-only diff — no
.py, no corpus, no pin touched, so no lane can move. The sibling Phase 1 branch ranuv run core test --suite deductive -qgreen (364 passed) against this same base in-session.