checkpoint

⚒️ Generated with [Fabro](https://fabro.sh)
This commit is contained in:
Fabro 2026-03-15 21:59:54 -04:00
parent 012664dc7f
commit adc0904c9e
4 changed files with 40 additions and 10 deletions

View file

@ -1,32 +1,36 @@
{
"timestamp": "2026-03-16T01:58:37.664339Z",
"current_node": "toolchain",
"timestamp": "2026-03-16T01:59:54.222570Z",
"current_node": "preflight_compile",
"completed_nodes": [
"start",
"toolchain"
"toolchain",
"preflight_compile"
],
"node_retries": {
"start": 1,
"toolchain": 1
"toolchain": 1,
"preflight_compile": 1
},
"context_values": {
"current.preamble": "Goal: # Wire up missing hook invocations\n\n## Context\n\nFive `HookEvent` variants exist in the enum and are documented in `docs/agents/hooks.mdx`, but `run_hooks()` is never called for them in the engine. Users can configure hooks for these events, but they silently never fire.\n\n**Events to wire up:** `StageRetrying`, `ParallelStart`, `ParallelComplete`\n**Events to mark as reserved:** `SandboxReady`, `SandboxCleanup` (sandbox lifecycle is managed outside the engine; wiring these requires significant architecture changes)\n\n## Changes\n\n### 1. Add StageRetrying hook calls in `engine.rs`\n\nFile: `lib/crates/fabro-workflows/src/engine.rs`\n\nTwo sites in `execute_with_retry`, both immediately after `WorkflowRunEvent::StageRetrying` emission and before `tokio::time::sleep(delay).await`:\n\n- **Site A (~line 1127):** error-retry path\n- **Site B (~line 1155):** explicit Retry status path\n\nPattern (same for both sites):\n```rust\n{\n let mut hook_ctx = HookContext::new(\n HookEvent::StageRetrying,\n context.run_id(),\n graph.name.clone(),\n );\n hook_ctx.node_id = Some(node.id.clone());\n hook_ctx.node_label = Some(node.label().to_string());\n hook_ctx.handler_type = node.handler_type().map(String::from);\n hook_ctx.attempt = Some(usize::try_from(attempt).unwrap_or(usize::MAX));\n hook_ctx.max_attempts = Some(\n usize::try_from(policy.max_attempts).unwrap_or(usize::MAX),\n );\n let _ = self.run_hooks(&hook_ctx, None).await;\n}\n```\n\nAvailable via: `self.run_hooks()` (engine method), `context.run_id()`, `graph.name`, `node`, `attempt`, `policy`.\n\n### 2. Add ParallelStart hook call in `parallel.rs`\n\nFile: `lib/crates/fabro-workflows/src/handler/parallel.rs`\n\nAfter `ParallelStarted` event emission (~line 301). Call `hook_runner.run()` directly since the handler has `services: &EngineServices` (which has `hook_runner` and `sandbox`):\n\n```rust\nif let Some(ref runner) = services.hook_runner {\n let hook_ctx = HookContext::new(\n HookEvent::ParallelStart,\n context.run_id(),\n graph.name.clone(),\n );\n let _ = runner\n .run(&hook_ctx, services.sandbox.clone(), None)\n .await;\n}\n```\n\n### 3. Add ParallelComplete hook call in `parallel.rs`\n\nSame file, after `ParallelCompleted` event emission (~line 713). Same pattern as ParallelStart but with `HookEvent::ParallelComplete`.\n\n### 4. Mark SandboxReady/SandboxCleanup as reserved\n\nFile: `lib/crates/fabro-workflows/src/hook/types.rs`\n\nAdd doc comments:\n```rust\n/// Reserved: hooks for this event are not yet invoked by the engine.\nSandboxReady,\n/// Reserved: hooks for this event are not yet invoked by the engine.\nSandboxCleanup,\n```\n\n### 5. Update docs\n\nFile: `docs/agents/hooks.mdx`\n\nIn the lifecycle events table, annotate `sandbox_ready` and `sandbox_cleanup` rows — e.g., append \"(not yet wired)\" to the description or add a note.\n\n## Verification\n\n1. `cargo fmt --check --all`\n2. `cargo clippy --workspace -- -D warnings`\n3. `cargo test --workspace` — existing tests pass, no regressions\n4. Manual test: create a workflow with a retrying node and a `post_tool_use`-style hook for `stage_retrying`, verify it fires in the CLI log\n\n",
"current.preamble": "Goal: # Wire up missing hook invocations\n\n## Context\n\nFive `HookEvent` variants exist in the enum and are documented in `docs/agents/hooks.mdx`, but `run_hooks()` is never called for them in the engine. Users can configure hooks for these events, but they silently never fire.\n\n**Events to wire up:** `StageRetrying`, `ParallelStart`, `ParallelComplete`\n**Events to mark as reserved:** `SandboxReady`, `SandboxCleanup` (sandbox lifecycle is managed outside the engine; wiring these requires significant architecture changes)\n\n## Changes\n\n### 1. Add StageRetrying hook calls in `engine.rs`\n\nFile: `lib/crates/fabro-workflows/src/engine.rs`\n\nTwo sites in `execute_with_retry`, both immediately after `WorkflowRunEvent::StageRetrying` emission and before `tokio::time::sleep(delay).await`:\n\n- **Site A (~line 1127):** error-retry path\n- **Site B (~line 1155):** explicit Retry status path\n\nPattern (same for both sites):\n```rust\n{\n let mut hook_ctx = HookContext::new(\n HookEvent::StageRetrying,\n context.run_id(),\n graph.name.clone(),\n );\n hook_ctx.node_id = Some(node.id.clone());\n hook_ctx.node_label = Some(node.label().to_string());\n hook_ctx.handler_type = node.handler_type().map(String::from);\n hook_ctx.attempt = Some(usize::try_from(attempt).unwrap_or(usize::MAX));\n hook_ctx.max_attempts = Some(\n usize::try_from(policy.max_attempts).unwrap_or(usize::MAX),\n );\n let _ = self.run_hooks(&hook_ctx, None).await;\n}\n```\n\nAvailable via: `self.run_hooks()` (engine method), `context.run_id()`, `graph.name`, `node`, `attempt`, `policy`.\n\n### 2. Add ParallelStart hook call in `parallel.rs`\n\nFile: `lib/crates/fabro-workflows/src/handler/parallel.rs`\n\nAfter `ParallelStarted` event emission (~line 301). Call `hook_runner.run()` directly since the handler has `services: &EngineServices` (which has `hook_runner` and `sandbox`):\n\n```rust\nif let Some(ref runner) = services.hook_runner {\n let hook_ctx = HookContext::new(\n HookEvent::ParallelStart,\n context.run_id(),\n graph.name.clone(),\n );\n let _ = runner\n .run(&hook_ctx, services.sandbox.clone(), None)\n .await;\n}\n```\n\n### 3. Add ParallelComplete hook call in `parallel.rs`\n\nSame file, after `ParallelCompleted` event emission (~line 713). Same pattern as ParallelStart but with `HookEvent::ParallelComplete`.\n\n### 4. Mark SandboxReady/SandboxCleanup as reserved\n\nFile: `lib/crates/fabro-workflows/src/hook/types.rs`\n\nAdd doc comments:\n```rust\n/// Reserved: hooks for this event are not yet invoked by the engine.\nSandboxReady,\n/// Reserved: hooks for this event are not yet invoked by the engine.\nSandboxCleanup,\n```\n\n### 5. Update docs\n\nFile: `docs/agents/hooks.mdx`\n\nIn the lifecycle events table, annotate `sandbox_ready` and `sandbox_cleanup` rows — e.g., append \"(not yet wired)\" to the description or add a note.\n\n## Verification\n\n1. `cargo fmt --check --all`\n2. `cargo clippy --workspace -- -D warnings`\n3. `cargo test --workspace` — existing tests pass, no regressions\n4. Manual test: create a workflow with a retrying node and a `post_tool_use`-style hook for `stage_retrying`, verify it fires in the CLI log\n\n\n## Completed stages\n- **toolchain**: success\n - Script: `command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1`\n - Stdout:\n ```\n cargo 1.94.0 (85eff7c80 2026-01-15)\n ```\n - Stderr: (empty)\n",
"graph.goal": "# Wire up missing hook invocations\n\n## Context\n\nFive `HookEvent` variants exist in the enum and are documented in `docs/agents/hooks.mdx`, but `run_hooks()` is never called for them in the engine. Users can configure hooks for these events, but they silently never fire.\n\n**Events to wire up:** `StageRetrying`, `ParallelStart`, `ParallelComplete`\n**Events to mark as reserved:** `SandboxReady`, `SandboxCleanup` (sandbox lifecycle is managed outside the engine; wiring these requires significant architecture changes)\n\n## Changes\n\n### 1. Add StageRetrying hook calls in `engine.rs`\n\nFile: `lib/crates/fabro-workflows/src/engine.rs`\n\nTwo sites in `execute_with_retry`, both immediately after `WorkflowRunEvent::StageRetrying` emission and before `tokio::time::sleep(delay).await`:\n\n- **Site A (~line 1127):** error-retry path\n- **Site B (~line 1155):** explicit Retry status path\n\nPattern (same for both sites):\n```rust\n{\n let mut hook_ctx = HookContext::new(\n HookEvent::StageRetrying,\n context.run_id(),\n graph.name.clone(),\n );\n hook_ctx.node_id = Some(node.id.clone());\n hook_ctx.node_label = Some(node.label().to_string());\n hook_ctx.handler_type = node.handler_type().map(String::from);\n hook_ctx.attempt = Some(usize::try_from(attempt).unwrap_or(usize::MAX));\n hook_ctx.max_attempts = Some(\n usize::try_from(policy.max_attempts).unwrap_or(usize::MAX),\n );\n let _ = self.run_hooks(&hook_ctx, None).await;\n}\n```\n\nAvailable via: `self.run_hooks()` (engine method), `context.run_id()`, `graph.name`, `node`, `attempt`, `policy`.\n\n### 2. Add ParallelStart hook call in `parallel.rs`\n\nFile: `lib/crates/fabro-workflows/src/handler/parallel.rs`\n\nAfter `ParallelStarted` event emission (~line 301). Call `hook_runner.run()` directly since the handler has `services: &EngineServices` (which has `hook_runner` and `sandbox`):\n\n```rust\nif let Some(ref runner) = services.hook_runner {\n let hook_ctx = HookContext::new(\n HookEvent::ParallelStart,\n context.run_id(),\n graph.name.clone(),\n );\n let _ = runner\n .run(&hook_ctx, services.sandbox.clone(), None)\n .await;\n}\n```\n\n### 3. Add ParallelComplete hook call in `parallel.rs`\n\nSame file, after `ParallelCompleted` event emission (~line 713). Same pattern as ParallelStart but with `HookEvent::ParallelComplete`.\n\n### 4. Mark SandboxReady/SandboxCleanup as reserved\n\nFile: `lib/crates/fabro-workflows/src/hook/types.rs`\n\nAdd doc comments:\n```rust\n/// Reserved: hooks for this event are not yet invoked by the engine.\nSandboxReady,\n/// Reserved: hooks for this event are not yet invoked by the engine.\nSandboxCleanup,\n```\n\n### 5. Update docs\n\nFile: `docs/agents/hooks.mdx`\n\nIn the lifecycle events table, annotate `sandbox_ready` and `sandbox_cleanup` rows — e.g., append \"(not yet wired)\" to the description or add a note.\n\n## Verification\n\n1. `cargo fmt --check --all`\n2. `cargo clippy --workspace -- -D warnings`\n3. `cargo test --workspace` — existing tests pass, no regressions\n4. Manual test: create a workflow with a retrying node and a `post_tool_use`-style hook for `stage_retrying`, verify it fires in the CLI log\n",
"failure_class": "",
"failure_signature": "",
"thread.toolchain.current_node": "preflight_compile",
"graph.model_stylesheet": "\n * { backend: api; model: claude-opus-4-6;}\n ",
"internal.fidelity": "compact",
"internal.retry_count.start": 1,
"internal.run_id": "01KKT5VGGG35Y853TNCTBVB39R",
"command.output": "cargo 1.94.0 (85eff7c80 2026-01-15)\n",
"current_node": "toolchain",
"command.output": "",
"current_node": "preflight_compile",
"command.stderr": "",
"internal.node_visit_count": 1,
"internal.thread_id": "start",
"internal.thread_id": "toolchain",
"graph.rankdir": "LR",
"outcome": "success",
"internal.retry_count.toolchain": 1,
"thread.start.current_node": "toolchain"
"thread.start.current_node": "toolchain",
"internal.retry_count.preflight_compile": 1
},
"logs": [],
"node_outcomes": {
@ -42,10 +46,20 @@
"start": {
"status": "success",
"duration_ms": 0
},
"preflight_compile": {
"status": "success",
"context_updates": {
"command.output": "",
"command.stderr": ""
},
"notes": "Script completed: cargo check -q --workspace 2>&1",
"duration_ms": 74054
}
},
"next_node_id": "preflight_compile",
"next_node_id": "preflight_lint",
"node_visits": {
"preflight_compile": 1,
"start": 1,
"toolchain": 1
}

View file

@ -0,0 +1,5 @@
{
"command": "cargo check -q --workspace 2>&1",
"language": "shell",
"timeout_ms": null
}

View file

@ -0,0 +1,5 @@
{
"duration_ms": 74053,
"exit_code": 0,
"timed_out": false
}

View file

@ -0,0 +1,6 @@
{
"status": "success",
"notes": "Script completed: cargo check -q --workspace 2>&1",
"failure_reason": null,
"timestamp": "2026-03-16T01:59:54.221688+00:00"
}