@amalgm/shell 0.1.92 → 0.1.94

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.
@@ -12,7 +12,8 @@ import { EntityRecordSqliteStore } from "./entity-record-store.js";
12
12
  import { observeEntityRecordPorts } from "./entity-record-observability.js";
13
13
  import { indexRowsByOutermostRoot } from "./ground-root-index.js";
14
14
  import { ContentCacheDownload, captureContentFile, hashContentFile, sealCapturedArtifact, } from "./content-cache-host.js";
15
- import { decodeContentWireBytes, encodeContentWireBytes } from "./content-wire-codec.js";
15
+ import { DirectContentPlane } from "./content-direct.js";
16
+ import { encodeContentWireBytes } from "./content-wire-codec.js";
16
17
  import { exactTextReplay, planGroundDetection, reconcileGroundUUIDs, } from "./detection/portable.js";
17
18
  import { AcceptedInboxResultIndex } from "./detection/accepted-result.js";
18
19
  import { sameNotebookBasisRow } from "./detection/notebook-basis.js";
@@ -23,10 +24,16 @@ import { gitEvidenceFingerprint, inspectGitRegistration, sameGitIdentity, } from
23
24
  import { projectMaterializedGraph } from "./materialized-graph.js";
24
25
  import { NodeWatchHost, } from "./watching/index.js";
25
26
  import { GroundCoordinator } from "./ground-coordination.js";
27
+ import { submitMutationOperation } from "./paged-mutation-submit.js";
26
28
  import { WireClient, WireRequestError } from "./wire-client.js";
27
29
  const SMALL_CONTENT_UPLOAD_CONCURRENCY = 16;
28
- const FILE_CONTENT_DOWNLOAD_CONCURRENCY = 4;
29
- const FILE_BATCH_DOWNLOAD_CONCURRENCY = 2;
30
+ /** Artifact lanes for a download phase. Direct storage fetches cost the
31
+ * gateway nothing, so parallelism is bounded by this machine's pipe rather
32
+ * than authority fairness. */
33
+ const FILE_CONTENT_DOWNLOAD_CONCURRENCY = 16;
34
+ /** Block lanes within one artifact. Most files are a single block; large
35
+ * repository packs fan their chunks across this. */
36
+ const DIRECT_BLOCK_DOWNLOAD_CONCURRENCY = 8;
30
37
  const DETECT_QUIET_MS = 12;
31
38
  const DETECT_MAX_DEFERRAL_MS = 75;
32
39
  const DETECT_RETRY_MS = 250;
