> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase20-session05-campaign-dag-recovery/spec.md).

# Session Specification

**Session ID**: `phase20-session05-campaign-dag-recovery` **Phase**: 20 - Orchestration Actionability Execution **Status**: Not Started **Created**: 2026-06-28 **Package**: null **Package Stack**: mixed TypeScript across `packages/protocol`, `apps/server`, and `apps/web`

***

## 1. Session Overview

This session upgrades campaign dispatch from a simple executable task loop into a dependency-aware serial scheduler. Approved campaign tasks should run only when their prerequisites have completed successfully, dependent tasks should hold or block when a required predecessor fails or is unavailable, and campaign state should reflect the actual execution graph instead of the presence of queue records.

It is next because Session 04 shipped executable campaign dispatch for terminal and Git payloads while explicitly deferring dependency graph scheduling. Sessions 02 and 03 already provide the queue terminal and Git execution paths, and Session 04 provides campaign task to queue to execution-run linkage. Session 05 should reuse those paths and add DAG recovery behavior in `PlanCampaignManager`.

The session keeps the MVP serial. It does not claim parallel campaign orchestration. The operator-facing result is a campaign graph that makes dependency order, failed or unavailable prerequisites, retryable tasks, and execution detail links visible without exposing raw commands, terminal output, Git output, diffs, broad paths, tokens, or provider payloads.

***

## 2. Objectives

1. Execute executable campaign tasks serially in dependency order so a task never dispatches before all required prerequisites complete.
2. Derive campaign and task states from actual DAG outcomes, including completed, in progress, blocked, failed, unavailable execution readiness, and planning-only tasks without false completion.
3. Implement retry behavior that resets and redispatches only failed or unavailable executable tasks while preserving previous queue and execution-run history.
4. Update campaign graph UI, copy, tests, docs, and browser evidence so operators can inspect dependency blocks, retry failed tasks, and follow execution detail links.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase20-session02-queue-terminal-execution` - Provides terminal executable queue dispatch, execution links, unavailable handling, and safe summaries.
* [x] `phase20-session03-queue-git-execution` - Provides Git executable queue dispatch, policy-blocked unavailable handling, and safe summaries.
* [x] `phase20-session04-campaign-executable-dispatch` - Provides campaign executable payload storage, queue linkage, coordinator dispatch, execution summaries, and campaign UI evidence.

### Required Tools Or Knowledge

* Node 26.2.0 and npm 11.16.0 from `.spec_system/CONVENTIONS.md`.
* Existing `PlanCampaignManager`, `TaskQueueManager`, `TaskExecutionCoordinator`, command-center route broadcasting, and web campaign graph helpers.
* Existing focused Vitest suites and Playwright command-center e2e suite.

### Environment Requirements

* Local repo checkout with npm workspaces installed.
* No hosted credentials, provider credentials, analytics, Worker proxy, remote execution, Docker runtime, or new native dependency is required.

***

## 4. Scope

### In Scope (MVP)

* Operators can dispatch approved campaigns with executable terminal or Git tasks in dependency order - Implement a serial scheduler that selects ready executable tasks only after prerequisites complete.
* Operators can see blocked dependents - Mark dependent tasks blocked or held when required prerequisites fail, are unavailable, are cancelled, or remain planning-only where execution is required.
* Operators can retry failed work - Reset only failed or unavailable executable tasks for retry, preserve previous run history, and avoid redispatching completed or planning-only tasks.
* Operators can inspect execution evidence - Keep queue ids, execution run ids, result summaries, and dependency labels visible in the campaign graph.
* Operators get truthful campaign state - Campaigns complete only when all dispatchable executable tasks complete and no required dependency remains failed, blocked, unavailable, or pending verification.

### Out Of Scope (Deferred)

* Parallel campaign orchestration - Reason: The PRD explicitly allows serial DAG execution and says not to claim concurrency until implemented and tested.
* New executor families beyond terminal and Git campaign tasks - Reason: Later Phase 20 sessions own file mutation, managed agent lifecycle, container posture, templates, and channel intake.
* Trusted automatic execution from channel or hosted input - Reason: Channel intake remains proposal-first and hosted/remote execution remains no-claim.
* New database, persistence, schema, or migration work - Reason: Current command-center state is manager-owned in local runtime memory.
* Broad raw execution detail in summaries, events, docs, or notifications - Reason: Sensitive command, output, diff, path, token, and provider detail remains scoped local detail only.

***

## 5. Technical Approach

### Architecture

Protocol remains the contract boundary for campaign/task state parsing, compact event entries, and blocked raw field rejection. The plan should not add a separate campaign execution model; it should keep using the Session 04 campaign task readiness and execution summary fields plus existing queue/execution-run records.

Server scheduling belongs in `PlanCampaignManager`, not in the route handler. The manager should normalize a campaign's tasks into a DAG, reject or block cycles and unknown dependency references, select ready executable tasks in stable serial order, dispatch each task through the existing queue and `TaskExecutionCoordinator`, then recalculate dependent and campaign state from the saved task outcomes. Dispatch and retry must keep idempotency keys stable enough to prevent duplicate triggers while allowing a later retry attempt to create a new execution run and leave the old run inspectable.

The web should render the graph in dependency-aware order and use product-facing labels for ready, waiting, completed, failed, unavailable, and retryable tasks. Campaign rows and broad events should remain compact. Scoped details are linked by queue and execution ids instead of copied into campaign rows.

### Design Patterns

* Protocol-first contracts: Shared state and compact event parsing changes land before server and web consumers.
* Manager-owned runtime boundaries: DAG scheduling, idempotency, task state transitions, and event changes stay in the campaign manager.
* Broad-summary plus scoped-detail split: Campaign rows show compact status and links, while queue/execution records own bounded detail.
* Existing coordinator reuse: Terminal and Git work continue through the shipped `TaskExecutionCoordinator` paths.

***

## 6. Deliverables

### Files To Create

| File                                                | Purpose                                                                                                          | Est. Lines |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/server/tests/planCampaignDagRecovery.test.ts` | Focused acceptance coverage for dependency order, blocked dependents, retry filtering, and previous run history. | \~320      |

