@amalgm/shell 0.1.153 → 0.1.154
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/PURPOSE.md +9 -1
- package/dist/detection/portable.js +27 -16
- package/dist/detection/portable.js.map +1 -1
- package/dist/user-ground-host.d.ts +9 -1
- package/dist/user-ground-host.js +38 -11
- package/dist/user-ground-host.js.map +1 -1
- package/npm-shrinkwrap.json +10 -12
- package/package.json +3 -3
package/PURPOSE.md
CHANGED
|
@@ -758,7 +758,15 @@ shell only assembles.
|
|
|
758
758
|
later records may Apply. When publication folds that tail, final ancestry
|
|
759
759
|
in the complete prefix places every result: a container created after the
|
|
760
760
|
snapshot can own later children, and a cross-root move vacates its old root;
|
|
761
|
-
old snapshot membership alone never chooses the result's root. The
|
|
761
|
+
old snapshot membership alone never chooses the result's root. The settled
|
|
762
|
+
fold passes through the repository parcel projection exactly as publication
|
|
763
|
+
does: a tail that turns a container into a repository retires that
|
|
764
|
+
container's snapshot children into its parcel, and a tail that turns a
|
|
765
|
+
repository back into a folder carries every newly independent descendant
|
|
766
|
+
first and the boundary retype last. Every retype into a container uses the
|
|
767
|
+
same visibility barrier because it may expose descendant ground, so no
|
|
768
|
+
committed delivery prefix can expose a partial tree and Add never selects
|
|
769
|
+
a graph the parcel law would not publish. The first
|
|
762
770
|
later record on an entity UUID establishes its immediate entity predecessor
|
|
763
771
|
from the complete snapshot prefix, after which ordinary dense per-entity gap
|
|
764
772
|
checking resumes. A publisher may name only the exact locally received
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* It only binds already-observed ground to durable UUIDs and asks Live to
|
|
5
5
|
* plan the exact Watch generation that Record may accept.
|
|
6
6
|
*/
|
|
7
|
-
import { CONTAINERS, captureTextChange, detectionBatch, diffDirState,
|
|
7
|
+
import { CONTAINERS, captureTextChange, detectionBatch, diffDirState, matchByInode, planDetectionBatch, travelingRecordUUIDs, } from "@amalgm/live";
|
|
8
8
|
/**
|
|
9
9
|
* Choose an exact text replay from cache evidence. The notebook's base head
|
|
10
10
|
* is logical history; cached base bytes are only an optional delta input.
|
|
@@ -108,35 +108,46 @@ export function planGroundDetection(input) {
|
|
|
108
108
|
const beforeByUuid = new Map(input.before.map((record) => [record.uuid, record]));
|
|
109
109
|
const afterRecords = input.after.map((row) => row.record);
|
|
110
110
|
const afterByUuid = new Map(input.after.map((row) => [row.record.uuid, row]));
|
|
111
|
-
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
const afterEnclosed = (record) => enclosedByRepositoryAncestor(record, (uuid) => afterRecordByUuid.get(uuid));
|
|
111
|
+
// Publication membership is the repository law itself, including nested
|
|
112
|
+
// repository spines. Enclosure alone is insufficient because a spine is
|
|
113
|
+
// enclosed but deliberately still travels.
|
|
114
|
+
const beforeTraveling = travelingRecordUUIDs(input.before);
|
|
115
|
+
const afterTraveling = travelingRecordUUIDs(afterRecords);
|
|
117
116
|
const transitions = [];
|
|
117
|
+
const visibilityBarriers = [];
|
|
118
118
|
for (const uuid of new Set([...beforeByUuid.keys(), ...afterByUuid.keys()])) {
|
|
119
119
|
const base = beforeByUuid.get(uuid) ?? null;
|
|
120
120
|
const current = afterByUuid.get(uuid) ?? null;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const repositoryBoundary = base?.type === "repo.git" || current?.record.type === "repo.git";
|
|
124
|
-
if (!repositoryBoundary
|
|
125
|
-
&& ((current === null && baseEnclosed)
|
|
126
|
-
|| (current !== null && resultEnclosed)))
|
|
121
|
+
if ((current === null && !beforeTraveling.has(uuid))
|
|
122
|
+
|| (current !== null && !afterTraveling.has(uuid)))
|
|
127
123
|
continue;
|
|
128
124
|
if (current === null) {
|
|
129
125
|
transitions.push({ truth: "absent", base });
|
|
130
126
|
continue;
|
|
131
127
|
}
|
|
132
|
-
|
|
128
|
+
const becameTraveling = !beforeTraveling.has(uuid) && afterTraveling.has(uuid);
|
|
129
|
+
const transition = {
|
|
133
130
|
truth: "present",
|
|
134
131
|
relPath: current.relativePath,
|
|
135
|
-
|
|
132
|
+
// A repository-owned child had no independent cloud record. Its local
|
|
133
|
+
// notebook row is identity evidence, not an authority base.
|
|
134
|
+
base: becameTraveling ? null : base,
|
|
136
135
|
result: current.record,
|
|
137
136
|
replay: current.replay ?? { kind: "structure" },
|
|
138
|
-
}
|
|
137
|
+
};
|
|
138
|
+
if (base !== null
|
|
139
|
+
&& base.type !== current.record.type
|
|
140
|
+
&& (current.record.type === "workspace" || current.record.type === "folder")) {
|
|
141
|
+
visibilityBarriers.push(transition);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
transitions.push(transition);
|
|
145
|
+
}
|
|
139
146
|
}
|
|
147
|
+
// Newly independent descendants must enter the official prefix before the
|
|
148
|
+
// parent retype makes them visible. The Send rail publishes that final
|
|
149
|
+
// visibility barrier alone.
|
|
150
|
+
transitions.push(...visibilityBarriers);
|
|
140
151
|
try {
|
|
141
152
|
return planDetectionBatch(batch, transitions);
|
|
142
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portable.js","sourceRoot":"","sources":["../../src/detection/portable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"portable.js","sourceRoot":"","sources":["../../src/detection/portable.ts"],"names":[],"mappings":"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"}
|
|
@@ -210,7 +210,15 @@ export declare class UserGroundHost {
|
|
|
210
210
|
* contains only through delivered results may still file unchanged
|
|
211
211
|
* descendants under the root that used to hold it, so that root's records
|
|
212
212
|
* join the base and the fold reruns until no probe widens it. Leaf results
|
|
213
|
-
* travel whole and never probe.
|
|
213
|
+
* travel whole and never probe.
|
|
214
|
+
*
|
|
215
|
+
* The published base is already the repository parcel projection; the tail
|
|
216
|
+
* is not. A result that turns a container into a repository says nothing
|
|
217
|
+
* about that container's snapshot children, which now ride in its parcel.
|
|
218
|
+
* Probing reads the unprojected fold so a spine the tail moved still widens
|
|
219
|
+
* through its old root, and the settled fold then passes through the one
|
|
220
|
+
* projection publication uses — no reader ever selects a graph the parcel
|
|
221
|
+
* law would not publish. */
|
|
214
222
|
private foldScopedPrefix;
|
|
215
223
|
/** Read one graph page by identity: cached pages come off local disk, the
|
|
216
224
|
* rest are fetched straight from content storage and cached on the way in.
|
package/dist/user-ground-host.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, lstatSync, realpathSync, readFileSync, readdirSync, readlin
|
|
|
3
3
|
import { open, readFile } from "node:fs/promises";
|
|
4
4
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { buildUserHomeManifest, buildUserManifest, liveMachineStateDir, scopedAmalgmDir, shippedUserHomeDeclaration, } from "@amalgm/core/identity";
|
|
6
|
-
import { CHUNK_BYTES, CONTENT_CONTRACT, INLINE_CARGO_MAX_BYTES, ENTITY_CLOUD_CONTRACT, ENTITY_CLOUD_SCHEMA_VERSION, artifactForRecord, canonicalVersion, checkContentManifest, classifyDirectory, classifyFile, classifyRegisteredRoot, containedRecords, createLocalEntityRecord, createEntityRecordAuthorityPort, convergeUserGround, decodeAcceptedEntityRecord, deriveUploadManifest, createUserGroundEnrollmentPolicy, isRepositoryMetadataEntry, indexRepositoryTerritory, downloadAll as downloadAllArtifacts, encodeEntityRecord, EntityApplyRail, EntityRecordRail, membershipHash, materializedSlotNames, pathIsSuspect, CONTENT_REFS_BATCH_OBJECTS, privateEntityResourceId, repositoryIdentityHash, sameRecords, snapshotFromRecords, stableJson, streamCargo, travelingRecords, upload as uploadArtifact, userGroundRecords, portableFileMode, GRAPH_HEAD_OPERATION_KIND, } from "@amalgm/live";
|
|
6
|
+
import { CHUNK_BYTES, CONTENT_CONTRACT, INLINE_CARGO_MAX_BYTES, ENTITY_CLOUD_CONTRACT, ENTITY_CLOUD_SCHEMA_VERSION, artifactForRecord, canonicalVersion, checkContentManifest, classifyDirectory, classifyFile, classifyRegisteredRoot, containedRecords, ContentPlacementChangedError, createLocalEntityRecord, createEntityRecordAuthorityPort, convergeUserGround, decodeAcceptedEntityRecord, deriveUploadManifest, createUserGroundEnrollmentPolicy, isRepositoryMetadataEntry, indexRepositoryTerritory, downloadAll as downloadAllArtifacts, encodeEntityRecord, EntityApplyRail, EntityRecordRail, membershipHash, materializedSlotNames, pathIsSuspect, CONTENT_REFS_BATCH_OBJECTS, privateEntityResourceId, repositoryIdentityHash, sameRecords, snapshotFromRecords, stableJson, streamCargo, travelingRecords, travelingRecordUUIDs, upload as uploadArtifact, userGroundRecords, portableFileMode, GRAPH_HEAD_OPERATION_KIND, } from "@amalgm/live";
|
|
7
7
|
import Database from "better-sqlite3";
|
|
8
8
|
import { atomicCopy, atomicWrite, ensurePrivateDir, ensureUserDir } from "./filesystem.js";
|
|
9
9
|
import { emitFilesStage, } from "./files-observability.js";
|
|
@@ -1324,7 +1324,15 @@ export class UserGroundHost {
|
|
|
1324
1324
|
* contains only through delivered results may still file unchanged
|
|
1325
1325
|
* descendants under the root that used to hold it, so that root's records
|
|
1326
1326
|
* join the base and the fold reruns until no probe widens it. Leaf results
|
|
1327
|
-
* travel whole and never probe.
|
|
1327
|
+
* travel whole and never probe.
|
|
1328
|
+
*
|
|
1329
|
+
* The published base is already the repository parcel projection; the tail
|
|
1330
|
+
* is not. A result that turns a container into a repository says nothing
|
|
1331
|
+
* about that container's snapshot children, which now ride in its parcel.
|
|
1332
|
+
* Probing reads the unprojected fold so a spine the tail moved still widens
|
|
1333
|
+
* through its old root, and the settled fold then passes through the one
|
|
1334
|
+
* projection publication uses — no reader ever selects a graph the parcel
|
|
1335
|
+
* law would not publish. */
|
|
1328
1336
|
async foldScopedPrefix(base, accepted, boundaryId) {
|
|
1329
1337
|
if (accepted.length === 0)
|
|
1330
1338
|
return base;
|
|
@@ -1333,14 +1341,14 @@ export class UserGroundHost {
|
|
|
1333
1341
|
throw new Error("cloud state is unavailable for a registry lookup");
|
|
1334
1342
|
const probed = new Set(base.map((record) => record.uuid));
|
|
1335
1343
|
let widened = base;
|
|
1344
|
+
let folded = recordsAtDeliveryPrefix(widened, accepted);
|
|
1336
1345
|
for (;;) {
|
|
1337
|
-
const folded = recordsAtDeliveryPrefix(widened, accepted);
|
|
1338
1346
|
const probes = containedRecords(folded, boundaryId)
|
|
1339
1347
|
.filter((record) => !probed.has(record.uuid)
|
|
1340
1348
|
&& (record.type === "workspace" || record.type === "folder" || record.type === "repo.git"))
|
|
1341
1349
|
.map((record) => record.uuid);
|
|
1342
1350
|
if (probes.length === 0)
|
|
1343
|
-
|
|
1351
|
+
break;
|
|
1344
1352
|
for (const uuid of probes)
|
|
1345
1353
|
probed.add(uuid);
|
|
1346
1354
|
const located = await graph.membership(new Set(probes));
|
|
@@ -1351,9 +1359,11 @@ export class UserGroundHost {
|
|
|
1351
1359
|
}
|
|
1352
1360
|
}
|
|
1353
1361
|
if (merged.size === widened.length)
|
|
1354
|
-
|
|
1362
|
+
break;
|
|
1355
1363
|
widened = [...merged.values()];
|
|
1364
|
+
folded = recordsAtDeliveryPrefix(widened, accepted);
|
|
1356
1365
|
}
|
|
1366
|
+
return travelingRecords(folded, sha256Hex);
|
|
1357
1367
|
}
|
|
1358
1368
|
/** Read one graph page by identity: cached pages come off local disk, the
|
|
1359
1369
|
* rest are fetched straight from content storage and cached on the way in.
|
|
@@ -1913,8 +1923,9 @@ export class UserGroundHost {
|
|
|
1913
1923
|
// straight from content storage over a presigned URL and opened
|
|
1914
1924
|
// locally; the engine plans whole waves against these primitives, so
|
|
1915
1925
|
// the wire carries only the key handoff and batched refs requests. A
|
|
1916
|
-
// retried read refreshes its URL
|
|
1917
|
-
//
|
|
1926
|
+
// retried read refreshes its URL in place. If physical placement moved,
|
|
1927
|
+
// Live discards every ref derived from that stale geometry and boundedly
|
|
1928
|
+
// replans the unresolved set; content identity remains immutable.
|
|
1918
1929
|
const { receipts, shape } = await downloadAllArtifacts([...unique.values()].map((want) => want.artifact), {
|
|
1919
1930
|
sha256Hex: timedSha256Hex,
|
|
1920
1931
|
localManifest: (artifact) => legs.timeSync("planMs", () => {
|
|
@@ -1937,9 +1948,12 @@ export class UserGroundHost {
|
|
|
1937
1948
|
signed = await refresh();
|
|
1938
1949
|
}
|
|
1939
1950
|
catch (error) {
|
|
1940
|
-
// A moved placement
|
|
1941
|
-
//
|
|
1942
|
-
//
|
|
1951
|
+
// A moved placement is a set-planning signal owned by Live,
|
|
1952
|
+
// not a permanent wire failure. Preserve it across the host
|
|
1953
|
+
// retry boundary so the whole unresolved set can replan.
|
|
1954
|
+
if (error instanceof ContentPlacementChangedError)
|
|
1955
|
+
throw error;
|
|
1956
|
+
// A refused re-resolution is not a transient byte fetch.
|
|
1943
1957
|
throw new WireRequestError({
|
|
1944
1958
|
type: "shared.error",
|
|
1945
1959
|
code: "entity_content_moved",
|
|
@@ -5481,11 +5495,20 @@ async function reconcileRoot(input) {
|
|
|
5481
5495
|
.map((row) => row.uuid);
|
|
5482
5496
|
const before = existingRows.map(portableRecord);
|
|
5483
5497
|
const beforeByUuid = new Map(before.map((record) => [record.uuid, record]));
|
|
5498
|
+
const afterLogicalRecords = [
|
|
5499
|
+
...rows.map((row) => row.record),
|
|
5500
|
+
...retainedMissingRows.map(portableRecord),
|
|
5501
|
+
];
|
|
5502
|
+
const beforeTraveling = travelingRecordUUIDs(before);
|
|
5503
|
+
const afterTraveling = travelingRecordUUIDs(afterLogicalRecords);
|
|
5484
5504
|
const entryByUuid = new Map(entries.map((entry) => [entry.uuid, entry]));
|
|
5485
5505
|
// Replays exist to mint Send records; a scan that plans none builds none —
|
|
5486
5506
|
// and its walk staged no cache bytes for replays to read.
|
|
5487
5507
|
const detected = !plansSendRecords ? [] : rows.map((row) => {
|
|
5488
|
-
const
|
|
5508
|
+
const localBase = beforeByUuid.get(row.record.uuid) ?? null;
|
|
5509
|
+
const becameTraveling = !beforeTraveling.has(row.record.uuid)
|
|
5510
|
+
&& afterTraveling.has(row.record.uuid);
|
|
5511
|
+
const base = becameTraveling ? null : localBase;
|
|
5489
5512
|
const entry = entryByUuid.get(row.record.uuid);
|
|
5490
5513
|
if (row.record.type !== "repo.git" && entry && territory.ownerOf(entry)) {
|
|
5491
5514
|
return {
|
|
@@ -6530,6 +6553,10 @@ async function retryContent(operation, eventualNotFound = false, attempts = 10)
|
|
|
6530
6553
|
}
|
|
6531
6554
|
catch (error) {
|
|
6532
6555
|
last = error;
|
|
6556
|
+
// Physical geometry moved. The current fetch unit and every sibling ref
|
|
6557
|
+
// came from one stale plan, so only Live's outer set loop may retry it.
|
|
6558
|
+
if (error instanceof ContentPlacementChangedError)
|
|
6559
|
+
throw error;
|
|
6533
6560
|
if (error instanceof WireRequestError
|
|
6534
6561
|
&& !error.retryable
|
|
6535
6562
|
&& !(eventualNotFound && error.code === "entity_content_not_found"))
|