> 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/phase19-session04-campaign-workbench/implementation-notes.md).

# Implementation Notes

**Session ID**: `phase19-session04-campaign-workbench` **Package**: cross-cutting (`apps/server`, `apps/web`, `packages/protocol`) **Started**: 2026-06-26 04:16 **Last Updated**: 2026-06-26 04:45

***

## Session Progress

| Metric              | Value     |
| ------------------- | --------- |
| Tasks Completed     | 20 / 20   |
| Estimated Remaining | 3-4 hours |
| Blockers            | 0         |

***

### Task T020 - Run focused checks and encoding validation

**Started**: 2026-06-26 04:43 **Completed**: 2026-06-26 04:45 **Duration**: 2 minutes

**Notes**:

* Ran source formatting on touched source/test files, then reran server and web typechecks plus focused tests.
* Ran lint, format check, diff whitespace, and ASCII/LF validation across touched files.

**Files Changed**:

* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded final verification evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T020 complete after evidence was recorded.

**Verification**:

* Command/check: `npx biome format --write <touched source and test files>`
  * Result: PASS - Biome formatted 22 files and fixed 9 files.
  * Evidence: Command exited 0.
* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server `tsc --noEmit` exited 0.
  * Evidence: Command exited 0 after formatting.
* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web `tsc -b --noEmit` exited 0.
  * Evidence: Command exited 0 after formatting.
* Command/check: `npm test -- apps/server/tests/planCampaignManager.test.ts apps/server/tests/commandCenterRoutes.test.ts apps/web/tests/orchestrationApi.test.ts apps/web/tests/commandCenterUi.test.ts apps/web/tests/commandCenterStore.test.ts apps/web/tests/OrchestrationPanel.test.tsx`
  * Result: PASS - 6 focused test files passed.
  * Evidence: 38/38 tests passed.
* Command/check: `npm run lint`
  * Result: PASS - Biome lint checked 668 files with no fixes.
  * Evidence: Command exited 0.
* Command/check: `npm run format:check`
  * Result: PASS - Biome format checked 666 files with no fixes.
  * Evidence: Command exited 0.
* Command/check: `git diff --check -- <touched files>`
  * Result: PASS - No whitespace errors printed.
  * Evidence: Command exited 0.
* Command/check: `for f in <touched files>; do LC_ALL=C grep -n '[^[:print:][:space:]]' "$f" && exit 1; grep -q $'\r' "$f" && printf 'CRLF %s\n' "$f" && exit 1; done; printf 'ASCII_LF_OK\n'`
  * Result: PASS - All checked files are ASCII/LF clean.
  * Evidence: Command printed `ASCII_LF_OK`.
* UI product-surface check: PASS - Focused component test covers workbench rendering and diagnostic-term absence.
* UI craft check: PASS - Focused component test reaches controls by accessible roles/names; typecheck and lint passed after formatting.

**BQC Fixes**:

* N/A - final verification only.

***

### Task T019 - Extend web API, store, UI helper, and component tests

**Started**: 2026-06-26 04:39 **Completed**: 2026-06-26 04:43 **Duration**: 4 minutes

**Notes**:

* Extended web API tests for campaign preview/dispatch and queue mutation stale-revision/invalid-reference handling.
* Extended UI helper tests for campaign graph rows and action availability.
* Extended store tests for queue mutation key cleanup.
* Extended component tests for campaign/queue workbench controls, preview/dispatch/create handlers, and bounded product-facing copy.

**Files Changed**:

* `apps/web/tests/orchestrationApi.test.ts` - added campaign and queue API helper coverage.
* `apps/web/tests/commandCenterUi.test.ts` - added graph and action availability coverage.
* `apps/web/tests/commandCenterStore.test.ts` - added queue event mutation cleanup coverage.
* `apps/web/tests/OrchestrationPanel.test.tsx` - added workbench component coverage and new API mocks.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T019 complete after evidence was recorded.

**Verification**:

* Command/check: `npm test -- apps/web/tests/orchestrationApi.test.ts apps/web/tests/commandCenterUi.test.ts apps/web/tests/commandCenterStore.test.ts apps/web/tests/OrchestrationPanel.test.tsx`
  * Result: PASS - 4 web test files passed.
  * Evidence: Web focused run passed 31/31 tests.
* UI product-surface check: PASS - Component test asserts workbench controls render and diagnostic terms `debug`, `shell ready`, and `data-source` are absent.
* UI craft check: PASS - Component test verifies native workbench buttons are reachable through the rendered campaign/queue regions.

**BQC Fixes**:

* Duplicate action prevention: Store and component tests cover in-flight mutation cleanup and action wiring.
* Accessibility and platform compliance: Component tests locate controls by role and accessible names.

***

### Task T018 - Extend server route tests

**Started**: 2026-06-26 04:39 **Completed**: 2026-06-26 04:43 **Duration**: 4 minutes

**Notes**:

* Extended command-center REST route tests with campaign preview, create, stale transition conflict, approval, dispatch, `/api` aliases, WebSocket plan/task/queue emissions, compact validation errors, and queue bridge snapshot checks.

**Files Changed**:

* `apps/server/tests/commandCenterRoutes.test.ts` - added campaign workbench route coverage.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T018 complete after evidence was recorded.

**Verification**:

* Command/check: `npm test -- apps/server/tests/planCampaignManager.test.ts apps/server/tests/commandCenterRoutes.test.ts`
  * Result: PASS - 2 server test files passed.
  * Evidence: `apps/server/tests/commandCenterRoutes.test.ts` passed 4/4 tests; focused server run passed 7/7 total tests.
* UI product-surface check: N/A - server route tests only.
* UI craft check: N/A - server route tests only.

**BQC Fixes**:

* Trust boundary enforcement: Route tests assert raw blocked payload fields return compact validation errors without echoing secret-like values.
* Contract alignment: Route tests assert command-center and task-queue WebSocket event families are emitted for campaign dispatch.

***

### Task T017 - Write server manager tests

**Started**: 2026-06-26 04:38 **Completed**: 2026-06-26 04:43 **Duration**: 5 minutes

**Notes**:

* Added focused manager tests for campaign preview/create idempotency, stale revisions, state transitions, dispatch queue bridging, and duplicate dispatch replay.

**Files Changed**:

* `apps/server/tests/planCampaignManager.test.ts` - new focused campaign manager tests.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T017 complete after evidence was recorded.

**Verification**:

* Command/check: `npm test -- apps/server/tests/planCampaignManager.test.ts apps/server/tests/commandCenterRoutes.test.ts`
  * Result: PASS - 2 server test files passed.
  * Evidence: `apps/server/tests/planCampaignManager.test.ts` passed 3/3 tests; focused server run passed 7/7 total tests.
* UI product-surface check: N/A - server manager tests only.
* UI craft check: N/A - server manager tests only.

**BQC Fixes**:

* Contract alignment: Tests assert queue bridge entries use `source: "plan"` and do not mark executor work completed.

***

### Task T016 - Wire OrchestrationShell action handlers

**Started**: 2026-06-26 04:35 **Completed**: 2026-06-26 04:37 **Duration**: 2 minutes

**Notes**:

* Added shell handlers for campaign preview, create, approve, pause, resume, cancel, refine, retry failed, dispatch, and queue create/update/reject/restore/unavailable/dispatch.
* Handlers use scoped mutation keys, bounded toasts, existing error-copy mapping, and refresh queue/command-center snapshots after accepted mutations.
* Cleanup is handled in `finally`, so offline, timeout, duplicate-trigger, stale-revision, and refresh-failure paths do not leave buttons stuck.

**Files Changed**:

* `apps/web/src/components/orchestration/OrchestrationShell.tsx` - added workbench action handlers, refresh helpers, mutation wrapper, toasts, and tab props.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T016 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: Workbench callbacks, API calls, refresh paths, and shell props compile.
* Command/check: static inspection of `apps/web/src/components/orchestration/OrchestrationShell.tsx`
  * Result: PASS - Handlers pass expected revisions, idempotency keys, mutation keys, and refresh snapshots after accepted changes.
  * Evidence: `withWorkbenchMutation` clears in-flight keys in `finally` and reports bounded failure toasts.