@@ -46,6 +53,7 @@ const GROUND_ROW_COLUMNS = [
46
53
  export class UserGroundHost {
47
54
  options;
48
55
  wire;
56
+ direct;
49
57
  watchHost;
50
58
  activeIdentity = null;
51
59
  rescanTimer = null;
@@ -74,6 +82,9 @@ export class UserGroundHost {
74
82
  runtimeVersion: options.runtimeVersion,
75
83
  requestTimeoutMs: options.wireRequestTimeoutMs,
76
84
  });
85
+ this.direct = new DirectContentPlane({
86
+ request: (frame, accept) => this.wire.request(frame, accept),
87
+ });
77
88
  this.watchHost = new NodeWatchHost({
78
89
  open: options.openWatch,
79
90
  onSignal: () => this.scheduleRescan(),
@@ -669,9 +680,10 @@ export class UserGroundHost {
669
680
  throw new Error("entity Record rail already started");
670
681
  await this.wire.open();
671
682
  // One floor, no per-feature gates: this shell and its gateway release
672
- // together, and the gateway ships first. 7 = one content contract and
673
- // deterministic manifest keys.
674
- if (this.wire.protocolVersion < 7) {
683
+ // together, and the gateway ships first. 9 = direct content downloads;
684
+ // an older gateway still relays download bytes itself and drops the key
685
+ // and presign frames this shell depends on.
686
+ if (this.wire.protocolVersion < 9) {
675
687
  throw new Error("gateway speaks an older wire protocol than this shell");
676
688
  }
677
689
  const store = new EntityRecordSqliteStore(initializeDatabase(this.databasePath(identity)));
@@ -1218,42 +1230,13 @@ export class UserGroundHost {
1218
1230
  measurements: { journey: trace?.journey ?? "bootstrap", kind: artifact.kind },
1219
1231
  });
1220
1232
  const cache = { target: null };
1221
- // A cold artifactno local manifest — is fetched whole in one round
1222
- // trip: get-artifact answers with the manifest and, for artifacts within
1223
- // the batch caps, every block packed in part order. Chunk reads then
1224
- // slice this buffer instead of paying a second round trip.
1225
- const prefetched = { bytes: null };
1226
- const sliceChunks = (packed, manifest, indexes) => {
1227
- const offsets = [];
1228
- let offset = 0;
1229
- for (const chunk of manifest.chunks) {
1230
- offsets.push(offset);
1231
- offset += chunk.bytes;
1232
- }
1233
- return Buffer.concat(indexes.map((index) => {
1234
- const chunk = manifest.chunks[index];
1235
- const start = offsets[index];
1236
- if (!chunk || start === undefined)
1237
- throw new Error(`content manifest has no chunk ${index}`);
1238
- return packed.subarray(start, start + chunk.bytes);
1239
- }));
1240
- };
1241
- const getChunk = async (manifest, index) => {
1242
- if (prefetched.bytes)
1243
- return sliceChunks(prefetched.bytes, manifest, [index]);
1244
- const chunk = manifest.chunks[index];
1245
- if (!chunk)
1246
- throw new Error(`content manifest has no chunk ${index}`);
1233
+ // Every storage objectthe manifest and each block — is fetched
1234
+ // straight from content storage over a presigned URL and opened locally;
1235
+ // the wire carries only the key handoff and signing requests. A retry
1236
+ // asks for a fresh URL every attempt.
1237
+ const fetchObject = async (object) => {
1247
1238
  requests += 1;
1248
- const frame = await retryContent(() => this.wire.request({
1249
- type: "private.entity-content.get",
1250
- resource_id: resourceId,
1251
- content_hash: artifact.contentHash,
1252
- kind: "chunk",
1253
- part_index: index,
1254
- sha256: chunk.sha256,
1255
- }, ["private.entity-content.data"]), true, retryAttempts);
1256
- const bytes = binaryFrameBytes(frame);
1239
+ const bytes = await retryContent(() => this.direct.fetchObject(resourceId, object), true, retryAttempts);
1257
1240
  downloadedBytes += bytes.byteLength;
1258
1241
  return bytes;
1259
1242
  };
@@ -1265,73 +1248,39 @@ export class UserGroundHost {
1265
1248
  // proves chunk identity; downloaded bytes are still hash-verified,
1266
1249
  // so a stale local manifest can only fail loudly, never corrupt.
1267
1250
  const local = knownManifest ?? readCachedManifest(cacheDir, artifact.contentHash);
1268
- if (local) {
1269
- cache.target = new ContentCacheDownload(cacheDir, artifact, local);
1270
- return local;
1271
- }
1272
- requests += 1;
1273
- const frame = await retryContent(() => this.wire.request({
1274
- type: "private.entity-content.get-artifact",
1275
- resource_id: resourceId,
1276
- content_hash: artifact.contentHash,
1277
- }, ["private.entity-content.artifact"]), true, retryAttempts);
1278
- const manifestJson = String(frame.manifest_json ?? "");
1279
- downloadedBytes += Buffer.byteLength(manifestJson);
1280
- const checked = checkContentManifest(JSON.parse(manifestJson), artifact.contentHash);
1281
- if (!checked.ok)
1282
- throw new Error(checked.error);
1283
- if (frame.complete === true) {
1284
- const decoded = await decodeContentWireBytes(binaryWireFrameBytes(frame), frame.content_encoding, Number(frame.bytes));
1285
- if (decoded.byteLength !== checked.value.bytes) {
1286
- throw new Error("artifact payload does not match its manifest");
1287
- }
1288
- prefetched.bytes = decoded;
1289
- downloadedBytes += Number(frame.wire_bytes ?? frame.bytes);
1290
- }
1291
- cache.target = new ContentCacheDownload(cacheDir, artifact, checked.value);
1292
- return checked.value;
1251
+ const manifest = local ?? await (async () => {
1252
+ const bytes = await fetchObject({ kind: "manifest", sha256: artifact.contentHash });
1253
+ const checked = checkContentManifest(JSON.parse(bytes.toString("utf8")), artifact.contentHash);
1254
+ if (!checked.ok)
1255
+ throw new Error(checked.error);
1256
+ return checked.value;
1257
+ })();
1258
+ cache.target = new ContentCacheDownload(cacheDir, artifact, manifest);
1259
+ return manifest;
1293
1260
  },
1294
1261
  hasChunk: async (_candidate, _manifest, index) => {
1295
1262
  if (!cache.target)
1296
1263
  throw new Error("download cache has no content manifest");
1297
1264
  return cache.target.hasChunk(index);
1298
1265
  },
1299
- getChunk: async (_candidate, manifest, index) => getChunk(manifest, index),
1300
- getChunkBatch: async (_candidate, manifest, indexes) => {
1301
- if (prefetched.bytes)
1302
- return sliceChunks(prefetched.bytes, manifest, indexes);
1303
- const frame = await retryContent(() => this.wire.request({
1304
- type: "private.entity-content.get-batch",
1305
- resource_id: resourceId,
1306
- content_hash: artifact.contentHash,
1307
- chunks: indexes.map((index) => ({
1308
- part_index: index,
1309
- sha256: manifest.chunks[index]?.sha256,
1310
- bytes: manifest.chunks[index]?.bytes,
1311
- })),
1312
- }, ["private.entity-content.data-batch"]), true, retryAttempts);
1313
- requests += 1;
1314
- const decoded = await decodeContentWireBytes(binaryWireFrameBytes(frame), frame.content_encoding, Number(frame.bytes));
1315
- downloadedBytes += Number(frame.wire_bytes ?? frame.bytes);
1316
- return decoded;
1266
+ getChunk: async (_candidate, manifest, index) => {
1267
+ const chunk = manifest.chunks[index];
1268
+ if (!chunk)
1269
+ throw new Error(`content manifest has no chunk ${index}`);
1270
+ return fetchObject({ kind: "block", sha256: chunk.sha256 });
1317
1271
  },
1318
1272
  putChunk: async (_candidate, _manifest, index, bytes) => {
1319
1273
  if (!cache.target)
1320
1274
  throw new Error("download cache has no content manifest");
1321
1275
  await cache.target.putChunk(index, bytes);
1322
1276
  },
1323
- putChunkBatch: async (_candidate, _manifest, indexes, bytes) => {
1324
- if (!cache.target)
1325
- throw new Error("download cache has no content manifest");
1326
- await cache.target.putChunkBatch(indexes, bytes);
1327
- },
1328
1277
  sealArtifact: async () => {
1329
1278
  if (!cache.target)
1330
1279
  throw new Error("download cache has no content manifest");
1331
1280
  const sealed = await cache.target.seal();
1332
1281
  return { local: sealed, bytes: sealed.bytes, contentHash: sealed.contentHash };
1333
1282
  },
1334
- }, artifact.kind === "file" ? { concurrency: FILE_BATCH_DOWNLOAD_CONCURRENCY } : {});
1283
+ }, { concurrency: DIRECT_BLOCK_DOWNLOAD_CONCURRENCY });
1335
1284
  this.stage({
1336
1285
  primitive: "download",
1337
1286
  stage: "immutable-content",
@@ -1819,20 +1768,16 @@ export class UserGroundHost {
1819
1768
  });
1820
1769
  }
1821
1770
  try {
1822
- frame = await this.wire.request({
1823
- type: "shared.mutation.submit",
1824
- envelope: {
1825
- resourceId: pending.resourceId,
1826
- authorityEpoch: pending.authorityEpoch,
1827
- mutationId: pending.mutationId,
1828
- deviceId: identity.deviceId,
1829
- baseVersion: pending.baseVersion,
1830
- contract: ENTITY_CLOUD_CONTRACT,
1831
- schemaVersion: ENTITY_CLOUD_SCHEMA_VERSION,
1832
- operationKind: replacement.kind,
1833
- operation: replacement,
1834
- },
1835
- }, ["shared.mutation.ack"]);
1771
+ frame = await submitMutationOperation(this.wire, {
1772
+ resourceId: pending.resourceId,
1773
+ authorityEpoch: pending.authorityEpoch,
1774
+ mutationId: pending.mutationId,
1775
+ deviceId: identity.deviceId,
1776
+ baseVersion: pending.baseVersion,
1777
+ contract: ENTITY_CLOUD_CONTRACT,
1778
+ schemaVersion: ENTITY_CLOUD_SCHEMA_VERSION,
1779
+ operationKind: replacement.kind,
1780
+ }, replacement);
1836
1781
  }
1837
1782
  catch (error) {
1838
1783
  if (trace?.journey === "register") {
@@ -4691,28 +4636,6 @@ function readyFromFrame(frame) {
4691
4636
  },
4692
4637
  };
4693
4638
  }
4694
- /** Expose the WebSocket payload as a view. Live verifies content blocks
4695
- * against their manifest, so the host must not copy or hash those bytes a
4696
- * second time before returning them to the portable operation. */
4697
- function binaryFrameBytes(frame) {
4698
- const bytes = binaryWireFrameBytes(frame);
4699
- if (frame.content_encoding !== undefined || bytes.length !== Number(frame.bytes)) {
4700
- throw new Error("wire content byte count does not match its header");
4701
- }
4702
- return bytes;
4703
- }
4704
- function binaryWireFrameBytes(frame) {
4705
- if (!(frame.data_bin instanceof Uint8Array)) {
4706
- throw new Error("wire content response is not a binary frame");
4707
- }
4708
- const bytes = Buffer.isBuffer(frame.data_bin)
4709
- ? frame.data_bin
4710
- : Buffer.from(frame.data_bin.buffer, frame.data_bin.byteOffset, frame.data_bin.byteLength);
4711
- if (bytes.length !== Number(frame.wire_bytes ?? frame.bytes)) {
4712
- throw new Error("wire content byte count does not match its header");
4713
- }
4714
- return bytes;
4715
- }
4716
4639
  /** Immutable content reads and writes are idempotent. Retry transient wire or
4717
4640
  * authority failures; reads additionally tolerate the brief not-found window
4718
4641
  * between an immutable object acknowledgement and globally visible R2 state. */