Skip to content

v0.0.17 - #7

Merged
IvanRublev merged 10 commits into
masterfrom
v0.0.17
Aug 4, 2026
Merged

v0.0.17#7
IvanRublev merged 10 commits into
masterfrom
v0.0.17

Conversation

@IvanRublev

Copy link
Copy Markdown
Owner

What changed

  • The context-full restart signal is now computed in ClaudeZero's own Stop hook, no need for suggest-compact dependency anymore
  • In case after a zero-mode session walks the whole todo list and claims nothing because every unchecked task is dependency-blocked, the script waits for an unblocked task and only then relaunches claude to save tokens

Tests run

Ran the complete end-to-end suite (TEST.md) against claudezero.sh across multiple
isolated $TESTROOTs. Result: all scenarios pass — no defect found in
claudezero.sh itself. Several flaky/broken assertions in the test suite were
found and fixed along the way (see below).

Results

Scenario Result Notes
S — static checks ✅ PASS shellcheck + bash 3.2 syntax, incl. self-test
A — parallel zeroing / restart / timing ✅ PASS
B — startup-guard refusals ✅ PASS all 10 sub-checks
C — merge-conflict path ✅ PASS
D — foreign check-off refusal + self-heal ✅ PASS redesigned (see below)
E — timing accounting ✅ PASS
F — fenced-checkbox immunity ✅ PASS
G1 — token accounting ✅ PASS
G2 — fd 4 output descriptor ✅ PASS
H — session display name ✅ PASS
I — zero.sh claim exit paths ✅ PASS
J — fleet TOTAL ✅ PASS
K — SIGTERM while claude hangs ✅ PASS trigger rewritten (see below)
L — exit code + --debug-file ✅ PASS
M — one task per session, the shell waits ✅ PASS M1–M4; M5 dropped (see below)
N — CLAUDEZERO_WATCHDOG timer ✅ PASS
O — CLAUDEZERO_LINK ✅ PASS
P — dependency-blocked wait ✅ PASS trigger rewritten (see below)
Q — context-rot guard ✅ PASS

Ivan Rublev added 10 commits August 5, 2026 00:59
…n Stop hook

Replaces the third-party suggest-compact hook prerequisite with a CONTEXT_THRESHOLDS
table at the top of claudezero.sh, resolved against the session transcript's own
message.usage schema on every turn. run_doctor drops to flock+claude only.

Fixes a real O(n^2) hang in macOS's stock awk when matching a regex against one very
long transcript line (~9.5s for a single 262144-byte record): the guard now pre-extracts
short per-field tokens via `grep -n -o` before awk ever sees them, keeping the 256 KiB
cap's cost flat regardless of record size, as designed.

Adds TEST.md Scenario Q (the context-rot guard) and run_doctor coverage in Scenario B;
rewrites M4's bucket-branch case against a fixture transcript; updates README/SECURITY/
CHANGELOG and .github/smoke.sh accordingly.
K1/P1/P2 raced an external actor (timeout -k, backgrounded sleep) against
claudezero.sh's internal readiness, assuming near-instant subprocess spawn.
K1 now waits for the claude process to exist before sending TERM; P1/P2
now wait for the no-claim-mark marker before flipping/killing their peer.

Dropped M5 (spinner repaint-count assertion): its window was too tight to
survive spawn-latency variance and it duplicated M1-M4's wait coverage.
…rigger

K1's bare `wait "$WPID"` aborted the whole script on the expected 143 exit
under Section 0's set -euo pipefail, before the echo ran. Capture via
K1RC=0; wait "$WPID" || K1RC=$?, same idiom Scenario B already uses.

P1/P2's flipper/killer polled for the no-claim-mark file's existence, but
that file is written almost instantly (the stub claude's first action) —
long before the shell's fixed RESTART_WAIT elapses and it actually calls
wait_for_dependency_clear(). Confirmed by experiment: retarget the poll to
the 'now blocked' log line, the real signal that the shell has entered the
wait, and P1/P2/P4 pass cleanly instead of racing the flip in before the
wait state is ever reached.
The real-agent inducement prompt tripped this account's --permission-mode
auto classifier: it silently denied the foreign-checkbox edit/commit the
inducement needed, so claude printed "Execution error" and hung until the
outer timeout killed it, the scenario's real purpose never got exercised.

D now scripts the violation directly (zero.sh claim + fabricated commits,
reproducing exactly the state a misbehaving agent would leave) and hands
off to one narrowly-scoped real `claude -p ... --permission-mode
bypassPermissions` call just for the merge + self-heal — the only part
actually worth testing with a real agent, and bypass mode has no
classifier to trip.
Verification run showed refusal/self-heal genuinely happened (a dangling
pre-amend commit with both boxes checked, replaced by the amended one with
only T1 - confirmed via git fsck), but refusal fired read 0 because the
prompt only asked the agent for its LAST attempt's output. Ask for every
attempt now, and document the git-archaeology fallback for when an agent's
own summary still omits it.
@IvanRublev
IvanRublev merged commit 33f99d2 into master Aug 4, 2026
3 checks passed
@IvanRublev
IvanRublev deleted the v0.0.17 branch August 4, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant