feat(substrate): v2 Phase 3 PR-A — watchdog from proven parts (WS-C, checks 11-12) - #109
Open
SamPlvs wants to merge 3 commits into
Open
feat(substrate): v2 Phase 3 PR-A — watchdog from proven parts (WS-C, checks 11-12)#109SamPlvs wants to merge 3 commits into
SamPlvs wants to merge 3 commits into
Conversation
…oracle checks 11-12) External checker in the LifecycleWrapper poll loop (not an LLM monitor, not a cron): hook-written per-agent heartbeats, never-block taxonomy applied before any intervention, bounded nudges through a pane-ready guard, rate-limit wait-and-resume replacing the headless retry loop, PID + process-start-time identity that never treats unknown as dead. - src/zo/watchdog.py (+ _watchdog_models/_watchdog_text/_proc): pure policy evaluate(), three-state freshness, taxonomy ported from oh-my-claudecode (MIT) with ZO adjustments (no bare 429/overloaded, awaiting_input added, bare "interrupt" excluded), tiered rate-limit patterns, local-tz reset parsing, positive-proof-only process death, WatchdogConfig/WatchdogState - src/zo/_hook_heartbeat.py + hookkit "heartbeat" handler on a new PostToolUse "*" hook (stdlib-only, ~60 ms; Stop→ready, PreCompact→compacting, SubagentStop/SessionEnd→shutdown); heartbeats sealed and gitignored - src/zo/_wrapper_watchdog.py WatchdogRunner ticked from BOTH loops before the liveness reads; evidence = heartbeat deltas + normalized text digest + progress-path mtimes + process-tree CPU time; tmux nudge via named paste buffer; rate-limit = paused state per poll, verified resume; timeout excludes paused time; escalation: tmux logs+STALLED, headless kills (config) - AgentStatus.PAUSED_RATE_LIMIT/STALLED; LeadProcess identity/resume_at fields; headless retry-with-backoff removed (exit while limited → RATE_LIMITED+resume_at) - ProjectConfig.watchdog, zo build/continue --no-watchdog, ZO_WATCHDOG=0, ZO_SESSION_ID threaded to hooks; delivery .zo/ gitignore templates updated - specs/watchdog.md rewritten to implemented reality (RFC cron tick superseded); docs cascade; README badge 1053 - recon artefacts + build contract under memory/zo-platform/research/2026-08-17-phase3-recon/ Verification: 929 → 1131 passed / 7 skipped, ruff clean, validate-docs 0 failures. Seeded tests for checks 11 (10-min stall escalated within one poll; rate-limited session never nudged) and 12 (pause auto-resumes on reset with verified progress) on both loops. Heartbeat hook observed firing live for the lead and workflow subagents in the build session. Memory: STATE session 041, DECISION_LOG (Phase 3 decisions + PR-A + correction of the PostToolUseFailure caveat), PRIORS PR-047/PR-048, session-041 summary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying zero-operators with
|
| Latest commit: |
52ae20c
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://98b4b1e1.zero-operators.pages.dev |
| Branch Preview URL: | https://claude-v2-phase3-substrate.zero-operators.pages.dev |
… CI-only red on 3.11/3.12
The watchdog CPU-evidence probe ran ps -A via subprocess.run(timeout=5) inside
the headless loop tests; CPython's Popen.wait doubling back-off sleeps leaked
into mock_sleep.call_args_list because mock.patch("zo.wrapper.time.sleep")
patches the global time module. Race-dependent reap timing made it red on
Linux CI and green on macOS. Autouse fixture patches
zo._wrapper_watchdog.process_tree_cpu_seconds -> None (CPU unknown), proven
with a counting Popen spy (2 spawns before, 0 after). PRIORS PR-049 +
DECISION_LOG failure note.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ting merge Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 3 / WS-C, part 1 of 2: the watchdog — an external checker in the
LifecycleWrapperpoll loop (not an LLM monitor, not a cron) built from the parts the 2026-08-12 review rated proven. Plan oracle checks 11–12. Part 2 (the fresh-context driver, PR-B) follows on the same branch line.zo._hook_heartbeat, ~60 ms) on a newPostToolUse "*"hook (+ Stop→ready, PreCompact→compacting, SubagentStop/SessionEnd→shutdown), keyedagent_idorlead-<session_id>, written under<memory_root>/heartbeats/, sealed against agent Write/Edit and gitignored (platform root + delivery.zo/templates).⎿ Interrupted by user); ZO additions:awaiting_input(a permission dialog is never sent Enter),compacting; no bare429/overloaded; tiered rate-limit patterns..zo/experiments), process-tree CPU time (a silent 40-min training call is not a stall), PID + process-start-time identity (positive proof only; EPERM = alive).error_type=stall severity=blocking+STALLEDat exit (never kills a human-facing pane); headless kills by default (kill_headless_on_escalate).RATE_LIMITED+resume_atfor the PR-B driver.ProjectConfig.watchdog: WatchdogConfig,zo build/continue --no-watchdog,ZO_WATCHDOG=0,ZO_WATCHDOG_STALL_SEC; CLI threadswatchdog/memory_root/ZO_SESSION_ID.specs/watchdog.mdrewritten to implemented reality (the RFC's cron-scheduled orchestrator tick and respawn/reroute ladder are superseded by the plan; respawn moves to PR-B); mdx status, COMMANDS/build.mdx flag; README badge.memory/zo-platform/research/2026-08-17-phase3-recon/(integration map withfile:line, PR-A build contract, raw mapper output).Structural finding (shapes PR-B)
Orchestrator.advance_phase()/mark_subtask_complete()have zero runtime callers — the automated gate,_auto_iterate_if_needed, the WS-Bmark_phase_passedflip and the only gate-nonce mint are unreachable in production today (zo build= one lead session per phase, thenend_session()). PR-B's driver is the first runtime caller. Recorded as PRIORS PR-047; decisions in DECISION_LOG 2026-08-17T09:00.Verification
pytest: 929 → 1131 passed / 7 skipped;ruff check src/clean;scripts/validate-docs.sh0 failures.stall_threshold_sec=600) is nudged ≤3× then escalated within one poll; a rate-limited session is never nudged; a permission dialog is never nudged. Check 12 — a rate-limit pause auto-resumes on reset with verified progress; timeout accounting excludes the pause._watchdog_tickasserted from both loops incl. the suspected-deadcontinuepath;zo buildpasseswatchdog=/memory_root=/zo_session_id=; heartbeats sealed (seeded Write denied);.gitignoreviagit check-ignore.agent_type=workflow-subagent,tick_count44 →shutdown) — PostToolUse carries agent identity. Also corrected:PostToolUseFailuredoes fire on nonzero-exit Bash (session-040 caveat withdrawn).Not in this PR (recorded)
Driver + fresh-context loop +
evaluate_loop_state(ledger=)+ restore cutover +zo phase set(PR-B); check 13 on the Linux box;_watchdog-ticks.jsonlrotation;wrapper.py1404 lines (split_wrapper_tmux.py); CPU-evidence idle threshold to verify on a real tmux session.🤖 Generated with Claude Code