* UI product-surface check: PASS - Toast text is bounded local campaign/queue copy and does not expose raw command data.
* UI craft check: PASS - Action disabled state is wired through existing in-flight and connection state.

**BQC Fixes**:

* Resource cleanup: Workbench mutation keys are cleared in `finally` for every handler path.
* Failure path completeness: Failures are routed through `reportMutationFailure` with visible toasts and command-center error state.

***

### Task T015 - Add mutation state cleanup for campaign and queue actions

**Started**: 2026-06-26 04:35 **Completed**: 2026-06-26 04:37 **Duration**: 2 minutes

**Notes**:

* Reused command-center in-flight mutation keys for campaign and queue workbench actions.
* Added queue event cleanup so accepted `task_queue_update` events clear scoped queue action keys.
* Shell handlers also clear keys in `finally` to cover rejected, offline, timeout, or refresh-failure paths.

**Files Changed**:

* `apps/web/src/store/useGameStore.ts` - clears scoped queue mutation keys on queue update events.
* `apps/web/src/components/orchestration/OrchestrationShell.tsx` - uses begin/clear command-center mutation helpers for campaign and queue actions.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T015 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: Store and shell mutation cleanup changes compile.
* Command/check: static inspection of `apps/web/src/store/useGameStore.ts`
  * Result: PASS - Queue updates clear keys matching the changed queue entry id.
  * Evidence: `task_queue_update` now applies `clearCommandCenterMutationKeysForChange` to `e.change.entryId`.
* UI product-surface check: N/A - store cleanup only.
* UI craft check: N/A - store cleanup only.

**BQC Fixes**:

* Duplicate action prevention: Queue and campaign controls share store-level in-flight state in addition to API helper in-flight guards.
* State freshness on re-entry: Accepted queue events and manual refreshes clear stale selected queue entries and scoped mutation state.

***

### Task T014 - Replace generic campaign pane rendering

**Started**: 2026-06-26 04:34 **Completed**: 2026-06-26 04:37 **Duration**: 3 minutes

**Notes**:

* Replaced the generic campaigns tab body with `CampaignWorkbench`, `QueueWorkbench`, and a compact related-record grid.
* Threaded connection state, in-flight keys, local queue entries, heroes, missions, and action callbacks through `OrchestrationTabs`.

**Files Changed**:

* `apps/web/src/components/orchestration/CommandCenterPanes.tsx` - composed campaign and queue workbenches in the campaigns tab.
* `apps/web/src/components/orchestration/OrchestrationTabs.tsx` - passed workbench dependencies and callbacks to panes.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T014 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: Campaign pane composition and tab props compile.
* Command/check: static inspection of `apps/web/src/components/orchestration/CommandCenterPanes.tsx`
  * Result: PASS - Campaign tab now renders workbench controls and keeps related command-center records scoped below them.
  * Evidence: Existing non-campaign tabs retain generic `PaneGrid` behavior.
* UI product-surface check: PASS - Campaigns tab now shows actionable local workbench controls instead of a generic record list.
* UI craft check: PASS - Workbench composition preserves existing dense panel rhythm and avoids nested page-level cards.

**BQC Fixes**:

* Contract alignment: The pane receives queue and command-center records from the existing store without adding duplicate UI state sources.

***

### Task T013 - Create QueueWorkbench

**Started**: 2026-06-26 04:33 **Completed**: 2026-06-26 04:37 **Duration**: 4 minutes

**Notes**:

* Added `QueueWorkbench` with create, update complete, reject, restore, mark unavailable, and dispatch controls.
* Queue actions use scoped in-flight keys and require reasons for reject/unavailable actions.

**Files Changed**:

