REQ-C-012: Commands with Network I/O Support --timeout
Tier: Command Contract | Priority: P0
Source: §11 Timeouts & Hanging Processes
Addresses: Severity: Critical / Token Spend: High / Time: Critical / Context: Low
Description
Every command that performs network I/O or any potentially long-running blocking operation MUST accept --timeout <duration> and --connect-timeout <duration> flags (where applicable). The framework registers these flags automatically for commands that declare has_network_io: true. Command authors MUST pass the configured timeout to all network calls; the framework MUST enforce that no network call is made without a finite timeout.
Acceptance Criteria
- A command with
has_network_io: truealways accepts--timeout - The configured
--timeoutvalue is passed to all network requests made by the command - A network call with no explicit timeout is flagged by the framework's static analysis rule
--timeout 0explicitly opts into no timeout (must be a deliberate choice, not the default)
Schema
Types: manifest-response.md · exit-code.md
The has_network_io boolean and the standard --timeout / --connect-timeout flags appear in the command's schema entry.
{
"has_network_io": {
"type": "boolean",
"description": "True if the command makes outbound network connections or long-running blocking I/O calls"
}
}
Wire Format
$ tool deploy --target staging --schema
{
"command": "deploy",
"has_network_io": true,
"flags": {
"target": { "type": "string", "required": true, "description": "Target environment name" },
"timeout": { "type": "string", "required": false, "default": "300s", "description": "Maximum total operation time; 0 = no timeout" },
"connect-timeout": { "type": "string", "required": false, "default": "10s", "description": "Maximum time to establish each connection" }
},
"exit_codes": {
"0": { "name": "SUCCESS", "description": "Deployment completed", "retryable": false, "side_effects": "complete" },
"10": { "name": "TIMEOUT", "description": "Deployment timed out after --timeout", "retryable": false, "side_effects": "partial" }
}
}
Example
A command that makes HTTP calls declares has_network_io: true at registration. The framework auto-registers --timeout and --connect-timeout and enforces that they are passed to all network calls.
register command "deploy":
danger_level: mutating
has_network_io: true
exit_codes:
SUCCESS (0): description: "Deployment completed", retryable: false, side_effects: complete
TIMEOUT(10): description: "Deployment timed out after --timeout", retryable: false, side_effects: partial
execute(args):
# Framework injects args.timeout and args.connect_timeout from flags
client = http_client(
timeout=args.timeout,
connect_timeout=args.connect_timeout,
)
client.post("/deploy", body={target: args.target})
# Any call without an explicit timeout → framework static analysis warning
Related
| Requirement | Tier | Relationship |
|---|---|---|
| REQ-F-011 | F | Provides: framework sets the default timeout value used when --timeout is not supplied |
| REQ-F-012 | F | Enforces: framework emits TIMEOUT (10) and structured JSON error when the timeout expires |
| REQ-C-001 | C | Composes: TIMEOUT (10) must be declared in the command's exit_codes map |
| REQ-C-008 | C | Composes: on timeout, multi-step commands emit completed_steps and failed_step via the step manifest |