zz_

e2956e9d ยท zzmq.dev@gmail.com/zz

Commit

e2956e9da0e18d255084ec77bf86c25699ccd858

Close the sandbox-failure feedback loop; headless banner + timestamps Three real fixes to make a changeset's own failure feed back into the protocol quickly and automatically, instead of needing a human to notice and restart: - PROPOSE_SYSTEM_PROMPT now tells the model exactly what its sandbox actually provides: Node's own built-in test runner only (import test/describe from "node:test", not Jest/Mocha/Vitest -- nothing installs those), real ESM (file extensions required on relative imports, export/import not module.exports/require). This directly targets the failure modes actually observed live (describe is not defined, Cannot find module 'vitest', extensionless import resolution, named-export-on-a-CommonJS-module) -- verified live after the fix: three different tasks each passed the sandbox on the first attempt, where they'd previously needed retries or failed outright. - proposeReview now re-runs the sandbox against the proposed files itself before asking the model to judge them -- never trust the contributor's own earlier pass as the final word, the same "never trust self-declared scope" principle review exists for already, extended to "never trust a self-declared passing test run." A sandbox failure here is an objective fact, not a judgment call, so it skips the model and denies outright with the real failure output as the reason. acceptReview's existing deny-branch already turns that into a fresh "work" ask carrying the failure as feedback, and zz work's own mainLoop is already a continuous poll -- so this closes the whole claim -> fail -> deny -> repost -> reclaim loop automatically, within the same running session, with no restart. Also: cli/lib/banner.ts extracts the ASCII banner/version logic out of zz.ts (now imports it) so zz work --stdio can print the full banner at the start of its own output too, and every --stdio log line is now timestamped (ISO 8601) so a captured log is actually parsable/sortable -- the TUI's own ActivityLog stays bare, since that's a live view where "when" is always "now." Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q8tksS4bucUkJguqksSVYR

Troy Howard <thoward37@gmail.com> -- 2026-10-13T21:58:27.000Z

Tree at this commit