* `apps/web/src/components/orchestration/QueueWorkbench.tsx` - new queue workbench component.
* `apps/web/src/components/orchestration/index.ts` - exported the new component.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T013 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: Queue workbench props and callbacks compile through the orchestration shell.
* Command/check: static inspection of `apps/web/src/components/orchestration/QueueWorkbench.tsx`
  * Result: PASS - Queue controls are native, accessible, and duplicate-aware.
  * Evidence: Buttons disable on disconnected state, in-flight action keys, invalid current states, and missing reject/unavailable reasons.
* UI product-surface check: PASS - Component copy stays on local queue state and bounded reasons; no raw commands or diagnostics are displayed.
* UI craft check: PASS - Uses compact rows, status pills, stable touch-target buttons, and focus-visible outlines.

**BQC Fixes**:

* Failure path completeness: Reject/unavailable actions cannot submit without a visible reason value.
* Duplicate action prevention: Buttons use queue action in-flight keys before enabling mutations.

***

### Task T012 - Create CampaignWorkbench

**Started**: 2026-06-26 04:31 **Completed**: 2026-06-26 04:37 **Duration**: 6 minutes

**Notes**:

* Added `CampaignWorkbench` with manual campaign intake, preview/create actions, campaign state controls, retry/dispatch controls, graph rows, and per-task expected-result refinement.
* Controls are native buttons, inputs, and textareas with accessible names and disabled states derived from connection and in-flight mutation state.

**Files Changed**:

* `apps/web/src/components/orchestration/CampaignWorkbench.tsx` - new campaign workbench component.
* `apps/web/src/components/orchestration/index.ts` - exported the new component.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T012 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: Campaign workbench props and callbacks compile through `CommandCenterPanes`, `OrchestrationTabs`, and `OrchestrationShell`.
* Command/check: static inspection of `apps/web/src/components/orchestration/CampaignWorkbench.tsx`
  * Result: PASS - Runtime surface uses bounded summaries, revision labels, state pills, and accessible controls.
  * Evidence: No debug/runtime/scaffolding copy is present in the component.
* UI product-surface check: PASS - Component copy is product-facing local campaign/queue workbench copy; no implementation diagnostics are shown.
* UI craft check: PASS - Uses existing `PanelSection`, `StatusPill`, focus-visible outlines, stable button sizing, and responsive grid patterns.

**BQC Fixes**:

* Accessibility and platform compliance: Controls use native inputs/buttons with `aria-label` where visible text is not enough.
* Duplicate action prevention: Buttons read scoped in-flight keys before enabling campaign actions.

***

### Task T011 - Add campaign graph and action availability helpers

**Started**: 2026-06-26 04:29 **Completed**: 2026-06-26 04:37 **Duration**: 8 minutes

**Notes**:

* Added campaign graph row normalization, campaign state copy, campaign action availability, and queue action availability helpers.
* Helpers use safe command-center labels and existing tone/status vocabulary to keep rows bounded and product-facing.

**Files Changed**:

* `apps/web/src/lib/commandCenterUi.ts` - added graph row and action availability helpers.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T011 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: New helper exports compile against workbench component usage.
* Command/check: static inspection of `apps/web/src/lib/commandCenterUi.ts`
  * Result: PASS - Helpers call safe label/redaction utilities and avoid raw payload display.
  * Evidence: Graph rows use `safeCommandCenterLabel`, `shortCommandCenterId`, and state/tone helpers.
* UI product-surface check: N/A - helper only.
* UI craft check: N/A - helper only.

**BQC Fixes**:

* Contract alignment: Helpers accept both full snapshot records and compact event records for campaigns, tasks, and queue entries.

***

### Task T010 - Add web API helpers for campaign and queue mutations

**Started**: 2026-06-26 04:26 **Completed**: 2026-06-26 04:37 **Duration**: 11 minutes

**Notes**:

* Added web API helpers for campaign preview, create, transition, refine, retry failed, dispatch, and queue create/update/reject/restore/unavailable/dispatch.
* Helpers reuse the existing local-server request wrapper, timeout handling, stale-revision mapping, duplicate-trigger guard, and refresh hook behavior.

