@agentsfleet/orly 0.5.0

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 (112) hide show
  1. package/.githooks/pre-commit +42 -0
  2. package/.githooks/pre-push +67 -0
  3. package/AGENTS.md +348 -0
  4. package/LICENSE +21 -0
  5. package/README.md +249 -0
  6. package/SOUL.md +90 -0
  7. package/audits/agents-md.md +497 -0
  8. package/audits/agents-md.sh +353 -0
  9. package/audits/cross-tier-rates.sh +105 -0
  10. package/audits/data.sh +185 -0
  11. package/audits/deinit-pairs.sh +224 -0
  12. package/audits/design-tokens.sh +143 -0
  13. package/audits/doc-read.sh +183 -0
  14. package/audits/error-codes.sh +221 -0
  15. package/audits/fixtures/clean.diff +15 -0
  16. package/audits/fixtures/dirty.diff +16 -0
  17. package/audits/lifecycle-anchors.sh +22 -0
  18. package/audits/logging.sh +217 -0
  19. package/audits/msid-ui.sh +144 -0
  20. package/audits/parity-dispatch.sh +51 -0
  21. package/audits/rule-ledger-lib.sh +264 -0
  22. package/audits/rule-ledger.sh +225 -0
  23. package/audits/rule-paths.sh +108 -0
  24. package/audits/spec-template.sh +258 -0
  25. package/audits/sql-mod.sh +102 -0
  26. package/audits/ufs.sh +303 -0
  27. package/bin/orly +26 -0
  28. package/core/operating-model.md +256 -0
  29. package/dispatch/edit_rules.md +69 -0
  30. package/dispatch/lib.sh +213 -0
  31. package/dispatch/lifecycle.md +187 -0
  32. package/dispatch/name_architecture.md +93 -0
  33. package/dispatch/verify.md +111 -0
  34. package/dispatch/write_any.md +740 -0
  35. package/dispatch/write_any.sh +49 -0
  36. package/dispatch/write_auth.md +36 -0
  37. package/dispatch/write_changelog.md +64 -0
  38. package/dispatch/write_documentation.md +45 -0
  39. package/dispatch/write_go.md +24 -0
  40. package/dispatch/write_http.md +45 -0
  41. package/dispatch/write_mdx.md +7 -0
  42. package/dispatch/write_python.md +8 -0
  43. package/dispatch/write_rust.md +38 -0
  44. package/dispatch/write_shell.md +8 -0
  45. package/dispatch/write_spec.md +105 -0
  46. package/dispatch/write_sql.md +112 -0
  47. package/dispatch/write_sql.sh +36 -0
  48. package/dispatch/write_ts_adhere_bun.md +493 -0
  49. package/dispatch/write_ts_adhere_bun.sh +37 -0
  50. package/dispatch/write_zig.md +852 -0
  51. package/dispatch/write_zig.sh +40 -0
  52. package/docs/CHANGELOG_VOICE.md +18 -0
  53. package/docs/DISPATCH_ARCHITECTURE.md +664 -0
  54. package/docs/DISPATCH_REVIEW_DISPOSITION.md +65 -0
  55. package/docs/DOCUMENTATION_RULES.md +209 -0
  56. package/docs/EXECUTE_DOC_READS.md +29 -0
  57. package/docs/HARNESS_VERIFY_OUTPUT.md +40 -0
  58. package/docs/LIFECYCLE_PATTERNS.md +316 -0
  59. package/docs/LOGGING_STANDARD.md +397 -0
  60. package/docs/ORLY_ARCHITECTURE.md +129 -0
  61. package/docs/REST_API_DESIGN_GUIDELINES.md +783 -0
  62. package/docs/RULE_ENFORCEMENT.md +41 -0
  63. package/docs/SCHEMA_CONVENTIONS.md +93 -0
  64. package/docs/TEMPLATE.md +411 -0
  65. package/docs/VERIFY_TIERS.md +57 -0
  66. package/docs/greptile-learnings/README.md +51 -0
  67. package/docs/greptile-learnings/RULES.md +1045 -0
  68. package/fixtures/registry-invalid.json +1 -0
  69. package/fixtures/registry-valid.json +18 -0
  70. package/fixtures/unclosed-pack-block.md +8 -0
  71. package/package.json +63 -0
  72. package/packs/language/go/rules.md +24 -0
  73. package/packs/language/mdx/rules.md +7 -0
  74. package/packs/language/python/rules.md +8 -0
  75. package/packs/language/rust/rules.md +38 -0
  76. package/packs/language/shell/rules.md +8 -0
  77. package/registry.json +405 -0
  78. package/schemas/evidence.schema.json +43 -0
  79. package/schemas/profile.schema.json +12 -0
  80. package/schemas/registry.schema.json +12 -0
  81. package/skills/orly-babysit-prs/SKILL.md +326 -0
  82. package/skills/orly-spec-new/SKILL.md +157 -0
  83. package/skills/orly-write-integration-test/SKILL.md +470 -0
  84. package/skills/orly-write-unit-test/SKILL.md +520 -0
  85. package/src/cli.test.ts +70 -0
  86. package/src/cli.ts +287 -0
  87. package/src/config.test.ts +226 -0
  88. package/src/config.ts +288 -0
  89. package/src/criteria.test.ts +137 -0
  90. package/src/criteria.ts +166 -0
  91. package/src/criteria_spec.ts +127 -0
  92. package/src/criteria_support.ts +53 -0
  93. package/src/gates.test.ts +183 -0
  94. package/src/gates.ts +169 -0
  95. package/src/gates_spec.test.ts +98 -0
  96. package/src/gates_test_support.ts +194 -0
  97. package/src/git_env.ts +20 -0
  98. package/src/install.test.ts +514 -0
  99. package/src/install.ts +447 -0
  100. package/src/install_nested.test.ts +32 -0
  101. package/src/model.test.ts +31 -0
  102. package/src/model.ts +245 -0
  103. package/src/references.test.ts +47 -0
  104. package/src/references.ts +147 -0
  105. package/src/render.test.ts +60 -0
  106. package/src/render.ts +94 -0
  107. package/src/surfaces.test.ts +43 -0
  108. package/src/surfaces.ts +89 -0
  109. package/src/validation.test.ts +11 -0
  110. package/src/validation.ts +87 -0
  111. package/src/verify.test.ts +13 -0
  112. package/src/verify.ts +59 -0
