feat: add the free-text flag constraint type text #122

Merged
pti merged 2 commits from feat/text-flag-constraint into main 2026-11-02 20:31:01 +01:00
Owner

Implements design/free-text-sanitization-tier.md. An operator marks one flag of one allow rule type text and its value accepts newlines, tabs, Markdown, punctuation and every shell metacharacter the strict rule refuses. The relaxed value is still refused when it starts with a dash, holds a carriage return or any other control character including ESC, or exceeds 64 KiB. Flag names, positional arguments, placeholder values and all other flag values keep the strict rule byte for byte. The type joins the single-source ConstraintType enum with a new Kind axis Relaxed. whitelist checks the relaxed rule where pattern and integer checks already run so a bad value is a policy denial with a reason, and reports the matched rule text flags in Decision.TextFlags. executor.Run takes that list and applies the classes per token in SanitizeCall. A flag not named there is strict even if an upstream caller forgets and a named one is still control-character and length checked, so a bug can under-relax but never over-relax. text is rejected for a placeholder. wraptool_request_capability accepts text in flag_types, both review UI type selects list it, a text flag MCP parameter description says free text is accepted, and doctor policy.unpatterned-value-flag treats text as a deliberate choice. The seam test gains a third sanitization half. Docs: configuration flag constraints table and a Free-text flags subsection, security argument sanitization, an examples recipe for fj pr create, changelog Added entry. Design status set to implemented with the section 4 checklist ticked and the TODO item closed. This PR body is flat prose because the live server has no text flag yet. Suggested host config after merge: under tools.fj allow rule pr create add flag_constraints with --title and --body of type text. 🤖 Generated with Claude Code

Implements design/free-text-sanitization-tier.md. An operator marks one flag of one allow rule type text and its value accepts newlines, tabs, Markdown, punctuation and every shell metacharacter the strict rule refuses. The relaxed value is still refused when it starts with a dash, holds a carriage return or any other control character including ESC, or exceeds 64 KiB. Flag names, positional arguments, placeholder values and all other flag values keep the strict rule byte for byte. The type joins the single-source ConstraintType enum with a new Kind axis Relaxed. whitelist checks the relaxed rule where pattern and integer checks already run so a bad value is a policy denial with a reason, and reports the matched rule text flags in Decision.TextFlags. executor.Run takes that list and applies the classes per token in SanitizeCall. A flag not named there is strict even if an upstream caller forgets and a named one is still control-character and length checked, so a bug can under-relax but never over-relax. text is rejected for a placeholder. wraptool_request_capability accepts text in flag_types, both review UI type selects list it, a text flag MCP parameter description says free text is accepted, and doctor policy.unpatterned-value-flag treats text as a deliberate choice. The seam test gains a third sanitization half. Docs: configuration flag constraints table and a Free-text flags subsection, security argument sanitization, an examples recipe for fj pr create, changelog Added entry. Design status set to implemented with the section 4 checklist ticked and the TODO item closed. This PR body is flat prose because the live server has no text flag yet. Suggested host config after merge: under tools.fj allow rule pr create add flag_constraints with --title and --body of type text. 🤖 Generated with Claude Code
feat(policy): add the free-text flag constraint type text
Some checks failed
Lint / lint (pull_request) Has been cancelled
Lint / sonarqube (pull_request) Has been cancelled
d60938542d
An operator can now mark one flag of one allow rule `type: text` so its
value accepts prose: newlines, tabs, Markdown, punctuation and every shell
metacharacter the strict rule refuses. The relaxed value is still refused
when it starts with `-`, holds a carriage return or any other control
character (ESC included), or exceeds 64 KiB. Everything else — flag names,
positional arguments, placeholder values and the values of all other
flags — keeps the strict rule byte for byte.

The type lives in the single-source ConstraintType enum with a new Kind
axis, Relaxed, that both consumers read. whitelist checks the relaxed rule
where pattern/integer checks already run, so a bad value is a policy
denial with a reason, and reports the matched rule's text flags in
Decision.TextFlags. executor.Run takes that list and applies the classes
per token in SanitizeCall; a flag not named there is strict even if an
upstream caller forgets, and a named one is still control-character- and
length-checked, so a bug can under-relax but never over-relax. text is
rejected for a placeholder, which sits before `--`.

wraptool_request_capability accepts text in flag_types, both review UI
type selects list it, a text flag's MCP parameter description says free
text is accepted, and doctor's policy.unpatterned-value-flag treats text
as a deliberate choice. The seam test gains a third, sanitization half.

Design: design/free-text-sanitization-tier.md (status now implemented,
§4 checklist ticked). Closes the TODO item.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
docs: record PR #122 on the free-text design and TODO entry
All checks were successful
Lint / lint (pull_request) Successful in 1m20s
Lint / sonarqube (pull_request) Has been skipped
80b8ddfad2
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pti merged commit 25721d9340 into main 2026-11-02 20:31:01 +01:00
pti deleted branch feat/text-flag-constraint 2026-11-02 20:31:01 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
pti/wraptool!122
No description provided.