**Files Changed**:

* `apps/web/src/lib/orchestrationApi.ts` - added campaign workbench and queue mutation API helpers and response guards.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T010 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/web run typecheck`
  * Result: PASS - Web TypeScript check completed with exit code 0.
  * Evidence: New API helper types and response guards compile.
* Command/check: static inspection of `apps/web/src/lib/orchestrationApi.ts`
  * Result: PASS - Helpers use `requestCommandCenterMutation` for duplicate-trigger prevention and bounded failure mapping.
  * Evidence: Campaign and queue helper calls include mutation keys, expected revision fields, idempotency keys, and response validators.
* UI product-surface check: N/A - API helper only.
* UI craft check: N/A - API helper only.

**BQC Fixes**:

* External dependency resilience: API calls inherit the existing local-server timeout and offline mapping.
* Contract alignment: Added response guards for campaign workbench and queue mutation responses.

***

### Task T009 - Inject campaign workbench dependencies into server route construction

**Started**: 2026-06-26 04:24 **Completed**: 2026-06-26 04:25 **Duration**: 1 minute

**Notes**:

* Instantiated `PlanCampaignManager` once in server construction using the existing command-center and task-queue managers.
* Passed the campaign manager and task queue into `commandCenterRouter` so campaign dispatch can emit both command-center and queue events.

**Files Changed**:

* `apps/server/src/server.ts` - injected campaign workbench dependencies into command-center route construction.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T009 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server TypeScript check completed with exit code 0.
  * Evidence: Server route construction compiles with the new command-center router dependencies.
* Command/check: static inspection of `apps/server/src/server.ts`
  * Result: PASS - `PlanCampaignManager` receives the same in-memory command-center and task-queue managers used by existing local routes.
  * Evidence: Server creates `planCampaigns` after `commandCenter` and passes `{ broadcaster, commandCenter, campaigns: planCampaigns, taskQueue }` to `commandCenterRouter`.
* UI product-surface check: N/A - server construction only.
* UI craft check: N/A - server construction only.

**BQC Fixes**:

* Contract alignment: The route layer composes the same manager instances used for snapshots and queue routes, avoiding duplicate state.

***

### Task T008 - Wire campaign workbench REST routes and WebSocket emissions

**Started**: 2026-06-26 04:23 **Completed**: 2026-06-26 04:25 **Duration**: 2 minutes

**Notes**:

* Added campaign workbench routes for preview, create, transition, refine, retry failed, and dispatch under the command-center route family.
* Accepted mutations emit command-center plan/task updates and queue updates when dispatch bridges tasks into the queue.
* Route handlers use the new schema parsers and bounded manager responses.

**Files Changed**:

* `apps/server/src/routes/commandCenter.ts` - added campaign workbench routes, response sender, and queue event emission helper.
* `apps/server/src/lib/commandCenterValidation.ts` - supplied route parsers used by the new handlers.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T008 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server TypeScript check completed with exit code 0.
  * Evidence: Command-center route dependency and campaign route integration compile.
* Command/check: static inspection of `apps/server/src/routes/commandCenter.ts`
  * Result: PASS - New routes validate ids and bodies before manager calls and emit bounded update events after accepted mutations.
  * Evidence: `sendCampaignResult` emits plan, task, and queue updates from manager change metadata.
* UI product-surface check: N/A - server routes only.
* UI craft check: N/A - server routes only.

**BQC Fixes**:

* Trust boundary enforcement: Campaign route handlers validate route ids and bodies before calling the manager.
* Contract alignment: Route responses include campaign, tasks, generatedAt, changes, duplicate, queue entries, and bounded failure metadata from one manager response shape.

***

### Task T007 - Add explicit queue restore and mark-unavailable transitions

**Started**: 2026-06-26 04:23 **Completed**: 2026-06-26 04:25 **Duration**: 2 minutes

**Notes**:

* Added explicit `restore`, `markUnavailable`, and `dispatch` methods to `TaskQueueManager`.
* Methods preserve expected-revision checks, mutation locks, duplicate idempotency protection, and compact conflict responses.
* Dispatch moves a queue entry to `in_progress` using the existing `update` transition type and does not claim executor completion.

**Files Changed**:

* `apps/server/src/managers/taskQueue.ts` - added queue control request type, transition idempotency map, and explicit transition methods.
* `apps/server/src/routes/orchestration.ts` - added route branches for queue restore, unavailable, and dispatch controls.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T007 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server TypeScript check completed with exit code 0.
  * Evidence: Queue manager and orchestration route changes compile.
* Command/check: static inspection of `apps/server/src/managers/taskQueue.ts`
  * Result: PASS - Restore and unavailable use explicit transition names; dispatch uses a bounded state update to `in_progress`.
  * Evidence: `restore`, `markUnavailable`, and `dispatch` route through `transitionEntry` with expected revision and idempotency handling.
* UI product-surface check: N/A - server queue behavior only.
* UI craft check: N/A - server queue behavior only.

**BQC Fixes**:

* Duplicate action prevention: Added transition idempotency map and per-transition locks (`apps/server/src/managers/taskQueue.ts`).
* Failure path completeness: Queue controls return existing compact 404/409 manager errors on missing entries, stale revisions, duplicate keys, or in-flight mutations.

***

### Task T006 - Add focused campaign/task helper methods

**Started**: 2026-06-26 04:19 **Completed**: 2026-06-26 04:25 **Duration**: 6 minutes

**Notes**:

* Added read-only campaign and task accessors on `OrchestrationCommandCenterManager`.
* Helpers return cloned records and preserve the existing manager-owned save/upsert boundary for all mutations.

**Files Changed**:

* `apps/server/src/managers/orchestrationCommandCenter.ts` - added `getCampaign`, `getTask`, and `listCampaignTasks`.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T006 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server TypeScript check completed with exit code 0.
  * Evidence: New helpers compile and are consumed by `PlanCampaignManager`.
* Command/check: static inspection of `apps/server/src/managers/orchestrationCommandCenter.ts`
  * Result: PASS - Helpers clone returned records and do not expose mutable maps.
  * Evidence: `getCampaign`, `getTask`, and `listCampaignTasks` return cloned records through the existing `clone` helper.
* UI product-surface check: N/A - server manager helper only.
* UI craft check: N/A - server manager helper only.

**BQC Fixes**:

* Contract alignment: Added narrow helpers instead of bypassing command-center manager storage from the campaign manager (`apps/server/src/managers/orchestrationCommandCenter.ts`).

***

### Task T005 - Add campaign and queue-control validators

**Started**: 2026-06-26 04:21 **Completed**: 2026-06-26 04:25 **Duration**: 4 minutes

**Notes**:

* Added schema-style parsers for campaign preview, create, transition, refine, dispatch, retry, and queue-control request bodies.
* Parsers reuse command-center protocol normalizers and recursively reject blocked raw payload field names before manager code sees input.
* Added bounded task parsing with unique optional task ids, safe dependency ids, bounded summaries, expected results, owner ids, assigned hero ids, idempotency keys, and expected revisions.

**Files Changed**:

* `apps/server/src/lib/commandCenterValidation.ts` - added campaign workbench and queue-control validation helpers.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T005 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server TypeScript check completed with exit code 0.
  * Evidence: New parser exports compile against route and manager inputs.
* Command/check: static inspection of `apps/server/src/lib/commandCenterValidation.ts`
  * Result: PASS - Validators call `rejectCommandCenterBlockedPayloadFields` and map protocol validation failures through compact invalid-request responses.
  * Evidence: Preview/create/refine/dispatch/queue-control parsers reject raw payload fields and use bounded command-center normalizers.
* UI product-surface check: N/A - server validation only.
* UI craft check: N/A - server validation only.

**BQC Fixes**:

* Trust boundary enforcement: Added route-level validation before campaign and queue mutation handlers (`apps/server/src/lib/commandCenterValidation.ts`).
* Error information boundaries: Validation errors expose field names and compact messages only (`apps/server/src/lib/commandCenterValidation.ts`).

***

### Task T004 - Create campaign manager behavior layer

**Started**: 2026-06-26 04:19 **Completed**: 2026-06-26 04:25 **Duration**: 6 minutes

**Notes**:

* Added `PlanCampaignManager` with preview, create, transition, refine, retry-failed, and dispatch behavior.
* Added manager-level mutation locks, idempotency replay handling, stale revision checks, bounded queue summaries, queue bridge creation with `source: "plan"`, and partial-failure state recording for dispatch.
* Kept execution claims conservative: dispatch queues local work and updates plan task state without claiming executor success.

**Files Changed**:

* `apps/server/src/managers/planCampaignManager.ts` - new campaign workbench manager and response/input types.
* `apps/server/src/managers/orchestrationCommandCenter.ts` - narrow campaign/task read helpers used by the manager.
* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded task evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T004 complete after evidence was recorded.

**Verification**:

* Command/check: `npm --workspace apps/server run typecheck`
  * Result: PASS - Server TypeScript check completed with exit code 0.
  * Evidence: `tsc --noEmit` passed after campaign manager integration.
* Command/check: static inspection of `apps/server/src/managers/planCampaignManager.ts`
  * Result: PASS - Manager uses bounded `title`, `summary`, and `expectedResult` fields; queue bridge writes plan references only.
  * Evidence: Dispatch creates queue entries with `source: "plan"` and `references: { planId }`; no raw prompt, command body, absolute path, terminal output, or artifact field is stored.
* UI product-surface check: N/A - server manager only.
* UI craft check: N/A - server manager only.

**BQC Fixes**:

* Duplicate action prevention: Added manager mutation locks and idempotency replay maps for create, transition, refine, retry, and dispatch (`apps/server/src/managers/planCampaignManager.ts`).
* Failure path completeness: Dispatch records failed task ids and partial-failure campaign state instead of silently dropping queue bridge failures (`apps/server/src/managers/planCampaignManager.ts`).

***

### Task T003 - Inspect current task queue transition behavior for restore, mark-unavailable, and dispatch needs

**Started**: 2026-06-26 04:17 **Completed**: 2026-06-26 04:18 **Duration**: 1 minute

**Notes**:

* Confirmed `TaskQueueManager` currently implements create, update, reject, list, get, event entries, counts, and queue event change conversion.
* Confirmed explicit restore and mark-unavailable manager methods are absent; current update semantics can move entries to non-rejected states but do not return the specific transition names required by the workbench.
* Confirmed dispatch can use a bounded state transition to `in_progress` without claiming executor completion.

**Files Changed**:

* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded queue transition inspection evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T003 complete after evidence was recorded.

**Verification**:

* Command/check: `sed -n '1,320p' apps/server/src/managers/taskQueue.ts`
  * Result: PASS - Current manager behavior and gaps were inspected.
  * Evidence: Found `create`, `update`, and `reject`; found no explicit `restore` or `markUnavailable` methods; found idempotency and mutation-lock behavior for create and entry mutation locks.
* Command/check: `sed -n '1,180p' apps/server/src/routes/orchestration.ts`
  * Result: PASS - Current task-queue REST route coverage was inspected.
  * Evidence: Found `GET /task-queue`, `POST /task-queue`, `PATCH /task-queue/:id`, and `POST /task-queue/:id/reject`; found no restore, unavailable, or dispatch-specific route branches.
* UI product-surface check: N/A - server inspection only.
* UI craft check: N/A - server inspection only.

**BQC Fixes**:

* N/A - server inspection only.

***

### Task T002 - Map existing campaign, task, and queue contract gaps before coding

**Started**: 2026-06-26 04:16 **Completed**: 2026-06-26 04:17 **Duration**: 1 minute

**Notes**:

* Confirmed `CommandCenterPlanCampaign` and `CommandCenterPlanTask` already carry bounded summary, expected-result, dependency, verification, revision, and state fields needed by the workbench.
* Identified the implementation gap as server behavior and route shapes rather than a required protocol enum change for the MVP.
* Confirmed queue entries already support `source: "plan"` and `references.planId`, which can link dispatched campaign work without raw prompt, command, absolute path, terminal, or artifact content.

**Files Changed**:

* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - recorded protocol-gap evidence.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T002 complete after evidence was recorded.

**Verification**:

* Command/check: `sed -n '1,620p' packages/protocol/src/orchestrationCommandCenter.ts`
  * Result: PASS - Existing campaign and task DTOs satisfy the bounded campaign workbench shape.
  * Evidence: Inspected state enums, `CommandCenterPlanCampaign`, `CommandCenterPlanTask`, compact error, mutation metadata, blocked payload categories, and blocked raw field names.
* Command/check: `sed -n '1,220p' packages/protocol/src/taskQueue.ts`
  * Result: PASS - Queue contract has plan source/link fields and explicit restore/mark-unavailable transition names.
  * Evidence: Inspected `TASK_QUEUE_SOURCE_VALUES`, `TASK_QUEUE_TRANSITION_VALUES`, `TaskQueueReferences`, create/update/reject request types, and mutation response shape.
* UI product-surface check: N/A - contract inspection only.
* UI craft check: N/A - contract inspection only.

**BQC Fixes**:

* N/A - contract inspection only.

***

## Task Log

### 2026-06-26 - Session Start

**Environment verified**:

* [x] Prerequisites confirmed
* [x] Tools available
* [x] Directory structure ready

***

### Task T001 - Verify completed Phase 19 prerequisites and current campaign/queue artifacts

**Started**: 2026-06-26 04:15 **Completed**: 2026-06-26 04:16 **Duration**: 1 minute

**Notes**:

* Confirmed Phase 19 Sessions 01-03 are complete in deterministic spec state.
* Confirmed prior web shell validation passed with all tasks complete and focused/root tests passing.
* Confirmed the current session directory contains `spec.md` and `tasks.md`.

**Files Changed**:

* `.spec_system/specs/phase19-session04-campaign-workbench/implementation-notes.md` - created session implementation log.
* `.spec_system/specs/phase19-session04-campaign-workbench/tasks.md` - marked T001 complete after evidence was recorded.

**Verification**:

* Command/check: `if [ -d .spec_system/scripts ]; then bash .spec_system/scripts/analyze-project.sh --json; else bash /home/aiwithapex/.codex/plugins/cache/apex-spec-system/apex-spec/2.1.3-codex/skills/apex-spec/scripts/analyze-project.sh --json; fi`
  * Result: PASS - Current session is `phase19-session04-campaign-workbench`; Phase 19 Sessions 01-03 are listed as completed.
  * Evidence: JSON reported `current_session_dir_exists: true`, current files `spec.md` and `tasks.md`, and completed sessions include `phase19-session01-protocol-and-events`, `phase19-session02-server-backbone`, and `phase19-session03-web-shell-and-store`.
* Command/check: `if [ -d .spec_system/scripts ]; then bash .spec_system/scripts/check-prereqs.sh --json --env; else bash /home/aiwithapex/.codex/plugins/cache/apex-spec-system/apex-spec/2.1.3-codex/skills/apex-spec/scripts/check-prereqs.sh --json --env; fi`
  * Result: PASS - Spec system, jq, git, and npm workspace manager checks passed.
  * Evidence: JSON reported `overall: pass` with no issues.
* Command/check: `sed -n '1,260p' .spec_system/specs/phase19-session03-web-shell-and-store/validation.md`
  * Result: PASS - Prior session validation is complete.
  * Evidence: Validation report shows `Result: PASS`, 20/20 tasks complete, focused web tests 43/43 passed, and root suite 2709/2709 passed with 1 skipped.
* UI product-surface check: N/A - setup inspection only.
* UI craft check: N/A - setup inspection only.

**BQC Fixes**:

* N/A - setup inspection only.

***


---

# 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/phase19-session04-campaign-workbench/implementation-notes.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.
