Skip to content

refactor(verification): weaken inv_field_001 axiom to document-level preservationFriendly (PR-B follow-up to #208)#219

Merged
stevenobiajulu merged 1 commit into
worktree-inv-field-001-prooffrom
weaken-fieldcontext-predicate-20260522
May 22, 2026
Merged

refactor(verification): weaken inv_field_001 axiom to document-level preservationFriendly (PR-B follow-up to #208)#219
stevenobiajulu merged 1 commit into
worktree-inv-field-001-prooffrom
weaken-fieldcontext-predicate-20260522

Conversation

@stevenobiajulu
Copy link
Copy Markdown
Member

Summary

Stacked on top of #208. Replaces the load-bearing residual axiom in Spec.lean from the per-subtree Tier2.FieldStructure.recursivelyWellformed (which requires ∀ ctx neutrality of every track-change wrapper subtree) to the new document-level Tier2.AcceptReject.preservationFriendly (which only asserts that accept and reject preserve the composed walk and begin/end balance).

The new predicate is strictly weaker than the old one and is future-compatible with ECMA-376 field fragmentation (#217). The old predicate happens to hold for the current safe-docx engine — Codex's review of #208 confirmed via inPlaceModifier.ts:717, 938, 1505, 1671, 1957, 2300 that the engine emits whole field sequences as single track-change wrappers. But when #217 lands and the engine starts fragmenting per ECMA-376 Part 4, the old ∀ ctx predicate breaks while preservationFriendly still holds.

This PR lands the predicate weakening before the engine refactor so the Lean side never has to live with a known-broken axiom.

Strength comparison (constructed by Codex during review)

Both predicates hold for a complete-field-in-<w:ins> (the engine's current shape). Only preservationFriendly holds for the ECMA-376 fragmented shape [fldChar begin, ins[instrText], fldChar separate, text, fldChar end] — the inner <w:ins> is not ∀ ctx-neutral but the document as a whole is preservation-friendly.

What changed

  • verification/lean/Tier2/AcceptReject.lean — adds preservationFriendly definition. Opens Tier2.FieldStructure to reuse the walk and count utilities.
  • verification/lean/Tier2/InvFieldOne.lean — adds new theorem field_structure_preserved_doc (the doc-level variant). ~25 lines. The legacy field_structure_preserved is retained for audit traceability.
  • verification/lean/LeanSpike/Spec.lean — replaces the axiom with compareDocumentXml_output_preservation_friendly. Rewires the inv_field_001 proof body. Updates the axiom docstring to explain the layering.
  • packages/docx-core/src/integration/lean-spec-bridge.test.ts — updates the comment block above the field-bearing fixtures to document that the existing assertRecursivelyWellformed over-check is now stricter than what the axiom requires; will need adjustment when inplace atomizer: emit fragmented fields per ECMA-376 Part 4 (split <w:ins>/<w:del> at field-character boundaries) #217 lands.

Out of scope

Test plan

Sequencing

This PR's base is worktree-inv-field-001-proof (i.e., it stacks on #208). After #208 merges, this PR can be retargeted to main.

🤖 Generated with Claude Code

…nt-level preservation friendliness

Closes peer-review concern D (predicate strength) from PR #208. Codex review
confirmed the current engine satisfies the stronger `∀ ctx` predicate, but the
ECMA-376 Part 4 deep-research report showed that a conformant emitter MUST
fragment fields across wrapper boundaries when modifying a field — fragmented
`<w:ins>`/`<w:del>` wrappers containing only `w:instrText`/`w:delInstrText`
are NOT `fieldContextNeutral` under `∀ ctx`. When safe-docx becomes
ECMA-376-conformant (tracked in #217), the stronger predicate will break.

This commit weakens the residual axiom to be future-compatible without
touching the engine.

## Predicate weakening

Adds `Tier2.AcceptReject.preservationFriendly` — a document-level property
asserting only that accept and reject preserve the *composed* field walk and
begin/end balance. Strictly weaker than the previous per-subtree
`Tier2.FieldStructure.recursivelyWellformed`:

  * Old: `validateFieldStructure d ∧ ∀ wrapper-subtree, fieldContextNeutral subtree`
    where `fieldContextNeutral bs := ∀ ctx, walkBlocks (.ok ctx) bs = .ok ctx`.
  * New: `validateFieldStructure d ∧ walkBlocks (.ok []) (acceptBlocks d.blocks)
    = walkBlocks (.ok []) d.blocks ∧ ...` (analogous for reject + balance).

The old predicate is retained in `Tier2.FieldStructure` and the legacy
`field_structure_preserved` lemma still compiles — they remain available for
audit traceability. Only `inv_field_001` is rewired to consume the new
predicate via the new `Tier2.InvFieldOne.field_structure_preserved_doc` lemma.

## Axiom replacement

`Spec.lean` replaces `compareDocumentXml_output_recursivelyWellformed` with
`compareDocumentXml_output_preservation_friendly`. The `inv_field_001` proof
body changes to compose the new axiom with `field_structure_preserved_doc`.
`#print axioms LeanSpike.inv_field_001` becomes:

  [propext, compareDocumentXml, compareDocumentXml_output_preservation_friendly, Quot.sound]

## TS bridge — explanatory comment

The existing `isFieldContextNeutral` / `assertRecursivelyWellformed` checks in
`lean-spec-bridge.test.ts` enforce the OLD stricter property. With the axiom
now weaker, these become an audit OVER-check: the engine currently satisfies
them (whole-field wrapping), but when #217 lands and the engine starts
fragmenting, these checks will need to be removed or relaxed. The comment
block above the field-bearing fixtures is updated to reflect this layering.

Ref: #208, #217
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
site Ready Ready Preview, Comment May 22, 2026 6:36am

Request Review

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