oi-gantry 0.2.0__tar.gz

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.
Files changed (164) hide show
  1. oi_gantry-0.2.0/.gitignore +12 -0
  2. oi_gantry-0.2.0/CHANGELOG.md +96 -0
  3. oi_gantry-0.2.0/PKG-INFO +133 -0
  4. oi_gantry-0.2.0/README.md +120 -0
  5. oi_gantry-0.2.0/SampleProject/README.md +50 -0
  6. oi_gantry-0.2.0/VERSION +1 -0
  7. oi_gantry-0.2.0/dist/claude/commands/gantry/acquire.md +348 -0
  8. oi_gantry-0.2.0/dist/claude/commands/gantry/ask.md +162 -0
  9. oi_gantry-0.2.0/dist/claude/commands/gantry/batch.md +574 -0
  10. oi_gantry-0.2.0/dist/claude/commands/gantry/connect.md +256 -0
  11. oi_gantry-0.2.0/dist/claude/commands/gantry/decide.md +512 -0
  12. oi_gantry-0.2.0/dist/claude/commands/gantry/diagnose.md +483 -0
  13. oi_gantry-0.2.0/dist/claude/commands/gantry/escalate.md +577 -0
  14. oi_gantry-0.2.0/dist/claude/commands/gantry/fix.md +357 -0
  15. oi_gantry-0.2.0/dist/claude/commands/gantry/hitl.md +288 -0
  16. oi_gantry-0.2.0/dist/claude/commands/gantry/memory.md +234 -0
  17. oi_gantry-0.2.0/dist/claude/commands/gantry/observe.md +488 -0
  18. oi_gantry-0.2.0/dist/claude/commands/gantry/pass.md +352 -0
  19. oi_gantry-0.2.0/dist/claude/commands/gantry/pull.md +329 -0
  20. oi_gantry-0.2.0/dist/claude/commands/gantry/report.md +179 -0
  21. oi_gantry-0.2.0/dist/claude/commands/gantry/resume.md +271 -0
  22. oi_gantry-0.2.0/dist/claude/commands/gantry/select.md +527 -0
  23. oi_gantry-0.2.0/dist/claude/commands/gantry/status.md +241 -0
  24. oi_gantry-0.2.0/dist/claude/commands/gantry/sync.md +313 -0
  25. oi_gantry-0.2.0/dist/claude/commands/gantry/take.md +618 -0
  26. oi_gantry-0.2.0/dist/claude/commands/gantry/verify.md +668 -0
  27. oi_gantry-0.2.0/dist/claude/commands/gantry.md +565 -0
  28. oi_gantry-0.2.0/dist/codex/prompts/gantry-acquire.md +345 -0
  29. oi_gantry-0.2.0/dist/codex/prompts/gantry-ask.md +158 -0
  30. oi_gantry-0.2.0/dist/codex/prompts/gantry-batch.md +570 -0
  31. oi_gantry-0.2.0/dist/codex/prompts/gantry-connect.md +252 -0
  32. oi_gantry-0.2.0/dist/codex/prompts/gantry-decide.md +508 -0
  33. oi_gantry-0.2.0/dist/codex/prompts/gantry-diagnose.md +480 -0
  34. oi_gantry-0.2.0/dist/codex/prompts/gantry-escalate.md +573 -0
  35. oi_gantry-0.2.0/dist/codex/prompts/gantry-fix.md +354 -0
  36. oi_gantry-0.2.0/dist/codex/prompts/gantry-hitl.md +284 -0
  37. oi_gantry-0.2.0/dist/codex/prompts/gantry-memory.md +230 -0
  38. oi_gantry-0.2.0/dist/codex/prompts/gantry-observe.md +485 -0
  39. oi_gantry-0.2.0/dist/codex/prompts/gantry-pass.md +348 -0
  40. oi_gantry-0.2.0/dist/codex/prompts/gantry-pull.md +326 -0
  41. oi_gantry-0.2.0/dist/codex/prompts/gantry-report.md +176 -0
  42. oi_gantry-0.2.0/dist/codex/prompts/gantry-resume.md +268 -0
  43. oi_gantry-0.2.0/dist/codex/prompts/gantry-select.md +524 -0
  44. oi_gantry-0.2.0/dist/codex/prompts/gantry-status.md +238 -0
  45. oi_gantry-0.2.0/dist/codex/prompts/gantry-sync.md +310 -0
  46. oi_gantry-0.2.0/dist/codex/prompts/gantry-take.md +614 -0
  47. oi_gantry-0.2.0/dist/codex/prompts/gantry-verify.md +665 -0
  48. oi_gantry-0.2.0/dist/codex/prompts/gantry.md +561 -0
  49. oi_gantry-0.2.0/dist/copilot/prompts/gantry-acquire.prompt.md +348 -0
  50. oi_gantry-0.2.0/dist/copilot/prompts/gantry-ask.prompt.md +161 -0
  51. oi_gantry-0.2.0/dist/copilot/prompts/gantry-batch.prompt.md +573 -0
  52. oi_gantry-0.2.0/dist/copilot/prompts/gantry-connect.prompt.md +255 -0
  53. oi_gantry-0.2.0/dist/copilot/prompts/gantry-decide.prompt.md +511 -0
  54. oi_gantry-0.2.0/dist/copilot/prompts/gantry-diagnose.prompt.md +483 -0
  55. oi_gantry-0.2.0/dist/copilot/prompts/gantry-escalate.prompt.md +576 -0
  56. oi_gantry-0.2.0/dist/copilot/prompts/gantry-fix.prompt.md +357 -0
  57. oi_gantry-0.2.0/dist/copilot/prompts/gantry-hitl.prompt.md +287 -0
  58. oi_gantry-0.2.0/dist/copilot/prompts/gantry-memory.prompt.md +233 -0
  59. oi_gantry-0.2.0/dist/copilot/prompts/gantry-observe.prompt.md +488 -0
  60. oi_gantry-0.2.0/dist/copilot/prompts/gantry-pass.prompt.md +351 -0
  61. oi_gantry-0.2.0/dist/copilot/prompts/gantry-pull.prompt.md +329 -0
  62. oi_gantry-0.2.0/dist/copilot/prompts/gantry-report.prompt.md +179 -0
  63. oi_gantry-0.2.0/dist/copilot/prompts/gantry-resume.prompt.md +271 -0
  64. oi_gantry-0.2.0/dist/copilot/prompts/gantry-select.prompt.md +527 -0
  65. oi_gantry-0.2.0/dist/copilot/prompts/gantry-status.prompt.md +241 -0
  66. oi_gantry-0.2.0/dist/copilot/prompts/gantry-sync.prompt.md +313 -0
  67. oi_gantry-0.2.0/dist/copilot/prompts/gantry-take.prompt.md +617 -0
  68. oi_gantry-0.2.0/dist/copilot/prompts/gantry-verify.prompt.md +668 -0
  69. oi_gantry-0.2.0/dist/copilot/prompts/gantry.prompt.md +564 -0
  70. oi_gantry-0.2.0/dist/cursor/commands/gantry-acquire.md +347 -0
  71. oi_gantry-0.2.0/dist/cursor/commands/gantry-ask.md +160 -0
  72. oi_gantry-0.2.0/dist/cursor/commands/gantry-batch.md +572 -0
  73. oi_gantry-0.2.0/dist/cursor/commands/gantry-connect.md +254 -0
  74. oi_gantry-0.2.0/dist/cursor/commands/gantry-decide.md +510 -0
  75. oi_gantry-0.2.0/dist/cursor/commands/gantry-diagnose.md +482 -0
  76. oi_gantry-0.2.0/dist/cursor/commands/gantry-escalate.md +575 -0
  77. oi_gantry-0.2.0/dist/cursor/commands/gantry-fix.md +356 -0
  78. oi_gantry-0.2.0/dist/cursor/commands/gantry-hitl.md +286 -0
  79. oi_gantry-0.2.0/dist/cursor/commands/gantry-memory.md +232 -0
  80. oi_gantry-0.2.0/dist/cursor/commands/gantry-observe.md +487 -0
  81. oi_gantry-0.2.0/dist/cursor/commands/gantry-pass.md +350 -0
  82. oi_gantry-0.2.0/dist/cursor/commands/gantry-pull.md +328 -0
  83. oi_gantry-0.2.0/dist/cursor/commands/gantry-report.md +178 -0
  84. oi_gantry-0.2.0/dist/cursor/commands/gantry-resume.md +270 -0
  85. oi_gantry-0.2.0/dist/cursor/commands/gantry-select.md +526 -0
  86. oi_gantry-0.2.0/dist/cursor/commands/gantry-status.md +240 -0
  87. oi_gantry-0.2.0/dist/cursor/commands/gantry-sync.md +312 -0
  88. oi_gantry-0.2.0/dist/cursor/commands/gantry-take.md +616 -0
  89. oi_gantry-0.2.0/dist/cursor/commands/gantry-verify.md +667 -0
  90. oi_gantry-0.2.0/dist/cursor/commands/gantry.md +563 -0
  91. oi_gantry-0.2.0/dist/gemini/commands/gantry/acquire.toml +347 -0
  92. oi_gantry-0.2.0/dist/gemini/commands/gantry/ask.toml +160 -0
  93. oi_gantry-0.2.0/dist/gemini/commands/gantry/batch.toml +572 -0
  94. oi_gantry-0.2.0/dist/gemini/commands/gantry/connect.toml +254 -0
  95. oi_gantry-0.2.0/dist/gemini/commands/gantry/decide.toml +510 -0
  96. oi_gantry-0.2.0/dist/gemini/commands/gantry/diagnose.toml +482 -0
  97. oi_gantry-0.2.0/dist/gemini/commands/gantry/escalate.toml +575 -0
  98. oi_gantry-0.2.0/dist/gemini/commands/gantry/fix.toml +356 -0
  99. oi_gantry-0.2.0/dist/gemini/commands/gantry/hitl.toml +286 -0
  100. oi_gantry-0.2.0/dist/gemini/commands/gantry/memory.toml +232 -0
  101. oi_gantry-0.2.0/dist/gemini/commands/gantry/observe.toml +487 -0
  102. oi_gantry-0.2.0/dist/gemini/commands/gantry/pass.toml +350 -0
  103. oi_gantry-0.2.0/dist/gemini/commands/gantry/pull.toml +328 -0
  104. oi_gantry-0.2.0/dist/gemini/commands/gantry/report.toml +178 -0
  105. oi_gantry-0.2.0/dist/gemini/commands/gantry/resume.toml +270 -0
  106. oi_gantry-0.2.0/dist/gemini/commands/gantry/select.toml +526 -0
  107. oi_gantry-0.2.0/dist/gemini/commands/gantry/status.toml +240 -0
  108. oi_gantry-0.2.0/dist/gemini/commands/gantry/sync.toml +312 -0
  109. oi_gantry-0.2.0/dist/gemini/commands/gantry/take.toml +616 -0
  110. oi_gantry-0.2.0/dist/gemini/commands/gantry/verify.toml +667 -0
  111. oi_gantry-0.2.0/dist/gemini/commands/gantry.toml +563 -0
  112. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-acquire.md +347 -0
  113. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-ask.md +160 -0
  114. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-batch.md +572 -0
  115. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-connect.md +254 -0
  116. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-decide.md +510 -0
  117. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-diagnose.md +482 -0
  118. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-escalate.md +575 -0
  119. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-fix.md +356 -0
  120. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-hitl.md +286 -0
  121. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-memory.md +232 -0
  122. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-observe.md +487 -0
  123. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-pass.md +350 -0
  124. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-pull.md +328 -0
  125. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-report.md +178 -0
  126. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-resume.md +270 -0
  127. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-select.md +526 -0
  128. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-status.md +240 -0
  129. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-sync.md +312 -0
  130. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-take.md +616 -0
  131. oi_gantry-0.2.0/dist/windsurf/workflows/gantry-verify.md +667 -0
  132. oi_gantry-0.2.0/dist/windsurf/workflows/gantry.md +563 -0
  133. oi_gantry-0.2.0/examples/README.md +69 -0
  134. oi_gantry-0.2.0/install.py +241 -0
  135. oi_gantry-0.2.0/pyproject.toml +51 -0
  136. oi_gantry-0.2.0/spec/feedback.md +146 -0
  137. oi_gantry-0.2.0/spec/lexicon.md +228 -0
  138. oi_gantry-0.2.0/spec/phases/acquire.md +134 -0
  139. oi_gantry-0.2.0/spec/phases/ask.md +57 -0
  140. oi_gantry-0.2.0/spec/phases/batch.md +90 -0
  141. oi_gantry-0.2.0/spec/phases/connect.md +29 -0
  142. oi_gantry-0.2.0/spec/phases/decide.md +176 -0
  143. oi_gantry-0.2.0/spec/phases/diagnose.md +38 -0
  144. oi_gantry-0.2.0/spec/phases/escalate.md +119 -0
  145. oi_gantry-0.2.0/spec/phases/fix.md +117 -0
  146. oi_gantry-0.2.0/spec/phases/gantry.md +81 -0
  147. oi_gantry-0.2.0/spec/phases/hitl.md +61 -0
  148. oi_gantry-0.2.0/spec/phases/memory.md +129 -0
  149. oi_gantry-0.2.0/spec/phases/observe.md +43 -0
  150. oi_gantry-0.2.0/spec/phases/pass.md +221 -0
  151. oi_gantry-0.2.0/spec/phases/pull.md +115 -0
  152. oi_gantry-0.2.0/spec/phases/report.md +87 -0
  153. oi_gantry-0.2.0/spec/phases/resume.md +31 -0
  154. oi_gantry-0.2.0/spec/phases/select.md +82 -0
  155. oi_gantry-0.2.0/spec/phases/status.md +27 -0
  156. oi_gantry-0.2.0/spec/phases/sync.md +73 -0
  157. oi_gantry-0.2.0/spec/phases/take.md +134 -0
  158. oi_gantry-0.2.0/spec/phases/verify.md +197 -0
  159. oi_gantry-0.2.0/spec/rules.md +55 -0
  160. oi_gantry-0.2.0/spec/surface.md +119 -0
  161. oi_gantry-0.2.0/src/gantry_adl/__init__.py +39 -0
  162. oi_gantry-0.2.0/src/gantry_adl/__main__.py +112 -0
  163. oi_gantry-0.2.0/src/gantry_adl/selfcheck.py +120 -0
  164. oi_gantry-0.2.0/tools/gantry_feedback.py +703 -0
