Commit e8f0c39
feat(graphs): every batch-lane rule now ends in a disposition (#237)
* docs(measurements): rule 1 fires once in 45 graphs, and that once is noise
Measure the batch-lane survey memo's rule-1 candidate — "two lanes in one
graph must not touch the same file" — before any lint is written, because
this repo rejected a predicate at 110 noise in 114 hits two days ago and an
unmeasured noise rate does not ship here.
The probe parses, never greps: shipped graphs go through graph.LoadFile so
every fragment `use:` is spliced before a node is counted, and each planned
graph.json in the operator corpus goes through graph.Parse. Population 45
graphs (8 shipped + 37 planned from 339 run directories), 216 resolved nodes.
The number that decides it is not the hit count but the firing population:
1 of 45 graphs declares two lanes. Not one planned graph declares a lane at
all, and cannot — validatePlannedNodeWorktree rejects `worktree:` on an
unreviewed plan — so no amount of extra operator history would grow it.
The single hit is CONTRIBUTING.md, quoted by both lanes as the address of a
commit-trailer convention and edited by neither: 1 noise in 1 hit. Even at
zero noise the predicate would judge text it cannot see, since which files a
lane owns arrives in --input and `lint` takes no --input. Every narrowing
that would clear the hit is fitted to it and re-measured against the same one
graph, and a test over shipped graphs only would be red today for the same
reason.
VERDICT: DO-NOT-SHIP. Rule 1 stays prose. Nothing in the engine changes: the
probe carries //go:build ignore, so `go build ./...` and `go test ./...` do
not see it.
Signed-off-by: jitokim <pigberger70@gmail.com>
Co-Authored-By: oh-my-graph <graphs@oh-my-graph.dev>
* test(graphs): the three batch-lane rules a parser can decide become assertions
The survey memo triaged the six hard-won rules in graphs/backlog-batch.yaml's
header. Three of them have a predicate that reads only declared fields, and
until now nothing held them: the header stated them, and drift was free.
Rule 5 — independent lanes fail independently. Weakly connected components of
`depends_on` over the RESOLVED graph (lane A is one authored node that splices
into four, so the file's `nodes:` list reads 2 where the run has 8); two or
more components must come with `on_fail: continue`. Measured over the eight
shipped templates: exactly one is multi-component — backlog-batch — and it
declares it at :84.
Rule 3 — cold-safe session prompts. `handoff: session` + `retry` starts the
retried attempt cold; LintSessions already warns about it, and stays advisory.
What is checkable is that the wording which survives a cold attempt exists
once, in e2e-verify, and that every shipped gate of this shape CITES it rather
than restating it. Four do: lane-a/e2e, e2e-b, and dev-review-pr's and
self-dev's e2e.
Rule 1 residual — a node with no `worktree:` in a graph whose other nodes have
one runs in the user's own tree, so it shares files with every lane at once.
That is the one collision the schema can decide; the rest of rule 1 stays
prose, measured in docs/measurements/0034 (DO-NOT-SHIP).
All three are tests over graphs/, never lint sweeps. A new sweep owes a
measured noise rate and the corpus that could produce one does not exist —
n=1 across everything this repo ships — and each rule's named false positive
(a deliberate fail-fast batch, an honest hand-written cold-safe prompt, a
coordinating node outside every lane) is a legitimate graph a warning would
reach a user with. Here the cost is a CI failure the rule's own author fixes.
Each carries the zero-population guard the gating-review test already uses: if
the shape it judges disappears from graphs/, the test says so instead of
passing while asserting nothing. Each was confirmed to bite by mutating
backlog-batch.yaml — halt, a lane-less dev-b, a hand-written e2e-b — and the
mutation was reverted.
Signed-off-by: jitokim <pigberger70@gmail.com>
Co-Authored-By: oh-my-graph <graphs@oh-my-graph.dev>
* test(graphs): the gate pair is symmetric, and now the test that pins it is too
"Ship both or neither" is stated three times in the graphs — backlog-batch's
rule 6, review-style.yaml, gated-lane.yaml — and
TestAGatingReviewCarriesItsRecoveryArc held only one direction of it. A
narrowed check with no arc failed the test. An arc with no narrowing hit the
`continue` on the advisory branch and passed.
That half is not symmetric decoration. A `feedback:` arc on a review whose
success_check still accepts `FINDINGS:` cannot be reached by the verdict it
was written for, so the finding it was meant to repair rides into the PR body
instead — while the graph, and the run's disclosure line, read like a lane
that gates.
Stated exactly, because "the arc never fires" would be one word too strong: a
review fragment declares no `verify`, so nonzero_exit and a reply that is
neither verdict can still reach the arc. Re-running the implementer over a
crashed or malformed review repairs nothing, because nothing was found. Dead
as a repair round is the claim, and it is the claim the doc comment makes.
No shipped graph is in this shape today — lane B advises with no arc, on
purpose — so this fires on nothing and guards the next author. Confirmed to
bite by giving review-b an arc; the mutation was reverted.
Signed-off-by: jitokim <pigberger70@gmail.com>
Co-Authored-By: oh-my-graph <graphs@oh-my-graph.dev>
* docs(graphs): every batch-lane rule now ends in a disposition
Three of the seven rules name the check that enforces them and whether it
warns or refuses; four say in one sentence why they are judgement and stay
prose. Rule 1's disposition carries the measurement that rejected its lexical
form (1 hit, 1 noise, DO-NOT-SHIP) rather than implying the rule is checked;
what survives of it is one test that reads no paths at all.
Rule 7 also settles the fragment question so the next author does not reopen
it: the lane shape is already graphs/fragments/gated-lane.yaml, and a second
lane fragment is not merely redundant — its dev prompt quotes
{{ feedback.review }}, which is a load error for a citing node that declares
no arc, so an advisory lane cannot cite it at all.
Header and comments only: every changed line in this diff begins with `#`,
and both runtimes' lint output for the graph is byte-identical to before.
Signed-off-by: jitokim <pigberger70@gmail.com>
Co-Authored-By: oh-my-graph <graphs@oh-my-graph.dev>
* docs(changelog): the batch-lane formalisation, including what it refused to ship
One Unreleased entry under Documented. It names the three tests that now
enforce rules 3, 5 and 6 over graphs/, the advisory lint that already covered
rule 3's risky shape, and the four rules that stay prose with the reason each.
The entry carries the measurement rather than only the outcome: 1 hit and 1
noise across 45 graphs and 216 resolved nodes, verdict DO-NOT-SHIP, with the
path to docs/measurements/0034-lane-file-ownership-predicate.md and the
command that recomputes it. A changelog that reported only the tests would
read as if rule 1 had been checked.
No release, no tag, no version string touched.
Signed-off-by: jitokim <pigberger70@gmail.com>
Co-Authored-By: oh-my-graph <graphs@oh-my-graph.dev>
---------
Signed-off-by: jitokim <pigberger70@gmail.com>
Co-authored-by: oh-my-graph <graphs@oh-my-graph.dev>1 parent d7efe95 commit e8f0c39
5 files changed
Lines changed: 979 additions & 9 deletions
File tree
- docs/measurements
- graphs
- internal/graph
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
147 | 202 | | |
148 | 203 | | |
149 | 204 | | |
| |||
0 commit comments