Skip to content

Work-Pass Governance

A work pass is a bounded unit of consequential architecture recommendation or repository work with an explicit outcome, work intent, operating mode, owner-granted commit cadence, scope, evidence set, commit boundary, and verification policy. The work-pass system turns orientation into visible state without pretending that state can replace engineering judgment or create authority.

StateMeaningConsequential Writes
UNORIENTEDNo receipt exists for this Codex session.Blocked by recognized hook paths.
ORIENTINGReserved for an evidence-gathering pass in progress.Not ready.
READYThe current branch, instruction fingerprint, declaration, and evidence record are coherent.Read-only for planning/recommendation; bounded implementation writes only with existing authority.
STALEContext, branch, instructions, or pass identity changed.Refresh first.
BLOCKEDRequired evidence or authority is unavailable.Stop and resolve the blocker.
COMPLETEThe declared pass was reconciled and verification evidence recorded.Prepare another receipt for another pass.

COMPLETE applies only to the declared scope. It is not a synonym for feature-complete, release-ready, or authorized to publish.

After reading the applicable contract, roadmap, docs, source, and tests, identify the closest implemented analogue for a consequential recommendation. Inspect the layers that make its behavior real, then record the reusable invariants, limitations, and intentional divergences—or the evidence that no analogue exists. Prepare the pass with repository- relative path prefixes and exact evidence files:

Terminal window
node .agents/skills/govern-work-pass/scripts/work-pass.mjs prepare \
--session <session-id> \
--pass <stable-pass-id> \
--outcome <concrete-outcome> \
--intent <planning-recommendation-or-implementation> \
--mode <deliberate-or-agentic> \
--commit-cadence <none-review-each-or-planned-boundaries> \
--scope <path-prefix> \
--evidence <exact-file-already-read> \
--roadmap <active-roadmap> \
--boundary <planned-commit-boundary>

Repeat --scope, --evidence, --boundary, --verify, and --exclusion as necessary. Add --sibling <path> when the pass makes a Wavemap/Waveguide parity claim. The explicit sibling path keeps private workstation layouts out of tracked configuration.

Planning and recommendation receipts require deliberate mode, no commit cadence, and a verification ceiling of none. They do not run tests, builds, or CI-parity commands. Implementation receipts may repeat --verify <narrow-verification-command> to declare narrow verification normally. When a broad local gate is genuinely required, add one exact --authorize-broad-verification <command> entry for each command already authorized by the owner or an explicit repository contract. Recording a command cannot create that authority, and adding arguments later produces a different command that remains denied.

Mode and cadence record authority already granted by the owner; choosing agentic or planned-boundaries cannot grant commit permission. A planned-boundary receipt must name the intended commit boundaries, and the orientation record should include the analogue files that were actually inspected without treating their hashes as a substitute for the analysis.

When references materially define acceptance quality, select --quality-profile reference-led and make its quality contract explicit. Declare each of architecture, behavior, presentation, interaction, accessibility, responsive, and testing with --dimension "<dimension> :: <source|not-applicable> :: <expectation-or-rationale>". Also declare the first bounded slice with --representative-slice-scope, identify the criteria it proves with --slice-criterion, and map each changed architecture family with --analogue "<changed-scope> :: <reference-path|no-analogue> :: <reuse-or-divergence-decision>". An analogue path must be exact inspected evidence; no-analogue records a searched, deliberate local design. Provide the full form architecture contract when the scope contains a front-end form or authoring family. The default standard profile does not require these fields and receives no additional reference-led permission restrictions.

Before editing any declared propagation path, exercise the representative slice and record its evidence:

Terminal window
node .agents/skills/govern-work-pass/scripts/work-pass.mjs checkpoint-slice \
--session <session-id> \
--verification <focused-command-and-result> \
--acceptance-result "<slice-id> :: passed :: <evidence>"

