REQ-F-015: Validate-Before-Execute Phase Order
Tier: Framework-Automatic | Priority: P0
Source: §14 Argument Validation Before Side Effects
Addresses: Severity: High / Token Spend: Medium / Time: Medium / Context: Low
Description
The framework MUST enforce a strict two-phase execution model for every command: all registered validate() hooks MUST complete successfully before any registered execute() hook is called. The framework MUST make it structurally impossible for a command to initiate a side effect inside a validation hook. Validation errors MUST be collected in full (all errors, not just the first) before reporting.
Acceptance Criteria
- A command with two validation errors reports both in a single invocation (not one per run)
- A command that fails validation never writes to the filesystem, network, or any external state
- The framework raises a registration error if a command registers an
execute()hook that is called before allvalidate()hooks complete - Validation failures always exit with code
2
Schema
Types: response-envelope.md
Validation error responses MUST include "phase": "validation" in the error object, and MUST collect all validation errors before reporting (see errors array):
{
"error": {
"code": "ARG_ERROR",
"message": "Validation failed",
"phase": "validation",
"errors": [
{ "field": "env", "message": "Unknown environment: staging2" },
{ "field": "replicas", "message": "Must be a positive integer" }
]
}
}
Wire Format
Validation failure response (exit code 2):
{
"ok": false,
"data": null,
"error": {
"code": "ARG_ERROR",
"message": "Validation failed",
"phase": "validation",
"errors": [
{ "field": "env", "message": "Unknown environment: staging2" },
{ "field": "replicas", "message": "Must be a positive integer" }
]
},
"warnings": [],
"meta": {
"request_id": "req_01HZ",
"command": "deploy",
"timestamp": "2024-06-01T12:00:00Z"
}
}
Example
Framework-Automatic: no command author action needed. The framework enforces the phase boundary structurally — execute() hooks are never called until all validate() hooks return success.
$ tool deploy --env staging2 --replicas -1
→ exit code: 2
→ stdout: {
"ok": false,
"error": {
"code": "ARG_ERROR",
"phase": "validation",
"errors": [
{"field": "env", "message": "Unknown environment: staging2"},
{"field": "replicas", "message": "Must be a positive integer"}
]
}
}
# No filesystem write occurred — both errors reported in one run
Related
| Requirement | Tier | Relationship |
|---|---|---|
| REQ-F-002 | F | Enforces: exit code 2 guarantee depends on this phase boundary |
| REQ-F-001 | F | Provides: ARG_ERROR (3) and PARTIAL_FAILURE (2) constants used in validation errors |
| REQ-F-004 | F | Provides: response envelope structure that carries the validation error |
| REQ-C-001 | C | Composes: commands must declare ARG_ERROR in their exit code map |