PreRunE Validate was skipped by direct RunE / proxy calls. Run both hooks
in one wrapper (Validate first), add pat chmod Validate, let Sheet outer
guards call ContractValidate first, and assert declare user_required
leaves expose Validate, required flags, or CallTool-defer confirm.
Co-authored-by: Cursor <cursoragent@cursor.com>
Without Validate, DeclareLeafMetadata no longer confirms before RunE-local
required checks. Wrap deps.Caller so the first MCP CallTool runs
ConfirmSafety; Validate-backed leaves keep confirm-after-PreRunE.
Co-authored-by: Cursor <cursoragent@cursor.com>
DeclareLeafMetadata user_required wraps were confirming before RunE-local
checks, so illegal calls got confirmation_required instead of real errors.
Allow Validate on PreRunE, migrate event stop and drive publish checks, and
lock the Sheet dual-gate transitional state.
Co-authored-by: Cursor <cursoragent@cursor.com>
- schemaSafetyFromDecl: drop the now-unreachable nil return; the tier
fill always produces a complete block for a declared Schema
- validateDispatchDecl: panic when ConfirmFirst is set without Risk —
it orders a confirmation that does not exist, and for declared-Schema
writes an empty Risk would silently publish the read safety tier
- RFC: document the boundary that write commands must declare Risk
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Risk (runtime confirmation) and Safety (schema metadata) are two
independent enums composed at embed time: explicit SafetyDecl fields >
CommandSpec.Safety tier > Risk.SafetyDefault(). The tier fill now also
covers idempotency, so an enum-only declaration is self-sufficient and
validateSchemaDecl no longer needs safety completeness checks.
devapp reclassifies its write leaves by reversibility: reversible
mutations declare LeafSafetyWrite (risk high->medium), create/robot
submit/version create declare LeafSafetyHighWrite, and delete/version
publish declare LeafSafetyDestructive (publish effect
write->destructive). Shared hand-written safety constants are deleted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- SchemaDecl on CommandSpec/LeafSpec declares the final ToolSpec payload;
framework converts in-process (no JSON bridge) and Schema assembly
pass-throughs it.
- Assembly fails closed on declared identity mismatched with the bound
entry and on reviewed fields in the declaration payload.
- RFC/homology/AGENTS docs pin declare=final-source, safety precedence
Final > Risk > gate, and light runtime write semantics.
Co-authored-by: Cursor <cursoragent@cursor.com>
Lift business flags/const params out of Call/PostMount, add typed
flag defaults and policy gates, and realign the RFC acceptance bar to
"no Execute/Call body exists only to assemble params".
Co-authored-by: Cursor <cursoragent@cursor.com>
The single Dispatch hook assumed every command is one MCP call, so the
Shortcut projection could only ever describe a command, never run it. Split
dispatch into Invoke (assembled toolArgs) and Orchestrate (multi-step), keep
RunE as the escape hatch, and reject specs that declare anything other than
exactly one at construction time. Ctx gives both hooks the same typed flag
accessors so orchestration no longer reaches for framework-specific plumbing.
Catalog output stays byte-identical.