# falsegreen
[](https://crates.io/crates/falsegreen)
[](LICENSE)
**Independent verification for coding agents.**
FalseGreen gives your AI coding agent an independent completion-authority loop. When the agent says "I'm done," FalseGreen runs your frozen acceptance criteria against an immutable source snapshot and tells the agent whether the work actually passes — instead of trusting the agent's own self-assessment.
This crate is the **client shim** — a tiny native binary that:
- speaks STDIO MCP to your coding agent (Codex, Claude Code, Cursor, etc.)
- authenticates one individual principal with an opaque FalseGreen access token
- snapshots the active local workspace before source-sensitive tools
- forwards tool calls over HTTPS to `mcp.falsegreen.com`
- stores a stable opaque device identity and its FalseGreen session locally
The verification, entitlement, and billing systems live server-side. This binary
contains no verification, subscription, price, or billing logic.
## Install
```sh
cargo install falsegreen
```
## Quick start
```sh
# 1. Activate this device and exchange your enrollment credential for a session
falsegreen login --token YOUR_FALSEGREEN_KEY
# 2. Install into your agent
falsegreen install codex # Codex CLI & Codex in VS Code (STDIO)
falsegreen install github-copilot # GitHub Copilot in VS Code (local STDIO)
falsegreen install claude-code # Claude Code (local STDIO)
falsegreen install opencode # OpenCode (local STDIO)
falsegreen install cursor # Cursor (local STDIO)
# 3. Verify
codex mcp list # for Codex
```
The agent launches `falsegreen mcp` locally so it can snapshot the workspace
before forwarding each source-sensitive operation.
Each installation has stable, independent principal and device identities.
Enrollment and Platform validation happen on the FalseGreen server; the shim
retains only opaque local identifiers and its `fgs_` session. Principal/device
count is not a commercial limit.
| `falsegreen_create_task` | Register a new task with a goal |
| `falsegreen_get_plan_schema` | Get the structured task-plan schema |
| `falsegreen_save_plan_draft` | Save an explicit plan revision |
| `falsegreen_validate_plan` | Validate plan structure and dependencies |
| `falsegreen_freeze_plan` | Freeze the plan before contract drafting |
| `falsegreen_get_plan` | Retrieve the current draft or frozen plan |
| `falsegreen_save_contract_draft` | Draft acceptance criteria |
| `falsegreen_validate_contract` | Validate the contract draft |
| `falsegreen_freeze_contract` | Freeze the contract and return its stable, unconsumed Verification Job ID |
| `falsegreen_get_assignment` | Get compact immutable requirements |
| `falsegreen_check_completion` | Start the independent verifier; hosted runs return a polling state |
| `falsegreen_verify` | Durably start full or focused verification and return a run ID immediately |
| `falsegreen_get_status` | Poll a durable run ID or task status without uploading the workspace |
| `falsegreen_get_verification_artifacts` | Get source-bound JSON attestation and PR report |
| `falsegreen_get_attestation_verification_key` | Get the public Ed25519 verification key |
| `falsegreen_get_repair_feedback` | Get failure details from the last run |
| `falsegreen_get_contract_schema` | Get the JSON schema for contracts |
| `falsegreen_get_contract` | Get the frozen contract |
| `falsegreen_mark_unresolved` | Mark a task as unresolved |
| `falsegreen_close_task` | Close a stale non-accepted task without claiming acceptance |
| `falsegreen_list_tasks` | List task lifecycle state and cleanup eligibility |
For larger tasks, planning is an optional phase between task creation and
contract drafting. A plan stores outcome-oriented work items, their dependency
DAG, observable acceptance conditions, required evidence, omission risks, and
overall acceptance. Draft revisions are retained explicitly. Freezing writes a
content-addressed immutable plan; contract criteria must map every planned
acceptance ID and planned evidence ID to required executable criteria before
the contract can freeze.
Once contract drafting begins, the plan cannot be revised. Simple tasks may
continue directly to contract drafting without a plan.
## How it works
```
Coding agent (Codex, Claude Code, Cursor, ...)
│
│ STDIO MCP (JSON-RPC over stdin/stdout)
▼
falsegreen ← this binary
│
│ workspace snapshot upload + MCP calls (HTTPS + X-API-KEY)
▼
mcp.falsegreen.com
│
├─ authenticate one distinct FalseGreen principal
├─ freshly authorize the organization's Platform before a new paid run
├─ resolve organization and tenant state server-side
└─ run verification engine
│
├─ materialize the uploaded workspace source
├─ snapshot an immutable source artifact
├─ execute frozen acceptance criteria
└─ return accepted / incomplete / unsafe
```
## Verification artifacts
`falsegreen_verify` commits an authority-bound request before asynchronous work
starts. Its response contains a durable `run_id`; poll that ID with
`falsegreen_get_status` until it leaves `QUEUED` or `RUNNING`. Reusing the same
explicit `idempotency_key` returns the existing run instead of starting duplicate
verification. A lost HTTP/MCP response or stopped poller does not cancel work.
After a controller restart, unrecoverable queued/running work fails closed as an
infrastructure failure and is never reconstructed as a verifier result.
If verification returns `FALSEGREEN_JOB_REQUIRED`, keep the current task and
frozen contract exactly as they are. Tell the user to buy a FalseGreen Job at
the provided FalseGreen site URL. Do not create a replacement task, abandon the
task, change the contract, or refreeze requirements. After purchase, retry
verification on that same task and frozen contract.
Every completed run with a retained source snapshot produces two stable files:
- `falsegreen-attestation.json` is canonical machine-readable evidence using
schema `falsegreen.attestation/v1`.
- `falsegreen-report.md` is a concise report suitable for attaching to a pull
request. FalseGreen does not post it to GitHub automatically.
The server also issues one opaque, shareable report URL. Its versioned canonical
payload includes the authoritative verdict, criteria/counts, verified source
identity, frozen contract identity, and the exact `server_generated_pr_summary`.
The payload digest is embedded in the existing FalseGreen attestation before it
is signed. The shim returns `report_id`, `report_url`, `verified_source_identity`,
and `server_generated_pr_summary` verbatim; it never creates a verdict.
Retrieve both with `falsegreen_get_verification_artifacts`. The optional
`run_id` selects a historical run; otherwise the task's latest completed run is
used. The response includes both artifacts inline, their filenames, status,
source digest, and signing status.
Execution provenance is captured automatically for supported runtimes. Python
commands retain the interpreter version. Cargo and rustc commands retain Cargo
and compiler versions, the exact `rustc -Vv` identity, host target, and tool
digests. Ruby, Bundler, Rails, and Rake commands retain the exact Ruby and
Bundler versions and executable digests. The compact values are also shown in
the Markdown report.
Ruby projects use a frozen `Gemfile.lock`. FalseGreen downloads the exact
RubyGems artifacts in its networked dependency zone, verifies and retains their
content manifest, then runs `bundle install --local` in a networkless build
zone. Workspace-local Bundler `PATH` sources are accepted only when their
normalized paths remain inside the immutable source snapshot; their contents
are bound by the source digest. Git and plugin sources remain rejected.
Verification remains networkless and receives the prepared bundle through
`BUNDLE_PATH`. Rails commands such as `bundle exec rails test`, `bundle exec
rake test`, and repository binstubs are supported; native gems build against the
image's Ruby headers and common database/system libraries.
Go modules are downloaded without compiling repository packages in the
network-constrained dependency zone. Verification receives a private module
cache and always runs with `GOTOOLCHAIN=local`, `GOPROXY=off`, and `GOSUMDB=off`.
When every frozen Go command explicitly selects `-mod=vendor` (directly or via
`GOFLAGS`), FalseGreen validates `vendor/modules.txt`, retains its digest as
dependency evidence, and skips module-proxy preparation entirely. The vendor
tree remains part of the immutable source digest.
The production image carries the latest qualified stable Go patch release;
repositories requiring a newer, unavailable toolchain fail before criteria run
instead of downloading one implicitly. Go attestations include the Go version,
GOOS/GOARCH, workspace mode, and binary digest.
GNU Fortran and dependency-free fpm projects run offline with gfortran/fpm
provenance. Ada projects support GNAT and GPRbuild; dependency-free Alire
projects can run offline. Because fpm and Alire do not provide a generally safe
fetch-only operation that FalseGreen has qualified, dependency-bearing projects
fail closed when frozen commands invoke those package managers instead of
executing package actions with network. Unused fpm.toml and alire.toml files do
not block CMake or GPRbuild verification and must not be removed from the source
snapshot.
SPARK is a distinct method: `spark_proof` evaluates GNATprove's summary and
SARIF artifacts. Prove/all modes report discharged, unproved, and justified
obligations; flow/check modes report clean, unresolved, and justified flow
checks without manufacturing theorem obligations. Neither mode can accept
based on process exit status alone. The managed GNATprove binary is an oracle
for Ada/SPARK consumer projects, not for modifications to GNATprove or gnat2why
itself; analyzer changes require a source-bound toolchain build.
Downloaded wheels, Cargo files, Ruby gems, Go modules, and frozen external artifacts enter
a shared toolchain-bound cache. Exact dependency requests skip resolution and
downloads on later runs, while a global SHA-256 object store deduplicates common
artifacts across different projects and tenants. Per-run views are read-only
hardlinks, expire after one day by default, and can be recreated from shared
entries. Size, age, and minimum-free-space policies bound the durable cache;
verification build directories remain private and temporary.
Rust/native builds that require publisher release archives can declare
`external_artifacts` in the task contract. FalseGreen freezes each artifact's
direct approved HTTPS release URL, SHA-256, byte size, archive handling, and
environment-variable binding. The dependency worker downloads only those
declared bytes, the controller verifies and safely extracts them, and the build
receives the resulting file or directory read-only with network access still
disabled. Artifact identity and the retained dependency-manifest digest are
included in the signed attestation and Markdown report.
The mandatory `source_digest` identifies the exact immutable normalized source
snapshot that the verifier executed. It is not interchangeable with a Git
commit: the attestation also records commit, ref, repository, and dirty state
when Git metadata is available, while the digest covers uncommitted and
untracked meaningful source files too. Absolute workspace paths, mtimes, `.git`, `.falsegreen`,
virtual environments, build outputs, and tool caches do not affect the digest;
file contents, relative paths, entry types, normalized executable modes, and
safe in-workspace symlink targets do.
Untracked files under the reserved `.verification/` directory remain in that
source digest and are available to frozen verifier commands, but they do not by
themselves mark published product source as dirty. Reports disclose their file
count separately. Tracked changes under `.verification/` and ordinary
untracked source still mark the workspace dirty.
For hosted verification, the native client uploads only the local HEAD, index,
and current branch ref as controller provenance. Initialized Git submodules are
snapshotted recursively, and each nested checkout must match the exact `160000`
gitlink commit in its parent index. Missing or mismatched checkouts fail before
verification. The hosted controller repeats those gitlink checks and records
each submodule path, expected and observed commit, repository, ref, and dirty
state in the signed attestation. Minimal Git metadata remains controller-only;
it never enters the immutable source artifact or verifier workspace.
Git workspace uploads are enumerated from the index plus untracked, non-ignored
files. A tracked file is therefore always included even when a later ignore rule
matches its name; ignored build products remain excluded. The client canonicalizes
the fetch origin to credential-free HTTPS for provenance while leaving the local
fetch and push configuration unchanged.
Production attestations for accepted runs are Ed25519 signed. Call
`falsegreen_get_attestation_verification_key` (or read
`falsegreen://attestation-key`) for the raw base64 public key and stable key ID.
Hosted reviewers can also fetch the same public material from
`GET /v1/attestation-key` without an API key.
The signature covers the canonical JSON document with `signature.value` set to
`null`. Changing status, source binding, evidence, environment, or any other
field invalidates it. Local deployments may leave signing optional; those
artifacts say `algorithm: "none"` and the report explicitly says unsigned.
An attestation is evidence that the recorded criteria produced the recorded
result for one exact source state. It is not a claim that a PR is universally
safe, bug-free, or formally verified.
## Commands
### `falsegreen mcp`
Run the MCP server over STDIO. This is what Codex launches automatically. You rarely run this manually.
### `falsegreen login --token <key>`
Activate the current device through FalseGreen, exchange an enrollment
credential for an opaque access token, and store that token locally. The shim
does not retain the enrollment credential. Re-login on the same installation
rotates its session without consuming another device slot.
### `falsegreen logout`
Release the current device activation, revoke the FalseGreen session, and
remove local credentials. If the server cannot release the activation, local
credentials are kept so logout can be retried.
### `falsegreen status`
Show authentication state, session ID, and API endpoint.
### `falsegreen install <agent>`
Install FalseGreen into an agent's MCP configuration. Supported agents:
| Codex CLI & VS Code | `falsegreen install codex` | STDIO | `~/.codex/config.toml` |
| GitHub Copilot | `falsegreen install github-copilot` | STDIO | `.vscode/mcp.json` |
| Claude Code | `falsegreen install claude-code` | STDIO | `.mcp.json` |
| OpenCode | `falsegreen install opencode` | STDIO | `opencode.json` |
| Cursor | `falsegreen install cursor` | STDIO | `.cursor/mcp.json` |
Each agent spawns `falsegreen mcp` as a local subprocess. The shim authenticates
and communicates with the hosted service over HTTPS.
## Configuration
### Environment variables
| `FALSEGREEN_KEY` | *(none)* | API key (overrides stored credentials) |
| `FALSEGREEN_API_URL` | `https://mcp.falsegreen.com/v1/mcp` | MCP service URL |
| `FALSEGREEN_WORKSPACE_URL` | derived from MCP URL | Workspace upload URL (self-hosted overrides only) |
### Credentials file
`~/.config/falsegreen/credentials.toml`:
```toml
token = "fgs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
session_id = "cred_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```
## Why the shim is required for local workspaces
The hosted verifier cannot read paths on your machine. The shim snapshots the
local workspace and uploads it before task creation, contract validation and
freezing, and completion checks. Connecting directly to the HTTP MCP endpoint
does not provide that filesystem bridge and therefore cannot verify a local
workspace.
## License
Apache-2.0. See [LICENSE](LICENSE) for details.