### Files To Modify

| File                                                           | Changes                                                                                                                     | Est. Lines |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `packages/protocol/src/orchestrationCommandCenter.ts`          | Align campaign task parsing and compact event state semantics for DAG recovery without allowing raw execution fields.       | \~70       |
| `packages/protocol/tests/orchestrationCommandCenter.test.ts`   | Cover DAG task dependency fields, unavailable readiness, compact events, and blocked raw fields.                            | \~90       |
| `apps/server/src/managers/planCampaignManager.ts`              | Add serial DAG scheduling, dependency blocking, retry filtering, idempotent redispatch, and campaign state derivation.      | \~320      |
| `apps/server/src/routes/commandCenter.ts`                      | Ensure dispatch and retry responses broadcast campaign, task, queue, and execution changes produced by DAG recovery.        | \~40       |
| `apps/server/tests/planCampaignManager.test.ts`                | Update manager coverage for dependency order, cycle/unknown dependency blocking, partial failure, and retry behavior.       | \~180      |
| `apps/server/tests/commandCenterRoutes.test.ts`                | Prove REST and WebSocket campaign DAG dispatch, retry, safe events, and no raw payload leakage.                             | \~140      |
| `apps/web/src/lib/orchestrationApi.ts`                         | Validate any DAG recovery response fields and preserve execution links in campaign responses.                               | \~50       |
| `apps/web/src/lib/commandCenterUi.ts`                          | Sort campaign graph rows by dependency order and add labels for blocked, waiting, retryable, failed, and unavailable tasks. | \~130      |
| `apps/web/src/components/orchestration/CampaignWorkbench.tsx`  | Render dependency block, retry, queue, and execution evidence with product-facing copy and accessible controls.             | \~110      |
| `apps/web/src/components/orchestration/OrchestrationShell.tsx` | Update dispatch and retry toasts for DAG completion, blocked dependents, unavailable tasks, and retry outcomes.             | \~50       |
| `apps/web/tests/commandCenterUi.test.ts`                       | Cover dependency-aware graph ordering, labels, action availability, and privacy-safe output.                                | \~110      |
| `apps/web/tests/CommandCenterPanes.test.tsx`                   | Cover campaign graph retry and execution links without raw detail leakage.                                                  | \~110      |
| `apps/web/tests/orchestrationApi.test.ts`                      | Cover DAG response parsing and execution link preservation.                                                                 | \~60       |
| `apps/web/tests/OrchestrationPanel.test.tsx`                   | Cover shell dispatch/retry feedback and duplicate-trigger prevention.                                                       | \~70       |
| `tests/e2e/orchestration-command-center.e2e.ts`                | Add browser proof for blocked dependency inspection and retry of a failed campaign task.                                    | \~180      |
| `apps/server/README_server.md`                                 | Document campaign DAG dispatch, retry, and blocked dependency boundaries.                                                   | \~30       |
| `apps/web/README_web.md`                                       | Document campaign graph execution state, retry UI, and privacy boundary.                                                    | \~30       |
| `docs/api/README_api.md`                                       | Document campaign dispatch and retry response semantics for dependency-aware execution.                                     | \~40       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Task B cannot dispatch until required task A has completed successfully.
* [ ] Failed or unavailable executable tasks block dependent tasks and prevent false campaign completion.
* [ ] Retry resets and reruns only failed or unavailable executable tasks, not completed, planning-only, or dependency-held tasks.
* [ ] Previous queue rows and execution runs remain inspectable after retry creates new execution evidence.
* [ ] Campaign state, task state, execution readiness, queue links, and execution run links mirror the actual DAG result.

