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.
State Model
Section titled “State Model”| State | Meaning | Consequential Writes |
|---|---|---|
UNORIENTED | No receipt exists for this Codex session. | Blocked by recognized hook paths. |
ORIENTING | Reserved for an evidence-gathering pass in progress. | Not ready. |
READY | The current branch, instruction fingerprint, declaration, and evidence record are coherent. | Read-only for planning/recommendation; bounded implementation writes only with existing authority. |
STALE | Context, branch, instructions, or pass identity changed. | Refresh first. |
BLOCKED | Required evidence or authority is unavailable. | Stop and resolve the blocker. |
COMPLETE | The 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.
Preparing A Receipt
Section titled “Preparing A Receipt”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:
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:
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.
What Is Cached
Section titled “What Is Cached”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.
Runtime Architecture
Section titled “Runtime Architecture”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:
| Module | Responsibility |
|---|---|
contracts.mjs | Receipt vocabulary, canonical arrays, defaults, and storage constants |
repository.mjs | Git identity, repository paths, evidence fingerprints, and receipt file I/O |
sibling.mjs | Generic sibling file comparison |
reference-quality.mjs | Reference declaration normalization, path gates, audits, and reconciliation |
lifecycle.mjs | Receipt preparation, evaluation, checkpoints, closeout, and retention |
cli-options.mjs | Argument 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.
Hook Lifecycle
Section titled “Hook Lifecycle”Project hooks are declared in .codex/hooks.json and resolve their script from the Git root so they work from nested app
directories.
| Event | Wavemap Behavior |
|---|---|
SessionStart | Reports the session’s effective work-pass state and reminds the agent to orient. |
UserPromptSubmit | Does not infer intent or authority from prompt phrases; the agent refreshes after a real conversational transition. |
PreCompact | Marks the receipt stale because the working context used to interpret evidence is changing. |
SubagentStart | Injects the repository and child-evidence boundary into the delegated task. |
PreToolUse | Preserves 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.
Runtime Observability
Section titled “Runtime Observability”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.
Trust And Activation
Section titled “Trust And Activation”Checked-in hooks do not silently become trusted merely because they exist. Bootstrap them with this sequence:
- 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.
- Start a bootstrap session, open
/hooks, inspect the project hook sources, and trust the exact definitions. - Start another fresh session with Wavemap still primary. The trusted
SessionStarthook should report the work-pass state and session identifier; the bootstrap session cannot replay a start event that was skipped before trust. - Run
$govern-work-passand 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.
Recovery And Troubleshooting
Section titled “Recovery And Troubleshooting”- Hook says
UNORIENTED: Run the skill’sinspect, read the required evidence, thenprepareusing the session ID supplied bySessionStart. - Hook says
STALE: Read the reasons fromstatus, refresh the changed evidence, and runrefresh. - A stale hook blocks
cator 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
psorpgrepto 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-verificationvalue 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.mdmanually 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:
node --test .codex/tests/work-pass.test.mjs