instar 1.3.728 → 1.3.730
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +259 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +11 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/FileClassifier.d.ts.map +1 -1
- package/dist/core/FileClassifier.js +11 -0
- package/dist/core/FileClassifier.js.map +1 -1
- package/dist/core/LocalSessionOwnershipStore.d.ts +5 -0
- package/dist/core/LocalSessionOwnershipStore.d.ts.map +1 -1
- package/dist/core/LocalSessionOwnershipStore.js +13 -0
- package/dist/core/LocalSessionOwnershipStore.js.map +1 -1
- package/dist/core/ModelSwapService.d.ts +13 -0
- package/dist/core/ModelSwapService.d.ts.map +1 -1
- package/dist/core/ModelSwapService.js +11 -0
- package/dist/core/ModelSwapService.js.map +1 -1
- package/dist/core/ModelTierEscalation.d.ts +10 -0
- package/dist/core/ModelTierEscalation.d.ts.map +1 -1
- package/dist/core/ModelTierEscalation.js +4 -0
- package/dist/core/ModelTierEscalation.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +35 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ProactiveSwapMonitor.d.ts +74 -20
- package/dist/core/ProactiveSwapMonitor.d.ts.map +1 -1
- package/dist/core/ProactiveSwapMonitor.js +349 -28
- package/dist/core/ProactiveSwapMonitor.js.map +1 -1
- package/dist/core/QuotaAwareScheduler.d.ts +70 -3
- package/dist/core/QuotaAwareScheduler.d.ts.map +1 -1
- package/dist/core/QuotaAwareScheduler.js +100 -16
- package/dist/core/QuotaAwareScheduler.js.map +1 -1
- package/dist/core/SessionBuildContextStore.d.ts +20 -0
- package/dist/core/SessionBuildContextStore.d.ts.map +1 -1
- package/dist/core/SessionBuildContextStore.js +20 -3
- package/dist/core/SessionBuildContextStore.js.map +1 -1
- package/dist/core/SessionManager.d.ts +33 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +105 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SessionOwnershipRegistry.d.ts +16 -0
- package/dist/core/SessionOwnershipRegistry.d.ts.map +1 -1
- package/dist/core/SessionOwnershipRegistry.js +13 -0
- package/dist/core/SessionOwnershipRegistry.js.map +1 -1
- package/dist/core/SessionRefresh.d.ts +116 -1
- package/dist/core/SessionRefresh.d.ts.map +1 -1
- package/dist/core/SessionRefresh.js +280 -17
- package/dist/core/SessionRefresh.js.map +1 -1
- package/dist/core/StateManager.d.ts +20 -0
- package/dist/core/StateManager.d.ts.map +1 -1
- package/dist/core/StateManager.js +72 -4
- package/dist/core/StateManager.js.map +1 -1
- package/dist/core/SwapAntiThrash.d.ts +329 -0
- package/dist/core/SwapAntiThrash.d.ts.map +1 -0
- package/dist/core/SwapAntiThrash.js +1025 -0
- package/dist/core/SwapAntiThrash.js.map +1 -0
- package/dist/core/SwapLedger.d.ts +168 -0
- package/dist/core/SwapLedger.d.ts.map +1 -0
- package/dist/core/SwapLedger.js +275 -0
- package/dist/core/SwapLedger.js.map +1 -0
- package/dist/core/SwapWorkGate.d.ts +100 -0
- package/dist/core/SwapWorkGate.d.ts.map +1 -0
- package/dist/core/SwapWorkGate.js +175 -0
- package/dist/core/SwapWorkGate.js.map +1 -0
- package/dist/core/WriteAdmission.d.ts +277 -0
- package/dist/core/WriteAdmission.d.ts.map +1 -0
- package/dist/core/WriteAdmission.js +514 -0
- package/dist/core/WriteAdmission.js.map +1 -0
- package/dist/core/WriteDomainRegistry.d.ts +132 -0
- package/dist/core/WriteDomainRegistry.d.ts.map +1 -0
- package/dist/core/WriteDomainRegistry.js +186 -0
- package/dist/core/WriteDomainRegistry.js.map +1 -0
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +12 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/core/types.d.ts +89 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/guardManifest.d.ts.map +1 -1
- package/dist/monitoring/guardManifest.js +58 -1
- package/dist/monitoring/guardManifest.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +3 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +3 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +20 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +1 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts +6 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +115 -3
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +65 -65
- package/src/scaffold/templates.ts +3 -1
- package/upgrades/1.3.729.md +92 -0
- package/upgrades/1.3.730.md +112 -0
- package/upgrades/side-effects/standby-write-reconciliation.md +62 -0
- package/upgrades/side-effects/swap-continuity-antithrash.md +118 -0
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WriteAdmission — ONE synchronous, in-memory decision point that classifies
|
|
3
|
+
* every write into a domain (machine-local / session-scoped / topic-scoped /
|
|
4
|
+
* cluster-shared) and admits or TYPED-refuses it, replacing the blanket
|
|
5
|
+
* lease-boolean standby guard with ownership-scoped write admission.
|
|
6
|
+
*
|
|
7
|
+
* Spec: docs/specs/standby-write-reconciliation.md (§3.2 decision table,
|
|
8
|
+
* §3.4 typed-refusal contract, §5 fail directions, §6 observability).
|
|
9
|
+
*
|
|
10
|
+
* Hard properties (invariant I2): the admission path is synchronous and
|
|
11
|
+
* in-memory ONLY — no fs, no network, no LLM, no await. It reads (a) the
|
|
12
|
+
* lease view the coordinator already maintains in memory (via injected
|
|
13
|
+
* `isReadOnly`), (b) the ownership index (boot-warmed + onCommit-updated,
|
|
14
|
+
* never `registry.read()`), (c) the domain registry. Refusal log rows are
|
|
15
|
+
* BUFFERED in memory and flushed off the admission path (a timer), so even
|
|
16
|
+
* observability never puts fs on the decision path.
|
|
17
|
+
*
|
|
18
|
+
* Authority ladder (§7): the layer only gains refusal authority at
|
|
19
|
+
* `dryRun:false` AND after the wave-2 write-surface inventory is complete
|
|
20
|
+
* (WRITE_SURFACE_INVENTORY_COMPLETE — the §9.14 ladder gate). Until then it
|
|
21
|
+
* evaluates + logs would-verdicts while the LEGACY blanket guard keeps
|
|
22
|
+
* enforcing (§9.6).
|
|
23
|
+
*/
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
import { monitorEventLoopDelay } from 'node:perf_hooks';
|
|
26
|
+
import { JsonlStore } from './storage/JsonlStore.js';
|
|
27
|
+
import { WRITE_SURFACE_INVENTORY_COMPLETE, } from './WriteDomainRegistry.js';
|
|
28
|
+
/** Legacy message preserved for log-scraping continuity (§7 migration parity). */
|
|
29
|
+
export function legacyReadOnlyMessage(operation) {
|
|
30
|
+
return `StateManager is read-only (this machine is on standby). Blocked: ${operation}`;
|
|
31
|
+
}
|
|
32
|
+
/** Thrown at the store seam for a refused write. Callers that today
|
|
33
|
+
* catch-and-log the string keep working — the legacy message is preserved. */
|
|
34
|
+
export class WriteRefusedError extends Error {
|
|
35
|
+
refusal;
|
|
36
|
+
constructor(refusal, operation) {
|
|
37
|
+
super(`${legacyReadOnlyMessage(operation)} [write-refused:${refusal.code}]`);
|
|
38
|
+
this.name = 'WriteRefusedError';
|
|
39
|
+
this.refusal = refusal;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const KNOWN_STATUSES = new Set([
|
|
43
|
+
'placing', 'active', 'transferring', 'released',
|
|
44
|
+
]);
|
|
45
|
+
/**
|
|
46
|
+
* The ownership index (§3.2, decided — was OQ1): owned by WriteAdmission,
|
|
47
|
+
* warmed by ONE synchronous `store.all()` scan at construction, updated via
|
|
48
|
+
* the `onCommit` hook at each substrate's own commit point. `admitWrite`
|
|
49
|
+
* NEVER calls `registry.read()` — negative answers come from memory.
|
|
50
|
+
*/
|
|
51
|
+
export class OwnershipIndex {
|
|
52
|
+
entries = new Map();
|
|
53
|
+
warmed = false;
|
|
54
|
+
_lastCasTransitionAt = null;
|
|
55
|
+
/** Ingest validation (round-2 L1): `ownerMachineId` must be a string and
|
|
56
|
+
* `status` a known FSM status — REGARDLESS of which store path surfaced the
|
|
57
|
+
* record (the warm-scan `all()` validates weaker than `loadOne`). A record
|
|
58
|
+
* failing ingest classifies malformed ⇒ fail-closed `ownership-unresolved`
|
|
59
|
+
* for that scope — never `not-owner` with `owner: null`. */
|
|
60
|
+
ingest(record, opts) {
|
|
61
|
+
if (!record || typeof record !== 'object')
|
|
62
|
+
return; // unkeyable — nothing to poison
|
|
63
|
+
const r = record;
|
|
64
|
+
if (typeof r.sessionKey !== 'string' || !r.sessionKey)
|
|
65
|
+
return; // unkeyable
|
|
66
|
+
if (typeof r.ownerMachineId !== 'string' || !KNOWN_STATUSES.has(String(r.status))) {
|
|
67
|
+
this.entries.set(r.sessionKey, 'malformed');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.entries.set(r.sessionKey, { owner: r.ownerMachineId, status: r.status });
|
|
71
|
+
}
|
|
72
|
+
if (opts?.fromCommit)
|
|
73
|
+
this._lastCasTransitionAt = new Date().toISOString();
|
|
74
|
+
}
|
|
75
|
+
/** Boot warm — ONE synchronous scan result, off the request path. */
|
|
76
|
+
warmFrom(records) {
|
|
77
|
+
for (const r of records)
|
|
78
|
+
this.ingest(r);
|
|
79
|
+
this.warmed = true;
|
|
80
|
+
}
|
|
81
|
+
lookup(sessionKey) {
|
|
82
|
+
if (!this.warmed)
|
|
83
|
+
return { state: 'unwarmed' };
|
|
84
|
+
const e = this.entries.get(sessionKey);
|
|
85
|
+
if (e === undefined)
|
|
86
|
+
return { state: 'none' };
|
|
87
|
+
if (e === 'malformed')
|
|
88
|
+
return { state: 'malformed' };
|
|
89
|
+
return { state: 'record', owner: e.owner, status: e.status };
|
|
90
|
+
}
|
|
91
|
+
get isWarmed() {
|
|
92
|
+
return this.warmed;
|
|
93
|
+
}
|
|
94
|
+
stats() {
|
|
95
|
+
return { entries: this.entries.size, lastCasTransitionAt: this._lastCasTransitionAt };
|
|
96
|
+
}
|
|
97
|
+
/** Test-parity helper: the full keyed view (never on the admission path). */
|
|
98
|
+
snapshot() {
|
|
99
|
+
return new Map(this.entries);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const DOMAINS = ['machine-local', 'session-scoped', 'topic-scoped', 'cluster-shared'];
|
|
103
|
+
const AGGREGATE_WINDOW_MS = 10 * 60 * 1000;
|
|
104
|
+
const LOG_BUFFER_MAX = 1000;
|
|
105
|
+
const RECENT_REFUSALS_MAX = 50;
|
|
106
|
+
const STARVED_WINDOW_THRESHOLD_MS = 1000;
|
|
107
|
+
export class WriteAdmission {
|
|
108
|
+
d;
|
|
109
|
+
index;
|
|
110
|
+
counters = new Map();
|
|
111
|
+
recentRefusals = [];
|
|
112
|
+
aggregate = new Map();
|
|
113
|
+
logBuffer = [];
|
|
114
|
+
logStore = null;
|
|
115
|
+
flushTimer = null;
|
|
116
|
+
histogram = null;
|
|
117
|
+
gaugeTimer = null;
|
|
118
|
+
starvedWindows = [];
|
|
119
|
+
lastGauge = { p50: 0, p99: 0, max: 0 };
|
|
120
|
+
constructor(deps, ownershipStore) {
|
|
121
|
+
this.d = deps;
|
|
122
|
+
for (const dom of DOMAINS)
|
|
123
|
+
this.counters.set(dom, { admitted: 0, refused: 0, wouldRefuse: 0, wouldAdmitChanged: 0 });
|
|
124
|
+
if (deps.logDir) {
|
|
125
|
+
this.logStore = new JsonlStore(path.join(deps.logDir, 'write-admission.jsonl'), {
|
|
126
|
+
maxBytes: 8 * 1024 * 1024, // bounded + rotated (§6)
|
|
127
|
+
keepSegments: 2,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
this.index = new OwnershipIndex();
|
|
131
|
+
// Hook-then-warm (§3.2.2 ordering): register the interface-level onCommit
|
|
132
|
+
// hook BEFORE the warm scan. The constructor is synchronous, so no commit
|
|
133
|
+
// can interleave between hook registration and the scan — the index can
|
|
134
|
+
// never miss a transition the local store saw.
|
|
135
|
+
if (ownershipStore) {
|
|
136
|
+
ownershipStore.onCommit = (rec) => this.onOwnershipCommit(rec);
|
|
137
|
+
}
|
|
138
|
+
// Boot warm: ONE synchronous store.all() scan AT CONSTRUCTION (§3.2.1) —
|
|
139
|
+
// deliberately off the request path. A store without all() (or none at
|
|
140
|
+
// all, e.g. pool-dark installs) warms empty: no peers' custody ⇒ scoped
|
|
141
|
+
// verdicts collapse via the pool-inactive clause anyway.
|
|
142
|
+
let records = [];
|
|
143
|
+
try {
|
|
144
|
+
records = ownershipStore?.all?.() ?? [];
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
// Loud, never silent: an unreadable warm scan leaves the index warmed-
|
|
148
|
+
// empty (fail toward today's verdicts via the decision table's
|
|
149
|
+
// absent arms) and the failure is visible on the status surface.
|
|
150
|
+
this.log({ seam: 'boot', event: 'warm-scan-failed', error: err instanceof Error ? err.message : String(err) });
|
|
151
|
+
}
|
|
152
|
+
this.index.warmFrom(records);
|
|
153
|
+
// §6 event-loop-lag gauge (~zero cost) — the P2-6 attribution instrument.
|
|
154
|
+
if (!deps.disableTimers) {
|
|
155
|
+
this.histogram = monitorEventLoopDelay({ resolution: 20 });
|
|
156
|
+
this.histogram.enable();
|
|
157
|
+
this.gaugeTimer = setInterval(() => this.sampleGauge(), 5000);
|
|
158
|
+
this.gaugeTimer.unref?.();
|
|
159
|
+
this.flushTimer = setInterval(() => this.flushLog(), 2000);
|
|
160
|
+
this.flushTimer.unref?.();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** The onCommit hook target (§3.2.2) — wire on BOTH shipped substrates. */
|
|
164
|
+
onOwnershipCommit(record) {
|
|
165
|
+
this.index.ingest(record, { fromCommit: true });
|
|
166
|
+
}
|
|
167
|
+
/** legacy = layer constructed but... never (construction implies enabled);
|
|
168
|
+
* dry-run = evaluating + logging, legacy guard enforcing;
|
|
169
|
+
* live = refusal authority (dryRun:false AND inventory complete — §9.14). */
|
|
170
|
+
mode() {
|
|
171
|
+
const inventoryComplete = this.d.inventoryComplete ?? WRITE_SURFACE_INVENTORY_COMPLETE;
|
|
172
|
+
return !this.d.dryRun && inventoryComplete ? 'live' : 'dry-run';
|
|
173
|
+
}
|
|
174
|
+
get isLive() {
|
|
175
|
+
return this.mode() === 'live';
|
|
176
|
+
}
|
|
177
|
+
get dryRun() {
|
|
178
|
+
return this.d.dryRun;
|
|
179
|
+
}
|
|
180
|
+
// ── The §3.2 decision table ────────────────────────────────────────────
|
|
181
|
+
/**
|
|
182
|
+
* Pure, synchronous, in-memory verdict (I2). Reads only the injected
|
|
183
|
+
* in-memory lease view, the ownership index, and the registry entry.
|
|
184
|
+
*/
|
|
185
|
+
evaluate(domain, scope, entry) {
|
|
186
|
+
switch (domain) {
|
|
187
|
+
case 'machine-local':
|
|
188
|
+
return { admit: true };
|
|
189
|
+
case 'cluster-shared':
|
|
190
|
+
return this.d.isReadOnly()
|
|
191
|
+
? { admit: false, refusal: this.refusal('lease-required', domain, scope, null) }
|
|
192
|
+
: { admit: true };
|
|
193
|
+
case 'session-scoped':
|
|
194
|
+
case 'topic-scoped': {
|
|
195
|
+
// Pool INACTIVE (§3.2, was S5): scoped domains collapse to the legacy
|
|
196
|
+
// lease boolean — byte-identical to today's standby behavior.
|
|
197
|
+
if (!this.d.isPoolActive()) {
|
|
198
|
+
return this.d.isReadOnly()
|
|
199
|
+
? { admit: false, refusal: this.refusal('read-only-standby', domain, scope, null) }
|
|
200
|
+
: { admit: true };
|
|
201
|
+
}
|
|
202
|
+
// Keying (§3.1): one index, two key derivations.
|
|
203
|
+
let topicKey = null;
|
|
204
|
+
if (scope?.topicId !== undefined && scope.topicId !== null) {
|
|
205
|
+
topicKey = String(scope.topicId);
|
|
206
|
+
}
|
|
207
|
+
else if (domain === 'session-scoped' && scope?.sessionId) {
|
|
208
|
+
let bound = null;
|
|
209
|
+
// The binding resolver is an in-memory map read by contract; treat a
|
|
210
|
+
// resolver throw as a binding miss (fail toward delivery — §5).
|
|
211
|
+
try {
|
|
212
|
+
bound = this.d.resolveTopicForSession?.(scope.sessionId) ?? null;
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
/* @silent-fallback-ok — §5 "binding unresolved" row: a resolver failure IS the
|
|
216
|
+
in-memory-map miss case and fails toward DELIVERY (unbound ⇒ admit,
|
|
217
|
+
machine-local-by-construction); refusing here would gate serving an inbound
|
|
218
|
+
message on a standby — the exact M2 regression the table forbids. */
|
|
219
|
+
bound = null;
|
|
220
|
+
}
|
|
221
|
+
topicKey = bound === null || bound === undefined ? null : String(bound);
|
|
222
|
+
}
|
|
223
|
+
if (topicKey === null) {
|
|
224
|
+
if (domain === 'session-scoped') {
|
|
225
|
+
// UNBOUND arm: machine-local-by-construction ⇒ ADMIT (M2).
|
|
226
|
+
return { admit: true };
|
|
227
|
+
}
|
|
228
|
+
// topic-scoped writes carry their topic id by definition (§3.2 n/a
|
|
229
|
+
// arm); a missing id resolves like the absent arm: legacy boolean.
|
|
230
|
+
return this.legacyBooleanVerdict(domain, scope);
|
|
231
|
+
}
|
|
232
|
+
const lk = this.index.lookup(topicKey);
|
|
233
|
+
if (lk.state === 'unwarmed' || lk.state === 'malformed') {
|
|
234
|
+
// Fail closed on GENUINE ambiguity only (I5).
|
|
235
|
+
return { admit: false, refusal: this.refusal('ownership-unresolved', domain, scope, null) };
|
|
236
|
+
}
|
|
237
|
+
if (lk.state === 'none' || lk.status === 'released') {
|
|
238
|
+
if (domain === 'session-scoped')
|
|
239
|
+
return { admit: true }; // today-equivalent (the carve-out)
|
|
240
|
+
// topic-scoped absent/released ⇒ legacy lease boolean (§9.18) unless
|
|
241
|
+
// the entry declares an I9-audited absent-window story.
|
|
242
|
+
if ((entry?.kind === 'kv' || entry?.kind === 'route') && entry.absentWindowStory) {
|
|
243
|
+
return { admit: true };
|
|
244
|
+
}
|
|
245
|
+
return this.legacyBooleanVerdict(domain, scope);
|
|
246
|
+
}
|
|
247
|
+
// Record in placing / active / transferring: admit iff the FSM's
|
|
248
|
+
// single named owner is this machine (§9.11 — ownerOf semantics).
|
|
249
|
+
if (this.d.thisMachineId !== null && lk.owner === this.d.thisMachineId) {
|
|
250
|
+
return { admit: true };
|
|
251
|
+
}
|
|
252
|
+
return { admit: false, refusal: this.refusal('not-owner', domain, scope, lk.owner) };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
legacyBooleanVerdict(domain, scope) {
|
|
257
|
+
return this.d.isReadOnly()
|
|
258
|
+
? { admit: false, refusal: this.refusal('read-only-standby', domain, scope, null) }
|
|
259
|
+
: { admit: true };
|
|
260
|
+
}
|
|
261
|
+
refusal(code, domain, scope, ownerId) {
|
|
262
|
+
const now = this.d.now?.() ?? Date.now();
|
|
263
|
+
const ownerNick = ownerId ? this.d.nicknameOf?.(ownerId) ?? null : null;
|
|
264
|
+
let hint;
|
|
265
|
+
switch (code) {
|
|
266
|
+
case 'not-owner':
|
|
267
|
+
hint = `This write belongs to ${ownerNick ? `'${ownerNick}'` : `machine ${ownerId}`} — re-send it there. (Advisory only: moving the topic is a consent-gated operator decision, not a step to auto-follow.)`;
|
|
268
|
+
break;
|
|
269
|
+
case 'lease-required':
|
|
270
|
+
hint = 'This is cluster-shared state; only the serving-lease holder writes it. Re-send to the lease holder.';
|
|
271
|
+
break;
|
|
272
|
+
case 'ownership-unresolved':
|
|
273
|
+
hint = 'Ownership for this scope could not be resolved right now — retry shortly.';
|
|
274
|
+
break;
|
|
275
|
+
case 'read-only-standby':
|
|
276
|
+
hint = 'This machine is on standby for this write; the serving machine handles it.';
|
|
277
|
+
break;
|
|
278
|
+
case 'admission-error':
|
|
279
|
+
hint = 'The write-admission layer failed while evaluating this write; refused fail-closed. Retry shortly.';
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
let leaseHolder = null;
|
|
283
|
+
try {
|
|
284
|
+
leaseHolder = this.d.leaseHolder?.() ?? null;
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
/* @silent-fallback-ok — I7: the refusal body's lease-holder decoration is best-effort
|
|
288
|
+
LOCAL knowledge; a reader failure only omits the advisory field, never changes the
|
|
289
|
+
verdict, and the refusal must never hang or throw on decoration. */
|
|
290
|
+
leaseHolder = null;
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
error: 'write-refused',
|
|
294
|
+
code,
|
|
295
|
+
domain,
|
|
296
|
+
...(scope ? { scope } : {}),
|
|
297
|
+
thisMachine: { machineId: this.d.thisMachineId, nickname: this.d.selfNickname?.() ?? null },
|
|
298
|
+
owner: ownerId ? { machineId: ownerId, nickname: ownerNick } : null,
|
|
299
|
+
leaseHolder,
|
|
300
|
+
asOf: new Date(now).toISOString(),
|
|
301
|
+
retryable: true,
|
|
302
|
+
hint,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
// ── Store seam (§3.3) ──────────────────────────────────────────────────
|
|
306
|
+
/**
|
|
307
|
+
* Verdict for StateManager.guardWrite. Returns:
|
|
308
|
+
* - 'admit' — pass (live authority admitted the write)
|
|
309
|
+
* - 'refuse' — throw the carried WriteRefusedError (live authority refused)
|
|
310
|
+
* - 'legacy' — dry-run/ladder-gated: caller runs today's legacy verdict
|
|
311
|
+
* A throw ANYWHERE inside is caught by the caller ⇒ legacy verdict (§5).
|
|
312
|
+
*/
|
|
313
|
+
guardStoreWrite(op, opts) {
|
|
314
|
+
const { domain, entry } = this.d.registry.domainForOp(op, opts?.key);
|
|
315
|
+
const verdict = this.evaluate(domain, opts?.scope, entry);
|
|
316
|
+
const surface = opts?.key ? `${op}:${opts.key}` : op;
|
|
317
|
+
if (this.isLive) {
|
|
318
|
+
this.record('store', surface, domain, verdict, opts?.scope);
|
|
319
|
+
if (verdict.admit)
|
|
320
|
+
return { enforce: 'admit' };
|
|
321
|
+
return { enforce: 'refuse', refusal: verdict.refusal };
|
|
322
|
+
}
|
|
323
|
+
// Dry-run: compute today's LEGACY verdict and log divergences — the
|
|
324
|
+
// graduation evidence (§6): wouldRefuse-but-today-succeeds = false
|
|
325
|
+
// positive to fix; wouldAdmit-but-today-throws = the fix landing.
|
|
326
|
+
const legacyThrows = this.d.isReadOnly() && !(opts?.legacySessionScoped && this.d.isPoolActive());
|
|
327
|
+
this.recordDryRun('store', surface, domain, verdict, legacyThrows, opts?.scope);
|
|
328
|
+
return { enforce: 'legacy' };
|
|
329
|
+
}
|
|
330
|
+
// ── Route seam (§3.4/§3.5) ─────────────────────────────────────────────
|
|
331
|
+
/**
|
|
332
|
+
* Verdict for a mutating HTTP route. Returns:
|
|
333
|
+
* - 'proceed' — route continues into today's exact flow
|
|
334
|
+
* - 'refuse' — respond 409 + Retry-After with the typed body
|
|
335
|
+
* An unwired route (no registry entry) always proceeds (I8). An admission-
|
|
336
|
+
* layer throw splits by domain (§9.16): machine-local PROCEEDS (fail toward
|
|
337
|
+
* delivery), scoped/cluster-shared REFUSE typed `admission-error` (fail
|
|
338
|
+
* closed). Both directions are logged + join the §6 aggregate.
|
|
339
|
+
*/
|
|
340
|
+
guardRouteWrite(method, routePath, scope) {
|
|
341
|
+
let entry = null;
|
|
342
|
+
try {
|
|
343
|
+
entry = this.d.registry.entryForRoute(method, routePath);
|
|
344
|
+
if (!entry)
|
|
345
|
+
return { action: 'proceed' };
|
|
346
|
+
const verdict = this.evaluate(entry.domain, scope, entry);
|
|
347
|
+
const surface = `${method.toUpperCase()} ${entry.pathPrefix}`;
|
|
348
|
+
if (this.isLive) {
|
|
349
|
+
this.record('route', surface, entry.domain, verdict, scope);
|
|
350
|
+
if (verdict.admit)
|
|
351
|
+
return { action: 'proceed' };
|
|
352
|
+
return { action: 'refuse', refusal: verdict.refusal, status: 409, retryAfterSeconds: 5 };
|
|
353
|
+
}
|
|
354
|
+
const legacyThrows = false; // routes never consulted the legacy guard (§1.2)
|
|
355
|
+
this.recordDryRun('route', surface, entry.domain, verdict, legacyThrows, scope);
|
|
356
|
+
return { action: 'proceed' };
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
const domain = entry?.domain ?? 'cluster-shared';
|
|
360
|
+
const surface = `${method.toUpperCase()} ${entry?.pathPrefix ?? routePath}`;
|
|
361
|
+
const direction = domain === 'machine-local' ? 'fail-open-proceed' : 'fail-closed-refuse';
|
|
362
|
+
this.log({
|
|
363
|
+
seam: 'route', surface, domain, verdict: 'admission-error', direction,
|
|
364
|
+
error: err instanceof Error ? err.message : String(err),
|
|
365
|
+
});
|
|
366
|
+
this.bumpAggregate(surface, 'admission-error', direction);
|
|
367
|
+
if (domain === 'machine-local' || !this.isLive)
|
|
368
|
+
return { action: 'proceed' };
|
|
369
|
+
return {
|
|
370
|
+
action: 'refuse',
|
|
371
|
+
refusal: this.refusal('admission-error', domain, scope, null),
|
|
372
|
+
status: 409,
|
|
373
|
+
retryAfterSeconds: 5,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// ── Observability (§6) ─────────────────────────────────────────────────
|
|
378
|
+
record(seam, surface, domain, verdict, scope) {
|
|
379
|
+
const c = this.counters.get(domain);
|
|
380
|
+
if (verdict.admit) {
|
|
381
|
+
c.admitted++;
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
c.refused++;
|
|
385
|
+
const { hint: _hint, ...bodyMinusHint } = verdict.refusal;
|
|
386
|
+
this.recentRefusals.push({ ...bodyMinusHint, seam, surface });
|
|
387
|
+
if (this.recentRefusals.length > RECENT_REFUSALS_MAX)
|
|
388
|
+
this.recentRefusals.shift();
|
|
389
|
+
this.log({ seam, surface, domain, scope, verdict: 'refused', code: verdict.refusal.code, owner: verdict.refusal.owner?.machineId ?? null, leaseHolder: verdict.refusal.leaseHolder });
|
|
390
|
+
this.bumpAggregate(surface, verdict.refusal.code, 'refused');
|
|
391
|
+
}
|
|
392
|
+
recordDryRun(seam, surface, domain, verdict, legacyThrows, scope) {
|
|
393
|
+
const c = this.counters.get(domain);
|
|
394
|
+
if (!verdict.admit && !legacyThrows) {
|
|
395
|
+
c.wouldRefuse++;
|
|
396
|
+
this.log({ seam, surface, domain, scope, verdict: 'would-refuse', code: verdict.refusal.code, owner: verdict.refusal.owner?.machineId ?? null });
|
|
397
|
+
}
|
|
398
|
+
else if (verdict.admit && legacyThrows) {
|
|
399
|
+
c.wouldAdmitChanged++;
|
|
400
|
+
this.log({ seam, surface, domain, scope, verdict: 'would-admit' });
|
|
401
|
+
}
|
|
402
|
+
else if (verdict.admit) {
|
|
403
|
+
c.admitted++; // agreement rows are counted, not logged (bounded log)
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
c.refused++; // both refuse — today's behavior, count only
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
bumpAggregate(surface, code, direction) {
|
|
410
|
+
const key = `${surface}|${code}|${direction}`;
|
|
411
|
+
const now = this.d.now?.() ?? Date.now();
|
|
412
|
+
let a = this.aggregate.get(key);
|
|
413
|
+
if (!a || now - a.windowStart > AGGREGATE_WINDOW_MS) {
|
|
414
|
+
a = { count: 0, windowStart: now, raised: false };
|
|
415
|
+
this.aggregate.set(key, a);
|
|
416
|
+
}
|
|
417
|
+
a.count++;
|
|
418
|
+
const threshold = this.d.refusalAggregateThreshold ?? 5;
|
|
419
|
+
if (a.count >= threshold && !a.raised) {
|
|
420
|
+
a.raised = true; // ONE deduped item per window — never per-event (§6)
|
|
421
|
+
try {
|
|
422
|
+
this.d.raiseAttention?.({
|
|
423
|
+
id: `agent:write-admission-${key.replace(/[^A-Za-z0-9:_-]+/g, '-').toLowerCase()}`,
|
|
424
|
+
title: `Write-admission: ${a.count}+ ${code} on ${surface}`,
|
|
425
|
+
body: `${a.count} ${code} verdicts (${direction}) for ${surface} within ${Math.round(AGGREGATE_WINDOW_MS / 60000)} min. A caller may be looping on refusals, or a guard may be broken — see GET /write-admission and logs/write-admission.jsonl.`,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
/* @silent-fallback-ok — the aggregate alert is observability; a failing attention
|
|
430
|
+
surface must never break (or recurse into) the admission path. The refusal rows
|
|
431
|
+
remain in the JSONL log, so the evidence is not lost. */
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/** Admission-layer throw at the STORE seam (§5): the caller fell back to the
|
|
436
|
+
* legacy verdict; record it so a broken guard is never log-only-invisible. */
|
|
437
|
+
noteStoreSeamError(op, err) {
|
|
438
|
+
this.log({ seam: 'store', surface: op, verdict: 'admission-error', direction: 'fail-legacy', error: err instanceof Error ? err.message : String(err) });
|
|
439
|
+
this.bumpAggregate(op, 'admission-error', 'fail-legacy');
|
|
440
|
+
}
|
|
441
|
+
log(row) {
|
|
442
|
+
if (!this.logStore)
|
|
443
|
+
return;
|
|
444
|
+
if (this.logBuffer.length >= LOG_BUFFER_MAX)
|
|
445
|
+
this.logBuffer.shift();
|
|
446
|
+
this.logBuffer.push(JSON.stringify({ ts: new Date(this.d.now?.() ?? Date.now()).toISOString(), ...row }));
|
|
447
|
+
if (this.d.disableTimers)
|
|
448
|
+
this.flushLog(); // test seam: synchronous visibility
|
|
449
|
+
}
|
|
450
|
+
/** Flush buffered rows to logs/write-admission.jsonl — OFF the admission
|
|
451
|
+
* path (I2: even observability never puts fs on the decision path).
|
|
452
|
+
* Routed through JsonlStore (Bounded Accumulation: bounded + rotated). */
|
|
453
|
+
flushLog() {
|
|
454
|
+
if (!this.logStore || this.logBuffer.length === 0)
|
|
455
|
+
return;
|
|
456
|
+
const rows = this.logBuffer.splice(0, this.logBuffer.length);
|
|
457
|
+
try {
|
|
458
|
+
for (const r of rows)
|
|
459
|
+
this.logStore.append(r);
|
|
460
|
+
}
|
|
461
|
+
catch (err) {
|
|
462
|
+
// Loud once per flush failure: observability loss must not be silent,
|
|
463
|
+
// but must also never throw into the admission path.
|
|
464
|
+
console.warn(`[write-admission] log flush failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
sampleGauge() {
|
|
468
|
+
if (!this.histogram)
|
|
469
|
+
return;
|
|
470
|
+
const h = this.histogram;
|
|
471
|
+
// monitorEventLoopDelay reports nanoseconds.
|
|
472
|
+
this.lastGauge = {
|
|
473
|
+
p50: Math.round(h.percentile(50) / 1e6),
|
|
474
|
+
p99: Math.round(h.percentile(99) / 1e6),
|
|
475
|
+
max: Math.round(h.max / 1e6),
|
|
476
|
+
};
|
|
477
|
+
if (this.lastGauge.max >= STARVED_WINDOW_THRESHOLD_MS) {
|
|
478
|
+
this.starvedWindows.push(this.d.now?.() ?? Date.now());
|
|
479
|
+
}
|
|
480
|
+
const dayAgo = (this.d.now?.() ?? Date.now()) - 24 * 60 * 60 * 1000;
|
|
481
|
+
this.starvedWindows = this.starvedWindows.filter((t) => t >= dayAgo);
|
|
482
|
+
h.reset();
|
|
483
|
+
}
|
|
484
|
+
eventLoopStats() {
|
|
485
|
+
return { ...this.lastGauge, starvedWindows24h: this.starvedWindows.length };
|
|
486
|
+
}
|
|
487
|
+
/** The GET /write-admission body (§6). */
|
|
488
|
+
status() {
|
|
489
|
+
return {
|
|
490
|
+
enabled: true,
|
|
491
|
+
dryRun: this.d.dryRun,
|
|
492
|
+
mode: this.mode(),
|
|
493
|
+
inventoryComplete: this.d.inventoryComplete ?? WRITE_SURFACE_INVENTORY_COMPLETE,
|
|
494
|
+
domains: DOMAINS.map((domain) => ({ domain, ...this.counters.get(domain) })),
|
|
495
|
+
recentRefusals: [...this.recentRefusals],
|
|
496
|
+
refusedClassifications: this.d.registry.refusedClassifications.map((r) => ({ reason: r.reason })),
|
|
497
|
+
ownershipIndex: this.index.stats(),
|
|
498
|
+
eventLoop: this.eventLoopStats(),
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/** Tear down timers/histogram (tests + shutdown). */
|
|
502
|
+
stop() {
|
|
503
|
+
if (this.flushTimer)
|
|
504
|
+
clearInterval(this.flushTimer);
|
|
505
|
+
if (this.gaugeTimer)
|
|
506
|
+
clearInterval(this.gaugeTimer);
|
|
507
|
+
this.flushTimer = null;
|
|
508
|
+
this.gaugeTimer = null;
|
|
509
|
+
this.flushLog();
|
|
510
|
+
this.histogram?.disable();
|
|
511
|
+
this.histogram = null;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
//# sourceMappingURL=WriteAdmission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WriteAdmission.js","sourceRoot":"","sources":["../../src/core/WriteAdmission.ts"],"names":[],"mappings":"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"}
|