diff --git a/ingestion/internal/mcp/tools_notes.go b/ingestion/internal/mcp/tools_notes.go index 617d596..0f9ba0c 100644 --- a/ingestion/internal/mcp/tools_notes.go +++ b/ingestion/internal/mcp/tools_notes.go @@ -268,6 +268,27 @@ func touchesFrontmatter(oldStr, newStr string) bool { // those cases at write time regardless of what this function decides, so // the only thing riding on this preview's accuracy is the envelope check // itself, not write safety. +// checkClaimEnvelope previews what old_str->new_str would produce and +// validates the resulting claim envelope before the real edit runs +// (hyperguild#123). Seven review rounds closed every plausible bypass in the +// fence-detection family (field-name substring, block-containment, +// fence-stripping, CRLF, UTF-8 BOM) and the first instance of a +// value-extraction gap (a folded YAML block scalar hiding a value behind an +// empty inline colon). +// +// Known, accepted v1 gap: frontmatterScalars's block-scalar fold is a +// best-effort approximation, not a YAML parser — a blank line interrupting a +// folded continuation, or other contrived multi-line YAML shapes not yet +// probed (block-scalar indicators `|`/`>`, inline comments on a key line, +// quoted multi-line values), can still hide an invalid value from +// ValidateEnvelope. Accepted deliberately rather than chased indefinitely: +// every bypass found so far requires the caller to already hold brain_edit +// write access and to deliberately construct a specific malformed-YAML shape +// with knowledge of this exact gap — a narrow, low-likelihood threat next to +// the diminishing returns of another incremental patch round. The real fix +// (a shared, tested, encoding-normalized frontmatter parser used by all +// three independent implementations in this codebase) is tracked separately +// as hyperguild#138, not bolted on here piece by piece. func checkClaimEnvelope(brainDir, path, oldStr, newStr string) error { if oldStr == "" { // hyperguild#115: strings.Replace treats "" as matching position 0,