4.3 KiB
4.3 KiB
Grey Queue State Machine
Sprint: SPRINT_20260118_018_Unknowns_queue_enhancement (UQ-005)
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:
assigneefield must be set - Triggers: Assignment notification to reviewer
- Validation: Cannot transition without assignee
Escalated
- Requires:
escalation_reasonfield - Triggers: Notification to security team
- Sets:
escalated_attimestamp
Rejected
- Records: Reason and who rejected
- Allows: Reopening back to Pending
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
All transitions are recorded in grey_queue_state_transitions table:
| Column | Description |
|---|---|
entry_id |
Grey queue entry reference |
from_state |
Previous state |
to_state |
New state |
transitioned_by |
User who triggered transition |
reason |
Optional reason for transition |
transitioned_at |
Timestamp |
metadata |
Additional context (JSONB) |
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:
devops/database/migrations/V20260119_001__Add_UnderReview_Escalated_Rejected_States.sql