Grey Queue State Machine
Sprint: SPRINT_20260118_018_Unknowns_queue_enhancement (UQ-005)
Status: forward contract, not operational. The state machine is implemented in code (
GreyQueueStateMachine), but noIGreyQueueRepositoryis registered in the deployed host and no grey-queue table exists, so every/api/grey-queue/*request answers501 Not Implemented(grey_queue_not_implemented). See architecture.md §6.
State Diagram
stateDiagram-v2
[*] --> Pending: Entry created
Pending --> Processing: Start processing
Pending --> UnderReview: Assign to reviewer
Pending --> Expired: TTL exceeded
Pending --> Dismissed: Manual dismissal
Processing --> Retrying: Processing failed (retry)
Processing --> UnderReview: Needs human review
Processing --> Resolved: Successfully resolved
Processing --> Failed: Max attempts exhausted
Retrying --> Processing: Retry attempt
Retrying --> Failed: Max attempts exhausted
Retrying --> Expired: TTL exceeded
UnderReview --> Escalated: Escalate to security
UnderReview --> Resolved: Reviewer resolves
UnderReview --> Rejected: Reviewer rejects
UnderReview --> Pending: Unassign (reset)
Escalated --> Resolved: Security resolves
Escalated --> Rejected: Security rejects
Escalated --> UnderReview: De-escalate
Rejected --> Pending: Reopen
Failed --> Pending: Reset for retry
Dismissed --> Pending: Reopen
Resolved --> [*]
Expired --> [*]
States
| State | Description | Entry Criteria | Exit Criteria |
|---|---|---|---|
| Pending | Awaiting initial processing | Entry created | Processing started, assigned, expired, or dismissed |
| Processing | Actively being processed by automation | Processing started | Retry, human review, resolved, or failed |
| Retrying | Waiting for retry after failed attempt | Processing failed | Retry attempt, max attempts, or TTL |
| UnderReview | Assigned to human reviewer | Needs human decision | Escalated, resolved, rejected, or unassigned |
| Escalated | Promoted to security team | Reviewer escalates | Security team decision |
| Resolved | Evidence now sufficient (terminal) | Automated or manual resolution | N/A |
| Rejected | Invalid or not actionable | Reviewer/security rejects | Can be reopened |
| Failed | Exhausted all retries (terminal-ish) | Max attempts exceeded | Can be reset |
| Expired | TTL exceeded (terminal) | Time limit reached | N/A |
| Dismissed | Manually dismissed (terminal-ish) | Operator dismissal | Can be reopened |
State Requirements
UnderReview
- Requires:
assigneein the request body (AssignForReviewRequest); optionalnotes - Validation:
GreyQueueStateMachine.ValidateUnderReviewTransitionrejects a blank assignee
Escalated
- Requires:
reasonin the request body (EscalateRequest) - Triggers: an
EscalationNotificationthrough the optionalINotificationPublisher(no production implementation is registered)
Rejected
- Requires:
reasonandrejectedByin the request body (RejectRequest) - Allows: Reopening back to Pending (
ReopenRequestrequiresreason)
Valid Transitions
Pending → [Processing, UnderReview, Expired, Dismissed]
Processing → [Retrying, UnderReview, Resolved, Failed]
Retrying → [Processing, Failed, Expired]
UnderReview → [Escalated, Resolved, Rejected, Pending]
Escalated → [Resolved, Rejected, UnderReview]
Resolved → [] (terminal)
Rejected → [Pending]
Failed → [Pending]
Expired → [] (terminal)
Dismissed → [Pending]
Transition Audit
Mutating grey-queue endpoints emit audit events under AuditModules.Unknowns (assign, escalate, reject, reopen, resolve, dismiss, and the other actions listed in architecture.md §2.2). No transition-history table exists; the former grey_queue_state_transitions table description was never implemented.
API Endpoints
| Endpoint | Transition |
|---|---|
POST /api/grey-queue/{id}/assign | → UnderReview |
POST /api/grey-queue/{id}/escalate | → Escalated |
POST /api/grey-queue/{id}/reject | → Rejected |
POST /api/grey-queue/{id}/reopen | → Pending |
POST /api/grey-queue/{id}/resolve | → Resolved |
POST /api/grey-queue/{id}/dismiss | → Dismissed |
GET /api/grey-queue/{id}/transitions | Get valid next states |
Code Reference
- State enum:
src/Unknowns/__Libraries/StellaOps.Unknowns.Core/Models/GreyQueueEntry.cs - State machine:
GreyQueueStateMachineclass in same file - Endpoints:
src/Unknowns/StellaOps.Unknowns.WebService/Endpoints/GreyQueueEndpoints.cs - Migration: none — there is no backing table. No live migration creates a
grey_queuetable (verified 2026-07-12 across every embedded, non-archived migration insrc/), and the previously citeddevops/database/migrations/V20260119_001__Add_UnderReview_Escalated_Rejected_States.sqldoes not exist. The state machine and endpoints are scaffolded but unbacked — seearchitecture.md§6 (“There is nogrey_queuetable”). Treat this document as the target contract, not as shipped persistence.
