Skip to content

Commit d77d189

Browse files
authored
Merge branch 'main' into fix/spawn-retry-window
2 parents 2ebd560 + f8eaa4f commit d77d189

7 files changed

Lines changed: 3054 additions & 12 deletions

CHANGELOG.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,61 @@ oh-my-graph is **alpha software**. The graph YAML schema, the CLI, and the
167167

168168
### Documented
169169

170+
- **Every rule in the batch-lane idiom now ends in a disposition: the check
171+
that enforces it, named, or one sentence saying why it is judgement**
172+
([`graphs/backlog-batch.yaml`](graphs/backlog-batch.yaml)). The header stated
173+
seven hard-won rules and left a reader to guess which of them anything
174+
enforced — a rule with a test behind it read exactly like one no code has
175+
ever looked at.
176+
177+
Three rules are mechanically checked, all three as tests over `graphs/` in
178+
`internal/graph/shipped_graphs_test.go`, so a violation fails THIS repo's
179+
build rather than warning at a user's own graph:
180+
`TestIndependentLanesFailIndependently` (rule 5 — two or more weakly
181+
connected components in the resolved graph must come with
182+
`on_fail: continue`), `TestASessionGateCitesTheColdSafeFragment` (rule 3 — a
183+
node that resumes a session and retries must have spliced `e2e-verify`, where
184+
the cold-safe wording exists once), and
185+
`TestAGatingReviewCarriesItsRecoveryArc`, extended to rule 6's second half:
186+
it already refused a narrowed review check with no `feedback:` arc, and now
187+
equally refuses an arc on a node whose check still accepts `FINDINGS:` — an
188+
arc the failing verdict can never reach. Rule 3's risky shape keeps its
189+
existing advisory warning from `handoff.LintSessions`; the test guards only
190+
what the warning cannot, that the wording has not been copied out by hand.
191+
192+
Rules 2, 4 and 7 stay prose, each saying why in the header: rule 2 would have
193+
to read prompt prose for an instruction, the predicate family this repo
194+
measured and rejected at 110 noise in 114 hits
195+
([`docs/measurements/0213-tool-grant-predicate.md`](docs/measurements/0213-tool-grant-predicate.md));
196+
rule 4's subject is a lane's diff, which does not exist when a graph is
197+
loaded; and rule 7 asks whether a repeat is a shape or a difference in a key,
198+
which is the judgement it exists to provoke.
199+
200+
Rule 1 — "lanes must not share files" — stays prose too, and was measured
201+
before it was written off, in
202+
[`docs/measurements/0034-lane-file-ownership-predicate.md`](docs/measurements/0034-lane-file-ownership-predicate.md).
203+
Over 45 graphs and 216 resolved nodes, only one graph can fire the predicate
204+
at all (a planned graph may not declare a `worktree:`), and the lexical form
205+
produced **1 hit, of which the hand-check made 1 noise** — both lanes cite
206+
`CONTRIBUTING.md` as the address of the commit-trailer convention and neither
207+
edits it. Verdict: DO-NOT-SHIP. The command is the address for those numbers:
208+
209+
```sh
210+
go run docs/measurements/0034-lane-file-ownership-predicate.go
211+
```
212+
213+
What survives of rule 1 reads no paths at all and is a test:
214+
`TestAWorktreeGraphLeavesNoNodeOutsideALane` refuses a graph that declares
215+
lanes and leaves some node without one, since that node runs in the user's
216+
own tree and so shares files with every lane at once.
217+
218+
No new `lint` sweep and no new load error — a new warning owes a measured
219+
noise rate, and the corpus that could measure one is n=1 across everything
220+
this repo ships. The header also settles the fragment question so it is not
221+
reopened: the lane shape is already a fragment,
222+
[`graphs/fragments/gated-lane.yaml`](graphs/fragments/gated-lane.yaml), and
223+
no second lane fragment is coming. Nothing in the graph body changed, and
224+
both runtimes' `lint` output for the eight shipped graphs is unchanged.
170225
- **ADR 0033 — the run, not the node, is the unit of engine-run evidence, and
171226
ADR 0030 is deliberately not extended one level down**
172227
([`docs/adr/0033-the-run-is-the-unit-of-evidence-not-the-node.md`](docs/adr/0033-the-run-is-the-unit-of-evidence-not-the-node.md),
@@ -202,6 +257,37 @@ oh-my-graph is **alpha software**. The graph YAML schema, the CLI, and the
202257
while `cmd/oh-my-graph/version.go:9` reads `0.11.0`. The clause that survived
203258
the deletion is the true half: a run that types nothing is byte-for-byte the
204259
run that shipped in v0.10.0.
260+
- **`graphs/backlog-batch.yaml`'s header diagrammed four nodes the graph no
261+
longer has, and its rule 1 advised an edit that will not load.** ADR 0029
262+
folded lane A into a single `use: gated-lane` node, and commit `d232ce4`
263+
deleted `dev-a`/`e2e-a`/`review-a`/`pr-a` — but that commit's diff on this
264+
file begins at `@@ -45,15 +45,24 @@`, so it never reached the header. The
265+
runtime ids are `lane-a/dev`, `lane-a/e2e`, `lane-a/review`, `lane-a/pr`, as
266+
the file's own body comment already said (`graphs/backlog-batch.yaml:88`) and
267+
as loading it prints:
268+
269+
```sh
270+
go run ./cmd/oh-my-graph run graphs/backlog-batch.yaml --dry-run \
271+
--input repo=/tmp --input checks_command="make local" \
272+
--input task_a=x --input task_b=y
273+
# Graph "backlog-batch" (8 nodes): lane-a/dev, lane-a/e2e, lane-a/review,
274+
# lane-a/pr, dev-b, e2e-b, review-b, pr-b
275+
```
276+
277+
The second line was worse than stale. Rule 1 offered "make dev-b depend on
278+
`pr-a`" as the way to serialize two overlapping tasks, and `depends_on:
279+
[pr-a]` is a load error — `depends_on unknown node`,
280+
`internal/graph/validate.go:454` — so a reader who took the advice got a
281+
graph that would not run. It now names `lane-a/pr`
282+
(`graphs/backlog-batch.yaml:16`). `init` emits this file and users copy it,
283+
which is why a stale comment here is a stale instruction to a stranger.
284+
285+
Comments only: no node, prompt, or key changed, the graph still validates at
286+
8 nodes, and no verdict clause moved, so the qualifier sweep's counts are
287+
untouched. The remaining thirteen shipped graphs and fragments were audited
288+
against v0.11.0 in the same pass and left alone — none of them names `auto`,
289+
so neither `--accept-loaded-user-config` nor anything else new in v0.11.0
290+
reaches them.
205291

206292
## [v0.11.0] - 2026-08-21
207293

0 commit comments

Comments
 (0)