REQ-F-004: Consistent JSON Response Envelope
Tier: Framework-Automatic | Priority: P0
Source: §2 Output Format & Parseability
Addresses: Severity: Critical / Token Spend: High / Time: Medium / Context: High
Description
The framework MUST wrap all command output in a standard JSON envelope. The envelope MUST always contain: ok (boolean), data (the command's primary output — present even when null or empty array), error (null on success, structured object on failure), warnings (array, may be empty), and meta (object with framework-populated fields). The schema of this envelope MUST NOT vary based on result count, command type, or success/failure state — the same top-level keys MUST always be present.
Acceptance Criteria
- A JSON schema validator for the envelope passes on every command's stdout output in JSON mode
datakey is present and non-absent on both success and failure responseserrorkey is present on all responses (null on success, structured object on failure)- Single-result and multi-result commands produce structurally identical envelopes
Schema
Types: response-envelope.md
Wire Format
Full envelope structure — all five top-level keys are always present regardless of outcome:
Success response:
{
"ok": true,
"data": { "id": "deploy-42", "status": "complete" },
"error": null,
"warnings": [],
"meta": { "duration_ms": 340, "request_id": "req_abc123" }
}
Failure response (same shape):
{
"ok": false,
"data": null,
"error": {
"code": "NOT_FOUND",
"message": "Cluster 'prod-eu' not found",
"retryable": false
},
"warnings": [],
"meta": { "duration_ms": 8 }
}
Example
Framework-Automatic: no command author action needed. The framework constructs the envelope after every command handler returns, deriving ok from the exit code and always emitting all five fields.
# Command handler returns successfully
handler returns: { id: "deploy-42", status: "complete" }
Framework wraps:
ok = true (derived: exit code is SUCCESS)
data = handler's return value
error = null
warnings= []
meta = { duration_ms: 340 }
# Command handler raises NOT_FOUND
Framework wraps:
ok = false (derived: exit code is NOT_FOUND)
data = null
error = { code: "NOT_FOUND", message: "...", retryable: false }
warnings= []
meta = { duration_ms: 8 }
Related
| Requirement | Tier | Relationship |
|---|---|---|
| REQ-F-001 | F | Provides: ok is derived from whether the exit code is SUCCESS (0) |
| REQ-F-003 | F | Composes: envelope is emitted whenever JSON mode is active |
| REQ-C-013 | C | Composes: error object structure is declared by REQ-C-013 |
| REQ-O-041 | O | Wraps: manifest output uses this envelope as its outer container |