You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Four sites told an agent to run make ze-verify with a 240s timeout,
while other paragraphs of the same rule said 25 to 30 minutes and half
an hour, ai/rules/testing.md said 4-10 minutes, and
scripts/dev/verify-lock.sh said ~2 min with MAX_LOCK_AGE 1800s. 240s was
the only one written as a directive and the one no producer supports. An
agent that obeyed it killed a healthy run and read the result as a red
tree.
The rule now names no timeout. It says run it in the foreground, wait,
never poll, do not kill it for being slow, give the call the largest
timeout your harness allows, and take the duration from
tmp/.ze-verify-duration.txt, which _record_duration in verify-lock.sh
actually writes. It quotes the corpus's two competing figures rather
than pretending they are absent.
Each directive is one physical line. condense_body in
scripts/dev/rules_condensed.py appends the bold-led LINE raw, so a
directive that wraps reaches ai/rules/CORE.md cut mid-clause. The
always-on digest now carries all four whole.
The migration is completed rather than half-landed:
ai/skills/ze-verify.md was the operative instruction at the point of use
and still banned run_in_background while citing a rule section that does
not exist, and still told agents to abandon the pass at 240s.
ai/skills/ze-check.md, ai/rationale/git-safety.md and a hook comment
carried the same number. ai/rationale/git-safety.md also carved out a
backgrounding exception that contradicted the rule it exists to explain.
A stale 22-stage count in a commands point file is fixed the same way,
by naming no count.
Five independent reviewers over three rounds found ten defects in the
first two drafts of this change, including that the fix had introduced
600s with no producer and cited MAX_LOCK_AGE from the opposite premise.
Round 3 closed at 0 blocker, 0 issue. plan/learned/1359 records that,
because the failure it documents caught the person writing the rule
against it, three times.
If a previous run is still going, `verify-lock.sh` blocks the second
35
39
invocation inside the same foreground Bash call until the lock releases.
@@ -42,8 +46,11 @@ Anti-patterns that look like "smart" backgrounding but break:
42
46
|`run_in_background: true` + `stat -c %Y` mtime check on `tmp/ze-verify.log`| Log is written continuously during the run; mtime never "settles" reliably |
43
47
|`run_in_background: true` then assume you'll be notified | You will be, but a concurrent polling/sleep loop in Bash can swallow the notification |
44
48
45
-
Legitimate reasons to background `ze-verify`:
46
-
- Genuinely independent work to do for >60s while it runs (rare).
47
-
48
-
In both cases: launch with `run_in_background: true` and **stop**. No
49
-
polling loop. Ever.
49
+
There is no legitimate reason to background it. `ai/rules/git-safety.md`
50
+
("Running ze-verify") says foreground, wait, never poll, and `ai/skills/ze-verify.md`
51
+
step 2 says the same. This paragraph used to carve out an exception for
52
+
"genuinely independent work to do for >60s while it runs", contradicting the
53
+
rule it exists to explain, and enumerating "both cases" under a single bullet.
54
+
Editing the tree during a run is what makes that exception unsafe: the gate
55
+
reads the working tree, so independent work invalidates the run it is waiting
Copy file name to clipboardExpand all lines: ai/rules/CORE.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,7 +70,7 @@ BLOCKING only when the commit could plausibly affect build, tests, or generated
70
70
| Anything that runs at build time or affects a binary | YES |
71
71
|`ai/**/*.md`, `.claude/**/*.md`, `plan/**/*.md`, `docs/**/*.md`, `README.md`| NO |
72
72
### Step 1: If `ze-verify` applies (BLOCKING)
73
-
`make ze-verify` (timeout 240s).
73
+
`make ze-verify`, in the foreground ("Running ze-verify" below).
74
74
### Structural Gates Are Never Known-Red (BLOCKING)
75
75
The item-2 "log to `plan/known-failures/`" path is for **non-deterministic** failures only -- flaky or environmental TEST reds (load-sensitive races, GC-pressure pool flakes, host-specific listener probes).
76
76
**The general escape is owner-only: `--structural-red-ok "<reason>"`** (the
@@ -110,7 +110,11 @@ One `make ze-verify*` (or `ze-chaos-verify`) at a time repo-wide -- parallel run
110
110
| If the run is yours (same tree), read `tmp/ze-verify.log` instead of re-running | Delete the lockfile |
111
111
| If "waiting for lock" appears, do other work | Start `go test` / `golangci-lint` / `bin/ze-test` in parallel (bypasses lock) |
112
112
### Running ze-verify
113
-
Foreground with 240s timeout.
113
+
Each directive below is one physical line on purpose.
114
+
**Run `make ze-verify` in the foreground, wait for it, and never poll: the foreground return IS the completion signal.**
115
+
**Do not kill it for being slow. Give the call the largest timeout your harness allows.**
116
+
**Never take a timeout from a duration written in a rule. The one measurement is `tmp/.ze-verify-duration.txt`.**
117
+
**Never edit the tree while a verify runs, yours or anybody's: it reads the working tree.**
114
118
### A SHARED CHECKOUT NEVER GIVES A CLEAN `ze-verify` (BLOCKING)
115
119
**Several agents work this checkout at once. `make ze-verify` reads the WORKING
116
120
TREE, so it reads their half-finished edits too, and a fully green run is unreachable by construction.
Copy file name to clipboardExpand all lines: ai/rules/git-safety.md
+24-4Lines changed: 24 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -249,7 +249,8 @@ No = skip and note in commit summary. Unsure = run.
249
249
250
250
### Step 1: If `ze-verify` applies (BLOCKING)
251
251
252
-
`make ze-verify` (timeout 240s). Not `go test`, not any subset.
252
+
`make ze-verify`, in the foreground ("Running ze-verify" below). Not `go test`,
253
+
not any subset.
253
254
Before any verify target, check freshness. A FRESH status covers the
254
255
byte-identical tree and forbids rerunning `make ze-verify` or
255
256
`make ze-verify-changed`. The check output is qualified by mode:
@@ -271,7 +272,7 @@ under `tmp/verify/`, `tmp/ze-verify-failures.log`,
271
272
272
273
```
273
274
[ ] 0. `scripts/dev/verify-status.sh check`. FRESH -> MUST NOT run `make ze-verify` or `make ze-verify-changed` again; note timestamp. STALE -> continue only if the table above says verification applies.
274
-
[ ] 1. `make ze-verify` (240s) only when status is STALE and the table above says YES. On failure read `tmp/ze-verify-failures.log` FIRST, choose a stage-local group, then open that group's `tmp/verify/<nn>-<stage>.log`.
275
+
[ ] 1. `make ze-verify` (foreground, largest timeout your harness allows, never killed early) only when status is STALE and the table above says YES. On failure read `tmp/ze-verify-failures.log` FIRST, choose a stage-local group, then open that group's `tmp/verify/<nn>-<stage>.log`.
275
276
[ ] 2. Failure from current work: fix + re-run. Pre-existing: fix after primary task in separate commit; if >10 min, log to `plan/known-failures/` (one `<make-target>-<test-name>.md` shard per failure).
276
277
```
277
278
@@ -479,8 +480,27 @@ PID-backed -- no cleanup after a crash.
479
480
480
481
### Running ze-verify
481
482
482
-
Foreground with 240s timeout. No background execution, no polling
483
-
loops. Wait for completion.
483
+
Each directive below is one physical line on purpose. `condense_body`
484
+
(`scripts/dev/rules_condensed.py`) emits a bold-led LINE raw into
485
+
`ai/rules/CORE.md`, so an instruction that wraps arrives there cut in half.
486
+
487
+
**Run `make ze-verify` in the foreground, wait for it, and never poll: the foreground return IS the completion signal.**
488
+
No background run, no sleep-and-check loop, no `tail` on a log that is still
489
+
growing.
490
+
491
+
**Do not kill it for being slow. Give the call the largest timeout your harness allows.**
492
+
A verify that is still running is not a verify that is hung, and killing one
493
+
costs the whole pass rather than the seconds it saves.
494
+
495
+
**Never take a timeout from a duration written in a rule. The one measurement is `tmp/.ze-verify-duration.txt`.**
496
+
This corpus disagrees with itself about how long a full pass takes: "25 to 30
497
+
minutes" below, "4-10 minutes" in `ai/rules/testing.md`. Both were typed by
498
+
hand. `_record_duration` (`scripts/dev/verify-lock.sh`) appends the real elapsed
499
+
seconds to that file, and when it is absent nothing here has measured it
Copy file name to clipboardExpand all lines: ai/rules/points/git-safety/before-any-commit/the-pre-commit-verify-checklist.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,6 @@ stage:
5
5
---
6
6
```
7
7
[ ] 0. `scripts/dev/verify-status.sh check`. FRESH -> MUST NOT run `make ze-verify` or `make ze-verify-changed` again; note timestamp. STALE -> continue only if the table above says verification applies.
8
-
[ ] 1. `make ze-verify` (240s) only when status is STALE and the table above says YES. On failure read `tmp/ze-verify-failures.log` FIRST, choose a stage-local group, then open that group's `tmp/verify/<nn>-<stage>.log`.
8
+
[ ] 1. `make ze-verify` (foreground, largest timeout your harness allows, never killed early) only when status is STALE and the table above says YES. On failure read `tmp/ze-verify-failures.log` FIRST, choose a stage-local group, then open that group's `tmp/verify/<nn>-<stage>.log`.
9
9
[ ] 2. Failure from current work: fix + re-run. Pre-existing: fix after primary task in separate commit; if >10 min, log to `plan/known-failures/` (one `<make-target>-<test-name>.md` shard per failure).
0 commit comments