@@ -0,0 +1,12 @@
1
+ # Runtime session state — per-machine, never shared.
2
+ session/
3
+ outbox/
4
+ *.json.gz
5
+
6
+ # Feedback reports stay on the machine that produced them.
7
+ adl-feedback_*.md
8
+ adl-feedback_*.json
9
+
10
+ __pycache__/
11
+ *.pyc
12
+ .DS_Store
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ Behavioural changes to the commands. Each entry says what an agent will *do differently*, because
4
+ that is the only thing a spec change can be judged on.
5
+
6
+ Commands are generated — edit `spec/`, run `build/compile.py`, reinstall. Never edit `dist/`.
7
+
8
+ ## 0.2.0 — packaged, versioned, self-updating
9
+
10
+ **A session now knows whether its own rules are current, before it takes the lock.**
11
+
12
+ - **Shipped as a Python distribution (`oi-gantry`).** `pip install -U oi-gantry` fetches the plugin;
13
+ `gantry sync` writes it into all six agent configs (claude, cursor, codex, windsurf, copilot,
14
+ gemini). One package, six agents, one upgrade path.
15
+ - **`acquire` step 0 — version check.** `gantry selfcheck` exits 10 when stale, and
16
+ `gantry selfcheck --update` upgrades and re-syncs in the same firing. A stale plugin used to be
17
+ invisible: it ran, it reported, and it did so under superseded rules.
18
+ - An unreachable index degrades to *unknown* and **does not block the run** — telemetry may never
19
+ stop delivery.
20
+ - A **major** version gap is refused, not auto-applied: it can change the phase contract the
21
+ session is part-way through, so it escalates as an operator decision.
22
+ - **Version is single-sourced** from `VERSION` and read by the package, the CLI, and the reporter's
23
+ `X-Gantry-Version` header. The installer now ships `VERSION` beside `gantry_feedback.py`, so a run
24
+ invoked with an unrelated interpreter no longer stamps every report `0+unknown`.
25
+ - **Fixed: `install.py --dir` was ignored for `--scope user`**, so any install or test silently
26
+ targeted the operator's real agent configs instead of the directory asked for. An explicit
27
+ `--dir` now wins for both scopes; `$HOME` remains the default.
28
+
29
+ ---
30
+
31
+ ## 2026-08-08 — grounding, parallelism, and the local loop
32
+
33
+ **21 commands** (was 19: `decide` and `batch` added).
34
+
35
+ ### Added
36
+
37
+ - **`decide`** — adjudicate a blocker instead of reporting it. Four questions that must pass before
38
+ "blocked" is allowed (named and probed *this firing*, body read not just the status code, two
39
+ alternatives tried, and — most often decisive — is the rule in this spec or one you invented), an
40
+ authority ladder defaulting to decide-and-act, and four ordered tiebreaks for contradictions.
41
+ Written because two of a session's three "genuinely blocked" items were false, one of them because
42
+ of a claim this spec had told it.
43
+ - **`batch`** — the unit of work is a conflict-free set, not a task. A cycle costs the same for one
44
+ task as for eight, so the speedup is amortising setup, **not** running more agents (the lock is
45
+ project-wide; there is no per-task lease). Batch the execution, never the evidence.
46
+
47
+ ### Changed
48
+
49
+ - **Evidence grammar for closes.** If you did not run it this firing, it is not evidence. Inference,
50
+ recall and absence are each named as impostors, with absence flagged as the dangerous one because
51
+ it feels like a finding.
52
+ - **Local-first loop.** `pull` now brings the stack up locally before editing; `verify` states the
53
+ division — local proves the change works, cloud proves it is what the platform and users will see.
54
+ Remote iteration is where the `exec` 504s, the 120s lock TTL and container-snapshot staleness bite.
55
+ - **`supersede-task` has three evidence shapes** — `by`, `by_tasks[]`, and `justification` for the
56
+ no-single-author case. Naming one sibling of a four-task suite is a guess dressed as provenance.
57
+ - **`PENDING` is not blocked** — it may be unpromoted. Read `startable` from `task-graph`, not
58
+ `status`.
59
+ - **Target triage before building.** `task-graph` reports `target_status`; a task whose target is
60
+ `missing_path` or `unresolvable_bucket_key` cannot be gated, so repair it first. `ns::…::general`
61
+ never grounds — derive the target from the description, `PUT` the file first (retarget rejects a
62
+ path that does not exist), then retarget.
63
+ - **Platform vocabulary in task text** — a word with no domain referent may be *platform* vocabulary,
64
+ not boilerplate. With the counter-caution: `lane`, `worker`, `gate` are ordinary domain words in
65
+ real products, and treating them as leaks discards genuine requirements.
66
+ - **Security sweeps must cover every method.** A GET-only sweep is why a publicly writable endpoint
67
+ survived. `401` vs `422` is the whole diagnosis.
68
+ - **`queued` has three endings** — applied, pending, or dead-lettered.
69
+ - **Proxy `404` is two different failures** — read the body, not the code.
70
+
71
+ ### Fixed
72
+
73
+ - **The reporter path was never the file, it was the cwd.** Reported missing three rounds running;
74
+ the file was always present, but the path was *relative* and the workflow requires the agent to
75
+ `cd` into the pulled repo. Now absolutised at install time, with the installer aborting if a
76
+ relative one survives.
77
+ - **Feedback had nowhere to go.** Every session printed `queued: no-endpoint`; the endpoint now
78
+ derives from `PROJECT_URL`.
79
+ - **Retracted: "HITL can never land while paused."** Wrong, and shipped by this spec. `SubmitHitl`
80
+ always had an arm; the queue is drained by the worker poll loop, ungated by `paused`.
81
+ - **Retracted: "a proxy 404 means no route."** It also means the app answered.
82
+
83
+ ---
84
+
85
+ ## 2026-08-06 — first feedback round
86
+
87
+ - `retarget-task` documented; an orphan target became a fix rather than an escalation.
88
+ - `manual-pass` takes `project_id`, not `project`.
89
+ - Reporter stopped discarding the session it exists to record (134 of 141 events were being dropped).
90
+ - Lock lifecycle for `/loop` firings.
91
+
92
+ ---
93
+
94
+ ## 2026-08-05 — initial
95
+
96
+ 19 commands across six vendors, compiled from one spec with a conformance gate.
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.5
2
+ Name: oi-gantry
3
+ Version: 0.2.0
4
+ Summary: GANTRY — the ADL plugin layer that drives a coding agent through a governed delivery loop
5
+ Author: Orion Innovation
6
+ License: Proprietary
7
+ Keywords: adl,claude,codex,coding-agent,copilot,cursor,gantry,gemini,windsurf
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Topic :: Software Development :: Quality Assurance
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+
14
+ # GANTRY
15
+
16
+ `/gantry` slash commands that turn any capable coding agent (Claude Code, Cursor, Codex, Windsurf,
17
+ Copilot, Gemini CLI) into a debugging **and coding** harness for one Encore/Nova project — driven
18
+ over the project's HTTP API, with the actual build-run-test work done on local disk.
19
+
20
+ - The rules themselves: [`spec/`](spec/) — every phase, in the order an agent runs them
21
+ - Mandatory feedback mechanism: [spec/feedback.md](spec/feedback.md)
22
+ - What changes per release, including retractions: [CHANGELOG.md](CHANGELOG.md)
23
+
24
+ ---
25
+
26
+ ## The general rule: GANTRY always runs with the swarm OFF
27
+
28
+ **`/gantry` must always turn the swarm off before it does anything.** The swarm and the coding agent
29
+ must never write to the same project at the same time — two writers on one tree produce reverts,
30
+ half-merges, and gate failures that belong to neither of them.
31
+
32
+ This holds **whether you run `/gantry` once or in a loop**, and it is not conditional on what you
33
+ intend to do. Even a read-only look is safer taken against a quiesced project.
34
+
35
+ - **Run to success** = the swarm does **no** coding. `/gantry` loops are the code producer: pull the
36
+ repo locally, complete the task with the real toolchain (docker, playwright, tests), push back to
37
+ git, sync the workspace, and flag the result.
38
+ - Because no swarm runs, **no gate runs either**. A task completed and proven locally is closed with
39
+ `pass` (ADL §8 preconditions enforced: cause not shared, real vantage-named proof, re-diff
40
+ immediately before passing). That is the intended path here, not a workaround.
41
+ - `acquire` performs the `swarm/stop` and verifies `paused==true`. If it cannot confirm `paused`,
42
+ **nothing else runs.**
43
+
44
+ **`is_on` is not the swarm.** Three orthogonal states — `is_on` (the container stack), `paused` (the
45
+ swarm's writing), and per-service subapp status. Turning the project on does not start the swarm, and
46
+ pausing the swarm does not stop the containers. Use `swarm/stop` to stop coding; never
47
+ `toggle {is_on:false}`, which tears the stack down and does not set `paused`.
48
+
49
+ ## The local workspace
50
+
51
+ GANTRY mirrors Nova's own layout so compose bind-mounts and relative paths resolve identically:
52
+
53
+ ```
54
+ ${ENCORE_LOCAL_LWD}/<PROJECT_ID>/<Project Name>/ # default base: /mnt/encore
55
+ ```
56
+
57
+ e.g. `/mnt/encore/proj-example-hifi/EXAMPLE-HIFI/`. Quote the paths — project names contain spaces. Point
58
+ `ENCORE_LOCAL_LWD` elsewhere to work outside `/mnt`.
59
+
60
+ ## Get started
61
+
62
+ **Copy the sample folder** — [SampleProject/](SampleProject/) has the commands pre-installed for all
63
+ six agents:
64
+
65
+ ```bash
66
+ cp -r SampleProject ~/GantryProjects/proj-xxxx
67
+ cd ~/GantryProjects/proj-xxxx && export ENCORE_LOCAL_LWD=~/GantryProjects
68
+ # fill in GANTRY-KICKOFF.md, then run /gantry
69
+ ```
70
+
71
+ **Or bootstrap it pre-filled** from a read-only probe of the live project:
72
+
73
+ ```bash
74
+ export GANTRY_API_KEY='...' # out-of-band; never an argument, never in a file
75
+ python3 examples/new-project.py --project-id proj-xxxx \
76
+ --url https://your-nova-host --dir ~/GantryProjects
77
+ ```
78
+
79
+ Creates the project folder, installs the commands into it, and writes a `GANTRY-KICKOFF.md`
80
+ pre-filled from the live project — task counts, `is_on`/`paused`, lock state, git remote, and any
81
+ blocker it can prove. See [examples/](examples/) for the template and a worked example.
82
+
83
+ ## Install manually
84
+
85
+ ```bash
86
+ python3 build/compile.py # spec/ -> dist/ (+ conformance gate)
87
+ python3 install.py --target claude --scope project --dir ~/GantryProjects
88
+ python3 install.py --list # all supported targets and their layouts
89
+ ```
90
+
91
+ Then `/gantry` in that folder. `--target all` installs every vendor; `--uninstall` removes exactly
92
+ what was installed.
93
+
94
+ ## Commands
95
+
96
+ `gantry` (router) · `connect` `acquire` `observe` `select` `diagnose` `fix` `verify` `hitl` `resume`
97
+ `escalate` `report` `status` · `pull` `sync` `take` `pass` · `ask` `memory`
98
+
99
+ ### `/gantry <prompt>` — just ask it
100
+
101
+ `/gantry` takes a free-form prompt and routes it, so you don't have to know the command names:
102
+
103
+ | You type | It does |
104
+ |---|---|
105
+ | `/gantry why is REQ-01b866c7 stuck?` | **Answers** from read-only state. No lock, no pause, no edits. |
106
+ | `/gantry pull it locally` | Runs that phase, and says which one it picked. |
107
+ | `/gantry finish the payment task` | Runs the full loop, scoped to that. |
108
+ | `/gantry should cancel refund before releasing inventory?` | Reaches a human via `ask` — it will not invent a requirement. |
109
+ | `/gantry` | Full loop. |
110
+
111
+ **Questions are answered, not executed.** When a prompt is ambiguous, GANTRY takes the cheaper,
112
+ reversible path — reply, or ask — rather than freezing the swarm. Reaching a human via
113
+ `POST /api/projects/{id}/chat` takes no lock and disturbs nothing; replies come back on the event
114
+ stream. It never blocks the session waiting for a reply, and never guesses an answer.
115
+
116
+ ## Non-negotiables
117
+
118
+ HTTP surface only — no SSH, no DB edits, no platform patching. Fix the real **shared** cause. Escalate
119
+ anything outside the surface rather than reaching around it. Every session writes a feedback report
120
+ before releasing the lock.
121
+
122
+ ## Documentation map
123
+
124
+ | File | For | Contains |
125
+ |---|---|---|
126
+ | `spec/` → `dist/` | the **agent** | the rules themselves — edit `spec/`, never `dist/` |
127
+ | [`CHANGELOG.md`](CHANGELOG.md) | **everyone** | what an agent will do differently, per release, including retractions |
128
+ | [`SampleProject/`](SampleProject/) | **new users** | the commands pre-installed for all six agents |
129
+ | [`examples/`](examples/) | **new users** | the kickoff template and a worked example |
130
+
131
+ **Retractions live in the changelog on purpose.** Two rules this spec shipped were wrong and were
132
+ believed by agents reasoning correctly from them — "HITL can never land while paused" and "a proxy
133
+ 404 means no route". A spec that quietly corrects itself teaches agents to distrust the correction.
@@ -0,0 +1,120 @@
1
+ # GANTRY
2
+
3
+ `/gantry` slash commands that turn any capable coding agent (Claude Code, Cursor, Codex, Windsurf,
4
+ Copilot, Gemini CLI) into a debugging **and coding** harness for one Encore/Nova project — driven
5
+ over the project's HTTP API, with the actual build-run-test work done on local disk.
6
+
7
+ - The rules themselves: [`spec/`](spec/) — every phase, in the order an agent runs them
8
+ - Mandatory feedback mechanism: [spec/feedback.md](spec/feedback.md)
9
+ - What changes per release, including retractions: [CHANGELOG.md](CHANGELOG.md)
10
+
11
+ ---
12
+
13
+ ## The general rule: GANTRY always runs with the swarm OFF
14
+
15
+ **`/gantry` must always turn the swarm off before it does anything.** The swarm and the coding agent
16
+ must never write to the same project at the same time — two writers on one tree produce reverts,
17
+ half-merges, and gate failures that belong to neither of them.
18
+
19
+ This holds **whether you run `/gantry` once or in a loop**, and it is not conditional on what you
20
+ intend to do. Even a read-only look is safer taken against a quiesced project.
21
+
22
+ - **Run to success** = the swarm does **no** coding. `/gantry` loops are the code producer: pull the
23
+ repo locally, complete the task with the real toolchain (docker, playwright, tests), push back to
24
+ git, sync the workspace, and flag the result.
25
+ - Because no swarm runs, **no gate runs either**. A task completed and proven locally is closed with
26
+ `pass` (ADL §8 preconditions enforced: cause not shared, real vantage-named proof, re-diff
27
+ immediately before passing). That is the intended path here, not a workaround.
28
+ - `acquire` performs the `swarm/stop` and verifies `paused==true`. If it cannot confirm `paused`,
29
+ **nothing else runs.**
30
+
31
+ **`is_on` is not the swarm.** Three orthogonal states — `is_on` (the container stack), `paused` (the
32
+ swarm's writing), and per-service subapp status. Turning the project on does not start the swarm, and
33
+ pausing the swarm does not stop the containers. Use `swarm/stop` to stop coding; never
34
+ `toggle {is_on:false}`, which tears the stack down and does not set `paused`.
35
+
36
+ ## The local workspace
37
+
38
+ GANTRY mirrors Nova's own layout so compose bind-mounts and relative paths resolve identically:
39
+
40
+ ```
41
+ ${ENCORE_LOCAL_LWD}/<PROJECT_ID>/<Project Name>/ # default base: /mnt/encore
42
+ ```
43
+
44
+ e.g. `/mnt/encore/proj-example-hifi/EXAMPLE-HIFI/`. Quote the paths — project names contain spaces. Point
45
+ `ENCORE_LOCAL_LWD` elsewhere to work outside `/mnt`.
46
+
47
+ ## Get started
48
+
49
+ **Copy the sample folder** — [SampleProject/](SampleProject/) has the commands pre-installed for all
50
+ six agents:
51
+
52
+ ```bash
53
+ cp -r SampleProject ~/GantryProjects/proj-xxxx
54
+ cd ~/GantryProjects/proj-xxxx && export ENCORE_LOCAL_LWD=~/GantryProjects
55
+ # fill in GANTRY-KICKOFF.md, then run /gantry
56
+ ```
57
+
58
+ **Or bootstrap it pre-filled** from a read-only probe of the live project:
59
+
60
+ ```bash
61
+ export GANTRY_API_KEY='...' # out-of-band; never an argument, never in a file
62
+ python3 examples/new-project.py --project-id proj-xxxx \
63
+ --url https://your-nova-host --dir ~/GantryProjects
64
+ ```
65
+
66
+ Creates the project folder, installs the commands into it, and writes a `GANTRY-KICKOFF.md`
67
+ pre-filled from the live project — task counts, `is_on`/`paused`, lock state, git remote, and any
68
+ blocker it can prove. See [examples/](examples/) for the template and a worked example.
69
+
70
+ ## Install manually
71
+
72
+ ```bash
73
+ python3 build/compile.py # spec/ -> dist/ (+ conformance gate)
74
+ python3 install.py --target claude --scope project --dir ~/GantryProjects
75
+ python3 install.py --list # all supported targets and their layouts
76
+ ```
77
+
78
+ Then `/gantry` in that folder. `--target all` installs every vendor; `--uninstall` removes exactly
79
+ what was installed.
80
+
81
+ ## Commands
82
+
83
+ `gantry` (router) · `connect` `acquire` `observe` `select` `diagnose` `fix` `verify` `hitl` `resume`
84
+ `escalate` `report` `status` · `pull` `sync` `take` `pass` · `ask` `memory`
85
+
86
+ ### `/gantry <prompt>` — just ask it
87
+
88
+ `/gantry` takes a free-form prompt and routes it, so you don't have to know the command names:
89
+
90
+ | You type | It does |
91
+ |---|---|
92
+ | `/gantry why is REQ-01b866c7 stuck?` | **Answers** from read-only state. No lock, no pause, no edits. |
93
+ | `/gantry pull it locally` | Runs that phase, and says which one it picked. |
94
+ | `/gantry finish the payment task` | Runs the full loop, scoped to that. |
95
+ | `/gantry should cancel refund before releasing inventory?` | Reaches a human via `ask` — it will not invent a requirement. |
96
+ | `/gantry` | Full loop. |
97
+
98
+ **Questions are answered, not executed.** When a prompt is ambiguous, GANTRY takes the cheaper,
99
+ reversible path — reply, or ask — rather than freezing the swarm. Reaching a human via
100
+ `POST /api/projects/{id}/chat` takes no lock and disturbs nothing; replies come back on the event
101
+ stream. It never blocks the session waiting for a reply, and never guesses an answer.
102
+
103
+ ## Non-negotiables
104
+
105
+ HTTP surface only — no SSH, no DB edits, no platform patching. Fix the real **shared** cause. Escalate
106
+ anything outside the surface rather than reaching around it. Every session writes a feedback report
107
+ before releasing the lock.
108
+
109
+ ## Documentation map
110
+
111
+ | File | For | Contains |
112
+ |---|---|---|
113
+ | `spec/` → `dist/` | the **agent** | the rules themselves — edit `spec/`, never `dist/` |
114
+ | [`CHANGELOG.md`](CHANGELOG.md) | **everyone** | what an agent will do differently, per release, including retractions |
115
+ | [`SampleProject/`](SampleProject/) | **new users** | the commands pre-installed for all six agents |
116
+ | [`examples/`](examples/) | **new users** | the kickoff template and a worked example |
117
+
118
+ **Retractions live in the changelog on purpose.** Two rules this spec shipped were wrong and were
119
+ believed by agents reasoning correctly from them — "HITL can never land while paused" and "a proxy
120
+ 404 means no route". A spec that quietly corrects itself teaches agents to distrust the correction.
@@ -0,0 +1,50 @@
1
+ # SampleProject — copy this folder to start
2
+
3
+ A ready-to-use GANTRY project folder with the `/gantry` commands already installed for **all six
4
+ agents**. Copy it, fill in the kickoff, and run.
5
+
6
+ ```bash
7
+ cp -r SampleProject ~/GantryProjects/proj-xxxx
8
+ cd ~/GantryProjects/proj-xxxx
9
+ export ENCORE_LOCAL_LWD=~/GantryProjects
10
+ export GANTRY_API_KEY='...' # out-of-band; never write it into a file
11
+ # fill in GANTRY-KICKOFF.md, then:
12
+ /gantry
13
+ ```
14
+
15
+ Prefer it pre-filled? `examples/new-project.py` does the same thing and populates the kickoff from a
16
+ read-only probe of the live project — task counts, `is_on`/`paused`, lock state, git remote:
17
+
18
+ ```bash
19
+ python3 examples/new-project.py --project-id proj-xxxx --url https://your-nova-host \
20
+ --dir ~/GantryProjects
21
+ ```
22
+
23
+ ## What's here
24
+
25
+ | | |
26
+ |---|---|
27
+ | `.claude/` `.cursor/` `.codex/` `.windsurf/` `.github/` `.gemini/` | the 19 `/gantry` commands, per agent |
28
+ | `GANTRY-KICKOFF.md` | the kickoff template — **fill this in before your first run** |
29
+
30
+ Only your agent's directory matters; delete the rest if you like. Each carries a
31
+ `.gantry-manifest.json` recording what GANTRY installed, so `install.py --uninstall` removes exactly
32
+ that and nothing else.
33
+
34
+ These command files are **generated** from `spec/` by `build/compile.py` and verified against
35
+ `dist/` by `compile.py --check`. Don't hand-edit them — edit the spec and rebuild, or your changes
36
+ vanish on the next build.
37
+
38
+ ## Before your first run
39
+
40
+ **The swarm will be turned off and kept off.** `/gantry` pauses it and verifies `paused==true` before
41
+ it writes anything. The swarm and a coding agent must never write to the same tree. You are the code
42
+ producer for the session.
43
+
44
+ **No swarm means no gate.** Nothing is running to award a task Done, so a task you finish and prove
45
+ locally is closed with `pass` — which enforces the preconditions (cause not shared, real
46
+ vantage-named proof, re-diff immediately before passing). A task still red gets **escalated**, not
47
+ passed.
48
+
49
+ **Fill in the kickoff.** It's the first thing an agent reads. Every fact you put there is one the
50
+ session doesn't have to re-derive — and one it can't get wrong.
@@ -0,0 +1 @@
1
+ 0.2.0