### Testing Requirements

* [ ] Protocol tests cover compact dependency and unavailable execution readiness parsing with raw field rejection.
* [ ] Server manager and route tests cover success, dependency ordering, cycle/unknown dependency blocking, failed/unavailable prerequisites, retry filtering, duplicate prevention, and safe events.
* [ ] Web unit/component/API tests cover dependency graph order, blocked labels, retry controls, execution links, loading/empty/error/offline states where applicable, and privacy-safe rendering.
* [ ] Playwright command-center desktop and mobile tests cover inspecting and retrying a failed campaign task without raw terminal or Git leakage.

### Non-Functional Requirements

* [ ] Serial scheduler remains deterministic by dependency order and stable task order.
* [ ] Broad campaign, queue, REST, WebSocket, docs, notification, and row summaries do not expose raw commands, stdout, stderr, diffs, patch bodies, commit messages, tokens, secrets, provider payloads, webhook raw bodies, or broad absolute paths.
* [ ] Existing queue terminal and Git dispatch behavior remains compatible.

### Quality Gates

* [ ] All files ASCII-encoded
* [ ] Unix LF line endings
* [ ] Code follows project conventions
* [ ] Primary user-facing surfaces contain product-facing copy only
* [ ] Focused protocol, server, web, Playwright, root quality, and `git diff --check` commands pass

***

## 8. Implementation Notes

### Working Assumptions

* Cross-package session scope is intentional: The analyzer reports `package: null`, the session stub lists `packages/protocol`, `apps/server`, and `apps/web`, and the behavior spans shared contracts, server scheduling, and browser UI. Planning can proceed with `Package: null` because all task paths are repo-root-relative and the affected packages are explicit.
* Previous execution history lives in queue and execution-run records: Session 04 already returns `queueEntries`, `executionLinks`, and `executionRuns`, and validation proved linked evidence. Retry can reset task readiness for redispatch while preserving old queue/execution records for history instead of copying raw detail onto campaign tasks.
* Serial DAG scheduling is the correct MVP: The session stub and PRD appendix explicitly allow serial execution and forbid claiming parallel orchestration before concurrency is implemented and tested.

### Conflict Resolutions

