# Work Queue and Dispatch Specification

**Status:** Canonical domain specification.  
**Purpose:** Define AWP's ordered work queue, dispatch eligibility, dependency constraints, reprioritization semantics, and relationship to Factory execution.

## 1. Scope

The Work Queue is the authoritative ordered view of work that is eligible, nearly eligible, blocked, waiting for a user, or already dispatched.

It exists to answer:

- what is running now;
- what is next;
- why it is next;
- what is blocked;
- which prerequisite is blocking it;
- what can be reprioritized;
- what cannot be moved because of dependency or policy constraints.

The queue is not a generic sortable list. It is an ordered execution-intent model with hard correctness constraints.

## 2. Queueable entities

A queue entry may reference a queueable work scope:

- Task;
- Phase;
- Wave;
- Plan;
- approved ad-hoc work item.

The initial UI should optimize for Tasks while preserving the more general model.

Each QueueEntry records at minimum:

```text
QueueEntry
  id
  projectId
  scopeType
  scopeId
  goalIds[]
  planId
  requestedPriority
  effectivePriority
  readinessState
  blockedBy[]
  dependsOn[]
  dependents[]
  queuePosition
  dispatchPolicy
  createdAt
  updatedAt
```

## 3. Dependency model

### 3.1 Hard dependency

A hard dependency means one work item must reach an allowed prerequisite state before its dependent may dispatch.

```text
Task B dependsOn Task A
```

means:

```text
A must satisfy dependencyCompletionPolicy
before B can become dispatch-eligible.
```

The default dependency completion policy is successful terminal completion. Plans may define a stricter or narrower completion condition, but a child scope may not weaken a parent safety ceiling.

### 3.2 Directed acyclic constraint

Hard execution dependencies form a **directed acyclic graph (DAG)**.

AWP must reject any command that would introduce a cycle.

Example rejected command:

```text
A -> B
B -> C
C -> A   // invalid: cycle
```

Informational relationships that are not execution dependencies must use a different relation type and must not participate in dispatch ordering.

### 3.3 Cross-plan dependencies

Dependencies may cross Plan boundaries inside the same Project when explicitly allowed.

Example:

```text
Plan: Runtime foundation
  Task A: durable event store

Plan: UI
  Task B: live activity panel

B dependsOn A
```

The UI must expose the cross-plan relationship clearly rather than making the dependency appear local to the UI Plan.

## 4. Readiness states

A QueueEntry must have one of these user-visible readiness categories:

```text
RUNNING
READY
BLOCKED_DEPENDENCY
BLOCKED_POLICY
WAITING_USER
PAUSED
DONE
CANCELLED
```

`READY` means all hard dependencies and required policy gates are satisfied.

`BLOCKED_DEPENDENCY` must include the exact unsatisfied prerequisite set.

## 5. Ordering model

Queue order expresses user intent **within the legal partial order imposed by dependencies and policy**.

A user-supplied priority does not override correctness.

AWP derives an effective queue order that satisfies:

1. dependency constraints;
2. policy / approval constraints;
3. resource / concurrency constraints;
4. user priority among otherwise legal candidates.

### 5.1 Legal placement range

For each queue item, AWP should compute a legal placement range:

```text
earliestLegalPosition
latestLegalPosition
```

The earliest legal position must be after every unresolved prerequisite that must precede it.

The latest legal position must be before any dependent whose ordering would become invalid if the item moved later.

This range is exposed to the UI so drag-and-drop can communicate constraints before the drop occurs.

## 6. Reprioritization commands

Supported commands:

```text
moveBefore(entryId, targetEntryId)
moveAfter(entryId, targetEntryId)
moveToPosition(entryId, position)
setPriority(entryId, priority)
```

Every command is validated transactionally against the dependency DAG and policy constraints.

If invalid, AWP returns a stable error with:

```text
code: QUEUE_ORDER_CONSTRAINT
entryId
desiredPosition
legalRange
blockingDependencies[]
blockingDependents[]
explanation
```

The server/domain model is authoritative. The UI may prevent invalid gestures proactively, but must not rely on client validation alone.

## 7. Dispatch eligibility

A queue entry may dispatch only when:

```text
all hard dependencies satisfied
AND required approvals satisfied
AND execution profile resolved
AND required provider capacity available
AND no explicit pause / hold
AND owning Plan/Project policy allows dispatch
```

The queue must distinguish:

```text
priority order
```

from:

```text
dispatch eligibility
```

An item may be visually high priority but still blocked.

## 8. Explainability requirements

For every non-terminal entry the domain read model must supply enough structured information for the UI to answer:

- Why is this item here?
- Why is it ahead of or behind another item?
- Which dependencies exist?
- Which dependency is currently unsatisfied?
- What must happen before it can dispatch?
- Can the user legally move it higher or lower?
- Which Goal and Plan does it advance?

Opaque scheduler/provider internals are secondary to this explanation.

## 9. Events

At minimum:

```text
QueueEntryAdded
QueueEntryMoved
QueueMoveRejected
QueueEntryBecameReady
QueueEntryBlockedByDependency
QueueEntryDependencyCleared
QueueEntryDispatched
QueueEntryPaused
QueueEntryCancelled
```

Events include causation/correlation IDs and the relevant dependency IDs where applicable.

## 10. Invariants

1. A dependent cannot dispatch before every required hard dependency satisfies its completion policy.
2. Hard dependency cycles are forbidden.
3. Queue reorder cannot violate dependency order.
4. Client-side drag/drop cannot bypass server/domain validation.
5. Every blocked state names the blocking relation or policy.
6. Cross-plan dependencies remain visible and navigable.
7. User priority is preserved whenever it does not violate dependency or policy constraints.

## 11. Acceptance criteria

- Creating a dependency immediately changes readiness and queue legality.
- Attempting to drag or command a Task ahead of an unmet dependency is rejected.
- The domain returns the legal placement range and blocking reason.
- Completing the final unmet prerequisite automatically makes the dependent eligible when no other gate remains.
- Cross-plan dependency chains are supported and explainable.
- Cycles are rejected deterministically with a readable cycle path.
