1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! What auto-provision did about one task queue, and why.
//!
//! Every arm is reported, including the ones where nothing was minted. A queue
//! that quietly got no worker is indistinguishable from a queue nobody asked
//! about, and the difference is the whole operator question: "I deployed a
//! document with a `harness` section and nothing is serving it."
use serde::{Deserialize, Serialize};
/// What was decided about one task queue.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum AutoWorkerDecision {
/// No record served this queue, so one was minted and converged.
Minted,
/// The queue's own auto record existed and named a DIFFERENT document, so
/// it was replaced and its worker restarted onto the new one.
Reminted,
/// The queue's own auto record already names this exact document. Nothing
/// was written; the running worker was left alone and merely converged.
Unchanged,
/// The record was written durably, and this server could NOT start it. The
/// record stands and the next boot's reconcile honours it; `detail` carries
/// the supervision failure and its remedy.
///
/// Distinct from every arm above because those all claim a running worker,
/// and claiming one that does not exist is the exact defect this whole lane
/// exists to end — one layer up.
RecordedNotRunning,
/// The queue's own auto record was deliberately STOPPED by an operator, and
/// their intent was preserved rather than reversed.
OperatorStopped,
/// The document no longer declares this queue, so the record this server
/// minted for it was withdrawn and its worker stopped.
Retired,
/// A record the OPERATOR authored already serves this queue. Their record
/// wins and nothing here touched or duplicated it.
OperatorRecord,
/// This server binds no liminal worker listener, so a minted record would
/// dial nothing. Refused, with the `[outbox]` remedy in `detail`.
DarkOutbox,
/// The document's harness names an agent THIS host cannot launch — an
/// absent or non-executable agent binary, or a literal working directory
/// that does not exist here. Refused with the missing path named; the
/// deploy itself landed. Measured 2026-08-26 on the estate: a fleet
/// document deployed from a Linux box minted workers on the Mac server
/// whose harness named `/home/aion/...` paths, and every dispatch routed
/// to them burned an attempt on a spawn that could only fail.
UnrunnableHarness,
/// Auto-provision could not be carried out. `detail` says what refused.
Failed,
}
impl AutoWorkerDecision {
/// Stable token for logs and metrics.
#[must_use]
pub const fn token(self) -> &'static str {
match self {
Self::Minted => "minted",
Self::Reminted => "reminted",
Self::Unchanged => "unchanged",
Self::RecordedNotRunning => "recorded-not-running",
Self::OperatorStopped => "operator-stopped",
Self::Retired => "retired",
Self::OperatorRecord => "operator-record",
Self::DarkOutbox => "dark-outbox",
Self::UnrunnableHarness => "unrunnable-harness",
Self::Failed => "failed",
}
}
/// Whether this outcome left the queue WITHOUT the built-in agent worker
/// the document asked for by declaring a `harness` section.
///
/// Three arms are deliberately NOT refusals, because in each of them a
/// person already decided: [`Self::OperatorRecord`] (their record serves
/// the queue), [`Self::OperatorStopped`] (they stopped it on purpose), and
/// [`Self::Retired`] (the document stopped declaring the queue).
#[must_use]
pub const fn is_refusal(self) -> bool {
matches!(
self,
Self::DarkOutbox | Self::Failed | Self::RecordedNotRunning | Self::UnrunnableHarness
)
}
/// Whether this outcome CLAIMS a running worker.
///
/// The claim is only ever made where a convergence returned success. It is
/// separated from the decision because a record can be written correctly
/// and still not run, and reporting those two as one thing is how a status
/// surface comes to say a worker started when no process exists.
#[must_use]
pub const fn claims_running(self) -> bool {
matches!(self, Self::Minted | Self::Reminted | Self::Unchanged)
}
}
/// One task queue's auto-provision outcome, as reported to the deploy caller,
/// the boot log, and the managed-worker status surface.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct AutoWorkerOutcome {
/// The task queue this is about.
pub task_queue: String,
/// The workflow type whose document declared the queue.
///
/// Carried so a document-level failure — one where no queue name could be
/// read out of the source at all — is still attributable to a document.
/// Without it two unparseable documents are one indistinguishable entry.
pub workflow_type: String,
/// What was decided.
pub decision: AutoWorkerDecision,
/// The deployment record's name, when there is one to name — the auto
/// record on the minted arms, the operator's own on [`AutoWorkerDecision::OperatorRecord`].
pub deployment: Option<String>,
/// The sentence an operator reads. ALWAYS present, on every arm: a
/// decision token with no account of itself is a decision nobody can act on.
pub detail: String,
}
impl AutoWorkerOutcome {
/// One outcome for a queue, with its account.
pub fn new(
task_queue: impl Into<String>,
workflow_type: impl Into<String>,
decision: AutoWorkerDecision,
deployment: Option<String>,
detail: impl Into<String>,
) -> Self {
Self {
task_queue: task_queue.into(),
workflow_type: workflow_type.into(),
decision,
deployment,
detail: detail.into(),
}
}
/// A refusal that could not be attributed to any one queue — the document
/// itself did not parse, so no queue name was ever read out of it.
pub fn document_level(workflow_type: impl Into<String>, detail: impl Into<String>) -> Self {
Self::new(
String::new(),
workflow_type,
AutoWorkerDecision::Failed,
None,
detail,
)
}
/// The key this outcome is kept under in the supervisor's per-queue log.
///
/// The task queue, because the operator's question is about a queue and one
/// queue has one auto record however many documents declare it. A
/// document-level failure has no queue, so it is keyed by the document
/// instead — otherwise two unparseable documents overwrite each other under
/// one blank name.
#[must_use]
pub fn log_key(&self) -> String {
if self.task_queue.is_empty() {
format!("document:{}", self.workflow_type)
} else {
self.task_queue.clone()
}
}
}