Skip to content

fix(plv): recognize structural mandate label variants - #55

Merged
ThoughtProof merged 5 commits into
mainfrom
cursor/mandate-label-variants-4bc0
Oct 30, 2026
Merged

ThoughtProof merged 5 commits into
mainfrom
cursor/mandate-label-variants-4bc0

Conversation

@ThoughtProof

@ThoughtProof ThoughtProof commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Structural mandate labels are recovered only from the preamble. One recognizer both cuts the span and closes that region, on a separate line or inline. The separator is ASCII space, tab, or a newline. NBSP, VT, FF, BOM, and EM SPACE before a section label recover no mandate, so an injected USER INSTRUCTION: or Mandate: after that point cannot become the quote.

Mandate texts are compared literally after the existing outer trim. Internal spaces, NBSP, BOM, and tabs are not collapsed, so two exclusive file targets are MANDATE_CONFLICT and the verdict is HOLD. An existing BLOCK is not loosened. A model quote is still kept and provenance-checked.

Fences still close only on the same character, with a run at least as long as the opener, and only ASCII spaces or tabs after that run. Package version stays 0.8.12. Sentinel is not changed. This PR stays a draft.

Owner patch on 18cd289

Ambiguous preamble boundaries now return a blocking conflict with no quote, so a real model quote cannot turn that case into ALLOW. The boundary scan stops at the first action or tool section, so labels in that content cannot erase a conflict already found. A trailing ASCII space or tab does not hide a non-structural separator before that run (NBSP plus space, or NBSP plus tab, stays ambiguous). A genuinely absent mandate stays absent.

Tests

The original 20 cases in src/plan/test-mandate-owner-review.ts are unchanged.

The owner's 17 boundary and literal-target cases are in src/plan/test-mandate-unicode-boundaries.ts. Assertions match unicode-boundaries-and-literals.test.mjs. The harness calls evaluateItem with a local model fixture; tier1 includes backend: 'llm' because Tier1Config requires it.

Extra negatives in that file cover VT, FF, NBSP, BOM, and EM SPACE before Proposed action:, Agent reasoning:, Tool output:, and WALLET BALANCE:, the same separators inline before Proposed action:, an injected Mandate: as well as USER INSTRUCTION:, and tab-versus-space filenames in both the conflicting and identical cases.

src/plan/test-mandate-boundary-scope.ts locks the owner patch: conflict scope, mixed separators, and the absent-versus-ambiguous distinction. Review harness files were run locally and were not committed.

Results on 18cd289

  • git apply --check then git apply of the owner patch: clean
  • npm ci: pass
  • npm run build: pass
  • npm run test:plan: 450 passed, 0 failed
  • node --test on tests/ask-verify-mode.test.mjs, tests/custom-provider.test.mjs, tests/rv-pipeline.test.mjs: 43 passed, 0 failed
  • npm run test:package: 2 passed, 0 failed
  • npm run check:boundaries: pass
  • owner review-tests/*.test.mjs: 45 passed, 0 failed

Sentinel

Still pinned to pot-cli@0.8.12. A pin bump waits on a published release. Not done here.

Open in Web Open in Cursor 

cursoragent and others added 5 commits October 29, 2026 20:32
Recognize Mandate, User mandate, Principal instruction, and bare
Principal mandate headers when they are real section headers, so an
omitted model quote is not floored to 0.25. Labels inside quotes, tool
output, or the proposed action do not count. Disagreeing sections fail
closed, and a fabricated model quote is never replaced by a fallback span.

Co-authored-by: Raul Jäger <raul@thoughtproof.ai>
Match fenced blocks by character and length, hold the verdict when
mandate sections conflict, ignore legacy labels after the action
boundary, and accept Principal mandate (verbatim): as a header.

Co-authored-by: Raul Jäger <raul@thoughtproof.ai>
CommonMark allows only ASCII spaces and tabs after a closing fence
marker. String.trim() also strips NBSP and other Unicode whitespace,
which closed the block early and recovered the text inside it.

Co-authored-by: Raul Jäger <raul@thoughtproof.ai>
One recognizer both cuts a mandate span and closes the mandate region,
including inline labels, and only ASCII space or tab is structural
whitespace. Other whitespace before a section label recovers nothing.
Mandate identity keeps internal characters, so a different space is a
conflict and holds the verdict.

Co-authored-by: Raul Jäger <raul@thoughtproof.ai>
Co-authored-by: Raul Jäger <raul@thoughtproof.ai>
@ThoughtProof
ThoughtProof marked this pull request as ready for review October 30, 2026 07:28
@ThoughtProof
ThoughtProof merged commit 280211c into main Oct 30, 2026
1 check passed
@ThoughtProof ThoughtProof mentioned this pull request Oct 30, 2026
5 tasks done
ThoughtProof added a commit that referenced this pull request Oct 30, 2026
Bump version to 0.8.13 and add CHANGELOG entry for #55.
@cursor
cursor Bot deleted the cursor/mandate-label-variants-4bc0 branch October 30, 2026 17:48
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.

2 participants