The checkpoint reconciles every slice criterion and runs the focused changed-file convention audit. Failed, blocked, or missing proof keeps propagation denied without staling the receipt. This makes the first implementation a real review boundary rather than allowing a superficially complete local pattern to spread across a family.

The declared outcome and scope bound the pass; its commit count is not a runtime limit. Around five commits is a useful reassessment point for deciding whether the work still serves one goal or should be split into another pass. A somewhat longer chain is appropriate when its methodical boundaries still compose the same outcome, but it must not silently absorb another feature or tangent.

Use status --session <session-id> before editing. Use refresh after re-reading evidence when the pass becomes stale. Use close --verification <command-and-result> only after reconciling the diff, roadmap, and verification evidence. Agentic and commit-authorized passes refuse to close while newly dirty in-scope work remains; commit the authorized boundary or restore the pre-pass state first. A started broad verifier is retained in the receipt and must be reconciled by a close result containing the exact command and its passed, failed, interrupted, or cancelled outcome.

Receipts live under .local/codex/work-pass/ with mode-restricted local files and are ignored by Git. Legacy receipts under .codex/state/work-pass/ remain readable during migration but are not updated. Receipts can contain local paths and branch evidence, so they must not be copied into public docs or commits.

Preparing or refreshing a pass opportunistically removes terminal COMPLETE, STALE, and BLOCKED receipts older than 30 days while preserving the current session and potentially active READY or ORIENTING sessions. Use prune --dry-run to preview the selection or --retention-days <positive-integer> to inspect another retention window.

The receipt caches content hashes, file metadata, branch identity, scope, and the pass declaration. This makes unchanged evidence cheap to identify after a resume and makes changes to AGENTS.md or the ledgers detectable.

It does not cache prose summaries as a substitute for source, and it does not directly control model-provider prompt token caching. Stable prompt prefixes may be cached by an agent platform as an implementation optimization, but repository correctness cannot depend on that opaque behavior. The durable optimization here is progressive disclosure: a concise AGENTS.md points to topic-specific ledgers, skill references, and graduated docs only when they are relevant.

Expected implementation edits do not stale a pass merely because an evidence source file changes. Scope or intent changes still require refresh, and mandatory instruction changes always invalidate readiness.

The CLI, project hook, and focused tests import the stable .agents/skills/govern-work-pass/scripts/lib/work-pass.mjs facade. Keep that public surface stable when reorganizing the runtime so hook trust and downstream callers do not need incidental import changes.

Internal ownership is intentionally directional:

ModuleResponsibility
contracts.mjsReceipt vocabulary, canonical arrays, defaults, and storage constants
repository.mjsGit identity, repository paths, evidence fingerprints, and receipt file I/O
sibling.mjsGeneric sibling file comparison
reference-quality.mjsReference declaration normalization, path gates, audits, and reconciliation
lifecycle.mjsReceipt preparation, evaluation, checkpoints, closeout, and retention
cli-options.mjsArgument parsing and the declarative mapping from CLI options to declarations

Dependencies flow from contracts into repository/reference concerns, then into lifecycle orchestration, and finally through the facade. Do not import the facade back into an internal module or let a lower-level module own lifecycle state; either creates a cycle and expands the change surface.

The work-pass runner deliberately remains dependency-free even though application CLIs use Commander. Governance must be able to bootstrap before workspace dependencies are installed. Its option-to-field mapping is still declarative so a new receipt field has one parsing/default/preservation definition instead of repeated one-off argument plumbing. Preserve the existing command names, option cardinality, errors, JSON output, and end-to-end CLI tests when extending it.

Generic governance files are mirrored byte-for-byte in Waveguide. Repository-specific ledgers and published guidance remain local. Update and verify each repository under its own READY receipt and commit boundary rather than copying a primary receipt across repositories.

Project hooks are declared in .codex/hooks.json and resolve their script from the Git root so they work from nested app directories.

