VoltFlow is a Codex workflow plugin for teams that want TDD, small diffs, useful subagents, and a deployment gate without turning every change into a ceremony.
It has one skill and one dependency-free Node hook. Session state lives in protected PLUGIN_DATA; it doesn't add ledgers or workflow files to the target repository. If a sandboxed controller command cannot access that directory, rerun the exact command with external permission instead of moving approval state into the worktree or temporary storage.
VoltFlow requires Node 20 or newer and Git. Add the Team Volt marketplace, then install the plugin:
codex plugin marketplace add Team-Volt/voltflow
codex plugin add voltflow@team-voltStart a new Codex task, run /hooks, inspect the VoltFlow hook commands, and trust them. A new task is required for Codex to load the installed skill and hooks.
Simple, low-risk edits with no executable behavior or deployment intent can skip the workflow before the first change. The agent records a reason with the controller, then VoltFlow stands down for that prompt: no TDD, validation, fingerprint, review, or Stop warning. Skipping never grants deployment approval.
VoltFlow classifies work as trivial, standard, or high. Each tier has a minimum review mode: self-review for trivial work, one composite reviewer for standard work, and two independent lanes for high-risk work. An active workflow can be upgraded, but it cannot be downgraded to bypass its gate.
Behavioral changes follow RED, GREEN, REFACTOR. The hook allows test edits before RED but blocks production edits until it has observed a failing test or the agent records a manual reproduction. Later test edits clear the current production-edit authorization without erasing the fact that RED occurred, so final review does not demand a fake rerun against already-fixed code. It also detects file changes made through shell commands after they run, so changing the tool name does not bypass evidence invalidation. Only a successful, directly executed test command records automated validation. Prose, generated output, and metadata-only work use tdd=exempt with the closest useful validation.
Validation must exercise each changed observable layer. Syntax checks cover syntax only; user-facing web changes need one real browser interaction at a supported viewport, or the final result must mark browser behavior as unverified.
Review receipts use one-time lane assignments and are tied to a Git fingerprint containing HEAD, staged and unstaged diffs, untracked-file content, executable mode bits, and configured ignored inputs. A failed lane or later edit invalidates earlier passes. If Git cannot produce a complete fingerprint, the gate fails closed instead of reusing a partial value.
The user can overrule the gate in ordinary language by clearly directing VoltFlow to deploy or release despite the missing gate, review, or approval. Questions, hypotheticals, negated instructions, and ordinary deploy requests do not arm an override. An override works once and only for the current fingerprint, and the agent can't create one through the controller CLI.
The main session selects a model and reasoning effort for each concrete assignment from the capabilities exposed by the current Codex installation. It chooses by difficulty, ambiguity, risk, and verifiability rather than pinning a model family to a role.
Mechanical work tends toward the fastest capable model at low or medium effort. Bounded implementation tends toward a balanced coding model at medium or high effort. Ambiguous integration, holistic review, and named high-risk boundaries justify stronger models or more reasoning. Independent reviewers should use a different model or reasoning configuration from the author when one is available.
Direct model and reasoning_effort overrides are used when the active spawn schema supports them. Otherwise VoltFlow uses the closest matching profile or inherits the parent only when its effort is known and not ultra; these fallbacks report routing degraded. If no compliant route exists, VoltFlow refuses the spawn and reports routing blocked. Explicit user selections are never silently substituted or downgraded.
VoltFlow never selects ultra reasoning for a subagent. An explicit ultra request is rejected as a policy conflict rather than replaced with another effort.
The complete selection rubric is in routing.md. Before each spawn, the main session reports the chosen model, reasoning effort, and a one-sentence reason. The assignment records them, and the subagent repeats them in its first update, so the route remains understandable inside the subagent session even when Codex hides spawn metadata.
VoltFlow does not call a subagent API from its Node runtime. The main Codex agent uses whichever host schema is available:
- Multi-agent v1 uses the namespaced
multi_agent_v1.spawn_agentfields, including directmodelandreasoning_effortoverrides. - Multi-agent v2 uses the flat
spawn_agentshape withtask_name,message, andfork_turns: "none". VoltFlow never uses full-history inheritance for a v2 spawn. It passes model settings only when that schema exposes them; otherwise it uses a verified non-ultra profile or parent, or refuses the spawn.
The lifecycle hooks consume SubagentStart and SubagentStop, so review receipts are independent of the spawn API version. Both host schemas are supported; the active schema still determines whether direct model and reasoning overrides are available.
VoltFlow supports subagents working in linked Git worktrees under one Codex task. The main agent still creates each worktree, assigns its branch and path, integrates the result, and removes the worktree when it is no longer needed.
Command tools normally select a worktree from their workdir, while edit tools use the paths they change. Some hosts report a subagent's commands with the parent cwd and no workdir; the controller binds that agent ID to its assigned worktree when the subagent runs the injected status command there. A linked worktree inherits the active tier, TDD mode, and review mode, but keeps its RED, validation, review, and deployment approval state separate.
Run controller commands from the worktree they apply to. Before merging a worker, run integrate --from <worker-worktree> in the integration worktree; VoltFlow accepts only current, validated evidence from the same workflow. Validate and review the merged result afterward. Review lanes that share a worktree run one at a time so generated test artifacts cannot stale both fingerprint-bound receipts.
To use v2 with per-subagent model and reasoning controls, add this to ~/.codex/config.toml:
[features.multi_agent_v2]
enabled = true
hide_spawn_agent_metadata = false
tool_namespace = "agents"If the file has a top-level model_catalog_json entry that points to a v1 catalog, remove that entry. Restart Codex and open a new task after changing the configuration. VoltFlow will set fork_turns: "none" on every v2 spawn so explicit model and reasoning_effort values are valid.
The prompt hook supplies the real plugin path, data path, and session id. These examples show the shape:
node <plugin-root>/scripts/voltflow.mjs start \
--data-dir <plugin-data> --session <session-id> \
--tier standard --tdd required --review single
node <plugin-root>/scripts/voltflow.mjs skip \
--data-dir <plugin-data> --session <session-id> \
--evidence "single prose edit with no deployment intent"
node <plugin-root>/scripts/voltflow.mjs red \
--data-dir <plugin-data> --session <session-id> \
--evidence "targeted reproduction failed for the expected reason"
node <plugin-root>/scripts/voltflow.mjs integrate \
--data-dir <plugin-data> --session <session-id> \
--from <validated-worker-worktree>
node <plugin-root>/scripts/voltflow.mjs validate \
--data-dir <plugin-data> --session <session-id> \
--evidence "npm test"
node <plugin-root>/scripts/voltflow.mjs review \
--data-dir <plugin-data> --session <session-id> \
--lane composite
node <plugin-root>/scripts/voltflow.mjs approve --self \
--data-dir <plugin-data> --session <session-id> \
--evidence "final diff checked against the request"
node <plugin-root>/scripts/voltflow.mjs gate \
--data-dir <plugin-data> --session <session-id>Give the token returned by review to that reviewer. Its final line must be VOLTFLOW_REVIEW: PASS <lane> <token> or VOLTFLOW_REVIEW: FAIL <lane> <token>.
Put the final gate command immediately before the provider's deploy command in the same local session or deploy wrapper. Plugin hooks are useful guardrails, but PreToolUse cannot intercept every possible side effect. VoltFlow does not yet provide a portable signed receipt for a separate remote CI machine, so do not describe the local state file as an authoritative remote boundary.
Built-in matching covers common package publishing, cloud deploy, infrastructure apply, release, and container push commands. Add project commands or MCP tools with .voltflow.json:
{
"deployPatterns": ["^make promote$"],
"deployTools": ["^mcp__cloud__promote$"],
"fingerprintPaths": ["dist/release-manifest.json"]
}Deploy values are case-insensitive regular expressions. fingerprintPaths contains exact relative paths for ignored material inputs; directories and globs are not expanded. Invalid configuration is reported in the workflow context and command execution fails closed until it is fixed.
Incomplete workflow evidence never replaces the answer Codex already wrote. The Stop hook reports the missing evidence as a system message, marks the task inactive, and leaves deployment denied until a later task validates and reviews the current fingerprint.
npm test