Adoption runbook
Product home: https://opengantry.ai · All docs: index.md
This runbook is the operational path for adopters using gantry locally. Product positioning and use cases: README · USE-CASES.md.
Open Source Gantry is vendor-neutral, local-first, git-native — the gantry CLI plus Git hooks and gantry verify over mission YAML (scope + gate_command). Execution never requires a hosted agent dashboard; optional future metadata hub integrations consume digest-only attestation receipts (gantry attest, gantry verify --receipt) — see ADR-0034.
First mission practice: KATA.md (~15 min, headless-friendly).
See also: FEATURES.md · COMPLIANCE-ISO.md · CHANGELOG.md (release history).
First run (onboarding)
Install gantry (Node.js 24+):
npm install -g @jeger-ai/opengantry
# or: npx @jeger-ai/opengantry <cmd>
gantry init --tutorial # guided loop after scaffold (~3 min)
# or:
gantry init
gantry onboarding # same strict checks as production
gantry planner set "$(git config user.email)"
gantry doctor
gantry pin .gitagent/missions/example.verify.yaml # optional; enables verify/scan without --mission
gantry verify # uses pin when set
Standard change loop (review → run → audit)
# 1. Human reviews mission BEFORE executor (Planner commit required)
gantry start "Fix login spinner" --msn MSN-0001 --skill-key ui --gate-command "npm test"
# Planner: review YAML scope/gates, then:
git add .gitagent/missions/MSN-0001.<slug>.yaml
git commit -m "[MSN-0001] legislate mission"
# 2. Pin + executor env (pin optional but recommended for day-one DX)
gantry pin .gitagent/missions/MSN-0001.<slug>.yaml
eval "$(gantry runtime env)"
# 3. Audit evidence: verify + grep
gantry verify --fix
gantry verify --json | jq -r '.error_code // "passed"'
git log --grep='MSN-0001' --oneline
gantry status --json --verbose
Legacy equivalent: gantry legislate "<intent>" --msn MSN-0001 --skill-key ui --gate-command "npm test".
gantry init composes per-tool recipes into docs/INTEGRATIONS.md. Non-interactive: gantry init --yes or gantry init --ides cursor,claude-code --no-ci.
Wire your IDE agent: INTEGRATIONS.md.
Regulated teams (ISO 27001 / ISO 42001)
If auditors ask how AI-assisted coding fits your ISMS or AI management system, see COMPLIANCE-ISO.md for control-to-artifact mapping (SOD, change authorization, trace evidence, enforcement tiers). OpenGantry does not grant certification — it produces the operational records assessors typically request.
Prevent unreviewed edits
Gantry Git hook enforcement (.githooks/pre-commit, .githooks/pre-push, IDE beforeShellExecution) complements the Gantry CLI — hard boundaries live in hooks, gantry verify, and runtime exec, not in a vendor cloud console.
- Planner-approved mission commit: among recent commits, the newest
[MSN-XXXX]from an allowlisted Planner email must modify the mission file passed to--mission. - Pre-push handoff:
gantry verify --pre-pushlets legislative stubs push for remote agent handoff; full verify (gate + trace) is still required before merge. - IDE writes are advisory: rules and
AGENTS.mdguide agents; hooks +gantry runtime execenforce hard boundaries.
Audit evidence cheatsheet
git log --grep='MSN-' --oneline
# Mission file: .gitagent/missions/<MSN>.<slug>.yaml
# Executor trace: repo-root EXECUTOR_LOG.md (verifier cites verbatim quotes)
gantry verify --mission .gitagent/missions/<file>.yaml
PR CI (this specimen): commits touching .gitagent/, EXECUTOR_LOG.md, hooks, or gxt-validate.yml need [MSN-NNNN] subjects unless the change satisfies a repository-declared trusted_automation rule in .gitagent/config.json (fail-closed when absent).
Trusted automation policy
Low-risk ecosystem bot maintenance can bypass manual mission authoring when all constraints in a committed policy rule pass. Each rule declares exactly one allowed_structural_changes kind (mixing kinds on a single rule is rejected at config load).
| Constraint | Meaning |
|---|---|
allowed_actors | Commit author email (git log -1 --format=%ae) must match an entry you legislated — no hardcoded vendor strings in the engine |
allowed_paths | Every MSN-enforced changed file must match a glob in the rule |
allowed_structural_changes | Structural kind — see table below (one kind per rule) |
max_net_loc | Total diff churn (additions + deletions) per evaluation; must be ≤ the hard cap for that kind |
| Kind | Use case | Hard max_net_loc cap | Structural checks |
|---|---|---|---|
workflow_version_pin | Dependabot workflow uses: version bumps | 5 | YAML structure unchanged; only existing uses: version segments may differ |
bounded_content | Security autofix bots (code scanning, Snyk, similar) | 100 | Content changes allowed inside allowed_paths; engine hard-rejects any touch under .gitagent/** or MANIFEST perimeter_protected even if listed in allowed_paths |
Example — workflow pins (this specimen repo):
{
"trusted_automation": {
"rules": [
{
"id": "workflow-dependency-bumps",
"allowed_actors": ["dependabot[bot]@users.noreply.github.com"],
"allowed_paths": [".github/workflows/**"],
"allowed_structural_changes": ["workflow_version_pin"],
"max_net_loc": 5
}
]
}
}
Ecosystem autofix bots
GitHub code scanning agentic autofix, Copilot SWE agent, Snyk fix PRs, and similar tools commit application-source changes without a [MSN-NNNN] subject. To let those PRs pass MSN CI without break-glass, add a separate bounded_content rule — opt-in per repository:
{
"id": "security-autofix-bots",
"allowed_actors": [
"223556219+Copilot@users.noreply.github.com",
"snyk-bot@snyk.io"
],
"allowed_paths": ["src/**", "package.json", "package-lock.json"],
"allowed_structural_changes": ["bounded_content"],
"max_net_loc": 80
}
Actor discovery: when CI fails MSN check on a bot PR, inspect the commit author on the failing commit (git log -1 --format=%ae <sha>) and add that exact email to allowed_actors. GitHub noreply formats vary by account; Snyk private-repo fix PRs may be opened on behalf of a human collaborator — those commits will not match snyk-bot@snyk.io unless you configure Snyk’s fixed GitHub account or add the collaborator email explicitly.
Not for break-glass: routine autofixes belong in trusted_automation. Reserve gantry verify --break-glass for production emergencies only (secret-gated, Planner post-incident review).
Evaluation is git-derived only (gxt-manifest-lib.mjs eval-commit / eval-range) — not CI environment variables. Missing or invalid config → full MSN/mission workflow remains enforced.
Role-based CLI output
gantry --audience executor start "…" # constraint-forward next steps
gantry --audience planner verify … # copyable git / mission hints
gantry --audience verifier verify … # silence unless [GXT_*] errors (CI)
export GXT_AUDIENCE=verifier # same as global --audience
Verify troubleshooting
gantry verify auto-resolves formatter line drift in EXECUTOR_LOG.md. Use --strict-trace only when you need exact line numbers. Pre-push: gantry verify --pre-push for legislative stub handoff.
Stale trace evidence
After gate + trace quote mapping, full verify binds each committed PASS quote line in EXECUTOR_LOG.md to the mission skill’s full tmvc_roots:
- Resolve the quote line (numeric anchor, fuzzy drift, or freeform anchor + quote).
git blame --porcelainon that line → attestation commit (skip when blame is all-zeros — uncommitted line; trace and code co-evolve in the working tree).git diff --name-only <attestationCommit> -- <tmvc_roots…>vs working tree — any path listed →Trace STALE(GXT_TRACE_STALE).
Re-run the gate, append a fresh unique trace line to EXECUTOR_LOG.md, update mission trace_quote, commit, and verify again. After interactive rebase/squash, historical attestation may be invalidated — expect to refresh traces.
Formatter guard (recommended): Add EXECUTOR_LOG.md to .prettierignore (Prettier) or an equivalent ignore for your formatter (Biome files.ignore, ESLint ignore, editor format-on-save exclude). Numeric anchors and stale-evidence git blame bind to committed line numbers; auto-formatting the log causes avoidable drift (verify can fuzzy-resolve, but prevention is cheaper). gantry init and gantry upgrade apply merge this entry automatically; existing repos should add it once manually or re-run upgrade.
Migration escape hatch: gantry verify --skip-stale-evidence (also skip_stale_evidence on MCP gxt_verify). Do not hash working-tree files in Node for this check — Git’s diff engine handles CRLF and .gitattributes correctly on all platforms.
MCP verify envelope
gxt_verify / handleVerify returns a flat VerifyResultPayload — same shape as gantry verify --json:
- Success:
{ "status": "passed", "phase": "full" | "pre_push_stub" | "break_glass", "exit_code": 0, … } - Failure:
{ "status": "failed", "phase": "<phase>", "error_code": "GXT_*", "fix_hints": [], "next_actions": [], "exit_code": N, … }
Init and parse failures use status: "failed", phase: "init" — not legacy { "status": "error" }. Other MCP tools (gxt_runtime_env, gxt_runtime_exec) still use { "status": "error" } until a future unification.
gantry verify --json and --fix are mutually exclusive; combining them returns GXT_INVALID_ARGUMENT (exit_code: 2).
Enforcement boundary
IDE Agent Write/Edit is advisory TMVC; hard boundaries live in runtime exec, gantry verify, and hooks.
| Tier | Mechanism | Enterprise control |
|---|---|---|
| Process-boundary | gantry runtime exec | Forbidden-zone scan + subprocess TMVC envelope |
| Deterministic hook | Cursor beforeShellExecution, pre-push verify | Governance path writes require mission + verify |
| Advisory | IDE rules, AGENTS.md, sessionStart context | IDE suggestions alone do not count as approval |
Per-tool closed-loop recipes: INTEGRATIONS.md.
Hooks (fast, scoped)
git config core.hooksPath .githooks
- post-checkout: creates
EXECUTOR_LOG.mdon feature branches when missing. - pre-commit:
gantry tmvc guard— advisory TMVC path warnings for staged files (stderr; exit 0). Skips when no pinned mission. SetGXT_TMVC_GUARD_STRICT=1or pass--strictto block. - pre-push:
gantry verify --pre-pushfor mission files changed on branch — ensures Planner review before remote handoff; full gate+trace still required to merge.
Record out-of-TMVC expansion before editing: gantry context-request --path <p…> --reason <text> (optional --stage-worker-log).
Break-glass (emergency only)
Emergency bypass for verify when production is down — not a substitute for mission review. Authorization requires GXT_BYPASS_SECRET matching .gitagent/foreman/BYPASS.sha256 (never commit the plaintext secret). Audit trail: refs/notes/gxt-bypass or --audit-commit.
Technical setup
printf '%s' 'your-team-secret' | sha256sum | awk '{print $1}' > .gitagent/foreman/BYPASS.sha256
export GXT_BYPASS_SECRET='your-team-secret'
gantry verify --break-glass --reason "Production auth down: hotfix session cookie" \
--mission .gitagent/missions/MSN-0001.<slug>.yaml
git push origin refs/notes/gxt-bypass
gantry doctor tests whether GXT_BYPASS_SECRET matches the anchor when set.
Substrate version drift: gantry doctor compares on-disk .gitagent/foreman/SUBSTRATE.version.json to the opengantry_version bundled with your installed gantry (same source as gantry upgrade). When behind, doctor emits a warn (exit 0) and suggests gantry upgrade after updating the npm package. Warnings do not fail gates that only check exit code.
Agent errors (machine vs human)
On runtime exec failure, a one-line human summary goes to stdout; full JSON goes to stderr and .gitagent/history/.ignored-last-error.json. Orchestrators read GXT_LAST_ERROR_FILE from gantry runtime env.
Metrics
gantry metrics
gantry metrics --json --ref main
Git-native only (single streamed git log pass). No local event ledger.
Routing proxy caveat: legislative_commits vs worker_trace_commits are path-touch heuristics, not historical gantry triage replay. JSON exposes this explicitly via gxt_extension_metadata (see below).
Metrics JSON envelope
gantry metrics --json includes a namespaced extension block so strict top-level parsers that only read primitive counters remain compatible:
{
"legislative_commits": 12,
"worker_trace_commits": 4,
"gxt_extension_metadata": {
"classification_mode": "PATH_TOUCH_PROXY",
"schema_version": 1
}
}
Classification rules (PATH_TOUCH_PROXY):
legislative_commits: commit touches.gitagent/missions/*withMSN-NNNNin the filename, subject starts with[MSN-NNNN], author is inGANTRY_PLANNER_EMAILS(non-empty allowlist entries only).worker_trace_commits: commit touchesEXECUTOR_LOG.mdand does not qualify as legislative (mutually exclusive; dual-touch legislative commits never increment worker-trace).- Human stdout labels
(proxy)on the counters; JSON usesgxt_extension_metadata.classification_modeinstead of suffixing field names.