Review of PR #136 found the gate trivially bypassable: touchesClaimEnvelope only fired when old_str/new_str contained the claim-envelope FIELD NAME as a substring, but a natural value-only diff (old_str: "asserted", new_str: "guessed" against a claim_provenance line) never mentions the field name and walked straight past it — notes.Edit wrote the invalid enum value to disk with zero error. Redesign the gate to be position-based instead of name-based: checkClaimEnvelope now checks whether old_str is physically contained within the note's frontmatter block (via the new frontmatterBlock helper), previews the exact strings.Replace the real edit would perform, and validates the resulting envelope before the edit is allowed to run. frontmatterScalars now builds on the shared frontmatterBlock helper. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>