@@ -0,0 +1,664 @@
1
+ # Dispatch Architecture — operating-model (v3, EXECUTED)
2
+
3
+ > Documentation prerequisite: read
4
+ > [`DOCUMENTATION_RULES.md`](./DOCUMENTATION_RULES.md) before editing this file.
5
+ > This internal explanation is not a published Markdown JSX (MDX) page, so page front matter and
6
+ > skeleton rules do not apply. Plain-language and acronym rules do.
7
+
8
+ Date: Jun 04, 2026 (proposed) · Jun 05, 2026 (Stage-2 executed)
9
+ Status: **v3 EXECUTED** — the Stage-2 atomic switchover landed on
10
+ `feat/resolver-architecture` (PR #18): the 20 `docs/gates/` cards + `ZIG_RULES.md`
11
+ + `BUN_RULES.md` dissolved into the 10 `dispatch/` entries; `docs/gates/` no longer
12
+ exists; `audits/agents-md.sh` enforces dispatch parity on every commit. The body
13
+ below is preserved as the design rationale **as proposed** (v2) — past-tense future
14
+ sections ("will", "Stage 2 does…") describe the now-completed migration; it is the
15
+ durable record of *why* the dispatch model exists, not a live to-do list.
16
+ Owner: Orly (Oracle)
17
+ Scope: `~/Projects/dotfiles` operating model + cross-repo rule-doc references
18
+
19
+ > Design doc, not a milestone spec (dotfiles has no `docs/v*/` train). Lands on
20
+ > `master` via `feat/dispatch-architecture`. **v2 supersedes v1** after a 7-lens
21
+ > adversarial Chief Technology Officer (CTO) review (38 findings confirmed: 19
22
+ > P0 / 16 P1 / 3 P2) returned **REWORK** — concept sound, migration plan
23
+ > under-scoped ~10×, two determinism claims overstated. v2 keeps the façade-pair
24
+ > core and rewrites the migration, the blast-radius accounting, and the claims to
25
+ > match what the mechanisms actually deliver. Every change below is grounded in a
26
+ > grep of the branch, not the review prose — file:line citations are real.
27
+ > **Per-finding disposition (all 38 + resolved/partial status) is tracked in
28
+ > [`DISPATCH_REVIEW_DISPOSITION.md`](./DISPATCH_REVIEW_DISPOSITION.md).**
29
+
30
+ ---
31
+
32
+ ## 0 · What changed from v1 (the review's verdict, absorbed)
33
+
34
+ | v1 claim / gap | v2 correction |
35
+ |---|---|
36
+ | "the two façades **cannot drift**" (headline invariant) | Downgraded to **"no missing symbol + prose-pinned thresholds."** The coherence audit proves symbol presence, not that a check enforces the prose. Real semantic anchors added (§3, §6.3). |
37
+ | §11 = cross-repo footnote | §8 = **primary in-dotfiles blast-radius inventory** (grounded, ~14 files). Cross-repo is downstream of it (§10). |
38
+ | Dissolve `docs/gates/` + rename `*_RULES.md` (single act) | **Staged, non-destructive migration** (§9): scaffold → prove equivalence → atomic switchover. `make audit` never goes red mid-flight. Rollback defined. |
39
+ | `make audit` "ALL CHECKS PASSED" as an acceptance bullet | The audit/hook/harness **rewrites are first-class deliverables** (§8, §13) and edit the harness → **explicit Indy sign-off required** (Hard-Safety rule). |
40
+ | "nothing unique dies" on merge | A **mechanical merge-loss proof** (`merge-coverage.sh`, §6.5). No card deleted until its delta-landed assertion is green. |
41
+ | `🟡` = JUDGMENT-open | **Glyph collision fixed** — `HARNESS_VERIFY_OUTPUT.md:19` already uses `🟡` for "violations addressed." v2 introduces **`🤔 DECIDE`** for judgment-open (§3.1). |
42
+ | JUDGMENT "mitigated" / "blocks the turn" | Honestly scoped: **proven for DETERMINISTIC, attested-by-honor for JUDGMENT.** A `HARNESS_VERIFY` JUDGMENT row makes the *attestation* auditable (§11). |
43
+ | Helper-absent → `🟣`, exit 0 | A DETERMINISTIC helper that is **absent hard-fails RED** (§10) — no silent green no-op. |
44
+ | `.git/hooks/pre-commit` backstop | Wired to **`.githooks/pre-commit`** (`core.hooksPath` = `.githooks`, confirmed) — `.git/hooks/` never runs on a fresh clone. |
45
+ | Dispatch run in dotfiles; leaf checks "just run" | **Execution-location model defined** (§10): `bin/link-agents-md` **symlinks** (confirmed `:160,176`), so the dispatch runs in the product repo against a symlink back to dotfiles. `DISPATCH_ROOT` (target repo) is derived from `git rev-parse --show-toplevel`, NOT `BASH_SOURCE` — so a symlinked dispatch scopes to the repo it runs in, not dotfiles. |
46
+ | fn≤50 / method≤70 sub-cap | **Not silently dropped** — `dispatch_length_gate` is file-cap only today (`lib.sh:107`); v2 names the sub-cap as a delegated/[JUDGMENT] decision in §13. |
47
+
48
+ > **This doc is the TARGET STATE, not current code.** The dispatch WIP on this
49
+ > branch (`dispatch/lib.sh`, `dispatch/write_zig.sh`) is v1-era: it still emits
50
+ > `🟡` for judgment, returns `🟣`/exit 0 on an absent helper, derives
51
+ > `DISPATCH_ROOT` from `BASH_SOURCE`, and wires `ufs.sh --all`. Every such
52
+ > correction below is *specified here and implemented during the staged
53
+ > migration* (§9), not already present. A second adversarial pass (Jun 04, 21
54
+ > resolved / 17 partial) confirmed the partials are "doc correct, code pending" —
55
+ > tracked as Stage-0 implementation work, not doc defects.
56
+
57
+ ---
58
+
59
+ ## 1 · Intent (the testable goal)
60
+
61
+ **Goal (as a test name):** *"Writing a `*.zig` file dispatches a SMALL ORDERED
62
+ façade set — the language façade (`dispatch/write_zig.md`) plus the one
63
+ cross-cutting façade (`dispatch/write_any.md`) — the agent reads, and the
64
+ matching deterministic `.sh` set the machine runs; every rule is tagged
65
+ DETERMINISTIC (has a `.sh` check + a prose-pinned fixture) or JUDGMENT (has a
66
+ Large Language Model (LLM) comprehension probe); the deterministic value lives
67
+ once (in the `.sh`) and the prose references it, so a fixture catches prose↔check
68
+ divergence; an audit ties tags ↔ checks ↔ evals ↔ merged-prose."*
69
+
70
+ > Not literally "one façade" — a write triggers its language façade composed with
71
+ > `write_any` (§5). Two façades, fixed and ordered, is still the single runnable
72
+ > question v1 lacked; the scatter it kills was 20 cards + 478-line prose doc, not
73
+ > "more than one file."
74
+
75
+ **Why:** Today the Zig discipline is scattered: `docs/ZIG_RULES.md` (478 lines),
76
+ `docs/gates/*.md` (20 cards), 10 `audits/*.sh`. Nothing makes "did I
77
+ adhere to all Zig rules?" a runnable, testable question. This unifies them into
78
+ a **façade pair per language** and proves adherence in both spaces.
79
+
80
+ **What v2 does NOT claim:** that the `.md` and `.sh` *cannot* diverge in meaning.
81
+ A symbol-presence audit cannot prove that. v2's mechanism for semantic coherence
82
+ is **single-source thresholds + prose-pinned fixtures** (§3, §6.1), not the tag.
83
+
84
+ ## 2 · Core insight — a dispatch is a FAÇADE PAIR over one gate set
85
+
86
+ A dispatch is not one file. It is the dispatcher *concept*, presenting two faces:
87
+
88
+ ```
89
+ ┌──────────── THE ZIG DISPATCH (one concept) ────────────┐
90
+ LATENT ──▶ │ dispatch/write_zig.md façade for the AGENT │
91
+ SPACE │ prose dispatcher: "writing zig? adhere to this." │
92
+ │ every § tagged [DETERMINISTIC → CODE] or [JUDGMENT] │
93
+ │ │ DETERMINISTIC tags link to ↓ │
94
+ DETERM. ──▶│ dispatch/write_zig.sh façade for the MACHINE │
95
+ SPACE │ owns the threshold values; runs the checkable │
96
+ │ subset → 🟢/🔴 + 🤔 judgment nudges │
97
+ │ │ calls ↓ │
98
+ │ audits/*.sh + inline checks (the leaf checks) │
99
+ └─────────────────────────────────────────────────────────┘
100
+ ```
101
+
102
+ - **`write_zig.md`** = `docs/ZIG_RULES.md` **merged with the Zig-relevant
103
+ `docs/gates/*.md` deltas**, perfected and made more deterministic — not a bare
104
+ rename. It gains per-section enforcement tags; mechanical content moves to the
105
+ `.sh`; teaching prose stays.
106
+ - **`write_zig.sh`** = the deterministic façade. **It owns every threshold value
107
+ verbatim** (`dispatch_length_gate 350`); the `.md` *references* the value
108
+ ("see `write_zig.sh::length`"), never restates the number. This is the v2
109
+ anti-drift mechanism — one source, not two copies bridged by a tag.
110
+
111
+ **`gates/*.md` is DISSOLVED selectively, not wholesale** (§5 taxonomy): authoring
112
+ gates merge into a façade `.md`; **process/meta gates stay in `AGENTS.md`**. Merge
113
+ is **merge-then-delete with a proof gate** (§6.5): a card is deleted only after
114
+ `merge-coverage.sh` confirms its non-boilerplate prose landed in a façade.
115
+
116
+ ## 3 · Enforcement tags + the semantic anchor
117
+
118
+ Each section of the latent façade carries exactly one tag. **The tag grammar is
119
+ frozen to one form** matching what `write_zig.sh` actually emits — a rule CODE,
120
+ not a `::function` reference (v1 mixed `sh::X` and `write_zig.sh::<check>`; both
121
+ are dropped):
122
+
123
+ | Tag | Meaning | Enforced by | Eval kind |
124
+ |---|---|---|---|
125
+ | `[DETERMINISTIC → CODE]` | machine can pass/fail it | the `.sh` row for `CODE` (e.g. `FLL`, `UFS`) | prose-pinned fixture (pass + fail) |
126
+ | `[JUDGMENT → CODE]` | no script can decide; agent decides at write time | agent reading the prose | LLM-judge scenario |
127
+ | `[container]` | structural wrapper heading, not a rule | nothing — its tagged subsections carry the real codes | skipped (coherence audit §6.3) |
128
+
129
+ Walk all ~40 ZIG sections + merged gate deltas; tag each. A DETERMINISTIC tag
130
+ whose CODE has no `.sh` row is a *build-the-check* TODO; a section that genuinely
131
+ can't be checked is honestly `[JUDGMENT]`. Structural wrapper headings (e.g.
132
+ "Merged from dissolved gate cards") carry `[container]` — the sole non-rule tag —
133
+ and the coherence audit skips them; their tagged subsections carry the real codes.
134
+
135
+ **The semantic anchor (the v2 fix for "false determinism"):**
136
+ 1. **Single source.** The numeric/threshold lives ONLY in the `.sh`
137
+ (`dispatch_length_gate 350`). The `.md` says "≤ the cap in
138
+ `write_zig.sh::length`" — it carries no competing number to drift.
139
+ 2. **Prose-pinned fixture.** For any rule whose prose states a bound, a fixture
140
+ pins it: `length_351_fail.zig` MUST exit 1. If someone edits the `.sh` cap to
141
+ 500, the 351 fixture flips to pass and `dispatch-evals` goes red. The
142
+ **fixture**, not the tag, is the drift detector.
143
+
144
+ ### 3.1 · Signal semantics (🟢 / 🔴 / 🤔) — and the glyph-collision fix
145
+
146
+ `HARNESS_VERIFY_OUTPUT.md:19` already defines `🟡 = violations addressed` (a
147
+ resolved-but-noted deterministic state, e.g. `LENGTH GATE | 🟡 files at cap`).
148
+ v1 reused `🟡` for "judgment open question" — the **opposite** semantics (open vs
149
+ resolved). v2 introduces a distinct glyph so one symbol never carries two
150
+ meanings:
151
+
152
+ | Signal | Meaning | Agent MUST | Exit |
153
+ |---|---|---|---|
154
+ | 🟢 GREEN | deterministic check passed | proceed | 0 |
155
+ | 🔴 RED | deterministic check failed | STOP, fix code, re-run | 1 (blocks) |
156
+ | 🟡 YELLOW | deterministic violation **addressed** (informational) | note it; existing meaning, unchanged | 0 |
157
+ | 🤔 DECIDE | judgment-only rule; no script can decide | read linked §, make the call, **state the verdict in chat** | 0 (does NOT block script) |
158
+
159
+ **Why a new glyph, not re-glyphing `🟡`:** re-glyphing the established
160
+ "violations addressed" cells touches an audited doc and retrains every agent on a
161
+ symbol they already know. `🤔` is additive — a new concept gets a new glyph. The
162
+ fix still requires a one-line `HARNESS_VERIFY_OUTPUT.md` legend update and an
163
+ `audits/agents-md.md` question pinning `🤔` (§8, §13).
164
+
165
+ **🤔 blocks the TURN, not the script** — see §11 for how that is made auditable
166
+ rather than honor-only.
167
+
168
+ ## 4 · Two worked gates (the concrete shape)
169
+
170
+ **GATE 1 — LENGTH (deterministic, single-source threshold):**
171
+ ```
172
+ write_zig.md §Length:
173
+ - `.zig` ≤ the cap in write_zig.sh::length; split by concern when over.
174
+ [DETERMINISTIC → FLL] (the number lives in the .sh, not here)
175
+ write_zig.sh: dispatch_length_gate 350
176
+ fixture: length_351_fail.zig → exit 1 (pins the prose bound; flips if cap moves)
177
+ run: FLL 🔴 File & Function Length Limits — foo.zig: 360 (cap 350) — split
178
+ → machine decides. pass/fail. prose carries no drift-able number.
179
+ ```
180
+
181
+ **GATE 2 — TAGGED-UNIONS (judgment, no script):**
182
+ ```
183
+ write_zig.md §Tagged unions for result types:
184
+ - Result with distinct failure modes → union(enum) w/ payload, not
185
+ optional-field struct. Callers need the *reason*, not the verdict.
186
+ [JUDGMENT → TGU]
187
+ write_zig.sh: dispatch_judgment "TGU" "result w/ failure modes? union(enum)…"
188
+ eval: evals/llms — scenario asserts union(enum), not optional struct
189
+ run: TGU 🤔 DECIDE — result w/ failure modes? union(enum), not optional-field
190
+ → agent decides, states verdict in chat; CONFORM audits the attestation.
191
+ ```
192
+
193
+ ## 5 · Dispatch set + gate disposition (all 20 mapped — no homeless gate)
194
+
195
+ | Latent façade (.md) | Deterministic façade (.sh) | Triggers |
196
+ |---|---|---|
197
+ | `write_zig.md` | `write_zig.sh` | `*.zig` |
198
+ | `write_ts_adhere_bun.md` | `write_ts_adhere_bun.sh` | `*.ts *.tsx *.js *.jsx` |
199
+ | `write_sql.md` | `write_sql.sh` | `schema/*.sql` |
200
+ | `write_any.md` | `write_any.sh` | any source (cross-cutting authoring rules) |
201
+
202
+ **Disposition taxonomy — all 20 mapped; 15 dissolve, 5 stay (NOT emptied):**
203
+
204
+ - **(A) Language-authoring gates → that language's façade.** `zig`, `pub-surface`,
205
+ `lifecycle` → `write_zig`; `ui-substitution`, `design-token` → `write_ts_adhere_bun`;
206
+ `schema-removal` → `write_sql`.
207
+ - **(B) Cross-cutting authoring gates → `write_any`.** `file-length`, `logging`,
208
+ `milestone-id`, `error-registry`, `ufs`, `greptile`, and the legacy-workaround
209
+ family (`nlr`, `nlg`, `legacy-design`). **Principle (not a junk drawer):**
210
+ `write_any` holds *language-agnostic authoring invariants that apply identically
211
+ to every source file* — literal hygiene, length, observability, milestone-free
212
+ naming, dead-code/legacy. The discriminator vs (C): (B) is checked **per file at
213
+ write time**; (C) governs the **lifecycle/process**, never a single file's bytes.
214
+ - **(C) Process / meta gates → STAY as `docs/gates/` bodies (NOT dissolved).**
215
+ `verification`, `invariance-suite`, `spec-template`, `architecture`, `doc-read`.
216
+ **Why they keep their `docs/gates/` cards (not inlined into `AGENTS.md`):**
217
+ `AGENTS.md` is 28744 / 29696 bytes — ~950 bytes headroom; five bodies cannot fit.
218
+ So `docs/gates/` is **never emptied** — it retains exactly these five cards. This
219
+ is also what de-fangs the "disk_count → 0 fails the parity check" risk (§9).
220
+
221
+ **The new parity invariant (the hard part v1 hand-waved).** `agents-md.sh`
222
+ check #9b becomes: `AGENTS.md dispatch-rows == (retained docs/gates/ bodies = 5)
223
+ + (dispatch façades = 4)`, and the empty-set guard (`:177`) flips from "≥1 gate
224
+ body" to "exactly the 5 process bodies present." `REQUIRED_GATES` (data.sh)
225
+ splits into `REQUIRED_PROCESS_GATES` (5) + `REQUIRED_DISPATCH` (4). No gate is
226
+ homeless, none double-homed, and the audit counts a well-defined mixed end-state.
227
+
228
+ ## 6 · EVALS — both spaces + two new proofs
229
+
230
+ ### 6.1 Deterministic façade evals — prose-pinned fixtures
231
+ ```
232
+ evals/dispatch/fixtures/
233
+ length_350_pass.zig → write_zig.sh expects exit 0
234
+ length_351_fail.zig → expects exit 1 (PINS the prose bound)
235
+ ufs_dup_string.zig → expects exit 1
236
+ deinit_missing.zig → expects exit 1
237
+ evals/dispatch/run.sh → runs each fixture, diffs actual vs expected exit
238
+ ```
239
+ Every `[DETERMINISTIC → CODE]` rule MUST have ≥1 pass + ≥1 fail fixture, and any
240
+ rule whose prose states a bound MUST have a fixture that pins it (§3).
241
+
242
+ ### 6.2 Latent façade evals — COMPREHENSION probes (rewire the EXISTING harness)
243
+ `evals/llms/run.sh` is a **cross-agent comprehension runner**
244
+ (claude/codex/amp/opencode, `:69-78`). It grades by exact match on a
245
+ `VERDICT: YES|NO` line over `fixtures.jsonl` (`:125-174`) — it is a *comprehension*
246
+ grader, **not an adherence judge** over free-form code. v2 is honest about that:
247
+ 1. **Repoint context.** `build_context()` (`:83-90`) currently cats
248
+ `"$GATES_DIR"/*.md`. Repoint to cat **`dispatch/*.md` PLUS the retained
249
+ `docs/gates/*.md`** (the 5 process cards, §5). Without this, `cat
250
+ "$GATES_DIR"/*.md` dies on a changed dir. `GATES_DIR` at `:22`.
251
+ 2. **JUDGMENT evals are comprehension probes, not adherence proofs.** A probe asks:
252
+ *"given `write_zig.md`, does the model correctly answer the TGU judgment
253
+ question (union vs optional-struct)?"* — a YES/NO the existing grader can score.
254
+ It proves the model **understands** the rule, NOT that a real diff **adhered**.
255
+ **Real-diff adherence is checked at `/review` + greptile, not in CI** — claiming
256
+ a CI judge proves adherence was v1's category error. A true adherence judge
257
+ (elicit code → rubric-grade with a pinned model) is **out of scope for v2**;
258
+ flagged in §16 if you want it scoped later.
259
+
260
+ ### 6.3 Coherence audit — `evals/dispatch/coverage.sh` (honest scope)
261
+ Proves **completeness and symbol-presence** — NOT prose semantics (that's §6.1's
262
+ fixtures). Fails if any of:
263
+ - a `[DETERMINISTIC → CODE]` tag has no row for `CODE` in **any** dispatch `.sh` (a *universal* code like `UFS` is wired once in its home façade — `write_any` — and satisfies the tag wherever the rule's prose appears; only a code wired in NO dispatch fails — §16 Decision 6);
264
+ - a DETERMINISTIC rule has no pass+fail fixture — this audit checks fixture *presence* only; the boundary-*pinning* of a bounded rule (the `351` flips if the cap moves) is proven by `run.sh` executing the boundary fixtures against the live cap, NOT by this audit (§6.1);
265
+ - a `[JUDGMENT]` rule has no comprehension probe (§6.2);
266
+ - a `.sh` CODE row has no tag in the `.md` (orphan check);
267
+ - **a CODE row delegates to a leaf helper that is absent / non-executable**
268
+ (closes the silent-green hole, §10);
269
+ - a CODE appears in `.sh` output with no gloss-map entry (no naked codes).
270
+
271
+ ### 6.4 Rule-code glosses — ONE canonical list
272
+ v1 already drifted: `lib.sh:45-61` carries codes (`FLL`/`LENGTH` duplicated;
273
+ `PUB`/`DRAIN`/`DEINIT`/`ARCH`/`XCOMPILE`) absent from the `RULES.md` legend and the
274
+ old §6.4 table. v2: **one canonical gloss list** in `RULES.md`; `lib.sh` mirrors it;
275
+ `dispatch-coverage.sh` fails on any divergence. Drop the `FLL`/`LENGTH`
276
+ duplicate. Delegated-only codes (`PUB`/`DRAIN`/`XCOMPILE`) get legend entries too.
277
+
278
+ ### 6.5 Merge-loss proof — `evals/dispatch/merge-coverage.sh` (NEW, keystone)
279
+ For each of the 15 authoring cards scheduled for deletion: assert every
280
+ non-boilerplate token-line appears in some `dispatch/*.md`, **or** is captured as
281
+ an explicit drop. **Honest scope (same discipline as §6.3):** this proves
282
+ *prose-token coverage*, NOT semantic equivalence and NOT trigger-enforcement —
283
+ that a reworded-but-faithful merge and an enforcement-orphaned trigger are *both*
284
+ risks the token scan alone won't catch. Three guards close the gameable holes the
285
+ adversarial pass flagged:
286
+ - **Frozen normalization** (not "normalized", hand-wave): lowercase → strip
287
+ markdown punctuation/backticks → collapse whitespace → tokenize to a word
288
+ multiset. The grammar is pinned in the script + a negative fixture proves an
289
+ orphaned sentence FAILS.
290
+ - **No agent self-certification.** The "intentionally-dropped" branch requires an
291
+ **Indy ack-quote** in the PR (Pull Request) body (per the deferral-discipline
292
+ rule) — the merging agent may not author its own drop justification.
293
+ - **Trigger-surface enforcement is separate.** Each dissolved card's machine
294
+ trigger (e.g. `milestone-id`'s `M[0-9]+_[0-9]+` regex, `ui-substitution`'s raw
295
+ element list) must reproduce as a `.sh` CODE row, verified by §6.3's tag↔check
296
+ wiring — token-coverage alone does not prove the trigger still fires.
297
+
298
+ A card is not deleted until its delta-landed assertion is green. Preserve any
299
+ `audits/agents-md.md` scenario that quotes a deleted body verbatim (§11).
300
+
301
+ ### 6.6 The docs tier — same grammar, one more class (M02_001)
302
+
303
+ Everything above governs `dispatch/`. The `docs/` rule tier sat outside every
304
+ coverage glob: hundreds of normative clauses with no enforcement class, no
305
+ report, and no signal when a trigger went dead. `audits/rule-ledger.sh` extends
306
+ this model there, reusing the tag grammar rather than forking it.
307
+
308
+ **One new class.** `[DETERMINISTIC → CODE]` and `[JUDGMENT → CODE]` keep their
309
+ meanings. `[UNENFORCED → reason]` is added, and its reason is prose on purpose:
310
+ a clause nobody checks should say *why* in the place a reader meets it. The
311
+ class exists so acknowledged prose is distinguishable from a clause nobody has
312
+ triaged — without it, both read as "untagged" and the backlog lies.
313
+
314
+ **Tag scope.** A tag alone on its line covers every clause beneath it until the
315
+ next heading; a tag at the end of a sentence covers that sentence. The `docs/`
316
+ tier is paragraph-shaped where `dispatch/` is section-shaped, and forcing one
317
+ tag per line would have meant editing prose to satisfy a counter.
318
+
319
+ **What counts as a clause.** A line carrying a normative keyword, outside
320
+ headings and markdown tables — a heading is a title, and a table row's `always`
321
+ is usually a column value. The count is a keyword heuristic and never gates:
322
+ the only reds are structural (a cited-but-unregistered doc, a registered path
323
+ missing from disk, a façade `.sh` with no `dispatch_init` scope, a stale
324
+ scoreboard).
325
+
326
+ **Where the registry lives.** `REGISTERED_DOCS` / `EXCLUDED_DOCS` /
327
+ `EXCLUDED_PREFIXES` in `audits/rule-ledger-lib.sh`. A `docs/*.md` cited by a
328
+ façade and absent from both lists is a parity red — silence is the one outcome
329
+ not allowed, because it under-reports the corpus. The generated scoreboard is
330
+ `docs/RULE_ENFORCEMENT.md`, currency-checked by `make audit`.
331
+
332
+ ## 7 · Firing planes (corrected wiring + latency)
333
+
334
+ | Plane | When | Invocation |
335
+ |---|---|---|
336
+ | Latent | EXECUTE, about to write | agent reads `write_zig.md`; runs `write_zig.sh <file>` (scoped to the touched file, NOT `--all`) |
337
+ | Anchor | CONFORM (end-of-turn) | `write_zig.sh --staged`; 🔴 → back to EXECUTE; 🤔 → state verdict |
338
+ | Backstop | COMMIT | **`.githooks/pre-commit`** (core.hooksPath, confirmed) runs `dispatch/*.sh --staged` — **dotfiles repo only;** product repos keep the 8 leaf audits (Reading A, §10.7) |
339
+ | Audit | pre-push + `make audit` | `dispatch-coverage.sh` + `merge-coverage.sh` wired into the SAME chain as `agents-md.sh` |
340
+ | Evals | pre-push + `make` | deterministic fixtures + live smoke; full `make llmevals` is explicit |
341
+
342
+ **Latency fix:** v1's `write_zig.sh` wired `ufs.sh --all` (full-tree scan)
343
+ on every per-edit call — contradicting "instant on no-match." v2 scopes leaf runs
344
+ to `DISPATCH_FILES` (teach `ufs.sh` a file-list mode; pass the staged set);
345
+ `--all` runs only on the Audit/Evals planes. State a measured latency on
346
+ `agentsfleet` before claiming "instant."
347
+
348
+ ## 8 · In-dotfiles blast radius (PRIMARY — grounded, ~14 files)
349
+
350
+ The dissolution + rename touches the operating model's own enforcement spine.
351
+ **Every edit below lands in the Stage-2 atomic commit (§9).** Citations verified
352
+ against `feat/dispatch-architecture`:
353
+
354
+ | File | Line(s) | What it pins | Must change to |
355
+ |---|---|---|---|
356
+ | `audits/agents-md.sh` | `:14` | `GATES_DIR=docs/gates` | derive from `dispatch/` |
357
+ | ″ | `:46-65` (#1) | `REQUIRED_GATES` ⊂ AGENTS.md index | dispatch-set inventory |
358
+ | ″ | `:171-187` (#8) | gate bodies; **`:177` empty-set guard** | dispatch-body completeness |
359
+ | ″ | `:190-209` (#9b) | parity `index==disk==REQUIRED` | dispatch parity |
360
+ | ″ | `:263-277` | both hooks must grep `docs/gates` | grep `dispatch/` |
361
+ | ″ | `:130-133` | `DOTFILES_RESIDENT` docs exist | new resident paths |
362
+ | `audits/data.sh` | `:36-46` | `REQUIRED_GATES` name array | dispatch set |
363
+ | ″ | `:70-78` | `DOTFILES_RESIDENT` (ZIG/BUN/greptile RULES) | `dispatch/*.md` |
364
+ | ″ | `:94-118` | `NAMED_SCENARIOS` 1:1 w/ invariance | mirror scenario edits |
365
+ | `.githooks/pre-commit` | trigger glob | gates `AGENTS.md`/`docs/gates` edits | add `dispatch/` |
366
+ | `.githooks/pre-push` | `:72` + guard | message + `docs/gates` guard | repoint + reword |
367
+ | `evals/llms/run.sh` | `:22`, `:83-90` | `build_context` cats `docs/gates/*.md` | cat `dispatch/*.md` |
368
+ | `evals/test-agents-md.sh` | `:39,46,165-167` | sandbox builds `docs/gates`+RULES; negative case asserts hook bites on dropped `docs/gates` | rewrite sandbox + negatives for dispatch model |
369
+ | `bin/link-agents-md` | `:35,37,45` | propagates `ZIG_RULES`/`BUN_RULES`/`docs/gates` → product repos | repoint + **add `dispatch/`** |
370
+ | `AGENTS.md` | `:66,212` | `*.zig`→ZIG_RULES; /review→ZIG_RULES | →`write_zig.md` + Dispatch table |
371
+ | `docs/EXECUTE_DOC_READS.md` | `:11,12` | zig→ZIG_RULES, ts→BUN_RULES | →façades |
372
+ | `docs/greptile-learnings/RULES.md` | `:42,91` | cross-ref ZIG_RULES sections | →`write_zig.md` |
373
+ | `docs/LIFECYCLE_PATTERNS.md` | `:3,311` | sister-doc refs ZIG_RULES | →`write_zig.md` |
374
+ | `docs/LOGGING_STANDARD.md` | `:193,195,263,283-285` | BUN_RULES §9/§10, ZIG_RULES | →façades |
375
+ | `docs/TEMPLATE.md` | `:139,142,154,356` | ZIG/BUN doc-read rows | →façades |
376
+ | `docs/ZIG_RULES.md` | `:415` | refs BUN_RULES §2 | `git rm` (deleted; cross-ref already resolved in the merged `write_zig.md`) |
377
+ | `audits/logging.sh` | `:152` | fail message cites `BUN_RULES §10` | →`write_ts_adhere_bun.md §logging` |
378
+ | `skills/orly-spec-new/SKILL.md` | `:63` | names `ZIG_RULES.md`/`BUN_RULES.md` as per-surface rule files | →façades (verify sync scope before assuming it ships to product repos) |
379
+ | `docs/HARNESS_VERIFY_OUTPUT.md` | `:19,26-36` | `🟡 = violations addressed` | add `🤔 DECIDE` legend + JUDGMENT row (§11) |
380
+
381
+ **Magnitude:** ~30+ edits across ~16 files, all in one atomic commit. This is the
382
+ work v1 never scoped — it is the dominant cost, not a footnote.
383
+
384
+ **Completeness is machine-enforced, not trust-the-table.** A
385
+ `zero-dangling-ref` audit gates Stage 2: `grep -rIl 'ZIG_RULES\|BUN_RULES\|docs/gates/[a-z-]*\.md'`
386
+ across the tree (minus this doc, git history, and the 5 retained process cards)
387
+ must return **zero** hits. The table above is the human map; the grep is the gate
388
+ — it catches any ref site (like `logging.sh` / `SKILL.md`) the table missed.
389
+
390
+ **Product-repo files are out of scope (Reading A — Indy, confirmed).** This
391
+ inventory is dotfiles-only: no product repo's `make/harness.mk` or
392
+ `.githooks/pre-commit` is edited by the migration. The 8 leaf audits remain each
393
+ repo's commit-plane + harness enforcement and reach it as `link-agents-md`
394
+ **symlinks**, so the one in-scope leaf edit (`logging.sh:152`, fail-message
395
+ repoint) propagates with **zero product-repo commit**. Dispatch ship to product
396
+ repos as **agent-facing files only** (§10.7) — never wired into a product Makefile
397
+ or hook.
398
+
399
+ ## 9 · Migration plan — staged, non-destructive (the keystone fix)
400
+
401
+ The Invariance Suite Gate is **no-override** and derives the gate set from disk
402
+ with 3-way parity, so any intermediate state where `docs/gates/` is half-gone
403
+ fails `make audit` — which the hooks run unconditionally, blocking the very commit.
404
+ v2 therefore **never lets `make audit` go red mid-flight**:
405
+
406
+ **Stage 0 — Scaffold (purely additive; gates + RULES untouched).** Create
407
+ `dispatch/{lib,write_zig,write_ts_adhere_bun,write_sql,write_any}.{sh}` and the
408
+ `.md` façades (merge ZIG_RULES + gate deltas) ALONGSIDE the still-present
409
+ `docs/gates/` and `docs/ZIG_RULES.md`. Add `evals/dispatch/`,
410
+ `dispatch-coverage.sh`, `merge-coverage.sh`. **`make audit` stays
411
+ green** (nothing removed). One or more commits.
412
+
413
+ **Stage 1 — Prove equivalence (still additive).** `merge-coverage.sh` green
414
+ (every gate-card delta landed in a façade). `dispatch-evals/run.sh` green.
415
+ `make llmevals` green against the new dispatch context. Dispatch and legacy gates
416
+ both present and passing. **`make audit` stays green.** Commit.
417
+
418
+ **Stage 2 — Atomic switchover (the ONLY harness-editing commit → Indy sign-off).**
419
+ In ONE commit: all §8 edits + zero-dangling-ref grep green + `git rm
420
+ docs/ZIG_RULES.md docs/BUN_RULES.md` — **deletion, not `git mv`**: the prose was
421
+ already additively merged into `dispatch/write_zig.md` (657 lines) and
422
+ `dispatch/write_ts_adhere_bun.md` in Stage 0, so a `git mv` would clobber the
423
+ merged façades; `merge-coverage.sh` is the proof-of-no-loss — + `git rm` the **15
424
+ authoring cards only** (the 5 process cards STAY, §5; only after §6.5 green) +
425
+ `git rm` the now-spent **merge-coverage set** (`evals/dispatch/merge-coverage.sh`,
426
+ `merge_coverage.py`, `merge-coverage-drops.tsv`, `fixtures/merge_orphan_card.md`)
427
+ — one-shot migration scaffolding, dead once the cards are gone (RULE NDC) — +
428
+ AGENTS.md gate-index → Dispatch table (4 rows) + slimmed 5-row process-gate index +
429
+ `link-agents-md` repoint & dispatch-add.
430
+
431
+ **Why atomic IS green (the fresh-eyes "impossible" objection, resolved).** The
432
+ pre-commit hook runs the *worktree's* `agents-md.sh` against the *worktree*.
433
+ In this single commit the rewritten audit AND the new tree are both
434
+ staged-and-saved together, so the **new** parity check (`5 process + 4 dispatch`,
435
+ §5) evaluates the **new** state — never the old check against a half-migrated tree.
436
+ `docs/gates/` is never emptied (5 cards stay), so the `:177` empty-set guard is
437
+ satisfied throughout. Run `make audit && make test-audit` as a **pre-flight on the
438
+ fully-staged worktree** before `git commit`; the hook then re-confirms. No
439
+ `--no-verify`, ever.
440
+
441
+ **Rollback.** Stages 0–1 are additive → nothing to revert. Stage 2 is one commit →
442
+ `git revert` restores the full prior spine (gate cards live in git history; the
443
+ merge was additive prose, so reverting loses no rule). No kill-switch needed
444
+ because no destructive state exists before Stage 2.
445
+
446
+ **Per Hard-Safety:** Stage 2 edits `audit-*.sh` + hooks (a harness/gate) → it
447
+ requires **explicit Indy sign-off naming the files + reason**, captured in the PR
448
+ Session Notes. The agent does not switch over unilaterally.
449
+
450
+ ## 10 · Execution-location & cross-repo delivery
451
+
452
+ **The problem v1 ignored — and the symlink twist the adversarial pass caught:**
453
+ `dispatch_resolve_files --staged` discovers files via `git -C "$DISPATCH_ROOT"`,
454
+ where `DISPATCH_ROOT` is derived from `BASH_SOURCE` (`lib.sh:35`). But
455
+ **`bin/link-agents-md` SYMLINKS** (`ln -s`, confirmed `:160,176`) — it does not copy.
456
+ So a dispatch "shipped" into `agentsfleet` is a symlink back to
457
+ `~/Projects/dotfiles/dispatch/`, and a `BASH_SOURCE`-derived `DISPATCH_ROOT`
458
+ resolves to **dotfiles**, not `agentsfleet` — the Zig checks scan dotfiles' empty
459
+ tree and pass **vacuously**, exactly the bug propagation was supposed to cure.
460
+
461
+ **v2 model — separate the two roots `lib.sh` currently conflates:**
462
+ 1. **`DISPATCH_HOME`** (where the scripts live, for `source lib.sh` + finding
463
+ `audits/`) — from `BASH_SOURCE`. Follows the symlink to dotfiles; that's
464
+ correct for *locating the code*.
465
+ 2. **`TARGET_ROOT`** (the repo being checked, for `--staged` git discovery AND the
466
+ leaf-check scope) — from **`git rev-parse --show-toplevel`** of the CWD (or the
467
+ file arg's dir). This resolves to `agentsfleet` when the symlinked dispatch is run
468
+ from inside `agentsfleet`, so discovery and the leaves (`ufs.sh` etc., which
469
+ already root off `--show-toplevel`) **agree on the same repo**. Robust whether
470
+ sync copies or symlinks.
471
+ 3. **Ship dispatch into each product repo via `bin/link-agents-md`** (add a
472
+ `dispatch:dispatch` entry to the link list). With (2), the symlink is now safe.
473
+ 4. **Dotfiles = source-of-truth + fixture/eval host**, not where Zig checks run on
474
+ real code. `evals/dispatch/` fixtures are the only place these checks
475
+ are provable in dotfiles (it has no `*.zig`).
476
+ 5. **`dispatch_run_helper` hard-fails (🔴, `DISPATCH_RC=1`) on an absent
477
+ DETERMINISTIC helper** — never `🟣`/exit 0. `🟣` is reserved for
478
+ `dispatch_delegate`. `dispatch-coverage.sh` enforces helper presence (§6.3).
479
+ 6. Add a `link-agents-md` propagation test + a **staleness note:** symlinks are always
480
+ current; a product-repo *real-file* override triggers `link-agents-md`'s existing
481
+ warn-and-skip (`:171`) — flagged, not silent. Add `dispatch/*.md` to
482
+ `DOTFILES_RESIDENT`.
483
+ 7. **Product repos are NOT rewired (Reading A — Indy, confirmed).** `link-agents-md`
484
+ ships `dispatch/{*.md,*.sh}` into each product repo as **agent-facing files**
485
+ (read at EXECUTE; runnable on a touched file) — but **no product repo's
486
+ `make/harness.mk` or `.githooks/pre-commit` is edited.** The 8 leaf audits
487
+ (`audit-ufs` … `audit-msid-ui`, symlinked in) stay each repo's codebase-wide
488
+ mechanical net; dispatch are the per-file authoring lens + the dotfiles-side
489
+ coherence/merge audits (§6.3/§6.5). The §7 Backstop plane is therefore
490
+ **dotfiles-only** — it fires against `evals/dispatch/` fixtures (dotfiles
491
+ has no real `*.zig`/`*.ts`), which keeps the §8 zero-dangling-ref grep and the
492
+ Stage-2 sign-off scoped to dotfiles.
493
+
494
+ ## 11 · JUDGMENT enforcement — honest, and made auditable
495
+
496
+ `dispatch_judgment` prints a `🤔` row and exits 0. No script can decide a taste
497
+ question, and faking determinism on one is the anti-goal. So the claim is scoped
498
+ honestly: **DETERMINISTIC rules are proven; JUDGMENT rules are attested.** v2
499
+ makes the *attestation* auditable rather than pure honor-system:
500
+
501
+ - Add a **JUDGMENT row to `HARNESS_VERIFY_OUTPUT.md`** (`HARNESS_KEYS` in
502
+ `data.sh:62-67`). **Honest scope:** the audit check is `grep -qF "$kw"
503
+ AGENTS.md` (`agents-md.sh:117`) — it verifies the row *exists* in the prose
504
+ (so CONFORM always lists a judgment line), NOT that a *specific turn*
505
+ answered its `🤔`. Per-turn answering is **not machine-checked** — claiming
506
+ otherwise was the overclaim the coverage pass flagged.
507
+ - **The machine backstop is the deferred ledger, not this row.** A turn-scoped
508
+ verdict ledger that `pre-commit` refuses until each `🤔` has a `CODE: applied|N/A`
509
+ ack is the only thing that mechanically blocks an unanswered judgment. Deferred
510
+ to §16 Q1 — without it, judgment adherence is attested + comprehension-probed
511
+ (§6.2), not enforced. Stated plainly, not dressed up.
512
+ - **Cross-agent caveat:** headless non-Orly agents (codex/amp/opencode) emit `🤔`
513
+ to stdout with no chat audience; the comprehension probe (§6.2) is the only
514
+ signal for them. The turn-verdict ritual is interactive-Orly best-effort.
515
+
516
+ **Invariance-questionnaire migration (part of Stage 2).** Dissolving the 15
517
+ authoring cards can strand `audits/agents-md.md` scenarios that assert facts about
518
+ those bodies. Before deletion: `grep` the questionnaire for every scenario that
519
+ (a) quotes a dissolved body verbatim, (b) requires a per-body structural section
520
+ (the review flagged a `Scope (M70)` requirement), or (c) triggers on "edits any
521
+ `docs/gates/*.md`". Each must be **relocated, retired, or rebased onto the façade
522
+ with an Indy ack** so it stays answerable-YES. The review named ~7.10/13.1/14.5/
523
+ 22.4/23.1 — **confirm exact IDs at execution** (the grep is the source of truth,
524
+ not these numbers). `NAMED_SCENARIOS` parity (`data.sh:94-118`) keeps the
525
+ keyword count honest but does not make a YES answer true — that's manual.
526
+
527
+ §1/§9 language is downgraded accordingly: "proven, not promised" holds for the
528
+ DETERMINISTIC half; the JUDGMENT half is "attested + eval-sampled."
529
+
530
+ ## 12 · Invariants (code-enforced)
531
+
532
+ 1. One verdict format — all `.sh` source `lib.sh`.
533
+ 2. **No missing symbol** (not "no drift") — coherence audit (§6.3).
534
+ 3. **No threshold drift** — single-source value + prose-pinned fixture (§3, §6.1).
535
+ 4. Determinism — caps intrinsic to file content, never git history.
536
+ 5. Every rule classified — no untagged section (audit-enforced).
537
+ 6. Every rule evaluable — DETERMINISTIC→fixture, JUDGMENT→judge (audit-enforced).
538
+ 7. No rule lost on merge — `merge-coverage.sh` (§6.5).
539
+ 8. No naked codes — one canonical gloss list (§6.4).
540
+ 9. No silent green — absent DETERMINISTIC helper → 🔴 (§10).
541
+ 10. One glyph, one meaning — `🟡` addressed, `🤔` decide (§3.1).
542
+
543
+ ## 13 · Acceptance criteria
544
+
545
+ **Dispatch assets**
546
+ - [ ] `dispatch/{lib,write_zig,write_ts_adhere_bun,write_sql,write_any}.{sh}` exist
547
+ - [ ] `dispatch/{write_zig,write_ts_adhere_bun,write_sql,write_any}.md` exist; every § tagged; thresholds single-sourced in the `.sh`
548
+ - [ ] `file-length` fn≤50 / method≤70 sub-cap **implemented as a leaf check OR honestly tagged `[JUDGMENT]`** — named explicitly, not collapsed into "300/350"
549
+ - [ ] glyph `🤔 DECIDE` defined; `🟡` left as "violations addressed"
550
+
551
+ **Evals & proofs**
552
+ - [ ] `evals/dispatch/` fixtures: every DETERMINISTIC rule pass+fail; every prose bound pinned
553
+ - [ ] `evals/llms/` JUDGMENT scenario per rule; `build_context` repointed to `dispatch/`
554
+ - [ ] `evals/dispatch/coverage.sh` clean (tags↔checks↔evals↔helper-presence↔glosses)
555
+ - [ ] `evals/dispatch/merge-coverage.sh` clean (every deleted card's delta landed)
556
+ - [ ] one canonical gloss list (`RULES.md` ↔ `lib.sh`); `FLL`/`LENGTH` dup removed
557
+
558
+ - [ ] `dispatch/lib.sh`: `DISPATCH_HOME` (BASH_SOURCE) vs `TARGET_ROOT` (`git rev-parse --show-toplevel`) split (§10); absent DETERMINISTIC helper → 🔴 not 🟣/0
559
+ - [ ] `docs/EXECUTE_DOC_READS.md`: doc-reads trigger rows for the NET-NEW façades (`write_sql.md`, `write_any.md`), not just repointed zig/ts rows
560
+
561
+ **Harness rewrites (first-class; Stage-2; Indy sign-off)**
562
+ - [ ] `data.sh`: `REQUIRED_GATES` → `REQUIRED_PROCESS_GATES` (5) + `REQUIRED_DISPATCH` (4); `DOTFILES_RESIDENT`→`dispatch/*.md`; `NAMED_SCENARIOS` mirrors invariance edits
563
+ - [ ] `agents-md.sh`: checks #1/#8/#9b derive the mixed end-state; parity `index == 5 process bodies + 4 dispatch`; empty-set guard → "exactly the 5 process cards present"; hook-trigger check greps `dispatch/` + `docs/gates/`
564
+ - [ ] `.githooks/pre-commit` + `pre-push` repointed (NOT `.git/hooks/`)
565
+ - [ ] `evals/test-agents-md.sh` rewritten: sandbox + negative cases prove the NEW coherence audit bites
566
+ - [ ] `HARNESS_VERIFY_OUTPUT.md` JUDGMENT row + `🤔` legend; `audits/agents-md.md` question pinning `🤔` and the dispatch model
567
+ - [ ] `bin/link-agents-md` repointed + `dispatch:dispatch` added + propagation test
568
+
569
+ **Migration & references**
570
+ - [ ] Stage 0/1 commits keep `make audit` green; Stage 2 atomic; rollback note in PR
571
+ - [ ] `zero-dangling-ref` grep gate green (§8) — machine-enforced, not trust-the-table
572
+ - [ ] invariance-questionnaire migration done: stranded scenarios relocated/retired/rebased with Indy ack (§11)
573
+ - [ ] all §8 sibling-doc references repointed in the Stage-2 diff (incl. `logging.sh`, `SKILL.md`)
574
+ - [ ] cross-repo (`agentsfleet`) refs resolved via `link-agents-md` propagation (§10)
575
+ - [ ] `make audit` + `make test-audit` ALL CHECKS PASSED at Stage-2 boundary + invariance signoff
576
+
577
+ ## 14 · Failure modes → mitigations
578
+
579
+ | Failure | Mitigation |
580
+ |---|---|
581
+ | `.md` prose value drifts from `.sh` | single-source threshold + prose-pinned fixture (§3) — not the tag |
582
+ | DETERMINISTIC helper deleted/renamed → silent green | `dispatch_run_helper` → 🔴; coherence audit asserts helper presence (§10) |
583
+ | `make audit` red mid-migration blocks the commit | staged, additive migration; red only conceivable inside the one atomic Stage-2 commit (§9) |
584
+ | Unique gate prose lost on merge | `merge-coverage.sh` blocks deletion until delta lands (§6.5) |
585
+ | `llmevals` dies on empty `docs/gates/` under `set -e` | `build_context` repointed to `dispatch/` in Stage 2 (§6.2, §8) |
586
+ | Dispatch never reaches `agentsfleet` | added to `link-agents-md`; dispatch ship into product repos (§10) |
587
+ | `🤔` judgment silently ignored | CONFORM JUDGMENT row audited; Large Language Model (LLM) judge evaluation samples adherence (§11) |
588
+ | Glyph ambiguity | `🟡` and `🤔` disjoint, pinned by invariance question (§3.1) |
589
+ | Backstop never runs on fresh clone | wired to `.githooks/` (core.hooksPath), not `.git/hooks/` (§7) |
590
+
591
+ ## 15 · Discovery (consult log)
592
+
593
+ - **Façade-pair insight (Indy, Jun 04):** dispatch = `.md`+`.sh` pair, not one file.
594
+ - **Merge, not rename (Indy, Jun 04):** *"latentspace `dispatch/write_zig.md`
595
+ (merged perfected made more deterministic merge of the ZIG_RULES.md + the
596
+ gates/\*.md relevant to zig)"* → §2: façade `.md` is a merge of ZIG_RULES + zig
597
+ gate deltas; `zig.sh` renamed to `write_zig.sh` (the bare `zig.sh` name rejected).
598
+ - **Manifest rejected:** `.sh` is executable truth; manifest duplicates.
599
+ - **gates/\*.md dissolved selectively (v2):** authoring gates → façade; process
600
+ gates stay in AGENTS.md (§5) — v1's "all 20 → façades" was a category error.
601
+ - **new=300/edited=350 rejected:** git-state-dependent → flat caps, intrinsic.
602
+ - **Evals in both spaces (Indy, Jun 04):** fixtures + LLM-judge + coherence audit.
603
+ - **Glosses (Indy, Jun 04):** gloss map + RULES.md legend + baked into output.
604
+ - **Adversarial CTO review (Orly, Jun 04):** 7 lenses, 38 confirmed findings
605
+ (19 P0), verdict REWORK. v2 absorbs all P0/P1: staged migration (§9), primary
606
+ in-dotfiles blast radius (§8), downgraded drift claim + semantic anchor (§3),
607
+ merge-loss proof (§6.5), execution-location model (§10), glyph fix (§3.1),
608
+ honest JUDGMENT (§11), `.githooks` wiring (§7).
609
+ - **Decisions made this turn (Orly, pick-and-proceed):** (a) `🤔` for judgment
610
+ rather than re-glyph `🟡` — additive, lower blast radius; (b) staged migration
611
+ over single atomic diff — keeps `make audit` green and gives free rollback;
612
+ (c) dispatch ship into product repos via `link-agents-md` — the only way the Zig
613
+ checks run against real `*.zig`. Indy to confirm or redirect.
614
+ - **Stage-2 sign-off (Indy, Jun 04, 2026):** *"stage-2 yes signed off"* — context:
615
+ authorizes the Stage-2 atomic switchover to edit `audit-*.sh` + `.githooks` (a
616
+ harness/gate), satisfying the Hard-Safety harness-patch rule. The `🤔` glyph and
617
+ the JUDGMENT ledger remain open (§16, Q1/Q2).
618
+
619
+ ## 16 · Decisions (was: open questions)
620
+
621
+ 1. **JUDGMENT hardening — DEFERRED** (Indy, Jun 04, 2026: *"I defer the ledger,
622
+ its complicated"*). v2 ships judgment as **attested + comprehension-probed**
623
+ (§11); the turn-scoped verdict ledger is a possible later hardening, not v2 scope.
624
+ 2. **`🤔` glyph — pending confirm** (default: accept `🤔 DECIDE`, leaving `🟡` as
625
+ "violations addressed"; alternative is re-glyphing `🟡` in
626
+ `HARNESS_VERIFY_OUTPUT.md`). Cosmetic/semantic only — a colored-circle swap.
627
+ 3. **Stage-2 sign-off — GRANTED** (Indy, Jun 04, 2026, §15): the Stage-2 atomic
628
+ switchover may edit `audit-*.sh` + `.githooks` per the Hard-Safety harness-patch
629
+ rule.
630
+ 4. **Code length cap = 350 — RECONCILED** (Indy, Jun 04, 2026): the file-length
631
+ gate card's `350` is canonical for all code (`.zig`/`.ts`/`.tsx`/`.js`/`.py`/
632
+ `.rs`/`.go`/`.sql`). `write_zig.sh`'s stray `300` corrected to `350`; the §3/§4/
633
+ §6.1 examples regenerated at `350`/`351`. Every dispatch's `dispatch_length_gate`
634
+ equals the gate's `350`, so the early-warning never diverges from enforcement.
635
+ 5. **`.md` doc/spec length caps — DEFERRED** (Indy, Jun 04, 2026): `.md` stays
636
+ exempt from the length gate (status quo). The long merged façades (`write_zig.md`
637
+ 654L, `write_ts_adhere_bun.md` 486L) are therefore legal. Tiered doc/spec caps
638
+ (e.g. docs 350 / specs 400) are a possible post-Stage-2 task, not v2 scope.
639
+ 6. **UFS enforcement consolidated to `write_any`** (Indy, Jun 04, 2026): `UFS` is a
640
+ universal rule, so it is run-wired ONCE in `write_any.sh` (which fires for every
641
+ source file). The `dispatch_run_helper "UFS"` rows were removed from
642
+ `write_zig.sh` + `write_ts_adhere_bun.sh`; their verbatim UFS prose stays, tagged
643
+ `[DETERMINISTIC → UFS]` but annotated as enforced-by-`write_any`. This restores
644
+ §5's "none double-homed" (enforcement is single-homed) and kills the redundant
645
+ full-tree `audit-ufs` scan on multi-language touches. `dispatch-coverage.sh`
646
+ (§6.3) accepts a universal code wired in any one dispatch.
647
+ 7. **Eval harnesses relocated to top-level `evals/`** (Indy, Jun 05, 2026): the
648
+ deterministic dispatch fixtures + the cross-agent comprehension probes moved
649
+ `audits/{dispatch-evals,llmevals}/` → `evals/{dispatch-evals,llmevals}/` — a
650
+ first-class test home, sibling of `dispatch/`. The merge-coverage drops
651
+ ledger moved out of `dispatch/` (the Stage-2 sync payload, where a
652
+ dotfiles-internal migration artifact must not ship) into
653
+ `evals/dispatch/`. `audits/` retains the `audit-*.sh` family. All
654
+ functional + spec path refs repointed; `DISPATCH_REVIEW_DISPOSITION.md`'s
655
+ review quote of the old path is left as a historical record.
656
+ 8. **Merge-coverage is a Stage-2 deletion gate, not a Stage-0 `make audit` check**
657
+ (Orly, Jun 05, 2026, pick-and-proceed): `merge-coverage.sh` is built +
658
+ self-tested (the orphan fixture bites) but NOT wired into `make audit` — at
659
+ Stage 0 the 15 cards still exist, and "a card is not deleted until its
660
+ assertion is green" (§6.5). Against the real merge it shows 13/15 cards fully
661
+ covered; `zig`/`pub-surface`/`lifecycle` surface ~40 reworded-away prose tokens
662
+ (classified — no lost rules; the PUB/DEINIT rules are tagged in `write_zig.md`).
663
+ These need Indy drop-acks in `evals/dispatch/merge-coverage-drops.tsv`
664
+ before the cards are deleted; wiring into `make audit` follows the acks.