Skip to content

feat(ocap): NamedPermissionPreset can clamp fs_read — clamp-grammar fix (#755)#768

Closed
hartsock wants to merge 1 commit into
feat/ocap-5-team-verifyfrom
feat/ocap-6-role-clamp
Closed

feat(ocap): NamedPermissionPreset can clamp fs_read — clamp-grammar fix (#755)#768
hartsock wants to merge 1 commit into
feat/ocap-5-team-verifyfrom
feat/ocap-6-role-clamp

Conversation

@hartsock

Copy link
Copy Markdown
Member

OCAP enforcement-floor stack — PR 6 of 8 · epic #749

Stacked on step 5 (#765). Review/merge after #765. Full order: #749.

What this does

M6 grammar gap: a preset couldn't narrow fs_read (to_caveat_profile hardcoded ScopeSpec::default()=All). NamedPermissionPreset now has an optional fs_read: Option<ScopeSpec> (serde default None ⇒ All — every existing preset byte-for-byte unchanged); a preset can now narrow fs_read when specified. Deferred (documented in-code): valid_for_generation (causal-window axis — follow-up) and default-deny (the empty clamp is correctly meet-identity; default-deny belongs in step 8's subtask-clamp derivation, not the general default).

Test plan

fs_read_clamp_narrows_reads (red on today — fs_read always All; green after) + back-compat (omitted ⇒ All) + config-parse. RED verified by revert. just check green. (Mechanical: fs_read: None added to 2 newt-tui test-fixture struct literals — unavoidable for a new field, behavior-preserving.)

Fixes #755. Part of #749. Refs #739, #741.

🤖 Generated with Claude Code

…ix (#755)

OCAP enforcement-floor stack (#749, PR 6/8; stacked on #765). The M6 grammar gap: a preset could
not narrow fs_read (to_caveat_profile hardcoded ScopeSpec::default()=All), even though
CaveatProfile/Caveats can. NamedPermissionPreset now has an optional fs_read: Option<ScopeSpec>
(serde default None => All, so every existing preset is byte-for-byte unchanged); to_caveat_profile
lowers it (Some narrows reads). A preset CAN now narrow fs_read when specified.

Deferred (documented in-code): valid_for_generation (a causal-window axis, not a preset clamp —
follow-up); the default-deny for un-annotated subtasks (an empty clamp is correctly meet-identity;
default-deny belongs in step 8's subtask-clamp derivation, not role_profile's general default —
flipping it would break back-compat for every preset consumer).

TDD: fs_read_clamp_narrows_reads (red on today — fs_read always All; green after) + back-compat
(omitted fs_read => All) + config-parse. RED verified by revert. just check green.

Mechanical: adding the field required `fs_read: None` in 2 exhaustive struct literals (newt-tui test
fixtures); behavior-preserving (consumer literals use ..default()).

Fixes #755. Part of #749. Refs #739, #741.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hartsock

Copy link
Copy Markdown
Member Author

Superseded by #781 — steps 3–6 collapsed onto current main after #751 merged + auto-closed the stack. Code is identical; review/merge there.

@hartsock hartsock closed this Jun 29, 2026
@hartsock hartsock deleted the feat/ocap-6-role-clamp branch June 29, 2026 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ocap Object-capability / authority-security; pending full design review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant