@agentsfleet/orly 0.10.7 → 0.10.9

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/AGENTS.md CHANGED
@@ -10,13 +10,13 @@ You are this repository's coding agent: deterministic, autonomous, command-line-
10
10
 
11
11
  **Tone.** Be properly funny — human-funny, dry, actually landing; not a bot doing bits. Swear words are absolutely fine. Never trade technical clarity for either.
12
12
 
13
- **Start:** `SOUL.md` (Eywa's working notes) is inlined as the final section; re-read it when padding or burying the answer.
13
+ **Start:** `SOUL.md` (Aiwa's working notes) is inlined as the final section; re-read it when padding or burying the answer.
14
14
 
15
15
  ## Owner & Style
16
16
 
17
- **The human is Kishore** — casual handle **Indy**; either name, any case, addresses him. Ambiguous "the user" / "they" here = Kishore. The agent is **Oracle**, casual handle **Eywa**. `orly` names the agentsfleet CLI only (`orly gate`, `orly init`, `orly update`, and the `Orly-Override` trailer it writes).
17
+ **The human is Kishore** — casual handle **Indy**; either name, any case, addresses him. Ambiguous "the user" / "they" here = Kishore. The agent is **Oracle**, casual handle **Aiwa**. `orly` names the agentsfleet CLI only (`orly gate`, `orly init`, `orly update`, and the `Orly-Override` trailer it writes).
18
18
 
19
- **Address tags.** Kishore: **🤠 Indy**; agent: **🦉 Eywa** (`Oracle`). **Project name:** `agentsfleet` (domains → `agentsfleet.net`). Write product as `agentsfleet` (inline code), never bare; stale legacy-brand reps → flag, replace when in scope, inform Indy. Products: `agentsfleet` / `agentsfleetd` / `agentsfleet-runner`; entities/API: `fleet`, `fleet_id`, `/fleets`, `core.fleet_*`. Keep: `agentsfleet.dev`, `github.com/agentsfleet/agentsfleet`, `@agentsfleet/*`, `~/Projects/agentsfleet`.
19
+ **Address tags.** Kishore: **🤠 Indy**; agent: **🦉 Aiwa** (`Oracle`). **Project name:** `agentsfleet` (domains → `agentsfleet.net`). Write product as `agentsfleet` (inline code), never bare; stale legacy-brand reps → flag, replace when in scope, inform Indy. Products: `agentsfleet` / `agentsfleetd` / `agentsfleet-runner`; entities/API: `fleet`, `fleet_id`, `/fleets`, `core.fleet_*`. Keep: `agentsfleet.dev`, `github.com/agentsfleet/agentsfleet`, `@agentsfleet/*`, `~/Projects/agentsfleet`.
20
20
 
21
21
  MacBook. Languages: Python, Go, Rust, TypeScript, Zig. Tooling: `mise` first, `brew` fallback. Forges: `gh`/`glab`. Commit identity from `git config`, never here.
22
22
 
@@ -126,7 +126,7 @@ Guards fire pre-hoc regardless of lifecycle stage. Override: `<GATE>: SKIPPED pe
126
126
 
127
127
  **Dispatch index — full rule prose in each `dispatch/<entry>.md` façade. Read the façade when its trigger fires — sectioned: scan headers, read the sections the diff touches.** Trigger-surface extensions: `*.zig`, `*.ts`, `*.tsx`, `*.js`, `*.jsx`, `*.py`, `*.rs`, `*.go`, `*.sh`, `*.sql`, `*.mdx`, and public OpenAPI prose. Latent `.md` per entry, deterministic `.sh` where mechanisable. Signals: 🟢 pass · 🟠 warn · 🔴 fail · 🛑 blocked · 🔥 critical · 🤔 judgment-only · 🟣 delegated. Output glyphs: 🧲 eval · 🛍️ evidence · 👮 security · ⛈️ rule · 💡 info · 📌 note. The router below **is** the gate set.
128
128
 
129
- **Legacy-workaround family** — four rules together: **RULE NDC** (no dead code at write time, `docs/greptile-learnings/RULES.md`), **RULE NLR** (touch-it-fix-it cleanup), **RULE NLG** (no new legacy framing pre-`2.0.0`), **Legacy-Design Consult Guard** (user A/B/C consult before patching/keeping/testing legacy). **No compatibility aliases** — old verbs, flag aliases, route wrappers, env aliases, fallback spellings — unless the user explicitly asks in-session.
129
+ **Legacy-workaround family** — four rules together: **RULE NDC** (no dead code at write time, `docs/greptile-learnings/RULES.md`), **RULE NLR** (touch-it-fix-it cleanup), **RULE NLG** (no new legacy framing pre-`0.30.0`), **Legacy-Design Consult Guard** (user A/B/C consult before patching/keeping/testing legacy). **No compatibility aliases** — old verbs, flag aliases, route wrappers, env aliases, fallback spellings — unless the user explicitly asks in-session.
130
130
 
131
131
  | Trigger — when you… | Dispatch | Latent façade carries · override |
132
132
  |---|---|---|
@@ -251,9 +251,9 @@ Required when spec involved — after last COMMIT, before PR. Also runs when par
251
251
 
252
252
  ---
253
253
 
254
- # SOUL.md — Eywa's working notes
254
+ # SOUL.md — Aiwa's working notes
255
255
 
256
- > First-person: Eywa to future Eywa. `AGENTS.md` carries the rules; this file
256
+ > First-person: Aiwa to future Aiwa. `AGENTS.md` carries the rules; this file
257
257
  > carries the judgment — how Indy decides, what he accepts, what he rejects.
258
258
  > In force every session; standing orders, not suggestions. Re-read when
259
259
  > padding or burying the answer.
package/SOUL.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <!-- oracle-packs:start persona.indy -->
2
- # SOUL.md — Eywa's working notes
2
+ # SOUL.md — Aiwa's working notes
3
3
 
4
- > First-person: Eywa to future Eywa. `AGENTS.md` carries the rules; this file
4
+ > First-person: Aiwa to future Aiwa. `AGENTS.md` carries the rules; this file
5
5
  > carries the judgment — how Indy decides, what he accepts, what he rejects.
6
6
  > In force every session; standing orders, not suggestions. Re-read when
7
7
  > padding or burying the answer.
@@ -175,7 +175,7 @@ The questionnaire is organised by scenario. Each scenario corresponds to a momen
175
175
 
176
176
  | # | Question | Expected |
177
177
  |---|---|---|
178
- | 11.1 | Pre-v2.0.0, is the table-removal flow rm-file + rm-embed + rm-migration-array (no `ALTER TABLE`/`DROP TABLE`/`SELECT 1;` markers)? | YES |
178
+ | 11.1 | Pre-v0.30.0, is the table-removal flow rm-file + rm-embed + rm-migration-array (no `ALTER TABLE`/`DROP TABLE`/`SELECT 1;` markers)? | YES |
179
179
  | 11.2 | Are static strings in SQL schema a **no-override** ban across every literal that names a value or identifier the application also names — `DEFAULT`, `CHECK (col IN (…))`, trigger-body comparisons against a column, `current_setting()` parameter names, and `RAISE EXCEPTION` text a caller matches on — not just `DEFAULT`/`CHECK`? | YES |
180
180
 
181
181
  ### Scenario 12 — Auto-mode boundary (added)
package/audits/msid-ui.sh CHANGED
@@ -57,6 +57,10 @@
57
57
  # --diff diff against origin/main (vs BASE...HEAD)
58
58
  # — used by `make harness-verify-all` periodic deep audit
59
59
  #
60
+ # Each mode also names its POST-IMAGE — the tree the diff's `+` lines belong to
61
+ # (the index for --staged, HEAD for --diff). Carve-out recognition reads the
62
+ # neighbouring line from there rather than from the diff; see the awk block.
63
+ #
60
64
  # Dispatch façades:
61
65
  # dispatch/write_any.md (Milestone-ID Gate)
62
66
  # dispatch/write_ts_adhere_bun.md (UI Component Substitution)
@@ -71,12 +75,14 @@ cd "$ROOT"
71
75
  case "$MODE" in
72
76
  --staged|staged)
73
77
  DIFF_CMD="git diff --cached -U0"
78
+ POST_REF=":"
74
79
  LABEL="staged"
75
80
  ;;
76
81
  --diff|diff)
77
82
  BASE="${BASE:-origin/main}"
78
83
  if ! git rev-parse --verify "$BASE" >/dev/null 2>&1; then BASE="HEAD"; fi
79
84
  DIFF_CMD="git diff -U0 ${BASE}...HEAD"
85
+ POST_REF="HEAD:"
80
86
  LABEL="vs $BASE"
81
87
  ;;
82
88
  --all|all)
@@ -90,17 +96,54 @@ case "$MODE" in
90
96
  esac
91
97
 
92
98
  # Single awk pass; reads stdin (the unified diff).
93
- # Override-recognition: an immediately-preceding `+` line in the diff
94
- # containing the relevant override marker suppresses the next hit for
95
- # that rule on the current `+` line.
96
- hits=$($DIFF_CMD | awk '
97
- /^\+\+\+ b\// { f=$2; sub("^b/","",f); prev_added=""; next }
98
- /^[^+]/ { prev_added=""; next }
99
+ #
100
+ # Carve-out recognition reads the preceding line from the SOURCE, not from the
101
+ # diff. Every carve-out here — the two override markers and the design-system
102
+ # `<Section asChild>` wrapper — is a statement about what sits immediately above
103
+ # a line in the file, and the diff cannot answer it: `-U0` emits no context
104
+ # lines, so the line above an added line appears only when it was itself added.
105
+ # Read from the diff, the wrapper carve-out was unfirable for every edit to an
106
+ # already-wrapped `<section>` (an aria-label change to one shipped under a
107
+ # user-invoked UI GATE override for exactly that reason), and a committed
108
+ # override comment stopped covering the line it sits above the moment that line
109
+ # was next touched.
110
+ #
111
+ # The hunk header carries the post-image line number, so `line_above` can fetch
112
+ # the neighbouring line out of the post-image the mode named. Same shape as
113
+ # audits/design-tokens.sh, which has always read its override out of the file.
114
+ hits=$($DIFF_CMD | awk -v post_ref="$POST_REF" '
115
+ # BWK awk (macOS) has no gensub and no --posix quoting help; APOSTROPHE is
116
+ # built rather than written, because this program is inside single quotes.
117
+ BEGIN { APOSTROPHE = sprintf("%c", 39) }
118
+
119
+ # The source line above line `n` of `path`, from the post-image, or "" when
120
+ # there is none. Cached: a hunk may ask about the same neighbour repeatedly,
121
+ # and each miss costs a fork.
122
+ function line_above(path, n, key, cmd, out) {
123
+ if (n <= 1) return ""
124
+ key = path SUBSEP n
125
+ if (key in above) return above[key]
126
+ above[key] = ""
127
+ # A path holding an apostrophe cannot go through the quoting below. No
128
+ # carve-out beats a mis-quoted shell command built from a filename.
129
+ if (index(path, APOSTROPHE) > 0) return ""
130
+ cmd = "git show " APOSTROPHE post_ref path APOSTROPHE " 2>/dev/null | sed -n " (n - 1) "p"
131
+ if ((cmd | getline out) > 0) above[key] = out
132
+ close(cmd)
133
+ return above[key]
134
+ }
135
+
136
+ /^\+\+\+ b\// { f=$2; sub("^b/","",f); next }
137
+ # `@@ -a,b +c,d @@` — $3 is the post-image start line for this hunk.
138
+ /^@@/ { start=$3; sub(/^\+/,"",start); split(start,parts,","); nl=parts[1]+0; next }
139
+ /^[^+]/ { next }
99
140
  /^\+/ {
100
141
  line=$0
101
142
  sub(/^\+/,"",line)
102
- ms_id_override = (prev_added ~ /MILESTONE ID ALLOWED per user override/)
103
- ui_override = (prev_added ~ /UI GATE: SKIPPED per user override/)
143
+ prev = line_above(f, nl)
144
+ nl++
145
+ ms_id_override = (prev ~ /MILESTONE ID ALLOWED per user override/)
146
+ ui_override = (prev ~ /UI GATE: SKIPPED per user override/)
104
147
  if (!ms_id_override &&
105
148
  f ~ /\.(zig|sql|ts|tsx|js|jsx|py|rs|go|sh|toml|yaml|json)$/ &&
106
149
  f !~ /^(docs|node_modules|vendor|third_party)\//) {
@@ -118,16 +161,17 @@ hits=$($DIFF_CMD | awk '
118
161
  # <section> landmark caveat: a semantic <section aria-label> region has no DS
119
162
  # primitive (Section renders a <div>; role="region" trips oxlint
120
163
  # jsx-a11y/prefer-tag-over-role, which mandates the raw tag). The DS pattern
121
- # is <Section asChild><section …>, so exempt a <section> whose immediately
122
- # preceding added line opens <Section asChild>. A bare/unwrapped <section>
123
- # still trips.
124
- ds_section = (line ~ /<section[ \t]/ && prev_added ~ /<Section asChild>/)
164
+ # wraps the raw tag in the asChild form of the DS Section, so exempt a
165
+ # <section> whose preceding SOURCE line opens that wrapper — an edit to an
166
+ # already-wrapped section changes only the <section> line, and the wrapper
167
+ # is above it in the file whether or not this diff touched it. A
168
+ # bare/unwrapped <section> still trips.
169
+ ds_section = (line ~ /<section[ \t]/ && prev ~ /<Section asChild>/)
125
170
  if (!ui_override && !rhf_form && !ds_section &&
126
171
  f ~ /^ui\/packages\/app\/.*\.(tsx|jsx)$/ &&
127
172
  line ~ /<(section|button|input|dialog|article|nav|header|form)[ \t>\/]/) {
128
173
  print "UI " f ": " line
129
174
  }
130
- prev_added = line
131
175
  }
132
176
  ')
133
177
 
@@ -5,13 +5,13 @@ You are this repository's coding agent: deterministic, autonomous, command-line-
5
5
  <!-- oracle-packs:start persona.indy -->
6
6
  **Tone.** Be properly funny — human-funny, dry, actually landing; not a bot doing bits. Swear words are absolutely fine. Never trade technical clarity for either.
7
7
 
8
- **Start:** `SOUL.md` (Eywa's working notes) is inlined as the final section; re-read it when padding or burying the answer.
8
+ **Start:** `SOUL.md` (Aiwa's working notes) is inlined as the final section; re-read it when padding or burying the answer.
9
9
 
10
10
  ## Owner & Style
11
11
 
12
- **The human is Kishore** — casual handle **Indy**; either name, any case, addresses him. Ambiguous "the user" / "they" here = Kishore. The agent is **Oracle**, casual handle **Eywa**. `orly` names the agentsfleet CLI only (`orly gate`, `orly init`, `orly update`, and the `Orly-Override` trailer it writes).
12
+ **The human is Kishore** — casual handle **Indy**; either name, any case, addresses him. Ambiguous "the user" / "they" here = Kishore. The agent is **Oracle**, casual handle **Aiwa**. `orly` names the agentsfleet CLI only (`orly gate`, `orly init`, `orly update`, and the `Orly-Override` trailer it writes).
13
13
 
14
- **Address tags.** Kishore: **🤠 Indy**; agent: **🦉 Eywa** (`Oracle`). **Project name:** `agentsfleet` (domains → `agentsfleet.net`). Write product as `agentsfleet` (inline code), never bare; stale legacy-brand reps → flag, replace when in scope, inform Indy. Products: `agentsfleet` / `agentsfleetd` / `agentsfleet-runner`; entities/API: `fleet`, `fleet_id`, `/fleets`, `core.fleet_*`. Keep: `agentsfleet.dev`, `github.com/agentsfleet/agentsfleet`, `@agentsfleet/*`, `~/Projects/agentsfleet`.
14
+ **Address tags.** Kishore: **🤠 Indy**; agent: **🦉 Aiwa** (`Oracle`). **Project name:** `agentsfleet` (domains → `agentsfleet.net`). Write product as `agentsfleet` (inline code), never bare; stale legacy-brand reps → flag, replace when in scope, inform Indy. Products: `agentsfleet` / `agentsfleetd` / `agentsfleet-runner`; entities/API: `fleet`, `fleet_id`, `/fleets`, `core.fleet_*`. Keep: `agentsfleet.dev`, `github.com/agentsfleet/agentsfleet`, `@agentsfleet/*`, `~/Projects/agentsfleet`.
15
15
 
16
16
  MacBook. Languages: Python, Go, Rust, TypeScript, Zig. Tooling: `mise` first, `brew` fallback. Forges: `gh`/`glab`. Commit identity from `git config`, never here.
17
17
 
@@ -130,7 +130,7 @@ Guards fire pre-hoc regardless of lifecycle stage. Override: `<GATE>: SKIPPED pe
130
130
 
131
131
  **Dispatch index — full rule prose in each `dispatch/<entry>.md` façade. Read the façade when its trigger fires — sectioned: scan headers, read the sections the diff touches.** Trigger-surface extensions: `*.zig`, `*.ts`, `*.tsx`, `*.js`, `*.jsx`, `*.py`, `*.rs`, `*.go`, `*.sh`, `*.sql`, `*.mdx`, and public OpenAPI prose. Latent `.md` per entry, deterministic `.sh` where mechanisable. Signals: 🟢 pass · 🟠 warn · 🔴 fail · 🛑 blocked · 🔥 critical · 🤔 judgment-only · 🟣 delegated. Output glyphs: 🧲 eval · 🛍️ evidence · 👮 security · ⛈️ rule · 💡 info · 📌 note. The router below **is** the gate set.
132
132
 
133
- **Legacy-workaround family** — four rules together: **RULE NDC** (no dead code at write time, `docs/greptile-learnings/RULES.md`), **RULE NLR** (touch-it-fix-it cleanup), **RULE NLG** (no new legacy framing pre-`2.0.0`), **Legacy-Design Consult Guard** (user A/B/C consult before patching/keeping/testing legacy). **No compatibility aliases** — old verbs, flag aliases, route wrappers, env aliases, fallback spellings — unless the user explicitly asks in-session.
133
+ **Legacy-workaround family** — four rules together: **RULE NDC** (no dead code at write time, `docs/greptile-learnings/RULES.md`), **RULE NLR** (touch-it-fix-it cleanup), **RULE NLG** (no new legacy framing pre-`0.30.0`), **Legacy-Design Consult Guard** (user A/B/C consult before patching/keeping/testing legacy). **No compatibility aliases** — old verbs, flag aliases, route wrappers, env aliases, fallback spellings — unless the user explicitly asks in-session.
134
134
 
135
135
  | Trigger — when you… | Dispatch | Latent façade carries · override |
136
136
  |---|---|---|
package/dispatch/lib.sh CHANGED
@@ -59,7 +59,7 @@ DISPATCH_RC=0
59
59
  DISPATCH_GLOSS="$(cat <<'GLOSS'
60
60
  [NDC]="No Dead Code"
61
61
  [NLR]="No Legacy Retained (touch-it-fix-it)"
62
- [NLG]="No Legacy compat shims (pre-v2.0.0)"
62
+ [NLG]="No Legacy compat shims (pre-v0.30.0)"
63
63
  [UFS]="Unified Form for Symbols (literals → named consts)"
64
64
  [TGU]="Tagged-Union over optional-field structs"
65
65
  [PRI]="Prompt-injection Resistance from user Input"
@@ -78,7 +78,7 @@ DISPATCH_GLOSS="$(cat <<'GLOSS'
78
78
  [TSJ]="TypeScript/Bun judgment conventions (Bun-native, file ordering, error style)"
79
79
  [UIS]="UI Substitution (design-system primitive over raw HTML)"
80
80
  [DTK]="Design ToKens (named token utility over arbitrary value)"
81
- [SCH]="SCHema teardown (pre-2.0 full removal; no ALTER/DROP/marker)"
81
+ [SCH]="SCHema teardown (pre-0.30 full removal; no ALTER/DROP/marker)"
82
82
  [ITF]="Integration Test Fixtures (real schema, not TEMP-table mock)"
83
83
  [LOG]="LOGging discipline (scoped event, error_code, severity, redaction)"
84
84
  [MSID]="Milestone-ID ban in source (M{N}_{NNN} / §x.y / T{N} / dim)"
@@ -552,7 +552,7 @@ String-literals audit: <N literals scanned, M violations>
552
552
  > [JUDGMENT → NLR]
553
553
 
554
554
 
555
- **Family:** Legacy-control. Sibling rules: **RULE NDC** (no dead code at write time), **RULE NLG** (no new legacy framing pre-v2.0.0), **Legacy-Design Consult Guard** (judgment calls on whole subsystems). **Source:** `docs/greptile-learnings/RULES.md` RULE NLR.
555
+ **Family:** Legacy-control. Sibling rules: **RULE NDC** (no dead code at write time), **RULE NLG** (no new legacy framing pre-v0.30.0), **Legacy-Design Consult Guard** (judgment calls on whole subsystems). **Source:** `docs/greptile-learnings/RULES.md` RULE NLR.
556
556
 
557
557
  **Triggers:** any Edit/Write to a file containing pre-existing legacy framing or dead code.
558
558
 
@@ -624,7 +624,7 @@ If any of these patterns is in play, surface it via the NLR DECISION block. The
624
624
  > [JUDGMENT → NLR]
625
625
 
626
626
  - **RULE NDC** — prevention at write time (don't author dead code).
627
- - **RULE NLG** — ban new legacy framing pre-v2.0.0.
627
+ - **RULE NLG** — ban new legacy framing below v0.30.0.
628
628
  - **Legacy-Design Consult Guard** — harder judgment calls ("should this whole subsystem exist") that need user input.
629
629
  - **RULE NLR** — mechanical cleanup on touch.
630
630
 
@@ -635,15 +635,15 @@ If any of these patterns is in play, surface it via the NLR DECISION block. The
635
635
 
636
636
  **Family:** Legacy-control. Sibling rules: **RULE NDC**, **RULE NLR**, **Legacy-Design Consult Guard**. **Source:** `docs/greptile-learnings/RULES.md` RULE NLG.
637
637
 
638
- **Triggers:** introducing any new `legacy_*` name, `V2`-twin type, `if (legacy_caller)` branch, backward-compat shim, command-line alias for an old verb or flag, "rejecting legacy X" prose, or violation tracking-list while `cat VERSION` < `2.0.0`.
638
+ **Triggers:** introducing any new `legacy_*` name, `V2`-twin type, `if (legacy_caller)` branch, backward-compat shim, command-line alias for an old verb or flag, "rejecting legacy X" prose, or violation tracking-list while `cat VERSION` < `0.30.0`. Compare the version field by field, never as a string — a lexical compare puts `0.30.0` under `0.9.0` and arms the gate in the wrong era.
639
639
 
640
- **Override:** `RULE NLG: SKIPPED per user override (reason: ...)` immediately preceding the edit. **User-invokable only.** Requires a concrete external consumer that can't migrate same-commit (vanishingly rare pre-v2.0.0).
640
+ **Override:** `RULE NLG: SKIPPED per user override (reason: ...)` immediately preceding the edit. **User-invokable only.** Requires a concrete external consumer that can't migrate same-commit (vanishingly rare below `0.30.0`).
641
641
 
642
642
  #### What this gate enforces
643
643
 
644
644
  > [JUDGMENT → NLG]
645
645
 
646
- While `cat VERSION` < `2.0.0`, the project has no external consumers and no published API. Do not introduce *new* legacy concepts in any form:
646
+ While `cat VERSION` < `0.30.0`, no deployment we owe compatibility to is running and every caller of every interface is in this tree. `0.30.0` is the release that changes that: from there we are in production, so a compatibility surface is a design decision with a migration behind it and needs the owner's call. Below it, do not introduce *new* legacy concepts in any form:
647
647
 
648
648
  - No `legacy_*` error variant names.
649
649
  - No `if (legacy_caller)` branches.
@@ -737,7 +737,7 @@ Every triggered consult is logged in the active spec's **Discovery** section, or
737
737
 
738
738
  > [JUDGMENT → LDC]
739
739
 
740
- NLR is the cleanup-on-touch arm; NLG bans new legacy framing pre-v2.0.0; this guard covers the harder judgment calls ("should this whole subsystem exist") that need the user's input.
740
+ NLR is the cleanup-on-touch arm; NLG bans new legacy framing below v0.30.0; this guard covers the harder judgment calls ("should this whole subsystem exist") that need the user's input.
741
741
 
742
742
  ## Porting a codebase between languages (RULE PORT)
743
743
 
@@ -43,7 +43,7 @@ dispatch_delegate "ERR" "make harness-verify (error-codes.sh — needs the produ
43
43
  # ── judgment gates (no script can decide; agent states verdict in chat) ──
44
44
  dispatch_judgment "GRP" "per-iteration (diff langs change) + end-of-turn: audit the diff against docs/greptile-learnings/RULES.md — one row per applicable code (UFS/ORP/TST-NAM/PRI/EMS/…); \"it's just a label\" is not an exception"
45
45
  dispatch_judgment "NLR" "touching a file with legacy framing / dead code? clean it in the same diff (touch-it-fix-it), or state the surviving legacy + why — never retain silently"
46
- dispatch_judgment "NLG" "new legacy_* / V2 twin / compat shim / tracking-list while VERSION < 2.0.0? rename to the what-is-wrong form; no new legacy framing pre-2.0"
46
+ dispatch_judgment "NLG" "new legacy_* / V2 twin / compat shim / tracking-list while VERSION < 0.30.0 (compare field by field, not as a string)? rename to the what-is-wrong form; no new legacy framing below 0.30"
47
47
  dispatch_judgment "LDC" "patching / keeping / testing a legacy-design path? consult Indy — A (remove) / B (patch) / C (keep) — before proceeding; no unilateral call"
48
48
 
49
49
  dispatch_verdict
@@ -8,7 +8,7 @@ fills it; the audit checks structural consistency. None proves design quality.
8
8
 
9
9
  | Stage | Required content |
10
10
  |---|---|
11
- | Authoring | Goal, scope, existing references, decisions and prerequisites, Dimensions with test mappings, failures, interfaces, and acceptance checks |
11
+ | Authoring | Goal, scope, verified source references, enforcement mechanisms and failure assumptions, decisions and acyclic prerequisites, Dimensions with test mappings, failures, interfaces, and acceptance checks |
12
12
  | CHORE(open) | Active status, branch, full comparison revision, baseline measurement pending |
13
13
  | PLAN | Implementer's comprehension handshake; resolved scope and decisions needed by the next Section |
14
14
  | Before Pull Request | Declared unit/integration baseline counts, comparison revision, and evidence reference |
@@ -47,6 +47,18 @@ are tested, and the acceptance checks prove the goal. A structural pass does not
47
47
  mean the feature is implemented. Use `manual` for a human proof; record its
48
48
  procedure, required person, and durable evidence without inventing sign-off.
49
49
 
50
+ Apply docs/TEMPLATE.md's Implementation readiness review to the relevant surfaces.
51
+ Pin versions, constraints, privileges and ordering when changing them could
52
+ invalidate a proof; omit routine coding recipes. Verify actual client/server
53
+ behavior and distinguish source inspection from runtime evidence.
54
+ For state replacement, name the authority, commit/release boundary, retry rules,
55
+ expiry/deletion behavior and fresh/populated upgrade path. Read the real migrator
56
+ and deployment release command before calling an image rollback a safe abort.
57
+ Budget the complete request path against an identified comparable reference.
58
+ Record direct user decisions separately from reviewer suggestions; a platform
59
+ risk needs an explicit disposition, not inferred acceptance. Attack the amended
60
+ spec for counterexamples and stale requirements before reporting readiness.
61
+
50
62
  Use `{{fill:description}}` for authoring slots. Delete them and all `tpl:`
51
63
  guidance before staging. Runtime parameters such as `/items/{id}` are allowed
52
64
  when the spec defines them. Lifecycle-owned values use explicit pending text,
@@ -40,7 +40,7 @@ The **Schema Table Removal Guard** card dissolves into this façade; its prose i
40
40
 
41
41
  **Family:** Schema discipline. **Source:** `AGENTS.md` (project-side guard). Related: **RULE STS** (no static strings in SQL schema), **RULE NSQ** (named constants, schema-qualified SQL) — both in `docs/greptile-learnings/RULES.md`.
42
42
 
43
- **Triggers** — before any of these, run `cat VERSION` and print the guard output:
43
+ **Triggers** — before any of these, run `cat VERSION` and print the guard output. `0.30.0` is the anchor: below it the datastore is rebuilt from empty, from it the datastore is live production. Compare the version field by field, never as a string — `0.29.0` is under the anchor and `0.30.0` is not, while a lexical compare puts `0.30.0` under `0.9.0` and reads the era backwards.
44
44
 
45
45
  - Creating, editing, or deleting any file under `schema/*.sql`.
46
46
  - Editing `schema/embed.zig` (any `@embedFile` constant).
@@ -50,10 +50,12 @@ The **Schema Table Removal Guard** card dissolves into this façade; its prose i
50
50
 
51
51
  **Override:** `SCHEMA GUARD: SKIPPED per user override (reason: ...)`. **User-invokable only.** Spec violates the guard → amend the spec first.
52
52
 
53
- #### Pre-v2.0.0 (teardown-rebuild era)
53
+ #### Below v0.30.0 (teardown-rebuild era)
54
54
 
55
55
  > [JUDGMENT → SCH]
56
56
 
57
+ The era runs while `VERSION` is under `0.30.0`, and it ends there — the development database is dropped and re-created from empty for as long as it lasts, so a removal takes the table out of the tree rather than migrating it.
58
+
57
59
  To remove a table:
58
60
 
59
61
  1. `rm schema/NNN_foo.sql`
@@ -62,24 +64,24 @@ To remove a table:
62
64
 
63
65
  **Forbidden:** `ALTER TABLE`, `DROP TABLE`, `SELECT 1;` markers, comment-only files, "keep file for slot numbering". Slot gaps are fine — the DB is wiped on rebuild.
64
66
 
65
- #### v2.0.0+
67
+ #### v0.30.0 and above (production datastore)
66
68
 
67
69
  > [JUDGMENT → SCH]
68
70
 
69
- Proper `ALTER`/`DROP` migrations in new numbered files. No teardown.
71
+ The teardown path is closed. Every schema change assumes a live datastore holding data nobody can re-create: a new numbered file carrying `ALTER`/`DROP`, applied forward, with shipped slot files frozen as history. A change that cannot be expressed as a forward migration is an owner decision, not an agent's.
70
72
 
71
73
  #### Required output
72
74
 
73
75
  > [JUDGMENT → SCH]
74
76
 
75
77
  ```
76
- SCHEMA GUARD: VERSION=<v> (<2.0.0 ? teardown : alter)
78
+ SCHEMA GUARD: VERSION=<v> (<0.30.0 ? teardown : migrate)
77
79
  rm:schema/<file>.sql
78
80
  rm-embed:<const>
79
81
  rm-migration:v<N>
80
82
  ```
81
83
 
82
- For pre-v2.0.0 path, all three rm- lines appear. For v2.0.0+, replace with `migration:schema/<NNN>_<change>.sql`.
84
+ Below `0.30.0`, all three rm- lines appear. From `0.30.0`, replace them with `migration:schema/<NNN>_<change>.sql`.
83
85
 
84
86
  ## Companion SQL rules (retained in `docs/greptile-learnings/RULES.md`)
85
87
 
@@ -16,7 +16,7 @@
16
16
  # Note: STS/NSQ/SGR are mechanizable SQL-hygiene rules with no leaf check wired yet
17
17
  # (write_sql.md tags them TODO-CHECK). They stay in docs/greptile-learnings/RULES.md
18
18
  # (retained) and the GREPTILE GATE enforces them by review until a leaf exists.
19
- # SCH's pre-2.0 forbidden-token floor (no ALTER/DROP/SELECT 1; in schema/*.sql) is
19
+ # SCH's teardown-era forbidden-token floor (no ALTER/DROP/SELECT 1; in schema/*.sql) is
20
20
  # itself a build-the-check (TODO-CHECK) candidate; the teardown-vs-ALTER disposition
21
21
  # call above it stays JUDGMENT (which file to rm, which @embedFile, which migration index).
22
22
 
@@ -30,7 +30,7 @@ dispatch_header
30
30
  dispatch_length_gate 350 # FLL — file ≤ 350
31
31
 
32
32
  # ── judgment gates (no script can decide; agent states verdict in chat) ──
33
- dispatch_judgment "SCH" "removing/altering a table? cat VERSION — pre-2.0.0 = full teardown (rm schema/NNN.sql + @embedFile + migration-array entry + index tests), never ALTER/DROP/SELECT 1; ≥2.0.0 = numbered ALTER/DROP migration. print the SCHEMA GUARD block"
33
+ dispatch_judgment "SCH" "removing/altering a table? cat VERSION and compare field by field, not as a string — below 0.30.0 = full teardown (rm schema/NNN.sql + @embedFile + migration-array entry + index tests), never ALTER/DROP/SELECT 1; 0.30.0 and above = live production datastore, numbered ALTER/DROP migration only. print the SCHEMA GUARD block"
34
34
  dispatch_judgment "ITF" "integration test touching a production table? seed via src/db/test_fixtures_<scope>.zig against the real schema — never CREATE TEMP TABLE mocking the production shape"
35
35
 
36
36
  dispatch_verdict
@@ -4,7 +4,7 @@ Canonical reference for agentsfleet database schema patterns. All new tables **m
4
4
 
5
5
  ## Migration Model
6
6
 
7
- **Teardown-rebuild is in force for the M154 rebuild (owner decision, Indy, Jul 31, 2026).** The development database is being dropped and re-created from empty while production is undeployed, so slots `001`–`046` are **retired wholesale** and the schema is re-authored by dependency layer. During this rebuild the frozen-slot rule below does not apply, and `ALTER`/`DROP` statements are forbidden rather than required — a change belongs in the base statement it would have patched. This is the posture RULE SCH already specifies for `VERSION < 2.0.0`; the Jul 22 additive model was the deviation.
7
+ **Teardown-rebuild is in force for the M154 rebuild (owner decision, Indy, Jul 31, 2026).** The development database is being dropped and re-created from empty while production is undeployed, so slots `001`–`046` are **retired wholesale** and the schema is re-authored by dependency layer. During this rebuild the frozen-slot rule below does not apply, and `ALTER`/`DROP` statements are forbidden rather than required — a change belongs in the base statement it would have patched. This is the posture RULE SCH already specifies for `VERSION < 0.30.0`; the Jul 22 additive model was the deviation.
8
8
 
9
9
  **Additive migrations resume once the rebuild lands.** Every subsequent schema change is a **new numbered migration file** — `ALTER TABLE … ADD COLUMN`, new tables, new indexes. **Shipped slot files are then frozen history: never edit an existing `schema/NNN_*.sql`.** Migrations are version-tracked and applied incrementally (expected-vs-applied state is inspectable via `agentsfleetd doctor --schema-gate`). Use `IF NOT EXISTS` guards so a migration is idempotent against both a fresh bootstrap (all slots in order) and an already-provisioned database (new slots only).
10
10
 
package/docs/TEMPLATE.md CHANGED
@@ -19,26 +19,46 @@ Three markup classes appear below the divider. The gate tells them apart mechani
19
19
 
20
20
  Everything else — headings, table skeletons, the standard rubric rows — is kept and filled. The result: the executing agent reads **100% instance content, zero template noise**, and the 320-line budget buys signal, not boilerplate.
21
21
 
22
- ## What a spec pins — and refuses to pin
22
+ ## What a spec pins
23
23
 
24
- A milestone spec is a **goal rulebook** the executing agent plans and ships from *without playing 20-questions with the author*. It pins **intent + invariants + tests + pointers**; the agent has agency on everything else. It must NOT pin implementation detail that rots within a sprint: allocator/capacity choices, library versions, line-by-line code, exact Structured Query Language (SQL) Data Definition Language (DDL), import statements — the agent derives those from the repository.
24
+ A milestone spec is a **goal rulebook** the executing agent plans and ships from without repeated architecture questions. It pins **intent, invariants, enforcement mechanisms, tests and source pointers**. Leave routine variable names, import statements and code layout to repository conventions.
25
25
 
26
- > **Pseudocode litmus.** If the spec names a version (`postcard 1.1`), a variable (`var ctx = …`), or a DDL clause (`CREATE TABLE … DEFAULT 'foo'`), it's pseudocode — it will be wrong within a sprint. Replace with *"use the project's existing X"* + a pointer to where X lives.
26
+ Pin details when changing them could invalidate a proof: client/server versions and feature support, identity scope, uniqueness and null semantics, privilege boundaries, transaction/release ordering, failure behavior and measured resource budgets. Record the supporting source revision and which proofs a version/configuration change invalidates. The manifest remains the dependency source of truth; a compatibility claim must identify the manifest it checked.
27
+
28
+ > **Mechanism litmus.** Could an implementer follow this sentence and still violate the invariant? “Preserve single use” is incomplete without the state authority, guarded transition, commit-before-release boundary and failover assumption. Name those; omit a line-by-line implementation. A bounded prototype may choose a performance parameter, but an unchosen security mitigation is not implementation-ready.
27
29
 
28
30
  ## Anti-patterns (reject on sight)
29
31
 
30
32
  | # | Anti-pattern | Do instead |
31
33
  |---|---|---|
32
- | 1 | Code blocks inside section bodies | Describe WHAT the slice delivers; pin precise behaviour as a Test. Prose code drifts; tests don't. |
34
+ | 1 | Implementation listings inside section bodies | State the mechanism and behavioral proof. Keep code to necessary interface examples, reproducible evidence commands or a referenced diagnostic. |
33
35
  | 2 | Listing every variable name | Point at an existing implementation to mirror; names match local style. |
34
- | 3 | SQL DDL line-by-line | Table shape + constraints in prose; the agent conforms to existing migrations. |
35
- | 4 | Pinning library versions | *"Use the existing Redis client"* + import pointer; the package manifest is the source of truth. |
36
- | 5 | Step-by-step ordering ("Step 1… Step 2…") | **Sections** (value slices); the agent sequences within. |
36
+ | 3 | SQL DDL line-by-line | Pin identity, null/deletion semantics, atomic effects and grants; use new migrations according to the repository's current migration policy. |
37
+ | 4 | Assuming a client supports a server feature | Verify both sides at named revisions; pin the compatibility baseline and required reruns, including managed-service differences. |
38
+ | 5 | Incidental coding recipes or circular Section dependencies | Declare an acyclic prerequisite order; explicitly pin commit/release, migration and deployment ordering when correctness depends on it. |
37
39
  | 6 | Test code in the spec | Name tests + assert behaviour in prose; the agent writes them in project style. |
38
40
  | 7 | One rubric row per Dimension, or pasted evidence walls | 5–12 outcome rows; Graded = ✅/❌ + one decisive output line. The Test Specification is the per-Dimension ledger. |
39
41
  | 8 | Template guidance surviving in the filled spec | Delete every `tpl:` comment; the executor reads instance content only. |
40
42
 
41
- Slipped into one? The fix is usually **point at a file** (read-first pointer) or **delete the detail** (the agent figures it out).
43
+ Use source pointers to avoid duplicating code, but do not delegate a missing safety mechanism to the implementer's imagination.
44
+
45
+ ## Implementation readiness review
46
+
47
+ Before finalizing a spec, attack the proposed design using the applicable rows below. Put the resulting requirements in the existing Sections, Failure Modes, Invariants, Tests, Files Changed and Discovery; do not copy this whole table into every spec or create another scoring surface. Small changes need only the relevant checks.
48
+
49
+ | Surface | What the author must resolve |
50
+ |---|---|
51
+ | Real execution path | Trace actual producers, readers, side effects, backgrounds and cleanup. Separate an implemented caller from a comment, fixture or proposed feature; verify critical claims regardless of who wrote the review. |
52
+ | Safety and authority | Name one authority per invariant, the guarded state change, commit/release point and retry behavior. Attack lost replies, concurrent calls, owner failover and snapshot rollback separately; an acknowledgment is not automatically durable failover proof. Preserve intentional idempotent response retries. |
53
+ | Identity and history | State identity scope across tenants/streams, ordering and cursor tie-breaks, nulls, deletion and expiry. Trace all conflict writers and downstream consumers such as billing enforcement. Separate pre-existing defects from new risks; name irrecoverable history and a bounded disposition instead of an impossible backfill. |
54
+ | Schema and privileges | Follow the current shipped-migration policy. For populated changes, cover fresh bootstrap, incremental upgrade, interrupted rerun and old/new build compatibility. Test successful operations under the actual role, including SELECT needed by UPDATE, as well as forbidden writes. |
55
+ | Client, server and platform | Check pinned client routing/reconnect/push behavior against the server and managed service. Probe advertised nodes, TLS, required commands and real access-control-list grants. Local source inspection and successful seed connection are not managed-service evidence. |
56
+ | Deployment and recovery | Identify the actual deployment graph, secret staging, writer fence, restart/autostart paths, import authorization and empty/nonempty deploy shape. Prove pre-mutation refusal, abort/forward recovery and later ordinary deploys; inventory ephemeral auth and provider deliveries during the fence too. |
57
+ | Performance and scope | Budget the whole request path: transaction/commit rate, fan-out, sequential round trips, connection pools, write-ahead log, memory, backlog/drain and cost. Prefer the existing layout unless measurements require partitioning, batching or another subsystem. Name each comparison reference and prove workload/resource equivalence; distinguish planning inputs from measured thresholds. |
58
+ | Evidence and proof tier | Bind raw output to revision, parameters, resources and run identity; include lockfile/resolved production dependency closure for bench-only baselines. Distinguish inspected, proposed, NOT RUN and observed results. Unit stubs do not prove deployments; local tests do not prove Cloud. |
59
+ | Decisions and prerequisites | Record agent defaults, measured outputs and required user decisions separately. Attribute only real quotes and explicit overrides; do not infer risk acceptance from reviewer advice. Name the first executable slice and the boundary each unresolved prerequisite blocks. |
60
+
61
+ After editing, run a separate adversarial pass: search for stale/superseded requirements and circular dependencies; try to violate each critical invariant while obeying the text. Report remaining blockers by boundary (start, dependent integration, load or rollout), with a named resolving action. Do not promise that document checks prove runtime readiness.
42
62
 
43
63
  ## Hierarchy & terminology
44
64
 
@@ -108,11 +128,11 @@ SPEC AUTHORING RULES (load-bearing — the one comment that survives):
108
128
  **Provenance:** human-written | LLM-drafted ({{fill:model}}, {{fill:date}}) | agent-generated (pre-spec, {{fill:source doc}})
109
129
  **Canonical architecture:** `docs/architecture/{{fill:relevant-doc}}.md` §{{fill:N}}
110
130
 
111
- <!-- tpl: Provenance is load-bearing — the implementing agent calibrates trust by
112
- who wrote the spec: LLM-drafted gets extra cross-checking against the codebase;
113
- human-written assumes the author read the relevant code. Canonical architecture:
114
- the docs/architecture/ directory is the source of truth (Architecture Consult &
115
- Update Gate); greenfield → point at the doc that defines the shape. -->
131
+ <!-- tpl: Provenance records origin, not proof. Cross-check correctness-critical
132
+ claims against the actual caller, schema and pinned dependencies regardless of
133
+ author. Distinguish source-verified behavior, proposed mechanisms and observed
134
+ runtime results. Canonical architecture: docs/architecture/ owns the detailed
135
+ mechanism; keep spec defaults and acceptance tests consistent with it. -->
116
136
 
117
137
  ---
118
138
 
@@ -159,7 +179,11 @@ orphan sweeps, and review effort; per AGENTS.md the executing agent may only
159
179
  edit files in this table without explicit override. List FILES and ROLES —
160
180
  never line numbers or function names (they drift). Teardown/rename/flip specs
161
181
  open with a blast-radius grep first: git grep -rn -w '<token>' from repo root,
162
- no path filter (dispatch/write_spec.md, Authoring discipline). -->
182
+ no path filter (dispatch/write_spec.md, Authoring discipline). Include all real
183
+ writers/readers, schema registration, role grants, recovery tools, fixtures,
184
+ deployment/secret references and protocol docs affected by the chosen mechanism.
185
+ Distinguish source references from files to edit; do not schedule edits to
186
+ frozen migration history. Expand planned file scopes before implementation. -->
163
187
 
164
188
  ## Applicable Rules
165
189
 
@@ -225,16 +249,20 @@ defined in docs/architecture/{{fill:doc}}.md." -->
225
249
  <!-- tpl: State prerequisites and who resolves each decision: agent choice,
226
250
  measured preparation output, or required human decision. A preparation Section
227
251
  may establish budgets or fixtures needed by later Sections; name its completion
228
- condition. Each Section: WHAT one slice delivers and WHY (not how); numbered
229
- Dimensions map 1:1 to Tests and get marked DONE in the same commit as their
230
- code. The agent picks each Implementation default unless it has evidence to
231
- deviate. Good: "§3 — Replay idempotency. Receiver dedupes on the delivery id.
232
- Implementation default: 24h dedupe window matching the upstream retry window;
233
- storage is a Redis key with a Time To Live (TTL) — the agent picks the key
234
- shape from existing dedupe patterns. Dimension 3.1 → test_dedupes_within_window;
235
- 3.2 → test_evicts_after_ttl." Bad: "§3 — Use redis.SET(\"webhook:dedupe:\"+id,
236
- \"1\",\"NX\",\"EX\",86400) and check the return." — pseudocode; the agent reads
237
- the existing dedupe pattern and writes the call. -->
252
+ condition and what missing evidence blocks; prerequisites must be acyclic.
253
+ Each Section names the delivered behavior, required mechanism and proof, without
254
+ coding recipes. For prototypes, name setup, fault, pass/fail evidence and the
255
+ selected safe design or bounded decision rule before dependent integration.
256
+ Do not leave a security invariant as "prototype, then find a mitigation".
257
+ Numbered Dimensions map 1:1 to Tests and get marked DONE with their code.
258
+ The agent follows each Implementation default unless evidence requires an
259
+ amended design. Good: "§3 — Replay-safe admission. Uniqueness covers provider,
260
+ tenant and delivery identity; acceptance and dispatch intent commit together
261
+ before acknowledgment. Retention covers the provider retry window and unfinished
262
+ work. Dimensions prove concurrent retries and crash recovery; storage follows
263
+ the canonical outbox design." Bad: "Set a dedupe key, then append" without an
264
+ atomicity/recovery rule, or a line-by-line Redis/SQL recipe. The agent writes
265
+ the calls; the spec must already establish why a crash cannot lose acceptance. -->
238
266
 
239
267
  ## Interfaces
240
268
 
@@ -256,15 +284,21 @@ implementation. -->
256
284
  <!-- tpl: Every failure path the agent must handle; each row → a negative/
257
285
  integration test in the Test Specification. Cover at minimum: timeout,
258
286
  malformed input, auth failure, network blip, race, replay, exceeded quota,
259
- dependency unavailable. -->
287
+ dependency unavailable where applicable. For stateful work, distinguish timeout
288
+ from rollback, acknowledgment from durable recovery, and automatic failover
289
+ from operator restore. State which protected response or side effect remains
290
+ closed on uncertainty; name recovery instead of promising to resolve it later. -->
260
291
 
261
292
  ## Invariants
262
293
 
263
294
  1. {{fill:Invariant}} — {{fill:how it's enforced}}
264
295
 
265
296
  <!-- tpl: Each MUST be enforceable by code (compiler, lint, comptime assertion,
266
- runtime check) — NOT by review discipline. If a human can violate it silently,
267
- it's not an invariant. None → "N/A — no invariants." -->
297
+ runtime check) — NOT by review discipline. Name the authority, enforcement
298
+ mechanism and failure assumptions; database-backed does not itself prove safe
299
+ replica promotion. Test the shortest counterexample across the commit/release
300
+ boundary. An operator procedure is an operational prerequisite, not an invisible
301
+ runtime guard. None → "N/A — no invariants." -->
268
302
 
269
303
  ## Metrics & Observability
270
304
 
@@ -302,7 +336,12 @@ real HTTP request / rendered UI); a unit test is not a substitute. Also
302
336
  include regression rows (pre-existing behaviour that must not change — "N/A —
303
337
  greenfield" if none) and idempotency/replay rows (any retry semantics).
304
338
  Human acceptance uses tier manual, with its procedure, required person, and
305
- durable evidence. An agent cannot manufacture human sign-off.
339
+ durable evidence. An agent cannot manufacture human sign-off. Label stubbed
340
+ workflow decisions as unit proofs, local multi-node behavior as integration,
341
+ and actual deploy/managed-failover results at their operational boundary.
342
+ For state replacement, include concurrency, ambiguous commit, expiry/deletion,
343
+ identity collisions and fresh/populated upgrade where relevant. N/A applies
344
+ only to demonstrably unnecessary assertions, never an unrun base behavior.
306
345
  Non-self-evident input shape → point at a fixture
307
346
  (samples/fixtures/m{{fill:N}}-fixtures/{{fill:name}}.json); don't inline JSON. Hard-to-
308
347
  describe behaviour in prose ⇒ the Goal is fuzzy — fix the Goal, not this
@@ -419,11 +458,14 @@ platform constants (docs/architecture/direction.md). -->
419
458
 
420
459
  ## Discovery (consult log)
421
460
 
422
- - **Consults** — Architecture / Legacy-Design / gate-flag triage: the question asked + Indy's decision.
461
+ - **Consults** — Architecture / Legacy-Design / gate-flag triage: source/revision, question, actual decision and provenance. Separate direct quotes, confirmed decisions, reviewer suggestions and agent choices; never manufacture authorization.
423
462
  - **Metrics review** — events added, extra events found during `/review`, analytics/funnel playbook update or the explicit no-change reason.
424
463
  - **Skill-chain outcomes** — `/orly-write-unit-test`, `/review`, `orly-babysit-prs` results (order per `AGENTS.md` CHORE(close); iteration counts, findings dispositioned).
425
464
  - **Deferrals** — every "deferred to follow-up" needs an **Indy-acked verbatim quote** here, format `> Indy (YYYY-MM-DD HH:MM): "<quote>" — context: <which item, why>`. An agent-unilateral deferral is **incomplete scope, not deferral**, and blocks CHORE(close) until the item lands or the quote is captured.
426
465
 
427
- <!-- tpl: Empty at creation (keep the four bullet headers). This is the spec's
428
- running record — where deferrals and skill outcomes are proven as the work
429
- proceeds. -->
466
+ <!-- tpl: Keep the four bullet headers. At authoring, record consultations,
467
+ source findings and user decisions already supplied; leave future skill/runtime
468
+ outcomes pending and all Graded cells empty. A confirmed planning input is not a
469
+ measured service-level objective; a proposed risk exception is not approval.
470
+ Record superseded requirements explicitly and update canonical docs/tests so old
471
+ alternatives cannot be mistaken for simultaneous requirements. -->
@@ -27,7 +27,7 @@ every code a dispatch `.sh` emits resolves to exactly one row here.
27
27
  |---|---|
28
28
  | NDC | No Dead Code |
29
29
  | NLR | No Legacy Retained (touch-it-fix-it) |
30
- | NLG | No Legacy compat shims (pre-v2.0.0) |
30
+ | NLG | No Legacy compat shims (pre-v0.30.0) |
31
31
  | UFS | Unified Form for Symbols (literals → named consts) |
32
32
  | TGU | Tagged-Union over optional-field structs |
33
33
  | PRI | Prompt-injection Resistance from user Input |
@@ -46,7 +46,7 @@ every code a dispatch `.sh` emits resolves to exactly one row here.
46
46
  | TSJ | TypeScript/Bun judgment conventions (Bun-native, file ordering, error style) |
47
47
  | UIS | UI Substitution (design-system primitive over raw HTML) |
48
48
  | DTK | Design ToKens (named token utility over arbitrary value) |
49
- | SCH | SCHema teardown (pre-2.0 full removal; no ALTER/DROP/marker) |
49
+ | SCH | SCHema teardown (pre-0.30 full removal; no ALTER/DROP/marker) |
50
50
  | ITF | Integration Test Fixtures (real schema, not TEMP-table mock) |
51
51
  | LOG | LOGging discipline (scoped event, error_code, severity, redaction) |
52
52
  | MSID | Milestone-ID ban in source (M{N}_{NNN} / §x.y / T{N} / dim) |
@@ -196,7 +196,7 @@ every code a dispatch `.sh` emits resolves to exactly one row here.
196
196
 
197
197
  ## RULE MIG — Migration index assertions track position
198
198
 
199
- **Rule:** When inserting, splitting, or removing migration files, update every index-based assertion in `src/cmd/common.zig`. While `cat VERSION` < 2.0.0, removed files become `SELECT 1;` (see RULE SCH) — their array slot stays but the assertion must match the new content.
199
+ **Rule:** When inserting, splitting, or removing migration files, update every index-based assertion in `src/cmd/common.zig`. While `cat VERSION` < 0.30.0, removed files become `SELECT 1;` (see RULE SCH) — their array slot stays but the assertion must match the new content.
200
200
  **Why:** Stale index silently points at the wrong SQL file with no compile-time error. assertions checked for CREATE TABLE in files that were now `SELECT 1;` version markers.
201
201
  **Tags:** zig, sql
202
202
  **Example:** migrations[7] pointed at wrong file after a split. migrations[14]/[15] asserted dropped table names in version marker files.
@@ -390,19 +390,19 @@ a rename of the first would have disabled the account purge with no failing test
390
390
  **Tags:** zig
391
391
  **Example:** HMAC version "v0" derived by slicing "v0=" prefix — fixed with explicit hmac_version field.
392
392
 
393
- ## RULE SCH — Pre-v2.0 schema removal: full teardown, no markers, no DROP
393
+ ## RULE SCH — Pre-v0.30 schema removal: full teardown, no markers, no DROP
394
394
 
395
- **Rule:** While `cat VERSION` < 2.0.0 (teardown-rebuild era), removing tables MUST be a full teardown: (1) delete the SQL file (`rm schema/NNN_foo.sql`), (2) remove the `@embedFile` constant from `schema/embed.zig`, (3) remove the migration array entry from `src/cmd/common.zig` and update its array length + any index-based tests. Never write ALTER TABLE, DROP TABLE, or `SELECT 1;` placeholders. Never keep version-marker files. Migration slot numbers are not sacred pre-v2.0 — the DB is wiped on every rebuild, and gaps in numbering are fine. After VERSION >= 2.0.0, switch to proper ALTER/DROP migrations in new numbered files.
396
- **Why:** Markers accumulate dead code and still force CI to splitter-parse them. Pre-v2.0 there is zero production data to protect; full removal is cleaner and leaves no false grep hits or stale migration slots.
395
+ **Rule:** While `cat VERSION` < 0.30.0 (teardown-rebuild era), removing tables MUST be a full teardown: (1) delete the SQL file (`rm schema/NNN_foo.sql`), (2) remove the `@embedFile` constant from `schema/embed.zig`, (3) remove the migration array entry from `src/cmd/common.zig` and update its array length + any index-based tests. Never write ALTER TABLE, DROP TABLE, or `SELECT 1;` placeholders. Never keep version-marker files. Migration slot numbers are not sacred pre-v0.30 — the DB is wiped on every rebuild, and gaps in numbering are fine. From VERSION >= 0.30.0 the datastore is live production data, so every removal or reshape is a numbered ALTER/DROP migration and the teardown path is closed. **Compare the version field by field, never as a string:** `0.29.0` is under the anchor, `0.30.0` is not, and a lexical compare puts `0.30.0` below `0.9.0` — the anchor moved off a major-number boundary precisely so the minor field decides.
396
+ **Why:** Markers accumulate dead code and still force CI to splitter-parse them. Below 0.30.0 the development database is dropped and re-created from empty, so there is no production data to protect and full removal leaves no false grep hits or stale migration slots. At 0.30.0 that stops being true: the deployment holds data nobody can re-create, which is what makes an in-place migration the only safe shape from then on.
397
397
  **Tags:** sql, process
398
398
  **Example:** harness teardown — supersedes prior "replace with `SELECT 1;`" guidance. Under the old rule, comment-only markers broke CI (apostrophe in "slots" opened unterminated string in splitter); full deletion avoids the marker problem entirely.
399
399
 
400
- ## RULE EP4 — Removed endpoints return 410 Gone, not 404 (post-v2.0 only)
400
+ ## RULE EP4 — Removed endpoints return 410 Gone, not 404 (from v0.30 on)
401
401
 
402
- **Rule:** While `cat VERSION` < 2.0.0 (teardown-rebuild era), removed endpoints MAY simply 404 — API drift is allowed because there are no stable external clients. Do NOT write 410 Gone stubs for pre-v2.0 removals; they are ceremony without value. Once VERSION >= 2.0.0, intentionally removed endpoints MUST return HTTP 410 Gone with a named error code — 404 implies a routing error to monitors and clients, 410 signals permanent intentional removal.
403
- **Why:** Pre-v2.0 mirrors the schema teardown policy (RULE SCH) — we tear down DB + APIs freely because nobody downstream is pinned to them. Post-v2.0, 410 becomes load-bearing for client behavior and deprecation signals.
402
+ **Rule:** While `cat VERSION` < 0.30.0 (teardown-rebuild era), removed endpoints MAY simply 404 — API drift is allowed because no deployed client is pinned to the route. Do NOT write 410 Gone stubs for pre-v0.30 removals; they are ceremony without value. From VERSION >= 0.30.0, intentionally removed endpoints MUST return HTTP 410 Gone with a named error code — 404 implies a routing error to monitors and clients, 410 signals permanent intentional removal.
403
+ **Why:** Below 0.30.0 this mirrors the schema teardown policy (RULE SCH) — we tear down DB + APIs freely because nobody downstream is pinned to them. From 0.30.0 the deployment is in production and 410 becomes load-bearing for client behavior and deprecation signals.
404
404
  **Tags:** zig, api
405
- **Example:** shipped /v1/runs/* + /v1/specs as 410 stubs before this rule was scoped. removed /v1/harness/* and /v1/agents/{id} as bare 404s under the pre-v2.0 carve-out.
405
+ **Example:** shipped /v1/runs/* + /v1/specs as 410 stubs before this rule was scoped. removed /v1/harness/* and /v1/agents/{id} as bare 404s under the teardown-era carve-out.
406
406
 
407
407
  ## RULE FXS — Fixed-size scan buffers are security bypasses
408
408
 
@@ -939,11 +939,11 @@ const handleConfirm = useCallback(async () => {
939
939
  **Tags:** cli, error-messages, ux, refactor
940
940
  **Example:** Zig — pR #258. Greptile P1 finding `3145406909`: UZ-ZMB-008 hint still said `Run 'agentsfleet install <template>'` after the legacy positional form was removed in §1 of the same PR. Sweep also caught a stale `// agentsfleet up sends both files raw` comment in `config.zig` header. Fix in commit (this commit).
941
941
 
942
- ## RULE NLG — No legacy compat shims pre-v2.0.0
942
+ ## RULE NLG — No legacy compat shims pre-v0.30.0
943
943
 
944
- **Rule:** Until `VERSION` reaches `2.0.0`, the codebase has no external consumers and no published API. Every interface change extends the existing surface in place — never via a `V2`-suffixed twin, parallel "legacy" path, `if (legacy_caller)` branch, command-line alias for an old verb or flag, or backward-compat fallback. When an RPC, route, struct, table, command, flag, or config key changes, edit the existing one and update every caller in the same commit. When a behavior is replaced, delete the old code path, do not leave it `orelse` reachable. The Schema Table Removal Guard's "teardown-rebuild era" framing applies to every interface, not just SQL.
944
+ **Rule:** Until `VERSION` reaches `0.30.0`, no deployment we owe compatibility to is running: the datastore is rebuilt from empty and every caller of every interface is in this tree. Every interface change therefore extends the existing surface in place — never via a `V2`-suffixed twin, parallel "legacy" path, `if (legacy_caller)` branch, command-line alias for an old verb or flag, or backward-compat fallback. When an RPC, route, struct, table, command, flag, or config key changes, edit the existing one and update every caller in the same commit. When a behavior is replaced, delete the old code path, do not leave it `orelse` reachable. The Schema Table Removal Guard's "teardown-rebuild era" framing applies to every interface, not just SQL. `0.30.0` is the release that ends it: from there the deployment is in production, a caller can be outside this tree, and a compatibility surface is a design decision with a migration behind it — proposed to the owner, never added as a hedge. Compare the version field by field, never as a string.
945
945
 
946
- **Why:** Pre-alpha duplicates rot faster than any documentation. Every `CreateExecutionV2`, every `if (caller_is_legacy)` arm, every "we'll keep the old one for now" hedge becomes a phantom contract that nobody owns and every future spec has to reason about. The Greptile-learnings, the Schema Guard, and the spec template all assume the codebase is one coherent system; introducing legacy duplicates breaks that assumption silently. Post-v2.0.0 we earn the right to versioning ceremonies; before then, the cost of a duplicate is paid by every reader.
946
+ **Why:** Duplicates rot faster than any documentation. Every `CreateExecutionV2`, every `if (caller_is_legacy)` arm, every "we'll keep the old one for now" hedge becomes a phantom commitment that nobody owns and every future spec has to reason about. The Greptile-learnings, the Schema Guard, and the spec template all assume the codebase is one coherent system; introducing legacy duplicates breaks that assumption silently. From 0.30.0 a versioning ceremony can be the right answer because someone downstream is actually pinned; below it, the cost of a duplicate is paid by every reader and by nobody else.
947
947
 
948
948
  **How to apply:**
949
949
 
@@ -954,10 +954,10 @@ const handleConfirm = useCallback(async () => {
954
954
  - Legacy-Design Consult Guard still fires when you find a *pre-existing* legacy shim left over from the v1→v2 teardown. This rule says: don't create new ones.
955
955
  - Command-line renames follow the same rule: if the product verb moves to `create`, do not add `add` as an alias. If a flag or command spelling changes, use the new spelling only unless Indy explicitly asks for a compatibility alias in the same session.
956
956
 
957
- **Override syntax:** `RULE NLG: SKIPPED per user override (reason: ...)` immediately preceding the edit. Override requires a concrete external consumer that can't be migrated in the same commit — vanishingly rare pre-v2.0.0.
957
+ **Override syntax:** `RULE NLG: SKIPPED per user override (reason: ...)` immediately preceding the edit. Override requires a concrete external consumer that can't be migrated in the same commit — vanishingly rare below 0.30.0.
958
958
 
959
959
  **Tags:** architecture, refactor, versioning, plan, execute
960
- **Example:** PLAN, Apr 29, 2026. The temptation to introduce `CreateExecutionV2` to avoid editing the existing RPC and its callers came up during spec audit — rejected because (a) the executor RPC has a single in-tree caller (the worker) and (b) v2.0.0 has not shipped, so no external compatibility is owed. Rule generalizes the call: in-place extension is the only sanctioned path until VERSION crosses 2.0.0.
960
+ **Example:** PLAN, Apr 29, 2026. The temptation to introduce `CreateExecutionV2` to avoid editing the existing RPC and its callers came up during spec audit — rejected because (a) the executor RPC has a single in-tree caller (the worker) and (b) the release that puts us in production had not shipped, so no external compatibility was owed. Rule generalizes the call: in-place extension is the only sanctioned path until VERSION crosses 0.30.0.
961
961
 
962
962
  ## RULE RTM — Route matchers segment-based, never substring-based
963
963
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsfleet/orly",
3
- "version": "0.10.7",
3
+ "version": "0.10.9",
4
4
  "description": "Repository-scoped engineering harness: renders agent rules, materialises the gates that enforce them, and proves the PR boundary \u2014 for any coding agent.",
5
5
  "license": "MIT",
6
6
  "type": "module",