* The Session 05 stub says campaign state may be `unavailable`, while the detailed Phase 20 state requirements and current `CommandCenterPlanCampaignState` protocol values define campaign states as `in_progress`, `completed`, `blocked`, and `failed` for execution outcomes. The chosen interpretation is to use campaign `blocked` for unavailable executor outcomes while preserving `unavailable` on queue rows, execution summaries, and task execution readiness.
* Existing Session 04 tests allow campaign dispatch to iterate all executable tasks regardless of dependencies, while Session 05 requires a DAG. The chosen interpretation is to replace only the flat dispatch expectations that conflict with dependency order and preserve the Session 04 executable payload, queue linkage, and scoped detail behavior.

### Key Considerations

* \[P19] Executor claims are family-scoped: This session may run only the terminal and Git campaign executor families already proven by Sessions 02-04.
* \[P19] Scoped detail stays separate from broad rows: Campaign graph rows and events must show compact evidence only.
* \[P03-packages/protocol] Protocol leads cross-package work: Shared task and event semantics should change before server and web consumers.
* \[P19] Command-center state is manager-owned: Idempotency, revisions, event emission, and bounded snapshots stay in managers.
* \[P19] Channel intake is proposal-first: Retry and dispatch controls remain local operator actions, not automatic remote or webhook execution.

### Potential Challenges

* Dependency cycles can deadlock dispatch: Detect cycles or unresolved dependencies before execution and mark affected tasks blocked with compact reasons.
* Retry can accidentally rerun successful work: Filter retry candidates by failed or unavailable executable outcome and assert completed tasks keep their existing queue/execution links.
* Partial failure can overstate campaign completion: Derive campaign state after every dispatch from the full task set, not only from tasks touched in the current mutation.
* Raw payload leakage can enter broad surfaces through cloned queue entries: Keep executable payloads private and test public responses/events for blocked raw fields.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Duplicate campaign dispatch or retry while serial execution is in flight.
* Dependent tasks running after a failed, unavailable, cancelled, or planning-only prerequisite.
* Raw command, terminal output, Git output, diff, path, token, secret, provider payload, or webhook raw body leakage into campaign rows, events, tests, docs, or notifications.

***

## 9. Testing Strategy

### Unit Tests

* Protocol tests for campaign task dependency fields, unavailable readiness, compact event parsing, and blocked raw field rejection.
* Server manager tests for topological order, success path, unknown dependency, cycle detection, failed dependency block, unavailable dependency block, retry filtering, idempotency, and previous execution history.
* Web helper tests for dependency-aware row ordering, status labels, action availability, and safe fallback copy.

### Integration Tests

* Command-center route tests for campaign create -> approve -> DAG dispatch -> execution run -> campaign completed.
* Route and WebSocket tests for failed/unavailable prerequisite blocking, retry failed, response change emission, and safe public payloads.
* Web component/API tests for DAG response parsing, campaign graph rendering, retry controls, duplicate prevention, and execution links.

### Runtime Verification

* Playwright command-center desktop and mobile flow where the operator inspects a blocked dependent task, retries the failed or unavailable executable task, and sees execution evidence links without raw terminal or Git leakage.

### Edge Cases

* Task B depends on task A and task A fails.
* Task B depends on task A and task A is unavailable because the executor is unavailable or policy-blocked.
* Task depends on an unknown task id.
* Tasks form a dependency cycle.
* Campaign has only planning-only tasks.
* Retry is triggered with completed, planning-only, dependency-held, failed, and unavailable tasks present.
* Duplicate dispatch/retry idempotency keys are replayed without duplicate queue entries or execution runs.

***

## 10. Dependencies

### Other Sessions

* Depends on: `phase20-session02-queue-terminal-execution`, `phase20-session03-queue-git-execution`, `phase20-session04-campaign-executable-dispatch`
* Depended by: `phase20-session06-file-mutation-core`, `phase20-session07-file-executor-integration`, later Phase 20 execution slices

***

## Next Steps

Run the `implement` workflow step to begin implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase20-session05-campaign-dag-recovery/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
