scripts: watchdog against runaway agents, resume instruction

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Marcos Paulo
2026-10-13 19:03:41 -03:00
parent 4746aed001
commit 175bbfda9c
3 changed files with 22 additions and 2 deletions
+10 -2
View File
@@ -15,8 +15,16 @@ run() {
cd "$wt"
PATH="$HOME/.cargo/bin:$PATH" CARGO_TARGET_DIR="$root/target/agent-$task" \
timeout 3000 pi -p --mode json --no-session --no-extensions --no-skills --no-themes -np --thinking low \
"$(cat "$root/scripts/waves/_common.md" "$1")"
) >"$root/.worktrees/$task.jsonl" 2>&1
"$(cat "$root/scripts/waves/_common.md" "$1")" >"$root/.worktrees/$task.jsonl" 2>&1 &
pid=$!
# watchdog: a runaway agent (rate-limit retry loop) floods its log; kill it past 40 MB
while kill -0 "$pid" 2>/dev/null; do
sz=$(stat -f %z "$root/.worktrees/$task.jsonl" 2>/dev/null || echo 0)
[ "$sz" -gt 41943040 ] && { pkill -P "$pid"; kill "$pid"; echo RUNAWAY >>"$root/.worktrees/$task.jsonl.flag"; }
sleep 10
done
wait "$pid"
)
rc=$?
# final assistant text -> <task>.log; empty means the agent never answered
python3 - "$root/.worktrees/$task.jsonl" >"$root/.worktrees/$task.log" <<'PY'
+2
View File
@@ -11,4 +11,6 @@ Rules, all mandatory:
- Do NOT run git commit, git add, or touch git state. Do not run commands outside your worktree.
- Final report (max 15 lines): what is implemented, the public API (signatures), test counts, anything skipped or any dependency you needed but did not have.
If your crate already contains files from an earlier attempt, read them first, keep what is correct and finish the task; do not start over.
YOUR TASK:
+10
View File
@@ -0,0 +1,10 @@
Crate: crates/whiteboard (notescraft-whiteboard, layer L1). SPEC section: 6 item 26 (Whiteboard bullet) and 12 (Whiteboard row). Allowed new dependencies: serde, serde_json, thiserror (`{ workspace = true }`).
Implement an Excalidraw-v2-compatible model and a deterministic hand-drawn shape generator (no UI):
1. Model: `Whiteboard { elements: Vec<Element>, app_state: serde_json::Value, files: serde_json::Value, extra: Map }`. `Element` has common fields (id, type, x, y, width, height, angle, stroke_color, background_color, fill_style, stroke_width, stroke_style, roughness, opacity, seed, version, version_nonce, is_deleted, group_ids, bound_elements, link, locked, updated) and `kind: ElementKind::{Rectangle, Diamond, Ellipse, Arrow{points,start_binding,end_binding,start_arrowhead,end_arrowhead}, Line{points}, Freedraw{points,pressures}, Text{text,font_size,font_family,text_align,vertical_align,container_id}, Image{file_id}, Frame{name}, Unknown{type_name}}`; every unknown field at every level preserved in an `extra` map and re-emitted. JSON keys are camelCase as in Excalidraw files (`strokeColor`, `isDeleted`, ...).
2. `Whiteboard::from_str(&str)` accepting `{"type":"excalidraw","version":2,"source":..,"elements":[..],"appState":{..},"files":{..}}`; tolerant of missing optional fields; caps (32 MiB, 100000 elements); `to_string_pretty()` canonical output with `"type":"excalidraw","version":2`; `read(write(read(x))) == read(x)`.
3. Builders: `Element::rectangle/ellipse/diamond/line/arrow/text(...)` with sensible defaults and a deterministic seed from an `IdGen` (16-char ids from a counter, no rand crate); `Whiteboard::add`, `delete` (sets isDeleted, keeps element), `bounding_box`.
4. Hand-drawn style: `rough::outline(&Element, style: Style::{HandDrawn, Clean}) -> Vec<Polyline>` returning polylines (each `Vec<[f32;2]>`) for rectangle/diamond/ellipse/line/arrow. HandDrawn perturbs points using a seeded xorshift RNG from `element.seed` and `roughness` (double stroke, small endpoint overshoot); same seed and element give bit-identical output; Clean returns exact geometry. No NaN/inf for any input (zero size, huge sizes clamped).
5. `Whiteboard::from_mermaid_layout` is OUT of scope (another crate does it).
Tests: fixtures in tests/fixtures (hand-written Excalidraw files: all element types, bound arrow, text in container, image with files entry, unknown element type, unknown fields everywhere); round trip and preservation tests; determinism test for rough outlines; degenerate geometry (zero width, NaN input from JSON is rejected); malformed JSON returns Err.