instar 1.3.365 → 1.3.367
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 +200 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +18 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/IntentTestHarness.d.ts +27 -0
- package/dist/core/IntentTestHarness.d.ts.map +1 -1
- package/dist/core/IntentTestHarness.js +91 -0
- package/dist/core/IntentTestHarness.js.map +1 -1
- package/dist/core/MeshRpc.d.ts +8 -0
- package/dist/core/MeshRpc.d.ts.map +1 -1
- package/dist/core/MeshRpc.js +6 -1
- package/dist/core/MeshRpc.js.map +1 -1
- package/dist/core/PeerPresencePuller.d.ts +6 -0
- package/dist/core/PeerPresencePuller.d.ts.map +1 -1
- package/dist/core/PeerPresencePuller.js +5 -0
- package/dist/core/PeerPresencePuller.js.map +1 -1
- package/dist/core/PeerVisibilityGuard.d.ts +83 -0
- package/dist/core/PeerVisibilityGuard.d.ts.map +1 -0
- package/dist/core/PeerVisibilityGuard.js +204 -0
- package/dist/core/PeerVisibilityGuard.js.map +1 -0
- package/dist/core/PendingPullLedger.d.ts +129 -0
- package/dist/core/PendingPullLedger.d.ts.map +1 -0
- package/dist/core/PendingPullLedger.js +239 -0
- package/dist/core/PendingPullLedger.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +20 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/WorkingSetManifest.d.ts +2 -0
- package/dist/core/WorkingSetManifest.d.ts.map +1 -1
- package/dist/core/WorkingSetManifest.js +13 -1
- package/dist/core/WorkingSetManifest.js.map +1 -1
- package/dist/core/WorkingSetPull.d.ts +157 -0
- package/dist/core/WorkingSetPull.d.ts.map +1 -0
- package/dist/core/WorkingSetPull.js +546 -0
- package/dist/core/WorkingSetPull.js.map +1 -0
- package/dist/core/WorkingSetPullCoordinator.d.ts +134 -0
- package/dist/core/WorkingSetPullCoordinator.d.ts.map +1 -0
- package/dist/core/WorkingSetPullCoordinator.js +306 -0
- package/dist/core/WorkingSetPullCoordinator.js.map +1 -0
- package/dist/core/types.d.ts +43 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/redteam/ScenarioPack.d.ts +30 -3
- package/dist/redteam/ScenarioPack.d.ts.map +1 -1
- package/dist/redteam/ScenarioPack.js +46 -1
- package/dist/redteam/ScenarioPack.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +4 -0
- 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 +1 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +5 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +47 -1
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/src/data/state-coherence-registry.json +48 -12
- package/src/scaffold/templates.ts +4 -0
- package/upgrades/{1.3.365.md → 1.3.366.md} +35 -0
- package/upgrades/1.3.367.md +134 -0
- package/upgrades/side-effects/intent-llm-judge.md +94 -0
- package/upgrades/side-effects/working-set-ci-absorb.md +29 -0
- package/upgrades/side-effects/working-set-parity-absorb.md +35 -0
- package/upgrades/side-effects/working-set-pull-p22a.md +121 -0
- package/upgrades/side-effects/working-set-trigger-p22b.md +115 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkingSetPull — P2.2 of multi-machine coherence: both sides of the
|
|
3
|
+
* chunked, bounded, verified `working-set-pull` mesh verb.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/WORKING-SET-HANDOFF-SPEC.md §3.2 (the verb), §3.5
|
|
6
|
+
* (never-clobber). Transport-agnostic: the server registers the serve side
|
|
7
|
+
* as the verb handler; the puller drives the receive side through an
|
|
8
|
+
* injected `send` seam (MeshRpcClient upstream).
|
|
9
|
+
*
|
|
10
|
+
* Load-bearing transport rules (§3.2):
|
|
11
|
+
* - Every response carries at most `pullMaxBatchBytes` (1 MiB default) of
|
|
12
|
+
* content — a single 32 MiB JSON.stringify is the host's DOCUMENTED
|
|
13
|
+
* event-loop-starvation root cause.
|
|
14
|
+
* - Cross-chunk consistency anchor: the offset-0 response alone carries the
|
|
15
|
+
* whole-file sha256 (ONE full read+hash, amortized) + a cheap fstat
|
|
16
|
+
* anchor {bytes, mtimeNs, ino}; later chunks carry the fstat anchor only.
|
|
17
|
+
* Anchor mismatch → restart FROM 0, bounded by chunkRestartCap, then the
|
|
18
|
+
* file is `unstable` (surfaced, never a livelock).
|
|
19
|
+
* - `busy` is retry-without-penalty: it never consumes the pending-pull
|
|
20
|
+
* breaker's failure budget (§3.2/§3.4).
|
|
21
|
+
* - maxTotalBytes counts ASSEMBLED, verification-passed bytes — never raw
|
|
22
|
+
* wire bytes (anchor restarts can't starve the set's remaining files).
|
|
23
|
+
* - Serve side: the FRESH manifest is the allowlist (recomputed per
|
|
24
|
+
* request); O_NOFOLLOW open + fd identity verify (TOCTOU defense);
|
|
25
|
+
* at most `serveConcurrency` requests served at once.
|
|
26
|
+
* - Receive side: peer relPath is HOSTILE input; full jail before any
|
|
27
|
+
* join; never-clobber with hash-suffixed alongside copies (cap 2,
|
|
28
|
+
* eviction via SafeFsExecutor — the single, narrow deletion exception).
|
|
29
|
+
*/
|
|
30
|
+
import crypto from 'node:crypto';
|
|
31
|
+
import fs from 'node:fs';
|
|
32
|
+
import path from 'node:path';
|
|
33
|
+
import { SafeFsExecutor } from './SafeFsExecutor.js';
|
|
34
|
+
import { computeWorkingSet, DEFAULT_WORKING_SET_CAPS, } from './WorkingSetManifest.js';
|
|
35
|
+
// ── Wire shapes ─────────────────────────────────────────────────────
|
|
36
|
+
export const DEFAULT_PULL_MAX_BATCH_BYTES = 1024 * 1024; // 1 MiB
|
|
37
|
+
export const DEFAULT_CHUNK_RESTART_CAP = 3;
|
|
38
|
+
export const DEFAULT_CHUNKS_PER_TICK = 8;
|
|
39
|
+
export const DEFAULT_SERVE_CONCURRENCY = 2;
|
|
40
|
+
export const DEFAULT_BUSY_RETRY_CAP = 10;
|
|
41
|
+
/**
|
|
42
|
+
* The serve-side handler — stateless per request except the concurrency
|
|
43
|
+
* gate. Registered by the server as the `working-set-pull` verb handler.
|
|
44
|
+
*/
|
|
45
|
+
export class WorkingSetPullServer {
|
|
46
|
+
inFlight = 0;
|
|
47
|
+
d;
|
|
48
|
+
constructor(deps) {
|
|
49
|
+
this.d = deps;
|
|
50
|
+
}
|
|
51
|
+
handle(cmd) {
|
|
52
|
+
const cap = this.d.serveConcurrency ?? DEFAULT_SERVE_CONCURRENCY;
|
|
53
|
+
if (this.inFlight >= cap)
|
|
54
|
+
return { busy: true }; // honest throttle (§3.2)
|
|
55
|
+
this.inFlight++;
|
|
56
|
+
try {
|
|
57
|
+
return this.handleInner(cmd);
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
this.inFlight--;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
handleInner(cmd) {
|
|
64
|
+
// The FRESH manifest is the allowlist — recomputed on every request,
|
|
65
|
+
// never cached across calls (§3.2). There is no generic file-read surface.
|
|
66
|
+
const manifest = computeWorkingSet({
|
|
67
|
+
stateDir: this.d.stateDir,
|
|
68
|
+
topic: cmd.topic,
|
|
69
|
+
runs: this.d.readRuns(cmd.topic),
|
|
70
|
+
caps: this.d.caps,
|
|
71
|
+
});
|
|
72
|
+
if (cmd.manifestOnly || !cmd.want?.length)
|
|
73
|
+
return { manifest };
|
|
74
|
+
const stateDir = realStateDir(this.d.stateDir);
|
|
75
|
+
const batchBudget = this.d.pullMaxBatchBytes ?? DEFAULT_PULL_MAX_BATCH_BYTES;
|
|
76
|
+
let budgetLeft = batchBudget;
|
|
77
|
+
const byRel = new Map(manifest.entries.map((e) => [e.relPath, e]));
|
|
78
|
+
const blobs = [];
|
|
79
|
+
const refused = [];
|
|
80
|
+
for (const want of cmd.want) {
|
|
81
|
+
if (budgetLeft <= 0)
|
|
82
|
+
break; // remaining wants ride the next request
|
|
83
|
+
const entry = byRel.get(want.relPath);
|
|
84
|
+
if (!entry) {
|
|
85
|
+
refused.push({ relPath: want.relPath, reason: 'refusedPolicy' });
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (entry.liveSource) {
|
|
89
|
+
refused.push({ relPath: want.relPath, reason: 'liveSource' });
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (entry.secretFlagged) {
|
|
93
|
+
refused.push({ relPath: want.relPath, reason: 'secretFlagged' });
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (entry.tooLarge) {
|
|
97
|
+
refused.push({ relPath: want.relPath, reason: 'tooLarge' });
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const abs = path.join(stateDir, entry.relPath);
|
|
101
|
+
const served = this.serveChunk(abs, want.offset, budgetLeft, entry.sha256);
|
|
102
|
+
if (served === 'gone') {
|
|
103
|
+
refused.push({ relPath: want.relPath, reason: 'goneSinceManifest' });
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (served === null) {
|
|
107
|
+
refused.push({ relPath: want.relPath, reason: 'refusedPolicy' });
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
budgetLeft -= Buffer.byteLength(served.dataB64, 'utf-8');
|
|
111
|
+
blobs.push({ ...served, relPath: want.relPath, offset: want.offset });
|
|
112
|
+
}
|
|
113
|
+
return { blobs, refused };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* TOCTOU-safe single-chunk read (§3.2): open O_NOFOLLOW (refuses a symlink
|
|
117
|
+
* swapped in at the final component), fstat the FD (regular file), and
|
|
118
|
+
* verify FD identity against a fresh lstat of the same path (same dev+ino
|
|
119
|
+
* → the fd IS the file at the jailed path, not a different object raced
|
|
120
|
+
* in). Bytes are read once; the offset-0 read covers the whole file so the
|
|
121
|
+
* assembly hash comes from the exact served bytes.
|
|
122
|
+
*/
|
|
123
|
+
serveChunk(abs, offset, budget, manifestSha) {
|
|
124
|
+
let fd;
|
|
125
|
+
try {
|
|
126
|
+
fd = fs.openSync(abs, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
const code = e.code;
|
|
130
|
+
if (code === 'ENOENT')
|
|
131
|
+
return 'gone';
|
|
132
|
+
return null; // ELOOP (symlink) and friends → policy refusal
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const st = fs.fstatSync(fd, { bigint: true });
|
|
136
|
+
if (!st.isFile())
|
|
137
|
+
return null;
|
|
138
|
+
let lst;
|
|
139
|
+
try {
|
|
140
|
+
lst = fs.lstatSync(abs, { bigint: true });
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return 'gone';
|
|
144
|
+
}
|
|
145
|
+
if (lst.ino !== st.ino || lst.dev !== st.dev)
|
|
146
|
+
return null; // raced object swap
|
|
147
|
+
const size = Number(st.size);
|
|
148
|
+
const anchor = {
|
|
149
|
+
bytes: size,
|
|
150
|
+
mtimeNs: st.mtimeNs.toString(),
|
|
151
|
+
ino: st.ino.toString(),
|
|
152
|
+
};
|
|
153
|
+
if (offset < 0 || offset > size)
|
|
154
|
+
return null;
|
|
155
|
+
if (offset === 0) {
|
|
156
|
+
// ONE full read+hash — the assembly authority. The first chunk is
|
|
157
|
+
// sliced from these exact bytes (read-once, hash-from-served-bytes).
|
|
158
|
+
const whole = Buffer.alloc(size);
|
|
159
|
+
let readTotal = 0;
|
|
160
|
+
while (readTotal < size) {
|
|
161
|
+
const n = fs.readSync(fd, whole, readTotal, size - readTotal, readTotal);
|
|
162
|
+
if (n <= 0)
|
|
163
|
+
break;
|
|
164
|
+
readTotal += n;
|
|
165
|
+
}
|
|
166
|
+
if (readTotal !== size)
|
|
167
|
+
return null; // shrank mid-read → refuse, puller restarts
|
|
168
|
+
const fileSha256 = crypto.createHash('sha256').update(whole).digest('hex');
|
|
169
|
+
const sliceLen = Math.min(size, maxContentBytes(budget));
|
|
170
|
+
const data = whole.subarray(0, sliceLen);
|
|
171
|
+
return {
|
|
172
|
+
dataB64: data.toString('base64'),
|
|
173
|
+
anchor,
|
|
174
|
+
fileSha256,
|
|
175
|
+
eof: sliceLen >= size,
|
|
176
|
+
...(manifestSha && fileSha256 !== manifestSha ? { changedSinceManifest: true } : {}),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const len = Math.min(size - offset, maxContentBytes(budget));
|
|
180
|
+
const buf = Buffer.alloc(len);
|
|
181
|
+
let got = 0;
|
|
182
|
+
while (got < len) {
|
|
183
|
+
const n = fs.readSync(fd, buf, got, len - got, offset + got);
|
|
184
|
+
if (n <= 0)
|
|
185
|
+
break;
|
|
186
|
+
got += n;
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
dataB64: buf.subarray(0, got).toString('base64'),
|
|
190
|
+
anchor,
|
|
191
|
+
eof: offset + got >= size,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
try {
|
|
196
|
+
fs.closeSync(fd);
|
|
197
|
+
}
|
|
198
|
+
catch { /* @silent-fallback-ok: double-close/EBADF on cleanup is harmless; the read already completed or failed above (WORKING-SET-HANDOFF-SPEC §3.2) */
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** base64 inflates 4/3 — convert a response-byte budget to raw content bytes. */
|
|
204
|
+
function maxContentBytes(budgetB64Bytes) {
|
|
205
|
+
return Math.max(0, Math.floor((budgetB64Bytes * 3) / 4));
|
|
206
|
+
}
|
|
207
|
+
function realStateDir(stateDir) {
|
|
208
|
+
try {
|
|
209
|
+
return fs.realpathSync(path.resolve(stateDir));
|
|
210
|
+
}
|
|
211
|
+
catch { /* @silent-fallback-ok: a not-yet-existing stateDir keeps its lexical path; the jail still bounds it (WORKING-SET-HANDOFF-SPEC §3.1) */
|
|
212
|
+
return path.resolve(stateDir);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
export class WorkingSetPuller {
|
|
216
|
+
d;
|
|
217
|
+
constructor(deps) {
|
|
218
|
+
this.d = deps;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Pull one topic's transferables from the nominee behind `send`.
|
|
222
|
+
* The caller (trigger/ledger layer) handles nomination, single-flight,
|
|
223
|
+
* staggered drain, and pending-pull filing off `needsPendingPull`.
|
|
224
|
+
*/
|
|
225
|
+
async pullTopic(topic) {
|
|
226
|
+
const caps = { ...DEFAULT_WORKING_SET_CAPS, ...this.d.caps };
|
|
227
|
+
const report = { topic, files: [], assembledBytes: 0, needsPendingPull: false };
|
|
228
|
+
let first;
|
|
229
|
+
try {
|
|
230
|
+
first = await this.sendWithBusyRetry({ type: 'working-set-pull', topic, manifestOnly: true });
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
report.needsPendingPull = true;
|
|
234
|
+
report.files.push({ relPath: '*', outcome: 'refused', reason: `transport: ${e.message}` });
|
|
235
|
+
return report;
|
|
236
|
+
}
|
|
237
|
+
if (first.busy) {
|
|
238
|
+
report.needsPendingPull = true;
|
|
239
|
+
report.files.push({ relPath: '*', outcome: 'busyExhausted' });
|
|
240
|
+
return report;
|
|
241
|
+
}
|
|
242
|
+
const manifest = first.manifest;
|
|
243
|
+
if (!manifest) {
|
|
244
|
+
report.files.push({ relPath: '*', outcome: 'refused', reason: 'no manifest in response' });
|
|
245
|
+
return report;
|
|
246
|
+
}
|
|
247
|
+
let chunksThisTick = 0;
|
|
248
|
+
const chunksPerTick = this.d.chunksPerTick ?? DEFAULT_CHUNKS_PER_TICK;
|
|
249
|
+
for (const entry of manifest.entries) {
|
|
250
|
+
if (entry.liveSource) {
|
|
251
|
+
report.files.push({ relPath: entry.relPath, outcome: 'liveSourceDeferred' });
|
|
252
|
+
report.needsPendingPull = true; // re-fires on the run's `stopped` (§3.4)
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (entry.secretFlagged || entry.tooLarge) {
|
|
256
|
+
report.files.push({
|
|
257
|
+
relPath: entry.relPath,
|
|
258
|
+
outcome: 'refused',
|
|
259
|
+
reason: entry.secretFlagged ? 'secretFlagged' : 'tooLarge',
|
|
260
|
+
});
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
// Budget on ASSEMBLED bytes only (§3.2) — checked before starting a file.
|
|
264
|
+
if (report.assembledBytes + entry.bytes > caps.maxTotalBytes) {
|
|
265
|
+
report.files.push({ relPath: entry.relPath, outcome: 'budgetExhausted' });
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
const out = await this.pullFile(topic, entry.relPath, () => {
|
|
269
|
+
chunksThisTick++;
|
|
270
|
+
if (chunksThisTick >= chunksPerTick) {
|
|
271
|
+
chunksThisTick = 0;
|
|
272
|
+
return this.yieldNow();
|
|
273
|
+
}
|
|
274
|
+
return Promise.resolve();
|
|
275
|
+
});
|
|
276
|
+
report.files.push(out.outcome);
|
|
277
|
+
if (out.assembled !== null && out.outcome.outcome === 'written') {
|
|
278
|
+
report.assembledBytes += out.assembled;
|
|
279
|
+
}
|
|
280
|
+
else if (out.outcome.outcome === 'skippedExisting' || out.outcome.outcome === 'alongside') {
|
|
281
|
+
report.assembledBytes += out.assembled ?? 0;
|
|
282
|
+
}
|
|
283
|
+
if (out.outcome.outcome === 'busyExhausted' || out.outcome.outcome === 'unstable') {
|
|
284
|
+
report.needsPendingPull = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return report;
|
|
288
|
+
}
|
|
289
|
+
// ---- one file: chunk loop + anchor + assembly verification ---------------
|
|
290
|
+
async pullFile(topic, relPath, perChunk) {
|
|
291
|
+
const restartCap = this.d.chunkRestartCap ?? DEFAULT_CHUNK_RESTART_CAP;
|
|
292
|
+
for (let attempt = 0; attempt <= restartCap; attempt++) {
|
|
293
|
+
const result = await this.pullFileOnce(topic, relPath, perChunk);
|
|
294
|
+
if (result === 'restart')
|
|
295
|
+
continue; // anchor change / assembly mismatch → from 0
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
// chunkRestartCap exhausted — the file won't sit still (§3.2): surfaced,
|
|
299
|
+
// never a livelock.
|
|
300
|
+
return { outcome: { relPath, outcome: 'unstable' }, assembled: null };
|
|
301
|
+
}
|
|
302
|
+
async pullFileOnce(topic, relPath, perChunk) {
|
|
303
|
+
const chunks = [];
|
|
304
|
+
let offset = 0;
|
|
305
|
+
let pinnedAnchor = null;
|
|
306
|
+
let pinnedSha = null;
|
|
307
|
+
// Hard request bound per attempt: a compliant 16MiB headline at 1MiB
|
|
308
|
+
// chunks needs 16 requests; 4096 is a misbehaving-server guard, never a
|
|
309
|
+
// working bound (P19 — every repeating behavior is bounded).
|
|
310
|
+
for (let req = 0; req < 4096; req++) {
|
|
311
|
+
let res;
|
|
312
|
+
try {
|
|
313
|
+
res = await this.sendWithBusyRetry({
|
|
314
|
+
type: 'working-set-pull',
|
|
315
|
+
topic,
|
|
316
|
+
want: [{ relPath, offset }],
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
return {
|
|
321
|
+
outcome: { relPath, outcome: 'refused', reason: `transport: ${e.message}` },
|
|
322
|
+
assembled: null,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
if (res.busy)
|
|
326
|
+
return { outcome: { relPath, outcome: 'busyExhausted' }, assembled: null };
|
|
327
|
+
const refusal = res.refused?.find((r) => r.relPath === relPath);
|
|
328
|
+
if (refusal) {
|
|
329
|
+
if (refusal.reason === 'liveSource') {
|
|
330
|
+
return { outcome: { relPath, outcome: 'liveSourceDeferred' }, assembled: null };
|
|
331
|
+
}
|
|
332
|
+
return { outcome: { relPath, outcome: 'refused', reason: refusal.reason }, assembled: null };
|
|
333
|
+
}
|
|
334
|
+
const blob = res.blobs?.find((b) => b.relPath === relPath);
|
|
335
|
+
if (!blob) {
|
|
336
|
+
// Budget-paged out of THIS response — re-request the same offset.
|
|
337
|
+
if (res.blobs?.length || res.refused?.length)
|
|
338
|
+
continue;
|
|
339
|
+
return { outcome: { relPath, outcome: 'refused', reason: 'empty response' }, assembled: null };
|
|
340
|
+
}
|
|
341
|
+
// Response bound BEFORE decode (§3.2): a peer answering with more than
|
|
342
|
+
// the batch ceiling (×4/3 b64 inflation + slack) is refused, never
|
|
343
|
+
// decoded. (The full pre-parse transport ceiling rides the client's
|
|
344
|
+
// bounded fetch at wiring time; this is the decode-side backstop.)
|
|
345
|
+
const ceiling = this.d.pullMaxBatchBytes ?? DEFAULT_PULL_MAX_BATCH_BYTES;
|
|
346
|
+
if (blob.dataB64.length > Math.ceil((ceiling * 4) / 3) + 1024) {
|
|
347
|
+
return { outcome: { relPath, outcome: 'refused', reason: 'oversize response' }, assembled: null };
|
|
348
|
+
}
|
|
349
|
+
if (offset === 0) {
|
|
350
|
+
if (!blob.fileSha256) {
|
|
351
|
+
return { outcome: { relPath, outcome: 'refused', reason: 'offset-0 missing fileSha256' }, assembled: null };
|
|
352
|
+
}
|
|
353
|
+
pinnedAnchor = blob.anchor;
|
|
354
|
+
pinnedSha = blob.fileSha256;
|
|
355
|
+
}
|
|
356
|
+
else if (pinnedAnchor && !anchorsEqual(pinnedAnchor, blob.anchor)) {
|
|
357
|
+
// Tear detected mid-file → restart FROM 0 (§3.2), bounded by caller.
|
|
358
|
+
return 'restart';
|
|
359
|
+
}
|
|
360
|
+
const data = Buffer.from(blob.dataB64, 'base64');
|
|
361
|
+
chunks.push(data);
|
|
362
|
+
offset += data.length;
|
|
363
|
+
await perChunk();
|
|
364
|
+
const delay = this.d.interChunkDelayMs ?? 0;
|
|
365
|
+
if (delay > 0)
|
|
366
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
367
|
+
if (blob.eof)
|
|
368
|
+
break;
|
|
369
|
+
if (data.length === 0)
|
|
370
|
+
return 'restart'; // zero-progress guard — re-anchor
|
|
371
|
+
if (req === 4095) {
|
|
372
|
+
return { outcome: { relPath, outcome: 'refused', reason: 'request bound exceeded' }, assembled: null };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
const whole = Buffer.concat(chunks);
|
|
376
|
+
const assembledSha = crypto.createHash('sha256').update(whole).digest('hex');
|
|
377
|
+
if (!pinnedSha || assembledSha !== pinnedSha) {
|
|
378
|
+
// mtime-preserving rewrite dodged the fstat anchor — assembly is the
|
|
379
|
+
// authority (§3.2); restart bounded by the caller.
|
|
380
|
+
return 'restart';
|
|
381
|
+
}
|
|
382
|
+
// Ownership recheck before EVERY write (§3.3) — superseded → abort quietly.
|
|
383
|
+
if (!this.d.stillCurrent()) {
|
|
384
|
+
return { outcome: { relPath, outcome: 'superseded' }, assembled: null };
|
|
385
|
+
}
|
|
386
|
+
const written = this.writeNeverClobber(relPath, whole, assembledSha);
|
|
387
|
+
return { outcome: written, assembled: written.outcome === 'refused' ? null : whole.length };
|
|
388
|
+
}
|
|
389
|
+
// ---- never-clobber landing (§3.5) ----------------------------------------
|
|
390
|
+
writeNeverClobber(relPath, content, sha) {
|
|
391
|
+
const stateDir = realStateDir(this.d.stateDir);
|
|
392
|
+
// Peer relPath is HOSTILE input (§3.2): relative only, no `..` segment,
|
|
393
|
+
// no absolute/drive/UNC prefix — validated BEFORE any join.
|
|
394
|
+
if (!isSafeRelPath(relPath)) {
|
|
395
|
+
return { relPath, outcome: 'refused', reason: 'hostile relPath' };
|
|
396
|
+
}
|
|
397
|
+
const dest = path.resolve(stateDir, relPath);
|
|
398
|
+
if (!isContained(stateDir, dest)) {
|
|
399
|
+
return { relPath, outcome: 'refused', reason: 'jail escape' };
|
|
400
|
+
}
|
|
401
|
+
// Parent-directory realpath containment: never create-through a
|
|
402
|
+
// peer-supplied symlink/junction chain (§3.2).
|
|
403
|
+
const parent = path.dirname(dest);
|
|
404
|
+
fs.mkdirSync(parent, { recursive: true });
|
|
405
|
+
let realParent;
|
|
406
|
+
try {
|
|
407
|
+
realParent = fs.realpathSync(parent);
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
return { relPath, outcome: 'refused', reason: 'parent unresolvable' };
|
|
411
|
+
}
|
|
412
|
+
if (!isContained(stateDir, realParent)) {
|
|
413
|
+
return { relPath, outcome: 'refused', reason: 'parent escapes jail' };
|
|
414
|
+
}
|
|
415
|
+
const finalDest = path.join(realParent, path.basename(dest));
|
|
416
|
+
let destExists = false;
|
|
417
|
+
let destIsSame = false;
|
|
418
|
+
try {
|
|
419
|
+
const lst = fs.lstatSync(finalDest);
|
|
420
|
+
if (lst.isSymbolicLink()) {
|
|
421
|
+
return { relPath, outcome: 'refused', reason: 'destination is a symlink' };
|
|
422
|
+
}
|
|
423
|
+
destExists = true;
|
|
424
|
+
const existing = fs.readFileSync(finalDest);
|
|
425
|
+
destIsSame = crypto.createHash('sha256').update(existing).digest('hex') === sha;
|
|
426
|
+
}
|
|
427
|
+
catch { /* @silent-fallback-ok: absent destination is the normal first-transfer case — proceed to the jailed write (WORKING-SET-HANDOFF-SPEC §3.5) */
|
|
428
|
+
}
|
|
429
|
+
if (destExists && destIsSame)
|
|
430
|
+
return { relPath, outcome: 'skippedExisting' };
|
|
431
|
+
if (!destExists) {
|
|
432
|
+
writeAtomic(finalDest, content);
|
|
433
|
+
return { relPath, outcome: 'written' };
|
|
434
|
+
}
|
|
435
|
+
// Destination differs → alongside copy (NEVER overwrite, §3.5):
|
|
436
|
+
// <sanitizedBasename>.from-<senderShortId>-<hash8><ext> — hash-suffix
|
|
437
|
+
// makes repeated divergent arrivals naturally idempotent.
|
|
438
|
+
const ext = path.extname(finalDest);
|
|
439
|
+
const base = sanitizeBasename(path.basename(finalDest, ext));
|
|
440
|
+
const shortId = sanitizeBasename(this.d.senderShortId).slice(0, 12) || 'peer';
|
|
441
|
+
const alongsideName = `${base}.from-${shortId}-${sha.slice(0, 8)}${ext}`;
|
|
442
|
+
const alongsidePath = path.join(realParent, alongsideName);
|
|
443
|
+
if (!isContained(stateDir, alongsidePath)) {
|
|
444
|
+
return { relPath, outcome: 'refused', reason: 'alongside escapes jail' };
|
|
445
|
+
}
|
|
446
|
+
if (!fs.existsSync(alongsidePath)) {
|
|
447
|
+
writeAtomic(alongsidePath, content);
|
|
448
|
+
this.evictAlongsideOverCap(realParent, base, ext, shortIdSafePrefix(base));
|
|
449
|
+
}
|
|
450
|
+
return { relPath, outcome: 'alongside', alongsidePath };
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Cap-2 alongside retention (§3.5) — the single, narrow deletion exception:
|
|
454
|
+
* alongside files only, inside the jail, through SafeFsExecutor. The
|
|
455
|
+
* evicted copy's content still exists on its producer machine (first-hop
|
|
456
|
+
* provenance) — nothing is lost to the fleet, only to this replica.
|
|
457
|
+
*/
|
|
458
|
+
evictAlongsideOverCap(dir, base, ext, _prefix) {
|
|
459
|
+
let names;
|
|
460
|
+
try {
|
|
461
|
+
names = fs.readdirSync(dir);
|
|
462
|
+
}
|
|
463
|
+
catch { /* @silent-fallback-ok: eviction is best-effort housekeeping; a failed listing only delays the cap (WORKING-SET-HANDOFF-SPEC §3.5) */
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
const re = new RegExp(`^${escapeRegExp(base)}\\.from-[A-Za-z0-9_-]+-[0-9a-f]{8}${escapeRegExp(ext)}$`);
|
|
467
|
+
const matches = names
|
|
468
|
+
.filter((n) => re.test(n))
|
|
469
|
+
.map((n) => {
|
|
470
|
+
const p = path.join(dir, n);
|
|
471
|
+
let mtimeMs = 0;
|
|
472
|
+
try {
|
|
473
|
+
mtimeMs = fs.lstatSync(p).mtimeMs;
|
|
474
|
+
}
|
|
475
|
+
catch { /* @silent-fallback-ok: a vanished alongside candidate simply sorts oldest; eviction stays bounded (WORKING-SET-HANDOFF-SPEC §3.5) */
|
|
476
|
+
}
|
|
477
|
+
return { p, mtimeMs };
|
|
478
|
+
})
|
|
479
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs); // newest first
|
|
480
|
+
for (const victim of matches.slice(2)) {
|
|
481
|
+
try {
|
|
482
|
+
SafeFsExecutor.safeUnlinkSync(victim.p, {
|
|
483
|
+
operation: 'working-set alongside cap-2 eviction (WORKING-SET-HANDOFF-SPEC §3.5)',
|
|
484
|
+
});
|
|
485
|
+
this.d.logger?.(`alongside evicted (cap 2): ${path.basename(victim.p)}`);
|
|
486
|
+
}
|
|
487
|
+
catch { /* @silent-fallback-ok: eviction failure leaves an extra alongside copy — bounded growth, surfaced by the degradation counter (WORKING-SET-HANDOFF-SPEC §3.5) */
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// ---- busy retry (penalty-free, bounded) -----------------------------------
|
|
492
|
+
async sendWithBusyRetry(cmd) {
|
|
493
|
+
const cap = this.d.busyRetryCap ?? DEFAULT_BUSY_RETRY_CAP;
|
|
494
|
+
let delay = 50;
|
|
495
|
+
for (let i = 0; i < cap; i++) {
|
|
496
|
+
const res = await this.d.send(cmd);
|
|
497
|
+
if (!res.busy)
|
|
498
|
+
return res;
|
|
499
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
500
|
+
delay = Math.min(delay * 2, 5000);
|
|
501
|
+
}
|
|
502
|
+
return { busy: true }; // exhausted — caller re-files the pending-pull intact
|
|
503
|
+
}
|
|
504
|
+
yieldNow() {
|
|
505
|
+
if (this.d.yieldFn)
|
|
506
|
+
return this.d.yieldFn();
|
|
507
|
+
return new Promise((r) => setImmediate(r));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
// ── shared helpers ──────────────────────────────────────────────────
|
|
511
|
+
function anchorsEqual(a, b) {
|
|
512
|
+
return a.bytes === b.bytes && a.mtimeNs === b.mtimeNs && a.ino === b.ino;
|
|
513
|
+
}
|
|
514
|
+
function isSafeRelPath(relPath) {
|
|
515
|
+
if (!relPath || typeof relPath !== 'string')
|
|
516
|
+
return false;
|
|
517
|
+
if (path.isAbsolute(relPath))
|
|
518
|
+
return false;
|
|
519
|
+
if (/^[A-Za-z]:[\\/]/.test(relPath))
|
|
520
|
+
return false; // drive prefix
|
|
521
|
+
if (relPath.startsWith('\\\\'))
|
|
522
|
+
return false; // UNC
|
|
523
|
+
const segs = relPath.split(/[\\/]+/);
|
|
524
|
+
if (segs.some((s) => s === '..' || s === ''))
|
|
525
|
+
return false;
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
function isContained(root, p) {
|
|
529
|
+
const rel = path.relative(root, p);
|
|
530
|
+
return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));
|
|
531
|
+
}
|
|
532
|
+
function sanitizeBasename(name) {
|
|
533
|
+
return name.replace(/[^A-Za-z0-9._-]/g, '_');
|
|
534
|
+
}
|
|
535
|
+
function shortIdSafePrefix(base) {
|
|
536
|
+
return `${base}.from-`;
|
|
537
|
+
}
|
|
538
|
+
function writeAtomic(dest, content) {
|
|
539
|
+
const tmp = `${dest}.tmp-${process.pid}-${content.length}`;
|
|
540
|
+
fs.writeFileSync(tmp, content);
|
|
541
|
+
fs.renameSync(tmp, dest);
|
|
542
|
+
}
|
|
543
|
+
function escapeRegExp(s) {
|
|
544
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
545
|
+
}
|
|
546
|
+
//# sourceMappingURL=WorkingSetPull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkingSetPull.js","sourceRoot":"","sources":["../../src/core/WorkingSetPull.ts"],"names":[],"mappings":"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"}
|