CLI Reference
provegate / gate commands.
The package installs two equivalent binaries: provegate and gate.
Implemented
gate status
Rebuilds workflow state from the artifact tree (_prds/_readiness/_tasks/_docs by
default), writes the snapshot (default _state/prds.json), and prints one line per work item
plus panel metrics:
$ gate status
PRD-001 In Progress readiness=PASS/8.7 tasks=12/45 config-state-locks
Implemented: 0
Latest implemented: —
wrote /repo/_state/prds.jsongate queue [--json]
The scheduling view: READY items sorted by readiness score (with conflict-surface overlap
warnings), IN-FLIGHT lock leases (stale-flagged), BLOCKED, and IN-REVIEW. --json emits the
machine shape (ready / readyOverlaps / inFlight / blocked / inReview).
gate push
$ gate push
No. Push is yours.
$ echo $?
1Fully implemented, permanently. The runner has no code path that pushes to a remote.
gate run [--dry-run] [--from-phase=4|5|6|7|merge] PRD-XXX
The deterministic close: builds the gate chain from gates.manifest.json (floor gates +
diff-conditional class defaults), executes the PRD's §11 commands through the command-safety
allowlist, checks the independent-review artifact schema, the durable-artifacts diff gate,
and the operator-acceptance guard, then archives the artifacts and performs the local
no-ff merge with post-merge verification — auto-reverting on failure. Ends with a handoff
card whose last line is the point: push is yours, the runner never pushes.
--dry-run prints the full plan (flagging any §11 command the safety gate would refuse)
and executes nothing. A nested non-dry-run invocation refuses (recursion sentinel).
gate land PRD-XXX
The merge step only — alias for run --from-phase=merge.
gate check PRD-XXX / gate check --wiring
The readiness lint: every FR needs Targets and a runnable §11 row, DO NOT present, Open
Questions empty, no bare placeholders, plus manifest hardCaps (targets-conditional
required-evidence rules). --wiring audits wire-or-delete: manifest commands must name
real scripts; verify:*-pattern scripts must be wired in the manifest/CI or carry a
shrink-only exception.
gate doctor --memory [--json]
Read-only diagnosis of a memory install: config containment, store root and index, record validation, at least one configured entrypoint carrying the index pointer, validator presence and package-script wiring, and Phase 7 reachability. Each check has a stable id you can grep or branch on.
It never edits config, manifests, entrypoints, scripts, or state — on the failing path as well as the passing one. A diagnostic that writes only when it fails is still a writer, and the failing path is when you can least afford a surprise edit.
Mandatory failures exit 1. Two checks only warn: CI reachability, because workflow
layouts are user-defined and absence there proves nothing this tool can establish; and
unfilled {{TOKEN}} placeholders, a real install defect that breaks no gate today. A
warning never changes the exit code.
A symlinked entrypoint is valid as long as it stays inside the repository — containment rejects escapes, not symlinks — and two entrypoints resolving to one real file count as one satisfied entrypoint rather than two.
Bare gate doctor prints usage and exits 1 rather than guessing a mode.
gate memory find [--query=<text>] [--paths=<a,b>] [--tag=<slug>] [--limit=N] [--json]
Deterministic local recall over the record store. Ranks by watched-path overlap, then exact name or tag, then description and name tokens, with the slug as a final tie-break — so the same question returns the same bytes on any machine. Default limit 20, allowed 1–1000.
Deterministic, not relevant. No embedding, no persistent index, no model, no network. A
record that matters but shares no watched path, no exact name or tag, and no description
token will not be found; find augments the always-loaded _brain/INDEX.md rather than
replacing it. Every hit carries the reasons it matched, so you can see which rule fired.
At least one selector is required — a selectorless find would be the whole store in slug order. Disabled memory refuses instead of returning an empty list, because an empty list reads as "nothing relevant" about a store that was never consulted. Superseded and unreadable records never appear: acting on a record the validator would reject is worse than finding nothing.
gate init [--dry-run] [--practices]
Scaffolds the workflow tree (artifact dirs × lifecycle states, state and locks dirs) plus
starter workflow.config.json and gates.manifest.json. Additive-only and idempotent:
nothing is ever overwritten; re-run any time. Roots at the nearest .git walking up from
the current directory, else the current directory itself.
--practices additionally installs the practices pack: the agent bootstrap templates,
the artifact templates, and scripts/verify/ — the checks that hold artifacts to what they
claim. The never-overwrite guarantee covers it too: every file that already exists is
reported as skipped, which is what makes --practices safe to add to a repository that has
already been scaffolded.
The pack creates files only. Adding its package.json scripts, wiring CI, and pasting
the agent-entry shims are deliberate manual steps — gate init prints them
(NEXT_STEPS.md) and performs none of them, because editing an adopter's package.json
and CI config is not something a scaffold should do behind their back.
gate new <slug> [--class=X] [--template=path]
Creates the next work item from the shipped PRD template: allocates the next free id
(max across ALL lifecycle states + 1 — completed and deferred ids are never reused),
substitutes id/slug/dates/status/class into the template, and writes
_prds/wip/prd-XXX-<slug>.md. Never overwrites; a concurrent gate new race is detected
and retried with the next id. --template points at a forked template (its metadata
anchors must survive the fork — a drifted template fails loudly).
gate open <PRD-XXX> [--steal] [--worktree]
Claims the PRD's declared ## Conflict Surface: checks the globs against every active
lease with the same overlap engine gate queue uses, then either writes a lease into the
locks dir or refuses (exit 1) naming each overlap. Claiming is atomic — no lease is
written while any conflict exists. Re-claiming your own PRD refreshes the lease
("already held"). A stale foreign lease still blocks, but --steal may take it over —
the takeover prints the victim's PRD, agent, and expiry; a valid foreign lease is never
stealable. A PRD with no conflict surface is refused: a claim over nothing protects
nothing.
Overlap is decided against the files two surfaces actually share; when a surface
covers a directory that does not exist yet (zero tracked files), the check falls
back to the patterns. That structural check is sound over the supported glob
grammar (**, *, ?, literals): sibling wildcards that can match a common
future path — src/api/*.ts against src/api/users.ts, or src/*/handlers/**
against src/auth/handlers/** — collide at claim time, not merge time, even on a
greenfield tree. The bias is deliberately conservative: an uncertain pair refuses
(recoverable by narrowing a surface) rather than risk a silent double-claim.
Genuinely disjoint surfaces (src/a/** against src/b/**) stay claimable in
parallel, and shared append-only manifests never count as a conflict.
--worktree extends the atomic claim to the checkout: after the lease installs, a
feature branch (from branches.featurePattern) and a linked worktree under the
configured worktree.dir are provisioned, and the lease is stamped with both.
The checkout is cut from the configured base ref, so the PRD and the control
files that decide what runs there (workflow.config.json, gates.manifest.json,
when present) must match the base ref first — missing OR edited-since-commit
both refuse, instead of producing a checkout whose PRD, layout, or gate policy
differs from the one just claimed. Provisioning failure (branch or path collision) rolls the
lease back — claim and checkout are one outcome. After gate run lands the merge, the runner removes the
worktree and deletes the merged branch; a dirty worktree refuses removal and
degrades to a handoff-card warning (never --force on user trees). Branch deletion
is decided by an explicit merge-base --is-ancestor proof against the configured
base — a branch not provably merged, the base itself, or any configured protected
branch is never deleted. When a parked primary checkout makes plain -d refuse a
proven-merged branch, deletion retries -d from a throwaway detached scratch
context at the base tip, so git's own mergedness and checked-out-branch guards
re-evaluate at delete time. Locks stay platform-agnostic: external worktree
managers keep working, the flag is optional sugar.
--hours=N overrides the lease duration (default 12h); a non-positive or
non-finite value is refused (exit 1).
gate renew <PRD-XXX> [--hours=N]
Extends your lease. Renew is the idempotent refresh path — the same code gate open uses to re-claim a PRD you already hold — so the Conflict Surface is
re-parsed and re-checked against active leases: a surface edited since the claim
is re-validated, not grandfathered, and a conflict discovered now refuses exactly
like a fresh claim. --hours sets the new duration. Renew before your lease goes
stale, so a rival's --steal never gets the chance.
gate release <PRD-XXX> [--force]
Drops a PRD's lease under the same claim mutex, so a release racing a claim can
never unlink a lease the claim just refreshed. Releasing your own lease is clean;
releasing one held by a different agent requires --force and prints the
victim (PRD, agent, expiry) — the takeover is reported, never silent. No lease for
the id is a no-op success ("nothing to release"); a malformed lease for the id
fails closed (no unlink, repair named). This retires hand-editing files under
_state/locks/.
Layout, id pattern, status vocabulary, and branch policy come from an optional
workflow.config.json; gate membership and policy from an optional gates.manifest.json —
see the package README for both surfaces.