EventWavemap Behavior
SessionStartReports the session’s effective work-pass state and reminds the agent to orient.
UserPromptSubmitDoes not infer intent or authority from prompt phrases; the agent refreshes after a real conversational transition.
PreCompactMarks the receipt stale because the working context used to interpret evidence is changing.
SubagentStartInjects the repository and child-evidence boundary into the delegated task.
PreToolUsePreserves recovery reads, enforces intent/scope, gates reference-led propagation, and gates broad verification.

The Bash guard intentionally uses a conservative read-only allowlist before READY. It includes standalone cat, rg, sed -n, supported Git inspection, and ps/pgrep-style process inspection. git remote get-url (including --push and --all) is available without a receipt, during read-only planning/recommendation, and after compaction so repository identity can be inspected; remote-changing commands still require implementation authority. The exact repository work-pass lifecycle script is admitted through repository-relative or absolute paths so a stale receipt cannot block the evidence or command needed to refresh itself. Shell classification respects quoting: punctuation such as | or ; inside a quoted regex or verification argument remains literal argument content. Actual unquoted pipelines, chaining, redirection, substitution, and background execution remain ineligible; split compound reads into standalone commands.

The same states permit gh pr view and explicit REST GET inspection such as gh api --method GET 'repos/{owner}/{repo}'; -X GET, -XGET and --method=GET are equivalent. API requests accept literal arguments, pagination and output-formatting options. Other methods, conflicting method flags, fields/body/header options, GraphQL, unknown options and shell-expanded API arguments remain outside this exception. The shell-composition guard still applies. These exceptions classify inspection commands; GitHub CLI installation, authentication, repository access and authority for remote changes remain separate requirements.

After READY the guard relies on the receipt, repository instructions, sandbox, and human authorization; arbitrary shell text cannot be classified perfectly. Recognized root-wide tests, builds, lint/typecheck/check commands, recursive pnpm, and Turbo runs require an exact authorized command in an implementation receipt. The apply_patch path receives stronger prefix-scope enforcement because its target paths are explicit.

For a reference-led implementation, that explicit patch path also distinguishes the representative slice from later propagation. Until checkpoint-slice records focused proof, an in-scope patch outside the slice is denied while the receipt remains READY. The checkpoint and final close run a high-signal changed-file audit for paths outside every declared architecture-analogue scope, duplicate imports, raw string unions, unstable React index keys, repeated static CSS-module lookups, declared form-library bypass, and parallel draft state. Those checks are intentionally mechanical and do not substitute for rendered, accessibility, or architecture review.

For an explicit sibling workdir, cwd, or patch path, PreToolUse resolves the repository actually being changed and evaluates that repository’s receipt. A READY Wavemap receipt therefore does not authorize Waveguide work. One patch also cannot span multiple repositories; split it so each target has its own scope, receipt, verification, and commit boundary.

Exact work-pass lifecycle commands remain available when a receipt is missing, stale, or complete so the agent can inspect, prepare, refresh, close, or prune state. Keep recovery invocations as standalone commands: shell control operators make a compound command intentionally ineligible for the conservative pre-READY allowlist.

Lifecycle commands also remain available for READY planning and recommendation receipts. Those intents still block project writes and verification, but closing or inspecting their receipt is governance state management rather than an implementation action and cannot grant new authority.

The hook uses Codex’s systemMessage output for state changes that should be visible to the operator. A session start surfaces the effective state and session identifier. User-prompt wording does not mutate the receipt; the agent refreshes only after the conversation actually changes intent or scope. After compaction, the immediate SessionStart event reports the stale state, so the pre-compaction hook does not emit a second warning for the same transition.

Codex clients surface systemMessage as a warning in the UI or event stream. It is lifecycle feedback, not a normal assistant-authored chat message. Transient statusMessage text may also appear while a hook runs, and a denied tool call shows its specific denial reason.

