-
-
Repository intelligence, committed to the repo: workspace.json feeds a deterministic gate, with an advisory reviewer in orbit.
-
Three planes: describe (committed), enforce (block-only hook), advise (read-only GPT-5.6). The gate can deny; it never certifies safe.
-
A deterministic DENY on checkout.ts with its evidenced co-change partner, stripe.ts, omitted from the change.
-
Git remembers commits. workspace.json remembers what breaks together.
Inspiration
A checkout change can compile, pass its tests, and still repeat a failure pattern the repository has already lived through.
The missing information may already exist in git history: a revert, an incident, or the repeated fact that two files changed together. But that history is rarely presented as structured evidence at the moment an agent decides what to edit.
That is the gap I wanted to address. Coding agents are strong at understanding the source tree in front of them. They are not automatically given a portable account of what the repository has learned over time: which files are fragile, which changes repeatedly travel together, and what evidence supports those claims.
In the Billfold demonstration, a request to round checkout totals initially produced a checkout-only patch. Before that patch landed, the hook identified src/webhooks/stripe.ts as a recorded co-change partner and denied the incomplete changeset. Codex then inspected the webhook and the repository history before proceeding.
workspace.json makes that history committed, inspectable, and actionable before the next edit lands.
What it does
workspace.json for Codex makes repository history available as portable evidence and enforces selected evidence-backed constraints before an edit is applied.
It reads workspace.json, an open and committed format describing repository structure, fragile files, co-change relationships, and the evidence supporting those records. It exposes that information to Codex through three separate planes.
Evidence. Read-only MCP tools answer questions before an edit: Is this file fragile? What happened to it? Which files have historically changed with it?
Every signal receives an evidence tier derived mechanically from its records:
ASSERTED: a claim exists, but no evidence record is attached. OBSERVED: something was recorded. VERIFIED: a whitelisted read-only command was rerun locally and reproduced the recorded output.
No producer, model, or human can directly assign a stronger tier.
Enforcement. A PreToolUse hook runs before Codex applies an apply_patch edit. When a file has OBSERVED or VERIFIED fragility evidence and the proposed changeset omits a recorded co-change partner, the hook denies the patch and cites the supporting evidence.
This is not a warning that the model can explain away. It is a deterministic block before the edit lands.
The hook enforces recorded path coverage. It does not claim that every partner always requires a functional modification, and it does not determine whether a partner edit is semantically sufficient.
Judgment. An optional read-only GPT-5.6 reviewer examines a completed diff and reasons about questions that deterministic rules cannot answer: whether the fix is coherent, whether a partner modification is substantive, and whether the change introduces another visible risk.
Its result is stored as an attributed review receipt, including the provider, model, scope, and response. It is always advisory. It never controls the hook, and a PASS result is never presented as a safety certification.
That separation is deliberate. Enforcement is mechanical, so it cannot be persuaded. Judgment is probabilistic, so it does not own the gate. Missing evidence is reported as missing or unknown, never as safe.
How I built it
The MCP evidence reader, deterministic hook, and editor surface run locally against one committed .agents/workspace.json file. They require no hosted workspace service and send no telemetry.
The optional GPT-5.6 review is a separate, explicit action. It sends only the diff supplied by the user to the configured OpenAI or OpenRouter endpoint and stores the resulting receipt locally. Deterministic enforcement continues to work without an API key.
I built the integration in Codex, and the first thing I did was try to make the hook fail.
Before writing the real enforcement rule, I connected a hook that denied every edit. I asked Codex to modify a file and watched the edit stop. I disabled the hook and watched the same class of edit proceed. Only after observing both the red path and the permitted path did I trust the mechanism enough to build on it.
That methodology mattered more than any individual implementation detail: a guard whose blocking path has never been observed is not yet a guard.
The broader system has three public pieces:
agents-audit is the current reference producer and validation tool; @workspacejson/codex-mcp consumes the evidence inside Codex; Billfold is the controlled public fixture used to reproduce the demonstrated behavior. Challenges I ran into
My own submission repeatedly failed the standard the product was intended to enforce.
I used adversarial review throughout the build, and within seventy-two hours it found five cases where the repository was green but the boundary behavior was wrong.
One response path could weaken a deny during payload truncation. The test fixtures were never large enough to reach that boundary.
A malformed workspace.json caused the hook to fail open without clearly informing either the human or the agent that repository intelligence was unavailable.
A payload-size limit protected the human-readable text response while leaving the structured response—the channel the client actually consumes—unbounded.
A committed Codex configuration launched the installer instead of the MCP server, so opening the repository broke the handshake.
Two path-matching implementations had drifted apart, allowing a partially matching path to weaken a denial into a warning.
The test suite was green in every case. The tests simply did not exercise the boundary where the product’s claim lived.
GPT-5.6 also showed me that my original demonstration proved the wrong thing.
I had built a fixture with real history, a failing test, a corrective commit, and clean red/green reproduction. The reviewer pointed out that the failing test demonstrated a route regression; it did not prove that omitting the named co-change partners caused the failure.
The fixture correlated with the claim instead of establishing it.
I rebuilt the public fixture around a recorded co-change relationship with no direct import or shared symbol connecting the files. I also narrowed the claim. I do not present the demonstration as proof that workspace.json universally improves a model’s independent reasoning. I present what I can reproduce: an incomplete, evidence-backed changeset is denied before application, the agent is forced to inspect the recorded relationship, and the completed change is verified and reviewed separately.
That correction cost me a day, and it was the most valuable result of the build.
What I learned
The failure pattern I kept finding in my own work is the same one this product is designed to expose.
A green test suite is evidence, not a conclusion. Verification that checks wiring does not necessarily check truth. A control whose failure path has never been exercised should not be treated as proven.
I found one useful predicate:
If something is presented as a measurement but cannot change in response to the condition it claims to measure, it is decoration.
A confidence value hardcoded to a constant, a tooltip that always reports the same rollback count, and a drift check that swallows its own failure can all look like measurements without measuring anything.
I designed the evidence model around that constraint.
Evidence tiers are derived mechanically from records. A producer cannot label its own claim VERIFIED. The consumer must rerun a read-only command and reproduce the recorded output.
The system can justify a bounded denial or warning. It deliberately cannot emit a general safety approval. A read-only check can reproduce specific evidence, but it cannot prove the absence of every possible risk. Absence of recorded risk is therefore reported as absence, not as safety.
Verify it yourself
There are two repositories and two different things to verify.
Plugin regression suite
Repository: workspace-json/codex-mcp
git clone https://github.com/workspace-json/codex-mcp.git cd codex-mcp npm ci npm run verify
npm run verify runs the repository-structure check, generator-version check, type checking, linting, build, unit tests, and smoke tests.
The documentation identifies which claims are automated, which are architectural invariants, and which were observed against a real Codex client.
Live enforcement
Repository: workspace-json/billfold
git clone https://github.com/workspace-json/billfold.git cd billfold npm install npx @workspacejson/codex-mcp install --with-hook
Restart Codex in the repository and use this prompt:
Finance wants checkout totals rounded to the nearest dollar before we charge. Update the checkout route so subtotals like 1234 cents charge as 1200.
The initial checkout-only apply_patch is denied before application. The denial names src/webhooks/stripe.ts as the omitted co-change partner and cites dated evidence recorded from Billfold’s own git history.
The hook then forces that relationship to be inspected and accounted for before the changeset can proceed.
npm test passes without understanding that historical relationship. That is intentional: the ordinary test suite validates current behavior, while the hook enforces a repository-history constraint that the tests do not encode.
Including a partner path clears the path-membership omission. It does not, by itself, prove that the partner modification is semantically sufficient. That judgment remains the responsibility of tests, human review, and the optional GPT-5.6 reviewer.
What’s next for workspace.json for Codex
Today, workspace.json primarily describes what the repository has learned from its past.
The next problem is concurrent work in the present.
When several agents operate in separate worktrees, two changes can each be locally correct, merge without a textual conflict, and still compose into an unsafe result because neither agent or reviewer saw both diffs together.
Recorded co-change evidence can expose that composition risk. A future consumer could compare active changesets across worktrees, identify historically coupled areas being modified independently, and request joint review before those changes converge.
That is the direction I plan to pursue: moving from repository memory before one edit to repository awareness across many simultaneous edits.
Built With
- codex
- gpt-5.6
- json-schema
- model-context-protocol
- node.js
- typescript
- vitest
- vs-code
- workspace.json
- zod
Log in or sign up for Devpost to join the conversation.