---
title: "Implementation Plan: Per-Project Orchestrator Lifecycle Hooks (v1)"
description: "- [ ] Step 0: Create Cucumber BDD suite skeleton + failing AC scenarios first (`AC-01`..`AC-18`) - [ ] Step 1: Add hooks config schema + semantic validation in `ralph-core` - [ ] Step 2: Add `ralph hooks validate` CLI command (human + JSON output) - [ ] Step 3: Implement `HookExecutor` (JSON stdin, timeout, output truncation) - [ ] Step 4: Add hook telemetry logging and diagnostics integration - ["
type: skill
canonical_url: https://claudary.paisolsolutions.com/skills/plan-13
source: "Claudary"
difficulty: intermediate
author: "Claude Code Knowledge Pack"
date: 2026-07-10T11:32:01.859Z
license: CC-BY-4.0
attribution: "Implementation Plan: Per-Project Orchestrator Lifecycle Hooks (v1) — Claudary (https://claudary.paisolsolutions.com/skills/plan-13)"
---

# Implementation Plan: Per-Project Orchestrator Lifecycle Hooks (v1)
- [ ] Step 0: Create Cucumber BDD suite skeleton + failing AC scenarios first (`AC-01`..`AC-18`) - [ ] Step 1: Add hooks config schema + semantic validation in `ralph-core` - [ ] Step 2: Add `ralph hooks validate` CLI command (human + JSON output) - [ ] Step 3: Implement `HookExecutor` (JSON stdin, timeout, output truncation) - [ ] Step 4: Add hook telemetry logging and diagnostics integration - [

## Overview

# Implementation Plan: Per-Project Orchestrator Lifecycle Hooks (v1)

## Checklist

- [ ] Step 0: Create Cucumber BDD suite skeleton + failing AC scenarios first (`AC-01`..`AC-18`)
- [ ] Step 1: Add hooks config schema + semantic validation in `ralph-core`
- [ ] Step 2: Add `ralph hooks validate` CLI command (human + JSON output)
- [ ] Step 3: Implement `HookExecutor` (JSON stdin, timeout, output truncation)
- [ ] Step 4: Add hook telemetry logging and diagnostics integration
- [ ] Step 5: Implement `HookEngine` dispatch for `loop.start` + `iteration.start`
- [ ] Step 6: Implement `on_error` dispositions (`warn`, `block`) end-to-end
- [ ] Step 7: Implement suspend core (`wait_for_resume`) + `ralph loops resume <id>`
- [ ] Step 8: Add suspend modes `retry_backoff` and `wait_then_retry`
- [ ] Step 9: Add remaining lifecycle mappings (`plan.created`, `human.interact`, `loop.complete`, `loop.error`)
- [ ] Step 10: Add opt-in metadata mutation (JSON-only, metadata namespace only)
- [ ] Step 11: Integrate hooks validation into preflight + update docs/examples
- [ ] Step 12: Add mutation testing gates for hooks-critical modules
- [ ] Step 13: Drive BDD suite to green + finalize traceability matrix + CI gate

**Sequencing rule (TDD/BDD-first):** Step 0 is mandatory before implementation steps. Build code incrementally to satisfy failing BDD scenarios.

---

## Step 0: Create Cucumber BDD suite skeleton + failing AC scenarios first (`AC-01`..`AC-18`)

**Objective**
Establish a BDD-first baseline so implementation is explicitly driven by requirements.

**Subtasks**
- 0a. Draft `AC-01..AC-18` → scenario mapping table (initial traceability skeleton).
- 0b. Create hook feature files and scenario placeholders per AC.
- 0c. Wire minimal step definitions into the existing e2e harness.
- 0d. Run and record a CI-safe red baseline.

**Implementation Guidance**
- Create Cucumber feature files under `crates/ralph-e2e/features/hooks/`.
- Add scenario/scenario-outline placeholders for all AC IDs (`AC-01`..`AC-18`).
- Implement minimal step definitions to execute scenarios against the existing harness.
- Mark scenarios as expected-failing/red for capabilities not yet implemented.

**Test Requirements**
- BDD runner executes all hook feature scenarios.
- Scenario naming includes AC IDs for traceability.
- Red baseline is reproducible in CI-safe mode.

**Integration Notes**
- Keep fixtures deterministic and avoid network-dependent steps.
- Do not block on full implementation here; this is scaffolding + red baseline.

**Demo**
- Run BDD suite and show AC-labeled scenarios are discovered and currently failing for unimplemented behavior.

---

## Step 1: Add hooks config schema + semantic validation in `ralph-core`

**Objective**
Create first-class config types for hooks and enforce v1 guardrails at config-validation time.

**Implementation Guidance**
- Add `HooksConfig`, `HookDefaults`, `HookSpec`, and hook enums (phase-event keys, `on_error`, `suspend_mode`) in `crates/ralph-core/src/config.rs` (or a new hooks config module re-exported from config).
- Add `hooks` to `RalphConfig` with safe defaults (`enabled: false`).
- Add semantic validation:
  - valid phase-event names only
  - required `name` + `command`
  - positive `timeout_seconds` / `max_output_bytes`
  - mutation shape is opt-in and JSON-only contract
  - reject non-v1 fields (global scope, parallel execution options)
- Keep behavior inert (no runtime dispatch yet).

**Test Requirements**
- Add serde parse tests for valid/invalid hooks YAML.
- Add validation tests for enum errors, missing fields, invalid limits, and non-goal fields.
- Ensure existing config tests still pass.

**Integration Notes**
- Must not alter current runtime behavior when hooks are absent/disabled.
- Keep backward compatibility with existing configs that omit `hooks`.

**Demo**
- `cargo test -p ralph-core config` passes.
- A sample config with `hooks.enabled: true` parses and validates.

---

## Step 2: Add `ralph hooks validate` CLI command (human + JSON output)

**Objective**
Provide a dedicated pre-run validation surface for hook configuration and command wiring.

**Implementation Guidance**
- Add a new CLI namespace in `crates/ralph-cli/src/main.rs` (e.g., `Hooks(HooksArgs)`) with `validate` subcommand.
- Implement `crates/ralph-cli/src/hooks.rs` similar to existing preflight command patterns.
- Validation output modes:
  - human-readable summary
  - JSON report for automation
- Validation should include config semantics and command resolvability checks (without executing hook scripts).

**Test Requirements**
- CLI unit/integration tests for:
  - success case
  - malformed config case
  - unknown phase-event case
  - JSON output shape

**Integration Notes**
- Reuse existing config source loading (`preflight::load_config_for_preflight`) for consistent behavior.
- Keep exit codes deterministic (`0` pass, non-zero fail).

**Demo**
- `ralph hooks validate -c ralph.yml` returns PASS/FAIL with actionable diagnostics.

---

## Step 3: Implement `HookExecutor` (JSON stdin, timeout, output truncation)

**Objective**
Build the core execution primitive for one hook invocation with v1 safety guarantees.

**Subtasks**
- 3a. Implement process spawn + command/env/cwd resolution.
- 3b. Implement JSON payload stdin write path.
- 3c. Implement timeout enforcement and termination handling.
- 3d. Implement stdout/stderr capture with `max_output_bytes` truncation.
- 3e. Finalize `HookRunResult` model and conversion helpers.

**Implementation Guidance**
- Add a new module (e.g., `crates/ralph-core/src/hooks/executor.rs`).
- Execution behavior:
  - spawn command with configured cwd/env
  - write lifecycle payload JSON to stdin
  - enforce timeout
  - capture stdout/stderr
  - truncate each stream to `max_output_bytes`
- Return structured `HookRunResult` with:
  - start/end timestamps
  - duration
  - exit code
  - timed_out flag
  - truncated stdout/stderr

**Test Requirements**
- Unit tests with fixture scripts for:
  - successful run
  - non-zero exit
  - timeout
  - oversized stdout/stderr truncation
  - stdin payload delivered

**Integration Notes**
- Keep executor pure and reusable by CLI validation and runtime dispatch.
- No lifecycle wiring yet.

**Demo**
- Executor tests show expected timeout and truncation behavior deterministically.

---

## Step 4: Add hook telemetry logging and diagnostics integration

**Objective**
Persist required hook observability data for each invocation.

**Implementation Guidance**
- Add hook telemetry log model and writer (new diagnostics file, e.g., `hook-runs.jsonl`, or extend orchestration event with hook entries).
- Required fields:
  - phase-event
  - hook name
  - start/end/duration
  - exit code
  - timeout flag
  - stdout/stderr (truncated)
  - disposition
- Ensure telemetry logging works regardless of pass/fail/suspend outcomes.

**Test Requirements**
- Serialization tests for telemetry entries.
- Diagnostics integration tests verifying file creation and required fields.

**Integration Notes**
- Respect `RALPH_DIAGNOSTICS` behavior and existing diagnostics conventions.

**Demo**
- Run with diagnostics enabled and confirm hook run entries are persisted in structured JSONL.

---

## Step 5: Implement `HookEngine` dispatch for `loop.start` + `iteration.start`

**Objective**
Ship first end-to-end lifecycle hook dispatch path with deterministic sequencing.

**Subtasks**
- 5a. Build hook resolver for phase-event lookup + declaration-order sequencing.
- 5b. Implement payload builder for loop/iteration context.
- 5c. Wire `pre/post.loop.start` dispatch boundaries.
- 5d. Wire `pre/post.iteration.start` dispatch boundaries.
- 5e. Add disabled/empty-config fast-path (no-op dispatch).

**Implementation Guidance**
- Add `HookEngine` orchestrator module to resolve configured hooks by phase-event.
- Wire dispatch into runtime boundaries:
  - `pre.loop.start` / `post.loop.start`
  - `pre.iteration.start` / `post.iteration.start`
- Build payload with context fields (`active_hat`, `selected_hat`, `selected_task`, loop IDs, iteration data).
- Execute hooks sequentially in declaration order.

**Test Requirements**
- Integration tests validating exact dispatch order and event-phase selection.
- Validate no dispatch occurs when hooks disabled.

**Integration Notes**
- Keep behavior additive; no blocking policy yet beyond telemetry collection.

**Demo**
- Configure simple echo hooks for loop/iteration events and observe ordered invocations + telemetry.

---

## Step 6: Implement `on_error` dispositions (`warn`, `block`) end-to-end

**Objective**
Enable policy outcomes from hook failures without suspend complexity yet.

**Implementation Guidance**
- Implement disposition resolver:
  - `warn`: continue
  - `block`: fail lifecycle action with clear user-facing reason
- Add consistent error messages in CLI output and diagnostics.
- Ensure block behavior is deterministic and non-ambiguous per phase.

**Test Requirements**
- Integration tests for warn-vs-block behavior at both loop.start and iteration.start phases.
- Verify blocked runs terminate with expected reason/exit behavior.

**Integration Notes**
- `block` should not leave partial internal state transitions for the current boundary.

**Demo**
- A failing hook with `on_error: warn` continues; with `on_error: block` stops with explicit reason.

---

## Step 7: Implement suspend core (`wait_for_resume`) + `ralph loops resume <id>`

**Objective**
Deliver operator-controlled suspension with durable state and explicit CLI resume.

**Subtasks**
- 7a. Define suspend-state schema and atomic file I/O (`suspend-state`, `resume-requested`).
- 7b. Implement runtime suspended-wait state machine with signal precedence.
- 7c. Add `ralph loops resume <id>` CLI plumbing and loop resolution.
- 7d. Add idempotency and invalid-state behavior for resume operations.
- 7e. Add end-to-end suspend → resume → continue tests.

**Implementation Guidance**
- Add suspension persistence:
  - `.ralph/suspend-state.json`
  - `.ralph/resume-requested`
- On `on_error: suspend` (default mode), enter suspended state and wait for resume/stop/restart signals.
- Add `Resume` subcommand to `crates/ralph-cli/src/loops.rs`:
  - `ralph loops resume <id>`
  - resolve loop via existing `resolve_loop`
  - validate suspended state
  - write resume signal atomically
  - idempotent no-op messaging when already resumed/not suspended

**Test Requirements**
- Unit tests for suspend state transitions and signal precedence.
- CLI tests for `loops resume` success, missing loop, non-suspended loop, idempotent retry.
- Integration test for suspend -> resume -> continue path.

**Integration Notes**
- Preserve precedence: stop/restart should outrank resume while suspended.

**Demo**
- Run with a suspending hook, observe paused state, then `ralph loops resume <id>` unblocks run.

---

## Step 8: Add suspend modes `retry_backoff` and `wait_then_retry`

**Objective**
Complete suspend behavior options required by design with bounded retry semantics.

**Subtasks**
- 8a. Implement bounded `retry_backoff` policy (schedule, cap, termination condition).
- 8b. Implement `wait_then_retry` flow (resume gate + single retry behavior).
- 8c. Add retry attempt metadata/telemetry fields.
- 8d. Build deterministic timing/test harness for retry behavior.

**Implementation Guidance**
- Add bounded backoff policy for `retry_backoff`.
- Add `wait_then_retry` flow:
  - wait for resume
  - retry hook once
  - apply disposition based on retry result
- Include metadata/telemetry to indicate mode and retry attempt counts.

**Test Requirements**
- Integration tests for both modes, including exhausted retries and mixed outcomes.

**Integration Notes**
- Keep backoff bounded and deterministic for test reliability.

**Demo**
- Show a failing hook recovering under `retry_backoff`, and a manual release under `wait_then_retry`.

---

## Step 9: Add remaining lifecycle mappings (`plan.created`, `human.interact`, `loop.complete`, `loop.error`)

**Objective**
Reach full mandatory v1 lifecycle coverage.

**Subtasks**
- 9a. Add `pre/post.plan.created` dispatch wiring.
- 9b. Add `pre/post.human.interact` dispatch wiring.
- 9c. Add `pre/post.loop.complete` dispatch wiring.
- 9d. Add `pre/post.loop.error` dispatch wiring.
- 9e. Add explicit success/error termination mapping tests.

**Implementation Guidance**
- Add dispatch points for:
  - `pre/post.plan.created` (derived from plan-topic publications)
  - `pre/post.human.interact`
  - `pre/post.loop.complete`
  - `pre/post.loop.error`
- Ensure `loop.complete` vs `loop.error` mapping follows termination reason success semantics.

**Test Requirements**
- Integration tests for all added event-phase mappings.
- Explicit tests proving no backpressure event hooks are required/included in v1.

**Integration Notes**
- Keep plan-created derivation explicit and documented to avoid hidden behavior.

**Demo**
- End-to-end run showing hook invocations across all mandatory v1 lifecycle events.

---

## Step 10: Add opt-in metadata mutation (JSON-only, metadata namespace only)

**Objective**
Enable safe, explicit v1 mutation surface without touching prompt/events/config.

**Implementation Guidance**
- Parse hook stdout JSON only when `mutate.enabled: true`.
- Accept only `{"metadata": {...}}` contract.
- Merge into reserved namespace (e.g., `hook_metadata.<hook_name>`).
- Surface parse/schema errors through disposition policy.

**Test Requirements**
- Unit tests for opt-in gating, valid merge, invalid JSON, invalid shape.
- Integration tests proving no mutation occurs when disabled.

**Integration Notes**
- Prevent key collisions by namespacing metadata per hook.

**Demo**
- Hook emits metadata; subsequent iteration payload includes namespaced injected metadata.

---

## Step 11: Integrate hooks validation into preflight + update docs/examples

**Objective**
Make hooks validation part of normal run safety and provide clear user guidance.

**Implementation Guidance**
- Add hooks check to `PreflightRunner::default_checks()`.
- Respect preflight skip/strict behavior.
- Update docs for:
  - hooks config schema
  - lifecycle phases
  - `ralph hooks validate`
  - `ralph loops resume <id>`
- Add one minimal sample config + script examples.

**Test Requirements**
- Preflight tests verifying hooks check pass/fail and skip behavior.
- CLI docs/command help snapshot tests where applicable.

**Integration Notes**
- Keep docs aligned with v1 non-goals to avoid over-promising.

**Demo**
- `ralph preflight` fails on broken hooks config and passes after fixes.

---

## Step 12: Add mutation testing gates for hooks-critical modules

**Objective**
Increase defect resistance by enforcing mutation quality on the new hooks runtime surfaces.

**Subtasks**
- 12a. Select mutation tooling + baseline command for this repo.
- 12b. Scope mutation targets to hooks-critical modules only.
- 12c. Run baseline mutation report and calibrate threshold

---

Source: [Claudary](https://claudary.paisolsolutions.com/skills/plan-13) · https://claudary.paisolsolutions.com
