@jeger-ai/opengantry 2.2.3 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -78
- package/dist/cli/commands/arch.js +4 -4
- package/dist/cli/commands/check-imports.js +1 -1
- package/dist/cli/commands/onboarding.js +5 -5
- package/dist/cli/commands/perimeter.js +2 -2
- package/dist/cli/commands/runtime.js +1 -1
- package/dist/cli/commands/scan.js +2 -2
- package/dist/cli/commands/teacher.js +1 -1
- package/dist/cli/commands/verify.d.ts +0 -2
- package/dist/cli/commands/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +3 -11
- package/dist/cli/commands/verify.js.map +1 -1
- package/dist/cli/lib/ajv-loader.d.ts +3 -0
- package/dist/cli/lib/ajv-loader.d.ts.map +1 -0
- package/dist/cli/lib/ajv-loader.js +10 -0
- package/dist/cli/lib/ajv-loader.js.map +1 -0
- package/dist/cli/lib/architecture-credential.js +1 -1
- package/dist/cli/lib/architecture-pointer.d.ts +0 -1
- package/dist/cli/lib/architecture-pointer.d.ts.map +1 -1
- package/dist/cli/lib/architecture-pointer.js +2 -5
- package/dist/cli/lib/architecture-pointer.js.map +1 -1
- package/dist/cli/lib/ast-discovery.js +1 -1
- package/dist/cli/lib/audience-output.js +7 -7
- package/dist/cli/lib/cli-io.js +1 -1
- package/dist/cli/lib/config-namespace.d.ts +18 -0
- package/dist/cli/lib/config-namespace.d.ts.map +1 -0
- package/dist/cli/lib/config-namespace.js +39 -0
- package/dist/cli/lib/config-namespace.js.map +1 -0
- package/dist/cli/lib/constants.d.ts +6 -5
- package/dist/cli/lib/constants.d.ts.map +1 -1
- package/dist/cli/lib/constants.js +6 -5
- package/dist/cli/lib/constants.js.map +1 -1
- package/dist/cli/lib/context-feed-store.d.ts +1 -1
- package/dist/cli/lib/context-feed-store.js +1 -1
- package/dist/cli/lib/dirty-missions.js +1 -1
- package/dist/cli/lib/doctor-core.d.ts.map +1 -1
- package/dist/cli/lib/doctor-core.js +8 -7
- package/dist/cli/lib/doctor-core.js.map +1 -1
- package/dist/cli/lib/doctor-integration.js +1 -1
- package/dist/cli/lib/doctor-substrate.js +4 -4
- package/dist/cli/lib/errors.d.ts.map +1 -1
- package/dist/cli/lib/errors.js +2 -1
- package/dist/cli/lib/errors.js.map +1 -1
- package/dist/cli/lib/file-merge-gxt.js +2 -2
- package/dist/cli/lib/fix-hints.d.ts +1 -0
- package/dist/cli/lib/fix-hints.d.ts.map +1 -1
- package/dist/cli/lib/fix-hints.js +10 -10
- package/dist/cli/lib/fix-hints.js.map +1 -1
- package/dist/cli/lib/git-metrics.js +1 -1
- package/dist/cli/lib/git-proof.d.ts +1 -1
- package/dist/cli/lib/git-proof.d.ts.map +1 -1
- package/dist/cli/lib/git-proof.js +5 -4
- package/dist/cli/lib/git-proof.js.map +1 -1
- package/dist/cli/lib/init-asset-catalog.d.ts +0 -2
- package/dist/cli/lib/init-asset-catalog.d.ts.map +1 -1
- package/dist/cli/lib/init-asset-catalog.js +1 -13
- package/dist/cli/lib/init-asset-catalog.js.map +1 -1
- package/dist/cli/lib/init-interactive.js +2 -2
- package/dist/cli/lib/init-plan.js +6 -6
- package/dist/cli/lib/init-tutorial.js +10 -10
- package/dist/cli/lib/kpi-engine.d.ts +6 -1
- package/dist/cli/lib/kpi-engine.d.ts.map +1 -1
- package/dist/cli/lib/kpi-engine.js +21 -22
- package/dist/cli/lib/kpi-engine.js.map +1 -1
- package/dist/cli/lib/kpi-scan.js +3 -3
- package/dist/cli/lib/legislate.d.ts.map +1 -1
- package/dist/cli/lib/legislate.js +11 -5
- package/dist/cli/lib/legislate.js.map +1 -1
- package/dist/cli/lib/manifest.js +2 -2
- package/dist/cli/lib/manifest.js.map +1 -1
- package/dist/cli/lib/mcp-governance.d.ts +0 -2
- package/dist/cli/lib/mcp-governance.d.ts.map +1 -1
- package/dist/cli/lib/mcp-governance.js +4 -5
- package/dist/cli/lib/mcp-governance.js.map +1 -1
- package/dist/cli/lib/mcp-tools-register.js +4 -4
- package/dist/cli/lib/missions/formatter.js +1 -1
- package/dist/cli/lib/missions/parser.d.ts.map +1 -1
- package/dist/cli/lib/missions/parser.js +7 -5
- package/dist/cli/lib/missions/parser.js.map +1 -1
- package/dist/cli/lib/missions/validator.d.ts.map +1 -1
- package/dist/cli/lib/missions/validator.js +3 -8
- package/dist/cli/lib/missions/validator.js.map +1 -1
- package/dist/cli/lib/msn-allocate.js +2 -2
- package/dist/cli/lib/onboarding-flow.js +5 -5
- package/dist/cli/lib/perimeter.d.ts +0 -2
- package/dist/cli/lib/perimeter.d.ts.map +1 -1
- package/dist/cli/lib/perimeter.js +1 -8
- package/dist/cli/lib/perimeter.js.map +1 -1
- package/dist/cli/lib/register-proposals.js +1 -1
- package/dist/cli/lib/runtime-env.d.ts.map +1 -1
- package/dist/cli/lib/runtime-env.js +7 -4
- package/dist/cli/lib/runtime-env.js.map +1 -1
- package/dist/cli/lib/skill-key.d.ts +12 -0
- package/dist/cli/lib/skill-key.d.ts.map +1 -0
- package/dist/cli/lib/skill-key.js +28 -0
- package/dist/cli/lib/skill-key.js.map +1 -0
- package/dist/cli/lib/staged-tmvc-guard.js +1 -1
- package/dist/cli/lib/start-orchestration.js +5 -5
- package/dist/cli/lib/status-report.js +3 -3
- package/dist/cli/lib/substrate-version.js +2 -2
- package/dist/cli/lib/surgeons/banned-import.d.ts +0 -1
- package/dist/cli/lib/surgeons/banned-import.d.ts.map +1 -1
- package/dist/cli/lib/surgeons/banned-import.js +0 -1
- package/dist/cli/lib/surgeons/banned-import.js.map +1 -1
- package/dist/cli/lib/surgeons/quarantine-import.d.ts +0 -5
- package/dist/cli/lib/surgeons/quarantine-import.d.ts.map +1 -1
- package/dist/cli/lib/surgeons/quarantine-import.js +0 -11
- package/dist/cli/lib/surgeons/quarantine-import.js.map +1 -1
- package/dist/cli/lib/surgeons/registry.d.ts +0 -1
- package/dist/cli/lib/surgeons/registry.d.ts.map +1 -1
- package/dist/cli/lib/surgeons/registry.js +0 -3
- package/dist/cli/lib/surgeons/registry.js.map +1 -1
- package/dist/cli/lib/surgeons/typescript-workspace.d.ts +1 -1
- package/dist/cli/lib/surgeons/typescript-workspace.js +3 -3
- package/dist/cli/lib/teacher-identity.d.ts +1 -2
- package/dist/cli/lib/teacher-identity.d.ts.map +1 -1
- package/dist/cli/lib/teacher-identity.js +11 -15
- package/dist/cli/lib/teacher-identity.js.map +1 -1
- package/dist/cli/lib/tmvc-path.d.ts.map +1 -1
- package/dist/cli/lib/tmvc-path.js +5 -2
- package/dist/cli/lib/tmvc-path.js.map +1 -1
- package/dist/cli/lib/trace.d.ts +0 -1
- package/dist/cli/lib/trace.d.ts.map +1 -1
- package/dist/cli/lib/trace.js +0 -3
- package/dist/cli/lib/trace.js.map +1 -1
- package/dist/cli/lib/types.d.ts +1 -1
- package/dist/cli/lib/upgrade-apply.js +5 -5
- package/dist/cli/lib/upgrade-plan.d.ts +1 -1
- package/dist/cli/lib/upgrade-plan.d.ts.map +1 -1
- package/dist/cli/lib/upgrade-plan.js +14 -14
- package/dist/cli/lib/upgrade-plan.js.map +1 -1
- package/dist/cli/lib/verify-engine.js +3 -3
- package/dist/cli/lib/verify-engine.js.map +1 -1
- package/dist/cli/lib/verify-failure-normalize.js +1 -1
- package/dist/cli/lib/verify-hints.d.ts.map +1 -1
- package/dist/cli/lib/verify-hints.js +10 -14
- package/dist/cli/lib/verify-hints.js.map +1 -1
- package/dist/cli/lib/verify-run.d.ts.map +1 -1
- package/dist/cli/lib/verify-run.js +3 -2
- package/dist/cli/lib/verify-run.js.map +1 -1
- package/dist/cli/lib/version.gen.d.ts +1 -1
- package/dist/cli/lib/version.gen.js +1 -1
- package/dist/cli/program-core.d.ts.map +1 -1
- package/dist/cli/program-core.js +6 -2
- package/dist/cli/program-core.js.map +1 -1
- package/package.json +10 -5
- package/templates/.cursor/hooks/gxt-before-shell.sh +2 -2
- package/templates/.cursor/hooks/gxt-session-start.sh +5 -5
- package/templates/.cursor/mcp.json +1 -1
- package/templates/.cursor/rules/opengantry-gxt-substrate.mdc +4 -4
- package/templates/.gitagent/foreman/MANIFEST.json +2 -2
- package/templates/.gitagent/foreman/SUBSTRATE.version.json +1 -1
- package/templates/.gitagent/foreman/TEACHER.allowlist.example +1 -1
- package/templates/.gitagent/missions/README.md +3 -3
- package/templates/.gitagent/teacher/ARCHITECTURE-ACCESS.md +8 -8
- package/templates/.gitagent/teacher/KPI-REPORT.schema.yaml +1 -1
- package/templates/.gitagent/teacher/MISSION-ARCHITECT.md +5 -5
- package/templates/.gitagent/teacher/MISSION.schema.yaml +2 -2
- package/templates/.gitagent/teacher/RULES.md +2 -2
- package/templates/.githooks/pre-commit +4 -4
- package/templates/.githooks/pre-push +6 -6
- package/templates/.github/workflows/gxt-validate.yml +8 -8
- package/templates/AGENTS.md +1 -1
- package/templates/integrations/asset-catalog.json +1 -1
- package/templates/integrations/compatibility.json +1 -1
- package/templates/integrations/recipes/_footer.md +6 -6
- package/templates/integrations/recipes/_preamble.md +9 -9
- package/templates/integrations/recipes/aider.md +1 -1
- package/templates/integrations/recipes/antigravity.md +1 -1
- package/templates/integrations/recipes/claude-code.md +1 -1
- package/templates/integrations/recipes/codex-cli.md +2 -2
- package/templates/integrations/recipes/cursor.md +3 -3
- package/templates/scripts/dev-validate.sh +1 -1
- package/templates/scripts/gxt-resolve-mission.sh +2 -2
- package/templates/scripts/gxt-runtime-env.sh +4 -4
- package/templates/scripts/validate-gxt.sh +1 -1
- package/templates/scripts/verify-pr-missions.sh +6 -6
- package/templates/skills/{gapman.md → gantry.md} +2 -2
- package/dist/cli/lib/verify-changed-missions.d.ts +0 -3
- package/dist/cli/lib/verify-changed-missions.d.ts.map +0 -1
- package/dist/cli/lib/verify-changed-missions.js +0 -30
- package/dist/cli/lib/verify-changed-missions.js.map +0 -1
- package/dist/cli/lib/verify-remediation.d.ts +0 -5
- package/dist/cli/lib/verify-remediation.d.ts.map +0 -1
- package/dist/cli/lib/verify-remediation.js +0 -3
- package/dist/cli/lib/verify-remediation.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
It is **not** a real-time conversational agent wrapper. Use OpenGantry when you need auditable, mission-scoped repository work with explicit Teacher approval and forensic trace.
|
|
6
6
|
|
|
7
|
+
> **Not [Gantry.io](https://gantry.io)?** **Open Source Gantry** is the **`gantry` CLI** for **local-first**, **vendor-neutral**, **git-native governance** in your repository — not a hosted observability dashboard. If you are looking for infrastructure monitoring, see [Gantry.io](https://gantry.io).
|
|
8
|
+
|
|
7
9
|
Use OpenGantry when you need:
|
|
8
10
|
|
|
9
11
|
- **Agent-assisted product delivery without silent scope creep:** keep velocity while forcing explicit mission scope and path boundaries.
|
|
@@ -13,10 +15,21 @@ Use OpenGantry when you need:
|
|
|
13
15
|
### What you get in production
|
|
14
16
|
|
|
15
17
|
- **Review before run:** workers do not complete the loop until a human-approved mission defines scope, gates, and trace rows.
|
|
16
|
-
- **No silent governance edits:** hooks and `
|
|
18
|
+
- **No silent governance edits:** hooks and `gantry verify` fail closed on law, manifest, and mission paths without a Teacher `[MSN-XXXX]` commit.
|
|
17
19
|
- **Audit in Git:** `git log --grep='MSN-0042'` plus `WORKER_LOG.md` quotes that verifiers must cite verbatim.
|
|
18
20
|
|
|
19
|
-
**Protocol (implementers):** under the hood, **GXT (Git-native eXecution and Trace)** binds law, Foreman routing, deterministic gates, and trace mapping to `WORKER_LOG.md`. This repository is both the **specimen** and the **template**. Run **`
|
|
21
|
+
**Protocol (implementers):** under the hood, **GXT (Git-native eXecution and Trace)** binds law, Foreman routing, deterministic gates, and trace mapping to `WORKER_LOG.md`. This repository is both the **specimen** and the **template**. Run **`gantry init`** (or **`gantry init --tutorial`**) in your repo and adapt it.
|
|
22
|
+
|
|
23
|
+
## Gantry CLI — local-first governance
|
|
24
|
+
|
|
25
|
+
**Open Source Gantry** ships as the **Gantry CLI** (`npm install -g @jeger-ai/opengantry`). Governance runs **in your repo** — missions, deterministic gates, and **Gantry Git hook** enforcement (`.githooks/`, IDE hooks) — without routing agent work through a vendor cloud dashboard.
|
|
26
|
+
|
|
27
|
+
| Goal | Read first |
|
|
28
|
+
|------|------------|
|
|
29
|
+
| **Install + first mission** | [Install](#install) → [`docs/ADOPTION.md`](docs/ADOPTION.md) → [`docs/KATA.md`](docs/KATA.md) |
|
|
30
|
+
| **Gantry CLI command reference** | [gantry CLI](#gantry-cli) |
|
|
31
|
+
| **Git hooks + enforcement** | [Enforcement boundary](#enforcement-boundary) · [`docs/ADOPTION.md`](docs/ADOPTION.md) § Prevent unreviewed edits |
|
|
32
|
+
| **Wire IDE agents** | [`docs/INTEGRATIONS.md`](docs/INTEGRATIONS.md) |
|
|
20
33
|
|
|
21
34
|
## Install
|
|
22
35
|
|
|
@@ -24,7 +37,7 @@ Requires **Node.js 24+**.
|
|
|
24
37
|
|
|
25
38
|
```bash
|
|
26
39
|
npm install -g @jeger-ai/opengantry
|
|
27
|
-
|
|
40
|
+
gantry init --tutorial
|
|
28
41
|
```
|
|
29
42
|
|
|
30
43
|
Or without a global install:
|
|
@@ -33,7 +46,7 @@ Or without a global install:
|
|
|
33
46
|
npx @jeger-ai/opengantry init --tutorial
|
|
34
47
|
```
|
|
35
48
|
|
|
36
|
-
Developing this repository from source: `npm ci && npm run build` — see [
|
|
49
|
+
Developing this repository from source: `npm ci && npm run build` — see [gantry CLI](#gantry-cli) and [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md).
|
|
37
50
|
|
|
38
51
|
*Want to see the ROI? Run `npm run examples:benchmark` to compare an orchestrator specimen (improvised agent glue) against OpenGantry's TMVC protocol.* (Requires clone + `npm run build` — see [`docs/ADOPTION.md`](docs/ADOPTION.md).)
|
|
39
52
|
|
|
@@ -41,6 +54,7 @@ Developing this repository from source: `npm ci && npm run build` — see [gapma
|
|
|
41
54
|
|
|
42
55
|
| Goal | Read first |
|
|
43
56
|
|------|------------|
|
|
57
|
+
| **Gantry CLI + local governance** | [Gantry CLI — local-first governance](#gantry-cli--local-first-governance) → [gantry CLI](#gantry-cli) |
|
|
44
58
|
| **Adopt in your repo (5 min)** | This README → [`docs/ADOPTION.md`](docs/ADOPTION.md) → [`docs/KATA.md`](docs/KATA.md) |
|
|
45
59
|
| **See benchmark ROI (3 min)** | [`examples/benchmark-agent/`](examples/benchmark-agent/) → [`docs/ADOPTION.md`](docs/ADOPTION.md) |
|
|
46
60
|
| **Wire IDE agents** | [`docs/INTEGRATIONS.md`](docs/INTEGRATIONS.md) |
|
|
@@ -54,31 +68,33 @@ Developing this repository from source: `npm ci && npm run build` — see [gapma
|
|
|
54
68
|
|
|
55
69
|
| Outcome | How OpenGantry delivers it |
|
|
56
70
|
|---------|---------------------------|
|
|
57
|
-
| **Lower onboarding friction** | `
|
|
71
|
+
| **Lower onboarding friction** | `gantry init --tutorial`, `gantry onboarding`, `gantry start "<intent>"`, `gantry status --json` |
|
|
58
72
|
| **No unreviewed agent scope** | Teacher reviews mission YAML **before** `runtime env` / worker execution; TMVC roots + forbidden zones enforce paths |
|
|
59
73
|
| **Audit-ready evidence** | `[MSN-XXXX]` commit subjects; verifier PASS requires a verbatim quote from `WORKER_LOG.md` |
|
|
60
74
|
| **Regulated / ISO-aligned workflows** | SOD, mission authorization, and Git-native trace — see [`docs/COMPLIANCE-ISO.md`](docs/COMPLIANCE-ISO.md) (27001 change control, 42001 AI governance) |
|
|
61
|
-
| **Faster recovery from failure** | Stable `GXT_*` error codes, `
|
|
75
|
+
| **Faster recovery from failure** | Stable `GXT_*` error codes, `gantry verify --fix`, role output via `--audience worker\|teacher\|verifier` |
|
|
62
76
|
|
|
63
|
-
**Protocol maturity:** substrate law **v0.5.0**; **`
|
|
77
|
+
**Protocol maturity:** substrate law **v0.5.0**; **`gantry` v2.2.5** — unified CLI naming (`gantry` primary; legacy `gapman` alias). Current npm publish: **v2.2.5**. See [.gitagent/teacher/RUNTIME.md](.gitagent/teacher/RUNTIME.md).
|
|
64
78
|
|
|
65
79
|
## Release timeline (latest first)
|
|
66
80
|
|
|
67
|
-
Current npm release in this repository: **`
|
|
81
|
+
Current npm release in this repository: **`gantry` v2.2.5**. Use [`docs/ADOPTION.md`](docs/ADOPTION.md) for the ordered runbook.
|
|
68
82
|
|
|
69
83
|
| Release | Highlights |
|
|
70
84
|
|---------|------------|
|
|
85
|
+
| **v2.2.5** | Quality remediation — recursive test glob ([#99](https://github.com/jeger-ai/opengantry/issues/99)), dead verify code prune ([#100](https://github.com/jeger-ai/opengantry/issues/100)–[#101](https://github.com/jeger-ai/opengantry/issues/101)), mechanical cleanups ([#107](https://github.com/jeger-ai/opengantry/issues/107)) |
|
|
86
|
+
| **v2.2.4** | Unified gantry naming cutover ([#94](https://github.com/jeger-ai/opengantry/issues/94)); docs positioning — Gantry.io disambiguation, long-tail SEO (`Open Source Gantry`, `Gantry CLI`, `Gantry Git hook`), vendor-neutral local governance framing ([#95](https://github.com/jeger-ai/opengantry/issues/95)–[#97](https://github.com/jeger-ai/opengantry/issues/97)) |
|
|
71
87
|
| **v2.2.3** | Declarative `trusted_automation` policy in `.gitagent/config.json` — repository-legislated bot maintenance bypass with `max_net_loc <= 5` ([#92](https://github.com/jeger-ai/opengantry/issues/92)) |
|
|
72
88
|
| **v2.2.2** | Time-to-Scaffold benchmark — `npm run examples:benchmark`, measured LOC matrix, adoption discovery ([#79](https://github.com/jeger-ai/opengantry/issues/79)) |
|
|
73
89
|
| **v2.2.1** | Thermo remediation — unified `NormalizedVerifyFailure` contract across JSON/human/context-feed; race-safe remediation snapshot writes; canonical `verify-presentation` entrypoint |
|
|
74
|
-
| **v2.2.0** | `
|
|
90
|
+
| **v2.2.0** | `gantry context-feed`, `gantry audit-rigor`, `virtual_capture` ephemeral virtualization ([#68](https://github.com/jeger-ai/opengantry/issues/68)), product positioning, docs quality ([#66](https://github.com/jeger-ai/opengantry/issues/66)–[#69](https://github.com/jeger-ai/opengantry/issues/69), [#76](https://github.com/jeger-ai/opengantry/issues/76)) |
|
|
75
91
|
| **v2.1.0** | Import-layer Code Surgeon (`check-import-layers.mjs --json`, AST quarantine, `GXT_IMPORT_LAYER_VIOLATION`); workspace-resolved optional TypeScript for surgeons |
|
|
76
|
-
| **v2.0.0** | `
|
|
92
|
+
| **v2.0.0** | `gantry scan` + KPI gate, `register`, `check-imports`, `perimeter`; BYO `llm_verifiers`; KPI stale binding on `--pre-push`/`--ci` |
|
|
77
93
|
| **v1.1.2** | Verify pipeline close-out (MSN-0034–0035); typed verify phases, trace status at parse boundary |
|
|
78
94
|
| **v1.1.1** | Lib/command boundary, unified `runVerifyCore`, typed remediation, CommandReporter, mission YAML emitter |
|
|
79
95
|
| **v1.1.0** | Stale trace evidence, mission purity PR lock, CI target lock, `verify --json`, doctor substrate drift warn |
|
|
80
|
-
| **v1.0.0** | `
|
|
81
|
-
| **v0.9.0** | `
|
|
96
|
+
| **v1.0.0** | `gantry init --tutorial`, global `--audience` / `GXT_AUDIENCE`, adoption-first README + runbook |
|
|
97
|
+
| **v0.9.0** | `gantry start`, `verify --fix`, `status --json`, `onboarding`, GXT error codes |
|
|
82
98
|
|
|
83
99
|
## What you get
|
|
84
100
|
|
|
@@ -88,10 +104,10 @@ Current npm release in this repository: **`gapman` v2.2.3**. Use [`docs/ADOPTION
|
|
|
88
104
|
| **Routing map** (skills, roots, forbidden zones, path risks) | [`.gitagent/foreman/MANIFEST.json`](.gitagent/foreman/MANIFEST.json) |
|
|
89
105
|
| **Foreman** (cheap, manifest-only triage) | [`.gitagent/foreman/SOUL.md`](.gitagent/foreman/SOUL.md) |
|
|
90
106
|
| **Worker Runtime Contract** (env exports for IDE agents / scripts) | [`.gitagent/teacher/RUNTIME.md`](.gitagent/teacher/RUNTIME.md) |
|
|
91
|
-
| **Bootstrap** (zero-friction substrate install) | `
|
|
107
|
+
| **Bootstrap** (zero-friction substrate install) | `gantry init` + packaged [`templates/`](templates/) |
|
|
92
108
|
| **Architecture pointer** (where agents find code layout) | [`.gitagent/ARCHITECTURE.pointer.json`](.gitagent/ARCHITECTURE.pointer.json), [ARCHITECTURE-DISCOVERY.md](.gitagent/teacher/ARCHITECTURE-DISCOVERY.md) |
|
|
93
|
-
| **Work order + commit receipt** | YAML via `
|
|
94
|
-
| **
|
|
109
|
+
| **Work order + commit receipt** | YAML via `gantry legislate` + [`.gitagent/teacher/MISSION.example.yaml`](.gitagent/teacher/MISSION.example.yaml); Markdown reference: [`.gitagent/teacher/MISSION.template.md`](.gitagent/teacher/MISSION.template.md), [`.gitagent/teacher/commit-template.md`](.gitagent/teacher/commit-template.md) |
|
|
110
|
+
| **gantry CLI** | `npm install -g @jeger-ai/opengantry` or `npx @jeger-ai/opengantry` — see [gantry](#gantry-cli) |
|
|
95
111
|
| **Full orientation + workflow diagram** | [`.gitagent/README.md`](.gitagent/README.md) |
|
|
96
112
|
|
|
97
113
|
Core behaviors in plain language:
|
|
@@ -105,9 +121,9 @@ Core behaviors in plain language:
|
|
|
105
121
|
## Start here (5 minutes)
|
|
106
122
|
|
|
107
123
|
```bash
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
124
|
+
gantry init --tutorial # or: gantry init && gantry onboarding
|
|
125
|
+
gantry teacher set "$(git config user.email)"
|
|
126
|
+
gantry start "Your first change" --msn MSN-0001 --skill-key <manifest-key>
|
|
111
127
|
# Teacher: review mission scope/gates, then commit [MSN-0001] including the mission file
|
|
112
128
|
git log --grep='MSN-' --oneline
|
|
113
129
|
```
|
|
@@ -122,29 +138,29 @@ Treat the following as a **portable kit** you can drop into any Git repository (
|
|
|
122
138
|
|
|
123
139
|
### Enforcement boundary
|
|
124
140
|
|
|
125
|
-
**Prevents unreviewed edits where it matters.** IDE Agent Write/Edit is advisory TMVC; hard boundaries live in `runtime exec`, `
|
|
141
|
+
**Prevents unreviewed edits where it matters.** IDE Agent Write/Edit is advisory TMVC; hard boundaries live in `runtime exec`, `gantry verify`, and hooks.
|
|
126
142
|
|
|
127
143
|
| Tier | Mechanism | Enterprise control |
|
|
128
144
|
|------|-----------|-------------------|
|
|
129
|
-
| **Process-boundary** | `
|
|
145
|
+
| **Process-boundary** | `gantry runtime exec` | Agent cannot touch forbidden paths during orchestrated runs |
|
|
130
146
|
| **Deterministic hook** | Cursor `beforeShellExecution`, pre-push verify | Shell/hook writes to governance files require mission + verify |
|
|
131
147
|
| **Advisory** | IDE rules, `AGENTS.md`, sessionStart context | IDE suggestions alone do not count as approval |
|
|
132
148
|
|
|
133
149
|
Per-tool recipes: [`docs/INTEGRATIONS.md`](docs/INTEGRATIONS.md) (see **Enforcement boundary**).
|
|
134
150
|
|
|
135
|
-
### 1. Bootstrap with `
|
|
151
|
+
### 1. Bootstrap with `gantry init` (recommended)
|
|
136
152
|
|
|
137
|
-
From a built OpenGantry tree (or after copying the `
|
|
153
|
+
From a built OpenGantry tree (or after copying the `gantry` CLI + `templates/` into your toolchain):
|
|
138
154
|
|
|
139
155
|
```bash
|
|
140
|
-
npm ci && npm run build # in the OpenGantry repo, or use a globally linked
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
npm ci && npm run build # in the OpenGantry repo, or use a globally linked gantry
|
|
157
|
+
gantry init --tutorial # recommended first run; or gantry init (wizard / --yes)
|
|
158
|
+
gantry teacher set "$(git config user.email)" # repo-local (recommended)
|
|
159
|
+
gantry doctor
|
|
144
160
|
git config core.hooksPath .githooks
|
|
145
161
|
```
|
|
146
162
|
|
|
147
|
-
`
|
|
163
|
+
`gantry init` bootstraps a target git repository from packaged templates:
|
|
148
164
|
|
|
149
165
|
- **TTY:** interactive wizard (`@clack/prompts`) — select IDE/agent integrations, doc path, skills preset, hooks, CI, architecture pointer.
|
|
150
166
|
- **Non-TTY / CI:** auto-applies default profile (core + Cursor + hooks + CI) — no hang.
|
|
@@ -156,7 +172,7 @@ Asset lifecycles:
|
|
|
156
172
|
- `scaffold_only` files (for example `MANIFEST.json`, `RULES.md`, `skills/*.md`, IDE pointer files) are created when missing and preserved when customized.
|
|
157
173
|
- `managed_strict` runtime assets (workflow, validate script, hooks, schema/rules pointers) prompt before overwrite in an interactive terminal; use `--force` to skip the prompt.
|
|
158
174
|
|
|
159
|
-
Init also composes **`docs/INTEGRATIONS.md`** (or your chosen path) from `templates/integrations/compatibility.json`, scaffolds **`.gitagent/ARCHITECTURE.pointer.json`**, and installs runtime scripts (`gxt-runtime-env.sh`, `gxt-pin-mission.sh`, …). Store local tokens for protected architecture sources with **`
|
|
175
|
+
Init also composes **`docs/INTEGRATIONS.md`** (or your chosen path) from `templates/integrations/compatibility.json`, scaffolds **`.gitagent/ARCHITECTURE.pointer.json`**, and installs runtime scripts (`gxt-runtime-env.sh`, `gxt-pin-mission.sh`, …). Store local tokens for protected architecture sources with **`gantry arch cred set`** (stdin only; git-ignored under `.gitagent/history/credentials/`).
|
|
160
176
|
|
|
161
177
|
After `init`, customize your manifest and skills, then legislate. See [`docs/ADOPTION.md`](docs/ADOPTION.md) for the exact ordered runbook.
|
|
162
178
|
|
|
@@ -166,7 +182,7 @@ After `init`, customize your manifest and skills, then legislate. See [`docs/ADO
|
|
|
166
182
|
Set `path_risks`, `risk_keywords`, and each skill's `tmvc_roots`, `forbidden_zones`, and `trust_threshold` to match **your** directories and risk appetite.
|
|
167
183
|
- Align **[`.gitagent/teacher/RULES.md`](.gitagent/teacher/RULES.md)** with your review policy (tiers, who counts as "human audit", merge gates).
|
|
168
184
|
- Point **deterministic gates** in missions at **your** stack (`npm test`, `pytest`, `cargo test`, etc.).
|
|
169
|
-
- Store mission files you intend to **`
|
|
185
|
+
- Store mission files you intend to **`gantry verify`** under **`.gitagent/missions/`** and configure **Teacher allowlist** per repo (`gantry teacher set`, `.gitagent/foreman/TEACHER.allowlist.local`, or `git config gantry.teacherEmails`).
|
|
170
186
|
|
|
171
187
|
**Concrete gate example** (YAML fields in a mission file; adjust paths and commands):
|
|
172
188
|
|
|
@@ -175,11 +191,13 @@ gate_command: "npm test -- src/components/Button.test.tsx"
|
|
|
175
191
|
gate_success_substring: "Tests: 1 passed"
|
|
176
192
|
```
|
|
177
193
|
|
|
178
|
-
The gate is whatever command **fails closed** for your repo (lint, typecheck, integration suite). One explicit command beats a vague "run tests somewhere." Primary reference: [`.gitagent/teacher/MISSION.example.yaml`](.gitagent/teacher/MISSION.example.yaml). Markdown missions remain supported (`
|
|
194
|
+
The gate is whatever command **fails closed** for your repo (lint, typecheck, integration suite). One explicit command beats a vague "run tests somewhere." Primary reference: [`.gitagent/teacher/MISSION.example.yaml`](.gitagent/teacher/MISSION.example.yaml). Markdown missions remain supported (`gantry verify` parses both); [`.gitagent/teacher/MISSION.template.md`](.gitagent/teacher/MISSION.template.md) is a human-readable reference, not the `legislate` default.
|
|
195
|
+
|
|
196
|
+
### gantry CLI
|
|
179
197
|
|
|
180
|
-
|
|
198
|
+
The **Gantry CLI** (`gantry`) is the primary interface for **Open Source Gantry** — local, vendor-neutral, git-native governance in your repository.
|
|
181
199
|
|
|
182
|
-
Requires **Node.js 24+** (Active LTS line). Published as **`@jeger-ai/opengantry`** on npm; the `
|
|
200
|
+
Requires **Node.js 24+** (Active LTS line). Published as **`@jeger-ai/opengantry`** on npm; the `gantry` binary is registered via `package.json` `bin` (see [`package.json`](package.json)). The legacy `gapman` command remains a compatibility alias. Config namespaces: `GANTRY_*` env vars and `git config gantry.*` (legacy `GAPMAN_*` / `gapman.*` values are still read silently). From source: `npm ci && npm run build` → `dist/cli/index.js`.
|
|
183
201
|
|
|
184
202
|
**Developing OpenGantry:** dogfood the full stack — [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) (missions, hooks, verify, `npm run validate`). Layer rules: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md). Adopters: [`docs/ADOPTION.md`](docs/ADOPTION.md). Roadmap: [`docs/BACKLOG.md`](docs/BACKLOG.md) · [Project board](https://github.com/orgs/jeger-ai/projects/2).
|
|
185
203
|
|
|
@@ -187,54 +205,54 @@ Requires **Node.js 24+** (Active LTS line). Published as **`@jeger-ai/opengantry
|
|
|
187
205
|
|
|
188
206
|
| Step | Command | Outcome |
|
|
189
207
|
|------|---------|---------|
|
|
190
|
-
| Onboard | `
|
|
191
|
-
| Scope + approve | `
|
|
192
|
-
| Prove work | `
|
|
208
|
+
| Onboard | `gantry init --tutorial` or `gantry onboarding` | Feel Teacher stamp + verify loop (~3 min) |
|
|
209
|
+
| Scope + approve | `gantry start` → Teacher `[MSN-…]` commit | Unreviewed stub cannot pass full verify |
|
|
210
|
+
| Prove work | `gantry verify` | Gate + log quotes + greppable history |
|
|
193
211
|
|
|
194
|
-
**Global output:** `
|
|
212
|
+
**Global output:** `gantry --audience worker\|teacher\|verifier\|platform <cmd>` (or `GXT_AUDIENCE=verifier` in CI — silence unless `[GXT_*]` errors).
|
|
195
213
|
|
|
196
214
|
| Command | Purpose |
|
|
197
215
|
|--------|---------|
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
203
|
-
| `
|
|
204
|
-
| `
|
|
205
|
-
| `
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
208
|
-
| `
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `
|
|
224
|
-
| `
|
|
216
|
+
| `gantry init` | Bootstrap substrate + IDE packs + hooks + CI. `--tutorial` runs guided first loop after scaffold. |
|
|
217
|
+
| `gantry upgrade` | Plan substrate updates (`gantry upgrade plan` / `--dry-run` for preview JSON). Stage with `gantry upgrade`; `gantry upgrade apply --mission …` after Teacher commit. |
|
|
218
|
+
| `gantry check` | Validate `MANIFEST.json` shape + **Rule 4.4** sync: every `manifest.skills` key must have `skills/<key>.md`, with no orphan skill files. |
|
|
219
|
+
| `gantry status` | GXT readiness dashboard (`--json`, `--verbose`, `--audience worker\|teacher\|verifier\|platform`). |
|
|
220
|
+
| `gantry start "<intent>"` | Goal-first orchestration: triage → legislate stub → runtime next steps (`--msn`, `--skill-key`, `--json`). |
|
|
221
|
+
| `gantry onboarding` | Interactive walkthrough of the strict mission loop. Blocks on corrupt configured integration state; allows pristine uninitialized repos. |
|
|
222
|
+
| `gantry doctor` | Active readiness check (manifest, Teacher email, bypass secret match, hooks, architecture pointer, integration staleness). Warnings exit 0. `--audience` tailors next steps. |
|
|
223
|
+
| `gantry triage "<intent>"` | Foreman-style routing ([`SOUL.md`](.gitagent/foreman/SOUL.md)). `--json` for machine output (may include non-binding `adr_hints` from [`.gitagent/out-of-scope/`](.gitagent/out-of-scope/README.md)). `--emit-mission --msn MSN-0007` writes `.gitagent/missions/ACTIVE_MISSION.md` by default on **DIRECT_EXECUTION** only. |
|
|
224
|
+
| `gantry teacher show\|set` | Repo-local Teacher git-proof allowlist (`.gitagent/foreman/TEACHER.allowlist.local`; avoids global `GANTRY_TEACHER_EMAILS` leaking across projects). |
|
|
225
|
+
| `gantry legislate "<intent>" --msn MSN-0007` | Emit stub **YAML** mission under `.gitagent/missions/` with explicit MSN (`--skill-key` when triage would escalate; `--gate-command` / `--gate-success-substring` for one-click handoff). Teacher still **`git commit`**-legislates from an allowlisted email. |
|
|
226
|
+
| `gantry mission validate --file <path>` | Validate a mission `.md` or `.yaml` (YAML checked against [`.gitagent/teacher/MISSION.schema.yaml`](.gitagent/teacher/MISSION.schema.yaml)). |
|
|
227
|
+
| `gantry mission snapshot --file <path>` | Write start-state JSON under `.gitagent/history/` (git HEAD, branch, dirty flag, manifest hash, hashes of files under the mission skill's `tmvc_roots`). |
|
|
228
|
+
| `gantry runtime env --mission <path>` | Worker Runtime Contract: emit `GXT_REPO_ROOT`, `GXT_MISSION_FILE`, `GXT_MSN_ID`, `GXT_SKILL_KEY`, `GXT_TMVC_ROOTS`, `GXT_FORBIDDEN_ZONES`, `GXT_WORKER_LOG`. Default: POSIX `export …` lines; `--json` for scripts. [.gitagent/teacher/RUNTIME.md](.gitagent/teacher/RUNTIME.md). |
|
|
229
|
+
| `gantry runtime exec --mission <path> -- <cmd…>` | Run worker command with mission env, telemetry capture, and forbidden-zone scan (strongest TMVC trap). |
|
|
230
|
+
| `gantry context-request --path <p…> --reason <text>` | Append a PENDING Context Request to `WORKER_LOG.md` (RULES §4 TMVC expansion). Uses pinned mission or `--mission`. `--stage-worker-log` opt-in stages the log. |
|
|
231
|
+
| `gantry tmvc guard [--strict]` | Pre-commit TMVC path guard: advisory warnings on staged paths outside mission `tmvc_roots` (stderr; exit 0). `--strict` or `GXT_TMVC_GUARD_STRICT=1` blocks. Skips when no pinned mission. |
|
|
232
|
+
| `gantry mcp serve` | Stdio MCP server exposing `gxt_*` tools (legislation, pin, runtime env, verify with `fix_hints`, `gxt_start_orchestration`, exec). `gxt_verify` uses the flat `--json` envelope — see [ADOPTION.md § MCP verify envelope](docs/ADOPTION.md). Configure via `.cursor/mcp.json`. |
|
|
233
|
+
| `gantry verify --mission <path>` | Teacher-approved mission commit + gate + trace. **`--json`** structured output (`status`, `phase`, `error_code`, `fix_hints`). **`--fix`** guided repair; when a **Code Surgeon** applies a quarantine mutation, logs `[SURGEON-MUTATION]` to `WORKER_LOG.md` and reruns full verify with fix disabled (never auto-PASS). CI: `--audience verifier` (errors only). Failures emit **`GXT_*`** codes. Optional **`kpi_gate`** phase reads committed [KPI report](.gitagent/teacher/KPI-REPORT.schema.yaml) (after gate, before trace). **`--ci`** / **`--pre-push`**: fail-closed on stale KPI evidence. |
|
|
234
|
+
| `gantry scan --mission <path>` | Run mission `llm_verifiers` (BYO commands) and write namespaced KPI report JSON for `kpi_gate`. |
|
|
235
|
+
| `gantry register <dir>` | AST discovery: propose skill scope from folder imports/exports (does not mutate `MANIFEST.json`). |
|
|
236
|
+
| `gantry check-imports <dir> --ban <spec…>` | Deterministic banned-import scan (usable as `gate_command`; no LLM). |
|
|
237
|
+
| `gantry perimeter [--base-ref <ref>] [--ci]` | Protected governance paths: local advisory; **`--ci`** requires verified commit signatures. |
|
|
238
|
+
| `gantry arch pointer` | Print architecture pointer summary for agents (`.gitagent/ARCHITECTURE.pointer.json`). |
|
|
239
|
+
| `gantry arch cred status\|set\|unset` | Git-ignored credential slots for authenticated external architecture sources (secrets via stdin only). |
|
|
240
|
+
| `gantry metrics [--json] [--ref main]` | Git-native governance rollup (`--json` includes `gxt_extension_metadata`). See [`docs/ADOPTION.md`](docs/ADOPTION.md). |
|
|
241
|
+
| `gantry context-feed [--json] [--clear]` | Read or atomically clear the latest verify remediation snapshot (`.gitagent/tmp/NEXT_REMEDIATION.json`) for IDE repair loops. |
|
|
242
|
+
| `gantry audit-rigor [--json] [--strict]` | Meta-governance audit: TypeScript strictness, coverage artifacts, MANIFEST wildcard hygiene. |
|
|
225
243
|
|
|
226
244
|
**Who can approve missions (Teacher allowlist):** only allowlisted identities can legislate missions that verify accepts. Precedence:
|
|
227
245
|
|
|
228
246
|
1. `.gitagent/foreman/TEACHER.allowlist` (+ optional gitignored `.local` merge)
|
|
229
|
-
2. `git config
|
|
230
|
-
3. `
|
|
247
|
+
2. `git config gantry.teacherEmails "a@x.com,b@y.com"`
|
|
248
|
+
3. `GANTRY_TEACHER_EMAILS` env (CI escape hatch only)
|
|
231
249
|
4. implicit `git config user.email` when nothing else is set
|
|
232
250
|
|
|
233
|
-
Use **`
|
|
251
|
+
Use **`gantry teacher set "$(git config user.email)"`** after clone — do not rely on a global shell export when you work across multiple projects.
|
|
234
252
|
|
|
235
253
|
### Worker Runtime quickstart
|
|
236
254
|
|
|
237
|
-
Agents (Cursor, Junie, local scripts) should not guess TMVC roots — read them from **`
|
|
255
|
+
Agents (Cursor, Junie, local scripts) should not guess TMVC roots — read them from **`gantry runtime env`**.
|
|
238
256
|
|
|
239
257
|
Each `--mission` path must refer to **an existing mission file** (ENOENT means the YAML or Markdown mission is missing). Split these into separate shell steps if you paste from docs.
|
|
240
258
|
|
|
@@ -251,7 +269,7 @@ node dist/cli/index.js runtime env --mission .gitagent/missions/example.verify.y
|
|
|
251
269
|
node dist/cli/index.js runtime exec --mission .gitagent/missions/example.verify.yaml -- <your-agent-command>
|
|
252
270
|
```
|
|
253
271
|
|
|
254
|
-
Inspect `GXT_TMVC_ROOTS`, `GXT_FORBIDDEN_ZONES`, and `GXT_WORKER_LOG`; write forensic trace quotes to **`WORKER_LOG.md`** (or `--worker-log` at verify time), then **`
|
|
272
|
+
Inspect `GXT_TMVC_ROOTS`, `GXT_FORBIDDEN_ZONES`, and `GXT_WORKER_LOG`; write forensic trace quotes to **`WORKER_LOG.md`** (or `--worker-log` at verify time), then **`gantry verify`** as usual.
|
|
255
273
|
|
|
256
274
|
**Legislate a stub mission (Teacher edits + commits — then wire `runtime env` to that file path):**
|
|
257
275
|
|
|
@@ -265,16 +283,16 @@ Details and variable semantics: [.gitagent/teacher/RUNTIME.md](.gitagent/teacher
|
|
|
265
283
|
|
|
266
284
|
### 3. Wire agents (and optionally CI)
|
|
267
285
|
|
|
268
|
-
- **[`docs/INTEGRATIONS.md`](docs/INTEGRATIONS.md)** — closed-loop agent integrations (enforcement boundary, remote handoff, per-tool recipes for Cursor, Claude Code, OpenAI Codex CLI, OpenCode, Junie, Antigravity, Cline, Aider, OpenHands). Installed by `
|
|
286
|
+
- **[`docs/INTEGRATIONS.md`](docs/INTEGRATIONS.md)** — closed-loop agent integrations (enforcement boundary, remote handoff, per-tool recipes for Cursor, Claude Code, OpenAI Codex CLI, OpenCode, Junie, Antigravity, Cline, Aider, OpenHands). Installed by `gantry init`.
|
|
269
287
|
- **[`AGENTS.md`](AGENTS.md)** tells agents to read **RULES** + **MANIFEST** before acting.
|
|
270
288
|
- **[`.cursor/rules/opengantry-gxt-substrate.mdc`](.cursor/rules/opengantry-gxt-substrate.mdc)** does the same for Cursor with `alwaysApply: true`.
|
|
271
289
|
- **CI:** this repo includes **[`.github/workflows/gxt-validate.yml`](.github/workflows/gxt-validate.yml)**:
|
|
272
290
|
- **PR governance (PR only):** mission PRs must target the **default branch** (`main` in this repo; `github.event.repository.default_branch` in init template, overridable via `GXT_INTEGRATION_BRANCH`) — prevents stacked mission merges.
|
|
273
|
-
- **
|
|
291
|
+
- **gantry:** `npm ci` / `npm run build`, then `gantry check`, `gantry doctor`, and unit tests.
|
|
274
292
|
- **Manifest (jq parity):** validates [`.gitagent/foreman/MANIFEST.json`](.gitagent/foreman/MANIFEST.json) via [`scripts/validate-gxt.sh`](scripts/validate-gxt.sh) `manifest`.
|
|
275
293
|
- **Changed-code quality (PR only):** ESLint complexity, import layers, line budgets on touched `src/cli/**/*.ts`.
|
|
276
294
|
- **MSN (PR only, path-scoped):** on **pull_request** only, any **non-merge** commit in the PR range that touches `.gitagent/`, repo-root `WORKER_LOG.md`, `.githooks/`, or [`.github/workflows/gxt-validate.yml`](.github/workflows/gxt-validate.yml) must have a subject starting with **`[MSN-NNNN]`** (four digits). Other paths (e.g. root `README.md` only) do not trigger this check.
|
|
277
|
-
- **Mission purity (PR only):** [`scripts/verify-pr-missions.sh`](scripts/verify-pr-missions.sh) requires exactly one `[MSN-NNNN]` in `${base}..${head}` commit subjects before full `
|
|
295
|
+
- **Mission purity (PR only):** [`scripts/verify-pr-missions.sh`](scripts/verify-pr-missions.sh) requires exactly one `[MSN-NNNN]` in `${base}..${head}` commit subjects before full `gantry verify` on changed missions.
|
|
278
296
|
- **Local (full stack):** [`scripts/dev-validate.sh`](scripts/dev-validate.sh) / `npm run validate` — superset of CI (includes changed-code + MSN vs `origin/main`).
|
|
279
297
|
|
|
280
298
|
```bash
|
|
@@ -295,10 +313,10 @@ Details and the workflow diagram: **[`.gitagent/README.md`](.gitagent/README.md)
|
|
|
295
313
|
|
|
296
314
|
### Advanced: manual vendoring
|
|
297
315
|
|
|
298
|
-
If you cannot run `
|
|
316
|
+
If you cannot run `gantry init`, copy at least:
|
|
299
317
|
|
|
300
318
|
- `.gitagent/` (entire tree)
|
|
301
|
-
- `skills/` (optional in minimal vendoring, but **required** for Rule 4.4: one `skills/<skill-key>.md` per manifest skill — enforced by `
|
|
319
|
+
- `skills/` (optional in minimal vendoring, but **required** for Rule 4.4: one `skills/<skill-key>.md` per manifest skill — enforced by `gantry check`)
|
|
302
320
|
- `.githooks/` (optional: creates an empty repo-root `WORKER_LOG.md` when you check out a feature branch)
|
|
303
321
|
- `AGENTS.md` (or merge its bullets into your existing agent instructions)
|
|
304
322
|
- Optionally `.cursor/rules/opengantry-gxt-substrate.mdc` if you use Cursor
|
|
@@ -318,10 +336,10 @@ Add to your **`.gitignore`** (if not already present):
|
|
|
318
336
|
|
|
319
337
|
```bash
|
|
320
338
|
npm install @jeger-ai/opengantry@latest
|
|
321
|
-
|
|
339
|
+
gantry upgrade
|
|
322
340
|
# Review .gitagent/.upgrade-tmp/; Teacher-commit the upgrade mission YAML
|
|
323
|
-
|
|
324
|
-
|
|
341
|
+
gantry upgrade --apply --mission .gitagent/missions/MSN-9001.upgrade-vX.Y.Z.yaml
|
|
342
|
+
gantry doctor
|
|
325
343
|
```
|
|
326
344
|
|
|
327
345
|
See [`docs/ADOPTION.md`](docs/ADOPTION.md) and [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md#substrate-upgrade-loop-adopters--dogfood).
|
|
@@ -361,7 +379,8 @@ Always **review the diff** before commit; never bulk-overwrite a customized `MAN
|
|
|
361
379
|
|
|
362
380
|
| Pattern | Typical shape | Audit / production readiness |
|
|
363
381
|
|---------|----------------|------------------------------|
|
|
364
|
-
| **GXT / OpenGantry** | Git-native missions, manifest routing, deterministic gates, auditable log mapped to **`WORKER_LOG.md`**, human `[MSN-XXXX]` approval + SOD ([`RULES.md`](.gitagent/teacher/RULES.md)) | **Autonomous Repository Engineering** — scoped missions, not always-on chat. Greppable missions + gate output + log quotes. |
|
|
382
|
+
| **GXT / OpenGantry** | Git-native missions, manifest routing, deterministic gates, auditable log mapped to **`WORKER_LOG.md`**, human `[MSN-XXXX]` approval + SOD ([`RULES.md`](.gitagent/teacher/RULES.md)) | **Autonomous Repository Engineering** — scoped missions, not always-on chat. Greppable missions + gate output + log quotes. **Local-first**, **vendor-neutral** governance engine in your repo. |
|
|
383
|
+
| Cloud observability / agent dashboards | Hosted UI for metrics, traces, or agent session visibility | Strong for **fleet visibility**; per-repo change authorization and Git-native audit artifacts are typically layered separately |
|
|
365
384
|
| Agent "swarm" / choreography layers | Orchestrates model calls across services; emphasizes throughput and parallelism | Strong on **coverage** of tasks; lineage and per-change evidence depends on tooling above the swarm |
|
|
366
385
|
| Unstructured desktop assistants | Reactive help in-editor or OS-wide; informal plans | Lightweight for exploration; weakest default for **reproducible** production sign-off without additional discipline |
|
|
367
386
|
|
|
@@ -369,7 +388,7 @@ GXT deliberately trades "always-on improvisation" for a **narrow, inspectable en
|
|
|
369
388
|
|
|
370
389
|
## Relationship to this repository
|
|
371
390
|
|
|
372
|
-
**jeger-ai/opengantry** is the **canonical reference tree** for **GXT** (manifest `schema_version` **v0.5.0** law + **`
|
|
391
|
+
**jeger-ai/opengantry** is the **canonical reference tree** for **GXT** (manifest `schema_version` **v0.5.0** law + **`gantry` v2.2.5** CLI). Install the CLI with `npm install -g @jeger-ai/opengantry`, or fork this repo and run `gantry init` in your project.
|
|
373
392
|
|
|
374
393
|
## Security
|
|
375
394
|
|
|
@@ -8,7 +8,7 @@ export function runArchPointer(options = {}) {
|
|
|
8
8
|
repoRoot = getRepoRoot(options.cwd);
|
|
9
9
|
}
|
|
10
10
|
catch (e) {
|
|
11
|
-
logError(e instanceof Error ? e.message.replace("
|
|
11
|
+
logError(e instanceof Error ? e.message.replace("gantry: ", "") : String(e));
|
|
12
12
|
setExitCode(2);
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
@@ -44,7 +44,7 @@ export async function runArchCredSet(options) {
|
|
|
44
44
|
try {
|
|
45
45
|
const values = parseCredentialValuesFromStdin(options.kind, stdin);
|
|
46
46
|
writeArchitectureCredential(repoRoot, options.slot, options.kind, values);
|
|
47
|
-
logInfo(`
|
|
47
|
+
logInfo(`gantry arch cred: stored slot=${options.slot} kind=${options.kind}`);
|
|
48
48
|
}
|
|
49
49
|
catch (e) {
|
|
50
50
|
logError(errorMessage(e));
|
|
@@ -63,11 +63,11 @@ export function runArchCredUnset(options) {
|
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
if (!removeArchitectureCredential(repoRoot, options.slot)) {
|
|
66
|
-
logError(`
|
|
66
|
+
logError(`gantry arch cred: slot ${options.slot} not found`);
|
|
67
67
|
setExitCode(2);
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
-
logInfo(`
|
|
70
|
+
logInfo(`gantry arch cred: removed slot=${options.slot}`);
|
|
71
71
|
}
|
|
72
72
|
export function runArchCredStatus(options = {}) {
|
|
73
73
|
let repoRoot;
|
|
@@ -3,7 +3,7 @@ import { logError, setExitCode } from "../lib/cli-io.js";
|
|
|
3
3
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
4
4
|
export function runCheckImports(options) {
|
|
5
5
|
if (options.ban.length === 0) {
|
|
6
|
-
logError("
|
|
6
|
+
logError("gantry check-imports: provide at least one --ban specifier");
|
|
7
7
|
setExitCode(2);
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
@@ -23,7 +23,7 @@ async function resolveOnboardingMissionPath(p, root, intent) {
|
|
|
23
23
|
logInfo(` ${onboardingVerifyHint(EXAMPLE_MISSION)}`);
|
|
24
24
|
return { missionPath, useExample };
|
|
25
25
|
}
|
|
26
|
-
p.log.step("Step 3 — Scaffold mission (
|
|
26
|
+
p.log.step("Step 3 — Scaffold mission (gantry start)");
|
|
27
27
|
const result = runStartOrchestration({
|
|
28
28
|
intent: intent.trim(),
|
|
29
29
|
writeMission: true,
|
|
@@ -59,7 +59,7 @@ export async function runOnboarding(options = {}) {
|
|
|
59
59
|
const { root } = loadWorkspace();
|
|
60
60
|
const manifestPath = path.join(root, ".gitagent", "foreman", "MANIFEST.json");
|
|
61
61
|
if (!fs.existsSync(manifestPath)) {
|
|
62
|
-
logError("Run
|
|
62
|
+
logError("Run gantry init first — substrate not found.");
|
|
63
63
|
setExitCode(2);
|
|
64
64
|
p.outro("Onboarding aborted");
|
|
65
65
|
return;
|
|
@@ -74,7 +74,7 @@ export async function runOnboarding(options = {}) {
|
|
|
74
74
|
p.log.step("Integration health");
|
|
75
75
|
for (const msg of blockers)
|
|
76
76
|
logWarn(` ${msg}`);
|
|
77
|
-
logError("Integration issues detected — run
|
|
77
|
+
logError("Integration issues detected — run gantry doctor or pass --force to continue.");
|
|
78
78
|
setExitCode(2);
|
|
79
79
|
p.outro("Onboarding aborted (integration gates)");
|
|
80
80
|
return;
|
|
@@ -88,8 +88,8 @@ export async function runOnboarding(options = {}) {
|
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
p.log.step("Step 1 — Teacher allowlist");
|
|
91
|
-
logInfo('
|
|
92
|
-
p.log.step("Step 2 — Declare intent (
|
|
91
|
+
logInfo(' gantry teacher set "$(git config user.email)"');
|
|
92
|
+
p.log.step("Step 2 — Declare intent (gantry start)");
|
|
93
93
|
const intent = await p.text({
|
|
94
94
|
message: "What do you want to build?",
|
|
95
95
|
placeholder: "Fix login spinner on checkout",
|
|
@@ -36,10 +36,10 @@ export function runPerimeter(options) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
if (result.violations.length > 0 && options.ci !== true) {
|
|
39
|
-
logInfo("
|
|
39
|
+
logInfo("gantry perimeter: advisory-only mode — no hard failures locally");
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
|
-
logInfo("
|
|
42
|
+
logInfo("gantry perimeter: OK");
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
catch (e) {
|
|
@@ -31,7 +31,7 @@ export function runRuntimeEnv(options) {
|
|
|
31
31
|
catch (e) {
|
|
32
32
|
const errno = typeof e === "object" && e !== null ? e.code : undefined;
|
|
33
33
|
if (errno === "ENOENT") {
|
|
34
|
-
logError(`runtime env: mission file not found: ${options.mission} (ENOENT). Use an existing mission path — e.g. .gitagent/missions/example.verify.yaml — or run
|
|
34
|
+
logError(`runtime env: mission file not found: ${options.mission} (ENOENT). Use an existing mission path — e.g. .gitagent/missions/example.verify.yaml — or run gantry legislate first, then pass that YAML path.`);
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
37
|
logError(errorMessage(e));
|
|
@@ -4,7 +4,7 @@ import { logError, logInfo, setExitCode } from "../lib/cli-io.js";
|
|
|
4
4
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
5
5
|
export function runScan(options) {
|
|
6
6
|
if (!options.mission) {
|
|
7
|
-
logError("
|
|
7
|
+
logError("gantry scan: --mission is required");
|
|
8
8
|
setExitCode(2);
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
@@ -16,7 +16,7 @@ export function runScan(options) {
|
|
|
16
16
|
process.stdout.write(`${JSON.stringify({ status: "ok", report_path: result.reportPath, report: result.report }, null, 2)}\n`);
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
logInfo(`
|
|
19
|
+
logInfo(`gantry scan: wrote ${result.reportPath}`);
|
|
20
20
|
logInfo(`metrics: ${Object.keys(result.report.metrics).length}`);
|
|
21
21
|
}
|
|
22
22
|
catch (e) {
|
|
@@ -19,7 +19,7 @@ export function runTeacherShow(options = {}) {
|
|
|
19
19
|
}
|
|
20
20
|
if (resolved.emails.length === 0) {
|
|
21
21
|
logInfo(`${CLI_NAME} teacher: no allowlist configured`);
|
|
22
|
-
logInfo(` Run:
|
|
22
|
+
logInfo(` Run: gantry teacher set "$(git config user.email)"`);
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
logInfo(`${CLI_NAME} teacher: ${resolved.emails.join(", ")}`);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { VerifyOptions } from "../lib/verify-engine.js";
|
|
2
2
|
export type { VerifyOptions } from "../lib/verify-engine.js";
|
|
3
3
|
export declare function runVerify(options: VerifyOptions): Promise<void>;
|
|
4
|
-
/** Exposed for tests that need silent phase evaluation without fix wrapper. */
|
|
5
|
-
export declare function evaluateVerifyForMission(options: VerifyOptions): import("../lib/verify-engine.js").VerifyPhaseResult;
|
|
6
4
|
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/verify.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/verify.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAM7D,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAqD7D,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDrE"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { logError, logInfo, setExitCode } from "../lib/cli-io.js";
|
|
2
2
|
import { gitRevParse } from "../lib/git.js";
|
|
3
|
-
import { parseMissionFile } from "../lib/missions/parser.js";
|
|
4
3
|
import { initFailurePayload } from "../lib/verify-presentation.js";
|
|
5
4
|
import { emitVerifyJson } from "../lib/verify-presentation.js";
|
|
6
|
-
import { evaluateVerifyPhases } from "../lib/verify-engine.js";
|
|
7
5
|
import { discoverChangedMissionFiles } from "../lib/verify-engine.js";
|
|
8
6
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
9
7
|
import { GapmanUserError, reportUserFacingError } from "../lib/errors.js";
|
|
@@ -33,12 +31,12 @@ async function runVerifyChangedMissions(options) {
|
|
|
33
31
|
const baseRef = resolveChangedMissionsBaseRef(root, options.baseRef);
|
|
34
32
|
const missions = discoverChangedMissionFiles(root, baseRef);
|
|
35
33
|
if (missions.length === 0) {
|
|
36
|
-
logInfo(`
|
|
34
|
+
logInfo(`gantry verify: no changed mission files vs ${baseRef}`);
|
|
37
35
|
return;
|
|
38
36
|
}
|
|
39
37
|
let worstExit = 0;
|
|
40
38
|
for (const mission of missions) {
|
|
41
|
-
logInfo(`
|
|
39
|
+
logInfo(`gantry verify: ${mission} (changed vs ${baseRef})`);
|
|
42
40
|
const result = await runVerifyCore({ ...options, mission, changedMissions: false });
|
|
43
41
|
if (!result.ok && result.exitCode > worstExit) {
|
|
44
42
|
worstExit = result.exitCode;
|
|
@@ -78,7 +76,7 @@ export async function runVerify(options) {
|
|
|
78
76
|
return;
|
|
79
77
|
}
|
|
80
78
|
if (!options.mission) {
|
|
81
|
-
logError("
|
|
79
|
+
logError("gantry verify: --mission is required (or use --changed-missions)");
|
|
82
80
|
setExitCode(2);
|
|
83
81
|
return;
|
|
84
82
|
}
|
|
@@ -98,10 +96,4 @@ export async function runVerify(options) {
|
|
|
98
96
|
reportUserFacingError(e);
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
|
-
/** Exposed for tests that need silent phase evaluation without fix wrapper. */
|
|
102
|
-
export function evaluateVerifyForMission(options) {
|
|
103
|
-
const { root, manifest } = loadWorkspace();
|
|
104
|
-
const mission = parseMissionFile(root, options.mission);
|
|
105
|
-
return evaluateVerifyPhases(root, mission, options, manifest);
|
|
106
|
-
}
|
|
107
99
|
//# sourceMappingURL=verify.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/cli/commands/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/cli/commands/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ajv-loader.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/ajv-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAQ5C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAItE"}
|