# Workflow Object Model Audit (CP-6 Phase 1)

Generated: 2026-04-28T09:10:06Z
Predecessor: post-cp5-entry-point-unification
Rollback: pre-cp6-workflow-object-model

## What CP-6 introduces

- `pipeline/core/workflow.py` — `WorkflowStep` + `Workflow` dataclasses, linear executor, hook points.
- One Phase 5 deliverable: test-only POC for keyframe→video Workflow (rescoped from production_loop.py migration after spec-review confirmed dispatches are in separate methods, not a sequential pair).
- JSON serialization: `Workflow.to_dict()` / `from_dict()`.
- No persistence in CP-6 — round-trip API only.
- No DIRECTOR step subtypes (CinematographyStep / StoryBeatStep / ShotConfigStep / ExpressionPoseStep deferred to CP-7+).

## Dispatch site inventory

```
Total dispatch sites in production code: 37
```

Full machine-readable list: `consultations/recoil/cp6-workflow-spec/cp6_phase1_dispatch_sites.json`.

## Migration candidate analysis

```
Recommended Phase 5 migration: pipeline/orchestrator/production_loop.py
Fallback: pipeline/orchestrator/pipeline.py
Rejected (out of scope or wrong shape):
  - pipeline/cli/generate.py — coverage-pass semantics, defer to CP-7
  - pipeline/tools/dispatch_cli.py — CLI per-invocation, not a workflow
  - pipeline/tools/test_via_steprunner.py — back-compat shim
```

Full machine-readable list: `consultations/recoil/cp6-workflow-spec/cp6_phase1_workflow_candidates.json`.

## Frozen contracts (do not touch in CP-6)

- `recoil/pipeline/core/dispatch.py` byte-stable
- `recoil/pipeline/core/receipts.py` byte-stable
- `recoil/pipeline/core/dispatch_context.py` byte-stable
- `recoil/pipeline/core/registry.py` byte-stable
- `recoil/execution/step_runner.py` byte-stable
- `recoil/execution/step_types.py` byte-stable
- All provider adapters byte-stable
- Sidecar `provenance.prompt` byte-stability (CP-3 lock)

## Tag verification

```
Parent post-cp5: f7ca2582f62f135427d60e3431273197d7aa4f36
Parent pre-cp6:  72cd9a98c51d7c66a92b10388d9445b9b04b6427
EM     post-cp5: 0f3893b24fdf75beb25212f2065792bddff118e6
EM     pre-cp6:  0f3893b24fdf75beb25212f2065792bddff118e6
```

## CP-6 phase plan

1. Phase 1: Audit + Tag (this doc)
2. Phase 2: WorkflowStep + Workflow + serialization
3. Phase 3: Linear executor + hook points
4. Phase 4: dispatch() integration
5. Phase 5: Standalone integration POC (test-only)
6. Phase 6: Workflow tests with real dispatch
7. Phase 7: Documentation
8. Phase 8: VERIFICATION DAY (HARD GATE)

---

## Post-CP-6 summary

CP-6 landed 2026-04-28. Net deliverables:

- New module: `recoil/pipeline/core/workflow.py` (~411 lines after Phase 4 quality pass)
  - `WorkflowStep` dataclass: 10 fields (step_id, modality, payload, depends_on, status, receipt, error, started_us, finished_us)
  - `Workflow` dataclass: workflow_id, steps, global_provenance, created_at
  - `StepStatus` Literal: pending | running | succeeded | failed | skipped
  - `Workflow.run` linear executor with DAG validation, dependency cascade skip, microsecond timestamps
  - `WorkflowValidationError` (raises on empty workflow / missing dep / self-dep / forward-ref / cycle)
  - Hook contract: pre_step / post_step / on_failure (synchronous, raise-propagates)
  - `_run_step_via_dispatch` integrates with `pipeline.core.dispatch.dispatch()`, merging provenance: `global_provenance < caller overrides < {workflow_id, workflow_step_id}` (workflow identity wins last)
  - Per-step DispatchContext built via `dataclasses.replace` (frozen-invariant preserved, validation re-runs)
  - JSON round-trip: `to_dict` / `from_dict` (executed workflows round-trip with all receipts intact)

- Five new test files in `recoil/pipeline/core/tests/`:
  - `test_workflow.py` (15 tests — dataclass construction + validation)
  - `test_workflow_serialization.py` (8 tests — round-trip)
  - `test_workflow_executor.py` (17 tests — DAG validation + status transitions + hooks, monkey-patched dispatch seam)
  - `test_workflow_dispatch_integration.py` (11 tests — real dispatch + stub StepRunner + executed-workflow round-trip)
  - `test_workflow_e2e_scenarios.py` (6 tests — production-shaped end-to-end)
  - `test_workflow_keyframe_video_poc.py` (4 tests — Phase 5 standalone POC)
  - **Total: 61 new tests, all passing.**

- `pipeline/core/__init__.py` re-exports `Workflow` and `WorkflowStep` into the public surface.

### What CP-6 deliberately did NOT migrate

- **No production-callsite migration.** Phase 5 was rescoped from migrating `production_loop.py` to a test-only POC after spec-review verified production_loop's keyframe and video dispatches are in separate methods called from separate orchestrator-loop iterations (NOT a sequential pair). CP-7+ will land the production migration when Take semantics are designed.
- **R2V / multi-shot bypass paths** (`runner.execute_pass()`, `runner.execute_wan_r2v()`, `runner.execute_multi_shot()`) — deferred per loraverse SYNTHESIS § Out of scope.
- **DIRECTOR step subtypes** (`CinematographyStep`, `StoryBeatStep`, `ShotConfigStep`, `ExpressionPoseStep`) — out of scope per JT brief; deferred to CP-7+ when Take/Beat/Scene exist.
- **No persistence layer** — only `to_dict` / `from_dict`. CP-7 may add disk persistence.
- **No async / parallel execution** — single-shot serial today; CP-7+ if production volume justifies.

### Frozen contracts preserved

All CP-5 frozen contracts byte-stable through CP-6:
- `pipeline/core/dispatch.py` (0 diff vs `pre-cp6-workflow-object-model`)
- `pipeline/core/receipts.py` (0 diff)
- `pipeline/core/dispatch_context.py` (0 diff)
- `pipeline/core/registry.py` (0 diff)
- `execution/step_runner.py` (0 diff)
- `execution/step_types.py` (0 diff)

Engine-memory subrepo: 0 diff vs `pre-cp6-workflow-object-model`.

### Rollback procedure

```bash
git checkout pre-cp6-workflow-object-model -- recoil/pipeline/core/workflow.py
git checkout pre-cp6-workflow-object-model -- recoil/pipeline/core/__init__.py
git rm recoil/pipeline/core/tests/test_workflow.py \
       recoil/pipeline/core/tests/test_workflow_serialization.py \
       recoil/pipeline/core/tests/test_workflow_executor.py \
       recoil/pipeline/core/tests/test_workflow_dispatch_integration.py \
       recoil/pipeline/core/tests/test_workflow_e2e_scenarios.py \
       recoil/pipeline/core/tests/test_workflow_keyframe_video_poc.py
```

### CP-7 entry conditions

- `post-cp6-workflow-object-model` tag will be placed in Phase 8 on parent + engine-memory.
- CP-6 hand-off doc: `consultations/recoil/cp6-workflow-spec/CP7_HANDOFF.md` (Phase 8).
- CP-7 work surface: Take/Beat/Scene data model wrapping WorkflowStep.receipt; production-callsite migration; Workflow persistence; deferred R2V/multi-shot bypass migration.
