Skip to content

feat(L1): Phase D slice 4 Phase 3a — tfuneff_lambda_retype_l1_m + is_tfuneff_ty#224

Merged
hyperpolymath merged 1 commit into
mainfrom
proof-debt/standards-134-phase-d-slice-4-phase-3-tfuneff-lambda-retype
May 30, 2026
Merged

feat(L1): Phase D slice 4 Phase 3a — tfuneff_lambda_retype_l1_m + is_tfuneff_ty#224
hyperpolymath merged 1 commit into
mainfrom
proof-debt/standards-134-phase-d-slice-4-phase-3-tfuneff-lambda-retype

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

  • Ships the retype lemma half of Phase 3 per formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md.
  • Adds is_tfuneff_ty predicate (Syntax.v) mirroring is_ground_nonlinear_ty.
  • Adds tfuneff_lambda_retype_l1_m lemma (Semantics_L1.v): retype TFunEff lambda value across (m, R, G) → (m, R', G) under side condition forall r, In r R' → In r R_in.
  • Phase 3b (substitution-lemma extension) DESCOPED to a follow-up PR after structural analysis revealed the T_Region_L1 fresh-region obstacle. STATE.a2ml documents the three candidate solutions.

Why split

SUBST-LEMMA-GENERALIZATION-DESIGN.md Phase 3 proposed two pieces (retype + substitution extension). Walking the substitution proof revealed: every retype across a threaded R_n inside the term e demands forall r, In r R_n → In r R_in_arg, and T_Region_L1 firings inside e introduce fresh r ∉ R_outer — freshness wrt the threaded R does not imply membership in the value-type's fixed R_in_arg. Three candidate fixes (syntactic side condition on e; universal-R Hv_type with per-case discharge; restrict to region-free terms) need Phase 4 prototyping of the actual subst 0 varg ebody shape before choosing. Phase 3a's retype lemma stands on its own as clean infrastructure usable in 3b and Phase 4.

Proof shape

tfuneff_lambda_retype_l1_m:

  • destruct Hval (10 value-form cases)
  • inversion Ht; subst; try discriminate
    • Non-ELam forms: types don't match TFunEff → discriminate.
    • ELam at TFun (legacy rules T_Lam_L1_Linear / T_Lam_L1_Affine): type mismatch TFun ≠ TFunEff → discriminate.
    • ELam at TFunEff (T_Lam_L1_Linear_Eff / T_Lam_L1_Affine_Eff): re-apply rule with new Hsub, body via eassumption.

Zero new admits, zero new axioms. Coqc 8.18.0 clean rebuild across all 10 .v files.

Owner-directive compliance (per CLAUDE.md 2026-05-27)

  • ✅ No closure of legacy preservation in Semantics.v (untouched).
  • ✅ No closure-support lemmas in Semantics.v (untouched).
  • ✅ No closure of residual Semantics_L1.v admits — strictly NEW orthogonal infrastructure.
  • ✅ No patching Typing.v (untouched).
  • ✅ No new Admitted / Axiom.
  • ✅ Anti-pattern detector clean.

Test plan

  • coqc -Q . Ephapax clean across all 10 .v files locally.
  • CI green on formal/ build job.

Refs: standards#134 (proof-debt epic), #220 (Phase 2), #213 (design doc).

…is_tfuneff_ty` predicate

Ships the TFunEff retype lemma half of Phase 3 per
`formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md`. The substitution-lemma
extension is descoped to Phase 3b after structural analysis revealed
the `T_Region_L1` fresh-region obstacle (see STATE.a2ml).

## What lands

`formal/Syntax.v`:
- `is_tfuneff_ty : ty -> bool` predicate mirroring `is_ground_nonlinear_ty`.
  Returns `true` for `TFunEff _ _ _ _` only.

`formal/Semantics_L1.v`:
- `tfuneff_lambda_retype_l1_m` lemma.
  Signature: retype a TFunEff lambda value across `(m, R, G) -> (m, R', G)`
  under the side condition `forall r, In r R' -> In r R_in`, where
  `R_in` is part of the value's type `TFunEff T1 T2 R_in R_out`.
  Same `m`, same `G`; cross-modality / cross-context retype is NOT
  required for the Phase 4 use-case and would require lifting body
  typing across `linear_to_affine`.

`.machine_readable/6a2/STATE.a2ml`:
- `next_action` -> Phase 3b (TFunEff substitution-lemma extension)
- `last_action` -> Phase 3a landed; documents Phase 3b descoping
  rationale (T_Region_L1 fresh-region obstacle) and three candidate
  solutions for 3b.

## Proof shape

Inverts on `is_value v` (10 constructor forms), then on `Ht`.
- Non-ELam value forms (EUnit, EBool, EI32, EPair, EInl, EInr, ELoc,
  EBorrow, EEcho) cannot type at `TFunEff …` (their formation rules
  produce different type shapes) — discriminated automatically.
- ELam at TFunEff resolves to either `T_Lam_L1_Linear_Eff` or
  `T_Lam_L1_Affine_Eff` (the `T_Lam_L1_Linear` / `T_Lam_L1_Affine`
  rules produce `TFun`, discriminated).
- Re-apply the appropriate `_Eff` rule with `Hsub` discharging the
  side condition; body typing carries unchanged via `eassumption`.

Zero new admits, zero new axioms. Coqc 8.18.0 clean rebuild across all
10 .v files.

## Phase 3b deferred — the obstacle

Extending `subst_typing_gen_l1_m` to cover `T1 = TFunEff …` substituends
requires lifting `Hv_type` to threaded R values inside the substitution
target `e`. For TFunEff values, each lift demands the side condition
`forall r, In r R_threaded -> In r R_in_arg`, where `R_in_arg` is FIXED
by the value's type. `T_Region_L1` firings inside `e` introduce fresh
regions `r ∉ R_outer`; the freshness wrt the threaded R does NOT imply
membership in `R_in_arg`. Three candidate solutions are sketched in
STATE.a2ml's `next_action`; choosing among them requires Phase 4
prototyping of `subst 0 varg ebody` shape.

Ground non-linear retype (Phase 1) doesn't hit this obstacle because
it is fully R-polymorphic without a side condition.

## Owner-directive compliance

- ✅ No closure of legacy `preservation` in `Semantics.v` (untouched).
- ✅ No new closure-support lemmas in `Semantics.v` (untouched).
- ✅ No closure of residual `Semantics_L1.v` admits via this work —
  strictly NEW infrastructure orthogonal to legacy.
- ✅ No patching `Typing.v` (untouched).
- ✅ No new `Admitted` or `Axiom` declarations.
- ✅ Anti-pattern detector clean (no sibling-region-disjointness side
  conditions; no admit-shuffling).

Refs: standards#134 (proof-debt epic).
@hyperpolymath hyperpolymath enabled auto-merge (squash) May 30, 2026 13:26
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 74 issues detected

Severity Count
🔴 Critical 13
🟠 High 13
🟡 Medium 48

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action perpolymath/standards/.github/workflows/governance-reusable.yml@main\n needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in abi-verify.yml",
    "type": "unknown",
    "file": "abi-verify.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in boj-build.yml",
    "type": "unknown",
    "file": "boj-build.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "unknown",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in governance.yml",
    "type": "unknown",
    "file": "governance.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in hypatia-scan.yml",
    "type": "unknown",
    "file": "hypatia-scan.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in instant-sync.yml",
    "type": "unknown",
    "file": "instant-sync.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in mirror.yml",
    "type": "unknown",
    "file": "mirror.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in rust-ci.yml",
    "type": "unknown",
    "file": "rust-ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in rust-ci.yml",
    "type": "unknown",
    "file": "rust-ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 45469e8 into main May 30, 2026
17 checks passed
@hyperpolymath hyperpolymath deleted the proof-debt/standards-134-phase-d-slice-4-phase-3-tfuneff-lambda-retype branch May 30, 2026 13:27
@hyperpolymath
Copy link
Copy Markdown
Owner Author

Phase 3b follow-up tracked in #225 (substitution-lemma extension; three candidate solutions documented).

@hyperpolymath
Copy link
Copy Markdown
Owner Author

Seam-analyst notes (for owner awareness, not blocking):

  1. SUBST-LEMMA-GENERALIZATION-DESIGN.md Phase 3 description ("ship retype + extend substitution") is over-optimistic — the two halves have very different difficulty. Worth an addendum noting the T_Region_L1 obstacle and the 3a/3b split. Could file as a docs-only follow-up.

  2. Parallel-session race noticed: another worktree at /tmp/ephapax-phase-3a on branch phase-d-slice-4-phase-3a-tfuneff-retype-2026-05-30 has a local commit for the same Phase 3a work (1648a08, not pushed). Per the branch-drift memory I didn't disturb that WIP; if its PR lands first, this PR rebases or closes. If this PR lands first, that session rebases.

  3. SUBST-LEMMA-GENERALIZATION-DESIGN.md Phase 4 plan refers to "Phase 3 lemma" (singular). With the 3a/3b split, Phase 4 case-coverage analysis needs updating to reflect that 3b is the actual blocker for the TFunEff non-linear T1 case.

hyperpolymath added a commit that referenced this pull request May 30, 2026
…226)

## TL;DR — P0 hotfix

\`main\` does NOT compile as of 2026-05-30 13:27:45Z. PR #224
admin-merged with auto-merge SQUASH ~7 minutes after PR #223, and both
added the same Lemma \`tfuneff_lambda_retype_l1_m\`. CI did not catch
the duplicate because the GitHub CI workflows currently exercise
governance / security scanners only — not the Coq build oracle.

Local rebuild:

\`\`\`
File "./Semantics_L1.v", line 1361, characters 6-32:
Error: tfuneff_lambda_retype_l1_m already exists.
\`\`\`

This PR removes the duplicate block (PR #224's copy, lines 1311-1382 of
post-merge file). Original (PR #223) at lines 1257-1278 is unchanged.
\`Syntax.is_tfuneff_ty\` (also added by #224) is INDEPENDENTLY useful
for Phase 3b precondition shape — preserved untouched.

## Verification

\`\`\`
$ cd /tmp/ephapax-design-amendment/formal && just all
coq_makefile -f _CoqProject -o build.mk
make -f build.mk
COQDEP VFILES
COQC Semantics_L1.v
COQC Counterexample.v
COQC Echo.v
COQC TypingL2.v
COQC L4.v
(exit 0)
\`\`\`

Rocq 9.1.1 / Coq 8.18. Zero new admits, zero new axioms, zero semantic
changes (the two duplicate lemmas were behaviorally equivalent modulo
argument order; v1 is kept as the earlier-merged canonical version).

## Net delta

- \`formal/Semantics_L1.v\`: 73 lines deleted (no insertions).

## Root-cause + follow-up

Parallel-session collision: two agent sessions both shipped Phase 3a
infrastructure within a 7-minute window without cross-checking. PR #223
merged at 13:21:06Z. PR #224 enabled auto-merge at 13:26:48Z (5min33s
after #223), so the author could not have known #223 was already merged
when arming auto-merge.

Mitigation surface for follow-up issues:
1. **Coq build oracle into CI** — currently zero gate at the
typechecking layer. ANY duplicate-Lemma / broken-proof PR will
admin-merge green. File issue to add a Coq build job to the workflow
set.
2. **Parallel-session signal** — pre-merge \`git log origin/main -5 --
formal/\` would have caught the collision. Could be a Hypatia rule on
parallel ephapax sessions.

## Owner-directive compliance

- Does NOT modify \`Semantics.v\`.
- Does NOT add new admits or axioms.
- Reverts a parallel-session collision; not a proof trick to close
legacy admits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
…near` + hotfix duplicate `tfuneff_lambda_retype_l1_m` (#228)

## Summary

Two L2-layer additions and one hotfix for a parallel-session merge
collision.

### Phase 4a — β-case closure for linear T1

The `T_App_L2_Eff` β-case (S_App_Fun step) closes for linear T1 via the
existing m-indexed substitution lemma `subst_typing_gen_l1_m`. Pure new
infrastructure orthogonal to legacy admits.

- **`preservation_l2_app_eff_beta_linear_l1`** — L1-level kernel. Takes
inverted T_App_L2_Eff premises (lambda formed at `TFunEff` + value
argument typed at `T1`) and produces the post-β L1 typing of `subst 0 v2
ebody`. Inversion on the lambda forces `T_Lam_L1_*_Eff`;
`value_R_G_preserving_l1` on the argument collapses `R_in` / `G''` to
`R` / `G`.
- **`preservation_l2_app_eff_beta_linear`** — L2 wrapper. Inverts both
`has_type_l2` hypotheses through `L2_lift_l1` (the `T_App_L2_Eff`
discriminate cases: lambda's head is `ELam` not `EApp`; argument is a
value so cannot be `EApp`). Defers to the L1 kernel and re-lifts via
`L2_lift_l1`.
- **`linear_value_retype_l1_m`** — small local m-poly helper. Linear
values at L1 are exactly locations (`T_Loc_L1` is m-polymorphic); retype
at any `m'`. Needed because `subst_typing_gen_l1_m`'s premise 5 uses the
bare `|=L1` notation which is Linear-mode-only, so the Affine branch
must re-derive the substituend at Linear.

**Phase 4 follow-ons** (NOT in this PR):
- 4b: ground-non-linear `T1` via Phase 2's
`subst_typing_gen_l1_m_ground_nonlinear`.
- 4c: TFunEff non-linear `T1` — blocked on Phase 3b (issue #225).
- 4d: compound non-linear — deferred to Phase 5.

These three helpers compose with `preservation_l2_via_l1` toward
eventual closure of `preservation_l2` over the full `has_type_l2`
judgment.

### Hotfix — duplicate \`tfuneff_lambda_retype_l1_m\`

PRs #223 and #224 (parallel-session merges 2026-05-30) both added
\`tfuneff_lambda_retype_l1_m\` with different argument orders, leaving
main with a Coq "already exists" compile error. CI didn't catch it
because there's no Coq build job in the gates — this PR surfaces that
gap as a seam observation (Coq is the only merge oracle for proof PRs,
but is not part of CI).

Kept the chronologically-first definition (PR #223: \`(Hval, Ht, HR')\`
arg order) and removed the second (PR #224: \`(Hval, Hsub, Ht)\`). Both
proofs were semantically equivalent. No external call sites existed yet,
so argument order is free choice.

## Build + assumption audit

- coqc 8.18.0 clean rebuild across all 10 .v files.
- \`Print Assumptions preservation_l2_app_eff_beta_linear\` shows only
the pre-existing \`region_liveness_at_split_l1_gen\` axiom inherited
transitively via \`subst_typing_gen_l1_m\`. **No new admits/axioms.**
- \`Print Assumptions linear_value_retype_l1_m\` shows "Closed under the
global context" — fully axiom-free.

## Owner-directive compliance (CLAUDE.md 2026-05-27)

- ✅ Does not close \`Theorem preservation\` in \`formal/Semantics.v\`.
- ✅ Does not extend \`Semantics.v\` / \`Typing.v\` /
\`Counterexample.v\`.
- ✅ Does not close any residual \`Semantics_L1.v\` admit (the
duplicate-removal is mechanical de-duplication, not proof closure).
- ✅ Works per-layer: L1 kernel + L2 wrapper, both at the post-redesign
m-indexed \`has_type_l1\` judgment.
- ✅ Reads \`PRESERVATION-DESIGN.md\` /
\`SUBST-LEMMA-GENERALIZATION-DESIGN.md\` first.
- ✅ No new \`Axiom\` or \`Admitted\` markers.

## Test plan

- [x] \`coqc -R . Ephapax\` rebuild across all 10 .v files, zero errors
/ warnings.
- [x] \`Print Assumptions\` audit shows no new axioms beyond the
pre-existing L1 \`region_liveness_at_split_l1_gen\`.
- [x] Duplicate hotfix verified by \`grep -n
"tfuneff_lambda_retype_l1_m\b" Semantics_L1.v\` showing single hit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
## Summary

Closes #227 — adds `.github/workflows/coq-build.yml` so the standing
directive "for proof PRs, the toolchain build is the ONLY merge oracle"
is machine-enforced.

## Today's incident motivating this

PR #224 admin-merged 7 min after PR #223; all 17 governance/scanner
checks were green; `coqc` was not run; main broke with
`tfuneff_lambda_retype_l1_m already exists`. Hotfix #226 restored
compilation; #227 was filed in parallel asking for the oracle gap to be
closed at workflow-level.

## What the workflow does

- Triggers on PR + push-to-main, scoped to `formal/**` paths (only fires
when proofs change).
- Container: `coqorg/coq:8.18` (matches `formal/Justfile`'s pinned
toolchain).
- Builds via the same recipe `formal/Justfile all` uses:
  ```
  coq_makefile -f _CoqProject -o build.mk
  make -f build.mk
  ```
- After a clean build, runs `Print Assumptions preservation_l2_via_l1`
and prints the tail. Any new `Admitted.` / `Axiom` slippage shows as a
workflow-output diff.

## What this PR does NOT do

- Branch-protection / required-check designation is **owner's call**
(admin-only in GitHub Settings). The workflow file ships first so the
check identity exists; one green run on main lets you mark it required.

## Test plan

- [ ] First CI run on this PR builds `formal/_CoqProject` clean
- [ ] `Print Assumptions preservation_l2_via_l1` output appears in the
log
- [ ] (Manual, post-merge) Mark `Coq build — formal/_CoqProject` as a
required check

## Refs

- Closes #227
- Refs #229 (sibling — the broader "no Coq oracle" surface this closes)
- Refs #226 (hotfix that motivated this)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
…DE.md DO #4 (closes nothing, files #235)

Pre-implementation review of Phase 3b's option (a) precondition

  (forall r, In r (regions_introduced_by e) -> In r R_in_v)

found it INSUFFICIENT to discharge T_Lam_L1_*_Eff body cases of the
planned subst_typing_gen_l1_m_tfuneff lemma.

Why: the substitution lemma recurses into inner lambda bodies (Phase
2 does so via the IH at formal/Semantics_L1.v:1929-1942). Inner
T_Lam_L1_*_Eff bodies type at the lambda's declared R_in_inner. R_in
is type-level — it lives in the TFunEff slot of the function's TYPE,
not in syntax. `regions_introduced_by(e)` only collects ERegion
subterms' first arguments; R_in_inner is invisible to it.

`tfuneff_lambda_retype_l1_m` (PR #224) requires R' ⊆ R_in_v to
discharge T_Lam_L1_*_Eff's side condition. We have no way to bound
inner R_in by R_in_v.

Phase 2's `subst_typing_gen_l1_m_ground_nonlinear` dodges this via
`ground_nonlinear_retype_l1_m`, which is fully (m, R, G)-polymorphic.
Phase 3b's TFunEff retype has no analogous escape.

Three resolution options documented:
  1. Syntactic helper `declared_lambda_r_ins` — requires ELam
     annotation extension (parameter type only in current syntax).
  2. Semantic precondition over the derivation — clean meaning,
     awkward in Coq.
  3. Leaf-only Phase 3b via `tfuneff_lambda_free e` predicate —
     tactical landing; Phase 5 compound-value redesign subsumes
     (1)/(2) at leisure.

Recommended: option (3). Owner decision required before Phase 3b
implementation can start.

This PR contains documentation only:
  - formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md gains a Phase 3b
    addendum documenting the gap and three resolution options.
  - .machine_readable/6a2/STATE.a2ml flips phase to
    `blocked-on-owner-decision` with next_action pointing at #235.

No formal/*.v changes.

Predecessor PRs unaffected:
  - Phase 4a (#228) MERGED.
  - Phase 4b (parallel session, #233) MERGED.
  - Phase 4c counterexample (#234) auto-merge pending.

Phase 4c's `Counterexample_L2.v` independently justifies the
conditional preservation_l2 statement regardless of which Phase 3b
resolution lands.

Per CLAUDE.md owner directive §DO #4 (escalate before patching):
this PR IS the escalation.

Owner-directive compliance:
  - No Semantics.v / Typing.v / Counterexample.v touch
  - No new Axiom / Admitted markers
  - No closure of residual Semantics_L1.v admits
  - No sibling-region-disjointness side conditions
  - No proposal to close `Theorem preservation` to Qed.

Refs: #225 (Phase 3b parking lot), #230 (regions_introduced_by
helper), #233 (Phase 4b), #234 (Phase 4c counterexample),

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
…DE.md DO #4 (closes nothing, files #235)

Pre-implementation review of Phase 3b's option (a) precondition

  (forall r, In r (regions_introduced_by e) -> In r R_in_v)

found it INSUFFICIENT to discharge T_Lam_L1_*_Eff body cases of the
planned subst_typing_gen_l1_m_tfuneff lemma.

Why: the substitution lemma recurses into inner lambda bodies (Phase
2 does so via the IH at formal/Semantics_L1.v:1929-1942). Inner
T_Lam_L1_*_Eff bodies type at the lambda's declared R_in_inner. R_in
is type-level — it lives in the TFunEff slot of the function's TYPE,
not in syntax. `regions_introduced_by(e)` only collects ERegion
subterms' first arguments; R_in_inner is invisible to it.

`tfuneff_lambda_retype_l1_m` (PR #224) requires R' ⊆ R_in_v to
discharge T_Lam_L1_*_Eff's side condition. We have no way to bound
inner R_in by R_in_v.

Phase 2's `subst_typing_gen_l1_m_ground_nonlinear` dodges this via
`ground_nonlinear_retype_l1_m`, which is fully (m, R, G)-polymorphic.
Phase 3b's TFunEff retype has no analogous escape.

Three resolution options documented:
  1. Syntactic helper `declared_lambda_r_ins` — requires ELam
     annotation extension (parameter type only in current syntax).
  2. Semantic precondition over the derivation — clean meaning,
     awkward in Coq.
  3. Leaf-only Phase 3b via `tfuneff_lambda_free e` predicate —
     tactical landing; Phase 5 compound-value redesign subsumes
     (1)/(2) at leisure.

Recommended: option (3). Owner decision required before Phase 3b
implementation can start.

This PR contains documentation only:
  - formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md gains a Phase 3b
    addendum documenting the gap and three resolution options.
  - .machine_readable/6a2/STATE.a2ml flips phase to
    `blocked-on-owner-decision` with next_action pointing at #235.

No formal/*.v changes.

Predecessor PRs unaffected:
  - Phase 4a (#228) MERGED.
  - Phase 4b (parallel session, #233) MERGED.
  - Phase 4c counterexample (#234) auto-merge pending.

Phase 4c's `Counterexample_L2.v` independently justifies the
conditional preservation_l2 statement regardless of which Phase 3b
resolution lands.

Per CLAUDE.md owner directive §DO #4 (escalate before patching):
this PR IS the escalation.

Owner-directive compliance:
  - No Semantics.v / Typing.v / Counterexample.v touch
  - No new Axiom / Admitted markers
  - No closure of residual Semantics_L1.v admits
  - No sibling-region-disjointness side conditions
  - No proposal to close `Theorem preservation` to Qed.

Refs: #225 (Phase 3b parking lot), #230 (regions_introduced_by
helper), #233 (Phase 4b), #234 (Phase 4c counterexample),

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
… axioms)

Ships the substitution-lemma half of Stage 1b. Closed TFunEff values
can now be substituted at depth k into leaf-only outer expressions
with full L1-typing preservation.

Lemma signature:

  forall m R Gin e T R' Gout,
    has_type_l1 m R Gin e T R' Gout ->
    forall k Ta Tb R_in_v R_out_v v u_in,
      nth_error Gin k = Some (TFunEff Ta Tb R_in_v R_out_v, u_in) ->
      is_value v ->
      tfuneff_lambda_free e = true ->                         (P1)
      (forall r, In r (regions_introduced_by e) -> In r R_in_v) ->  (P2)
      expr_closed_below 0 v = true ->                         (P3)
      has_type_l1 m R (remove_at k Gin) v
                  (TFunEff Ta Tb R_in_v R_out_v) R (remove_at k Gin) ->
      forall u_out,
        nth_error Gout k = Some (TFunEff Ta Tb R_in_v R_out_v, u_out) ->
        has_type_l1 m R (remove_at k Gin) (subst k v e) T R'
                    (remove_at k Gout).

Mirrors Phase 2's [subst_typing_gen_l1_m_ground_nonlinear] structurally
with two swaps:

- Phase 2's [ground_nonlinear_retype_l1_m] (R, G-poly retype for
  ground non-linear values, no side conditions) is replaced by
  [closed_value_typing_RG_poly_l1_m] (closed TFunEff value RG-poly
  retype, requires R' ⊆ R_in side condition). The side condition is
  discharged at each compound-rule call site via
  [sub_R_in_R_in_via_value_l1_m]: chain (sub-derivation R' ⊆ outer R
  via count_occ_le_l1_m) + (outer R ⊆ R_in_v via the substituent's
  T_Lam_L1_*_Eff formation side condition, extracted by
  value_TFunEff_R_subset_R_in_l1_m).

- Phase 2's [ground_nonlinear_value_shift_id_l1] is replaced by
  [closed_value_shift_id_l1_m] for binder-traversal shift-identity.

Inner T_Lam_L1_* / T_Lam_L1_*_Eff cases discharge via [discriminate]
on P1 (tfuneff_lambda_free (ELam _ _) = false).

Two new supporting lemmas in Semantics_L1.v:

- [closed_value_typing_RG_poly_l1_m] — combined RG-poly retype
  chaining [closed_value_typing_G_poly_l1_m] with
  [tfuneff_lambda_retype_l1_m] (PR #224).

- [value_TFunEff_R_subset_R_in_l1_m] — extracts the lambda-formation
  side condition R ⊆ R_in from any TFunEff value typing. Trivial
  inversion proof.

- [sub_R_in_R_in_via_value_l1_m] — packages the R-subset chain used
  at every compound-rule call site in subst_typing_gen_l1_m_tfuneff.

Print Assumptions verdict on all four new lemmas:
- subst_typing_gen_l1_m_tfuneff:                 Closed under the global context
- closed_value_typing_G_poly_l1_m:               Closed under the global context
- closed_value_typing_RG_poly_l1_m:              Closed under the global context
- closed_below_k_typing_outer_tail_irrelevant_l1_m: Closed under the global context

Zero new axioms. Zero new admits. Stage 1b's L1-level deliverable is
complete; the L2 β-wrapper [preservation_l2_app_eff_beta_tfuneff_l1]
+ L2-judgment surface lemma ship next on this branch.

Owner-directive compliance (CLAUDE.md 2026-05-27):
- ✅ No touch to formal/Semantics.v / Typing.v / Counterexample.v.
- ✅ No closure of residual Semantics_L1.v admits attempted.
- ✅ Anti-pattern detector clean across all four stages of the
  4-stage Phase 3b plan (#235#239 / #240 / #241 / #242).
- ✅ Strictly NEW infrastructure orthogonal to legacy.

Build oracle (coqc 8.18.0): clean across all 12 .v files.

Refs:
- ephapax issue #249 (Stage 1b tracking; this commit is the L1 half).
- ephapax PR #252 (Stage 1a prerequisite — tfuneff_lambda_free
  + Counterexample_L2_nested + design doc).
- ephapax issue #239 (parent Stage 1).
- formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md Phase 3b Stage 1b.

Co-Authored-By: Claude Opus 4.7 (1M context) <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