Successful guard checks remain silent to avoid flooding the conversation. Broad-verification starts are the exception: they are retained as a small receipt audit so an aborted command or compaction cannot be silently mistaken for completion. If SessionStart reports an unreconciled start, inspect live processes before restarting the command or claiming it has stopped. The local receipt is otherwise inspectable state, not a general append-only event log; use the work-pass CLI’s status command when more detail is needed.

Checked-in hooks do not silently become trusted merely because they exist. Bootstrap them with this sequence:

  1. Open a Codex project with the Wavemap repository as its primary folder. Waveguide may be a secondary folder, but the shared parent directory should not be primary when Wavemap governance is expected to run.
  2. Start a bootstrap session, open /hooks, inspect the project hook sources, and trust the exact definitions.
  3. Start another fresh session with Wavemap still primary. The trusted SessionStart hook should report the work-pass state and session identifier; the bootstrap session cannot replay a start event that was skipped before trust.
  4. Run $govern-work-pass and prepare the session-specific receipt before consequential edits.

Hook trust and work-pass readiness have different lifetimes. Codex persists trust against the hook definition’s current hash, so /hooks does not need to be repeated for every session. Review is required again when a hook definition changes, another branch supplies a different definition, or project trust is reset. Work-pass receipts remain session-specific because the model context interpreting the repository evidence is session-specific.

This is an intentional supply-chain boundary. A pull request that modifies .codex/hooks.json, .codex/scripts, the work-pass skill, or custom agent configuration should receive the same scrutiny as other executable developer tooling.

Filesystem access is separate from project discovery. An authorized session can inspect parent or sibling paths, but only the primary project’s AGENTS.md, skills, config, and hooks activate automatically.

  • Hook says UNORIENTED: Run the skill’s inspect, read the required evidence, then prepare using the session ID supplied by SessionStart.
  • Hook says STALE: Read the reasons from status, refresh the changed evidence, and run refresh.
  • A stale hook blocks cat or the exact refresh script: Treat this as a governance regression. The recovery allowlist must admit standalone evidence reads and the repository’s relative or absolute lifecycle script; do not bypass it with an unrelated write-capable tool.
  • A quoted regex or verification note is denied as a pipeline: Treat this as a governance regression. Quoted | and ; are argument text; only real, unquoted shell composition should make the command ineligible.
  • A broad verifier was interrupted or the session compacted: Use ps or pgrep to establish whether a child process remains before rerunning it. Reconcile the exact command and outcome during closeout.
  • A broad verifier is denied: Do not widen or rephrase the command speculatively. Confirm exact human or repository authority, then refresh with that one exact --authorize-broad-verification value if it is genuinely required.
  • Hook says COMPLETE: The prior pass is terminal. Prepare a new pass before consequential work; run that lifecycle command by itself rather than chaining it to another shell command.
  • Commit is denied: Confirm the owner granted commit authority in the current thread, then refresh the receipt with the corresponding cadence. Do not change cadence merely to bypass the gate.
  • Patch is outside scope: Decide whether the path is accidental. If it belongs, expand the declaration deliberately; do not bypass the guardrail.
  • Reference-led propagation is denied: Finish only the declared representative slice, run its focused proof, resolve convention findings, and record checkpoint-slice. Do not widen the slice merely to evade the review boundary.
  • Sibling work is denied: Prepare a READY receipt in the repository actually targeted by the workdir or patch. Do not reuse the primary repository’s receipt.
  • Sibling is unavailable: Record the comparison as unavailable and avoid a parity claim. Continue unrelated work.
  • Old receipts accumulate: Preview prune --dry-run; normal prepare and refresh operations already remove eligible terminal receipts after the default 30-day retention window.
  • Hooks are unavailable: Follow .agents/work-pass-ledger.md manually and state that the pass is manually oriented.
  • A hook appears wrong: Stop trusting the result as policy, inspect the checked-in script and tests, and fix the tooling in a separately reviewed pass.

Focused enforcement tests live at .codex/tests/work-pass.test.mjs and run with:

Terminal window
node --test .codex/tests/work-pass.test.mjs