@amalgm/live 0.2.26 → 0.2.28
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 +52 -29
- package/README.md +1 -2
- package/dist/contracts/index.d.ts +0 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +0 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/detection/record-proposal.d.ts +3 -2
- package/dist/detection/record-proposal.d.ts.map +1 -1
- package/dist/detection/record-proposal.js +9 -7
- package/dist/detection/record-proposal.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/machines/index.d.ts +0 -2
- package/dist/machines/index.d.ts.map +1 -1
- package/dist/machines/index.js +0 -2
- package/dist/machines/index.js.map +1 -1
- package/dist/records/authority.d.ts +23 -0
- package/dist/records/authority.d.ts.map +1 -0
- package/dist/records/authority.js +28 -0
- package/dist/records/authority.js.map +1 -0
- package/dist/records/codec.d.ts +6 -0
- package/dist/records/codec.d.ts.map +1 -0
- package/dist/records/codec.js +42 -0
- package/dist/records/codec.js.map +1 -0
- package/dist/records/contracts.d.ts +46 -0
- package/dist/records/contracts.d.ts.map +1 -0
- package/dist/records/contracts.js +114 -0
- package/dist/records/contracts.js.map +1 -0
- package/dist/records/inbox.d.ts +18 -0
- package/dist/records/inbox.d.ts.map +1 -0
- package/dist/records/inbox.js +34 -0
- package/dist/records/inbox.js.map +1 -0
- package/dist/records/index.d.ts +7 -0
- package/dist/records/index.d.ts.map +1 -0
- package/dist/records/index.js +7 -0
- package/dist/records/index.js.map +1 -0
- package/dist/records/outbox.d.ts +20 -0
- package/dist/records/outbox.d.ts.map +1 -0
- package/dist/records/outbox.js +44 -0
- package/dist/records/outbox.js.map +1 -0
- package/dist/registration/user-ground.d.ts +5 -2
- package/dist/registration/user-ground.d.ts.map +1 -1
- package/dist/registration/user-ground.js +14 -3
- package/dist/registration/user-ground.js.map +1 -1
- package/dist/watching/suspicion.d.ts.map +1 -1
- package/dist/watching/suspicion.js +29 -1
- package/dist/watching/suspicion.js.map +1 -1
- package/dist-cjs/contracts/binding.js +26 -0
- package/dist-cjs/contracts/binding.js.map +1 -0
- package/dist-cjs/contracts/content.js +99 -0
- package/dist-cjs/contracts/content.js.map +1 -0
- package/dist-cjs/contracts/docs.js +56 -0
- package/dist-cjs/contracts/docs.js.map +1 -0
- package/dist-cjs/contracts/events.js +44 -0
- package/dist-cjs/contracts/events.js.map +1 -0
- package/dist-cjs/contracts/frames/gateway.js +39 -0
- package/dist-cjs/contracts/frames/gateway.js.map +1 -0
- package/dist-cjs/contracts/frames/stream.js +20 -0
- package/dist-cjs/contracts/frames/stream.js.map +1 -0
- package/dist-cjs/contracts/frames/tunnel.js +60 -0
- package/dist-cjs/contracts/frames/tunnel.js.map +1 -0
- package/dist-cjs/contracts/index.js +34 -0
- package/dist-cjs/contracts/index.js.map +1 -0
- package/dist-cjs/contracts/presence.js +38 -0
- package/dist-cjs/contracts/presence.js.map +1 -0
- package/dist-cjs/contracts/resources.js +114 -0
- package/dist-cjs/contracts/resources.js.map +1 -0
- package/dist-cjs/contracts/snapshot.js +31 -0
- package/dist-cjs/contracts/snapshot.js.map +1 -0
- package/dist-cjs/contracts/validate.js +34 -0
- package/dist-cjs/contracts/validate.js.map +1 -0
- package/dist-cjs/detection/adapter-contract.js +168 -0
- package/dist-cjs/detection/adapter-contract.js.map +1 -0
- package/dist-cjs/detection/batch.js +71 -0
- package/dist-cjs/detection/batch.js.map +1 -0
- package/dist-cjs/detection/classify.js +48 -0
- package/dist-cjs/detection/classify.js.map +1 -0
- package/dist-cjs/detection/content.js +122 -0
- package/dist-cjs/detection/content.js.map +1 -0
- package/dist-cjs/detection/continuity.js +88 -0
- package/dist-cjs/detection/continuity.js.map +1 -0
- package/dist-cjs/detection/diff.js +193 -0
- package/dist-cjs/detection/diff.js.map +1 -0
- package/dist-cjs/detection/echo.js +25 -0
- package/dist-cjs/detection/echo.js.map +1 -0
- package/dist-cjs/detection/enrollment.js +189 -0
- package/dist-cjs/detection/enrollment.js.map +1 -0
- package/dist-cjs/detection/index.js +57 -0
- package/dist-cjs/detection/index.js.map +1 -0
- package/dist-cjs/detection/record-proposal.js +170 -0
- package/dist-cjs/detection/record-proposal.js.map +1 -0
- package/dist-cjs/detection/refusal.js +44 -0
- package/dist-cjs/detection/refusal.js.map +1 -0
- package/dist-cjs/detection/repository.js +67 -0
- package/dist-cjs/detection/repository.js.map +1 -0
- package/dist-cjs/detection/territory.js +82 -0
- package/dist-cjs/detection/territory.js.map +1 -0
- package/dist-cjs/detection/watch-boundary.js +51 -0
- package/dist-cjs/detection/watch-boundary.js.map +1 -0
- package/dist-cjs/entities/bytes.js +92 -0
- package/dist-cjs/entities/bytes.js.map +1 -0
- package/dist-cjs/entities/cloud.js +171 -0
- package/dist-cjs/entities/cloud.js.map +1 -0
- package/dist-cjs/entities/index.js +39 -0
- package/dist-cjs/entities/index.js.map +1 -0
- package/dist-cjs/entities/moves.js +85 -0
- package/dist-cjs/entities/moves.js.map +1 -0
- package/dist-cjs/entities/repo-states.js +256 -0
- package/dist-cjs/entities/repo-states.js.map +1 -0
- package/dist-cjs/entities/rules.js +216 -0
- package/dist-cjs/entities/rules.js.map +1 -0
- package/dist-cjs/entities/types.js +44 -0
- package/dist-cjs/entities/types.js.map +1 -0
- package/dist-cjs/files/commands.js +120 -0
- package/dist-cjs/files/commands.js.map +1 -0
- package/dist-cjs/files/index.js +19 -0
- package/dist-cjs/files/index.js.map +1 -0
- package/dist-cjs/index.js +39 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/machines/arbitration.js +41 -0
- package/dist-cjs/machines/arbitration.js.map +1 -0
- package/dist-cjs/machines/backoff.js +38 -0
- package/dist-cjs/machines/backoff.js.map +1 -0
- package/dist-cjs/machines/bootstrap.js +110 -0
- package/dist-cjs/machines/bootstrap.js.map +1 -0
- package/dist-cjs/machines/chunks.js +72 -0
- package/dist-cjs/machines/chunks.js.map +1 -0
- package/dist-cjs/machines/index.js +28 -0
- package/dist-cjs/machines/index.js.map +1 -0
- package/dist-cjs/machines/presence.js +53 -0
- package/dist-cjs/machines/presence.js.map +1 -0
- package/dist-cjs/merge/index.js +25 -0
- package/dist-cjs/merge/index.js.map +1 -0
- package/dist-cjs/merge/merge3.js +191 -0
- package/dist-cjs/merge/merge3.js.map +1 -0
- package/dist-cjs/package.json +1 -0
- package/dist-cjs/records/authority.js +31 -0
- package/dist-cjs/records/authority.js.map +1 -0
- package/dist-cjs/records/codec.js +48 -0
- package/dist-cjs/records/codec.js.map +1 -0
- package/dist-cjs/records/contracts.js +121 -0
- package/dist-cjs/records/contracts.js.map +1 -0
- package/dist-cjs/records/inbox.js +37 -0
- package/dist-cjs/records/inbox.js.map +1 -0
- package/dist-cjs/records/index.js +23 -0
- package/dist-cjs/records/index.js.map +1 -0
- package/dist-cjs/records/outbox.js +48 -0
- package/dist-cjs/records/outbox.js.map +1 -0
- package/dist-cjs/registration/index.js +19 -0
- package/dist-cjs/registration/index.js.map +1 -0
- package/dist-cjs/registration/user-ground.js +183 -0
- package/dist-cjs/registration/user-ground.js.map +1 -0
- package/dist-cjs/transfer/artifacts.js +75 -0
- package/dist-cjs/transfer/artifacts.js.map +1 -0
- package/dist-cjs/transfer/batches.js +44 -0
- package/dist-cjs/transfer/batches.js.map +1 -0
- package/dist-cjs/transfer/download.js +88 -0
- package/dist-cjs/transfer/download.js.map +1 -0
- package/dist-cjs/transfer/index.js +21 -0
- package/dist-cjs/transfer/index.js.map +1 -0
- package/dist-cjs/transfer/parallel.js +35 -0
- package/dist-cjs/transfer/parallel.js.map +1 -0
- package/dist-cjs/transfer/upload.js +161 -0
- package/dist-cjs/transfer/upload.js.map +1 -0
- package/dist-cjs/watching/coverage.js +54 -0
- package/dist-cjs/watching/coverage.js.map +1 -0
- package/dist-cjs/watching/index.js +24 -0
- package/dist-cjs/watching/index.js.map +1 -0
- package/dist-cjs/watching/suspicion.js +105 -0
- package/dist-cjs/watching/suspicion.js.map +1 -0
- package/dist-cjs/workspace/api.js +66 -0
- package/dist-cjs/workspace/api.js.map +1 -0
- package/dist-cjs/workspace/identity.js +32 -0
- package/dist-cjs/workspace/identity.js.map +1 -0
- package/dist-cjs/workspace/index.js +14 -0
- package/dist-cjs/workspace/index.js.map +1 -0
- package/dist-cjs/workspace/memory-store.js +21 -0
- package/dist-cjs/workspace/memory-store.js.map +1 -0
- package/dist-cjs/workspace/registry.js +98 -0
- package/dist-cjs/workspace/registry.js.map +1 -0
- package/dist-cjs/workspace/types.js +3 -0
- package/dist-cjs/workspace/types.js.map +1 -0
- package/package.json +30 -8
- package/dist/contracts/mutation.d.ts +0 -51
- package/dist/contracts/mutation.d.ts.map +0 -1
- package/dist/contracts/mutation.js +0 -55
- package/dist/contracts/mutation.js.map +0 -1
- package/dist/machines/journal.d.ts +0 -63
- package/dist/machines/journal.d.ts.map +0 -1
- package/dist/machines/journal.js +0 -71
- package/dist/machines/journal.js.map +0 -1
- package/dist/machines/ordering.d.ts +0 -53
- package/dist/machines/ordering.d.ts.map +0 -1
- package/dist/machines/ordering.js +0 -87
- package/dist/machines/ordering.js.map +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Batch move validation — the entity model's one-truth-transition law for
|
|
4
|
+
* addresses (engine docs/entity-model.md, "Continuity"): the slot law and
|
|
5
|
+
* acyclicity are STATE invariants — they constrain the graph after the
|
|
6
|
+
* batch, never the order inside it — so movers may hold each other's slots
|
|
7
|
+
* (directories exchange addresses on disk, and detection reports the
|
|
8
|
+
* endpoints). A single move is a batch of one.
|
|
9
|
+
*
|
|
10
|
+
* A PARENTLESS mover is ADOPTION: the whole tree joins another under one
|
|
11
|
+
* parent update — a tree boundary is never an identity boundary, so this
|
|
12
|
+
* is the same lawful move, not a special ceremony. Adoption sheds the root
|
|
13
|
+
* shape in the SAME transition: workspace is the root type only, so a
|
|
14
|
+
* parentless workspace landing under a parent lands as a folder — one
|
|
15
|
+
* write, never a two-step that could tear into a nested workspace.
|
|
16
|
+
*
|
|
17
|
+
* This module validates and PLANS; the host's store applies the returned
|
|
18
|
+
* writes in one transaction.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.planMoveBatch = planMoveBatch;
|
|
22
|
+
const types_js_1 = require("./types.js");
|
|
23
|
+
const rules_js_1 = require("./rules.js");
|
|
24
|
+
/**
|
|
25
|
+
* Validate one batch of moves as one transition and return the writes to
|
|
26
|
+
* land together. Refused whole when any move breaks a law: a mover named
|
|
27
|
+
* twice, an inactive mover, an invalid name, a non-container target, two
|
|
28
|
+
* movers claiming one slot, an occupied slot outside the batch, a cycle in
|
|
29
|
+
* the post-state parent graph, or an inactive target chain.
|
|
30
|
+
*/
|
|
31
|
+
function planMoveBatch(moves, port) {
|
|
32
|
+
const byUuid = port.byUuid.bind(port);
|
|
33
|
+
const rows = new Map(); // uuid -> current row
|
|
34
|
+
const post = new Map(); // uuid -> its move
|
|
35
|
+
for (const move of moves) {
|
|
36
|
+
const { uuid, name } = move;
|
|
37
|
+
if (post.has(uuid))
|
|
38
|
+
throw new Error(`one batch moves ${uuid} once, not twice`);
|
|
39
|
+
const row = (0, rules_js_1.mustGet)(uuid, byUuid);
|
|
40
|
+
if (row.status !== 'active') {
|
|
41
|
+
throw new Error(`only an active entity moves: ${uuid} is ${row.status}`);
|
|
42
|
+
}
|
|
43
|
+
(0, rules_js_1.validName)(name);
|
|
44
|
+
rows.set(uuid, row);
|
|
45
|
+
post.set(uuid, move);
|
|
46
|
+
}
|
|
47
|
+
const postParentOf = (uuid) => post.get(uuid)?.parentUUID ?? (0, rules_js_1.mustGet)(uuid, byUuid).parentUuid;
|
|
48
|
+
const targets = new Set();
|
|
49
|
+
for (const { uuid, parentUUID, name } of moves) {
|
|
50
|
+
const parent = (0, rules_js_1.mustGet)(parentUUID, byUuid);
|
|
51
|
+
if (!types_js_1.CONTAINERS.has(parent.type)) {
|
|
52
|
+
throw new Error(`only containers hold active children: ${parentUUID} is ${parent.type}, not workspace/folder/repo.git`);
|
|
53
|
+
}
|
|
54
|
+
const slot = `${parentUUID}\0${name}`;
|
|
55
|
+
if (targets.has(slot))
|
|
56
|
+
throw new Error(`slot taken: two movers claim (${parentUUID}, ${name}) in one batch`);
|
|
57
|
+
targets.add(slot);
|
|
58
|
+
const occupant = port.activeChildByName(parentUUID, name);
|
|
59
|
+
if (occupant && occupant.uuid !== uuid && !post.has(occupant.uuid)) {
|
|
60
|
+
throw new Error(`slot taken: active entity ${occupant.uuid} already owns (${parentUUID}, ${name}) — move or trash it first`);
|
|
61
|
+
}
|
|
62
|
+
// The target parent's whole post-state chain: acyclic and effectively
|
|
63
|
+
// active, walked once.
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
let cursor = parentUUID;
|
|
66
|
+
while (cursor !== null) {
|
|
67
|
+
if (cursor === uuid) {
|
|
68
|
+
throw new Error(`the parent graph is acyclic: ${uuid} cannot live under itself`);
|
|
69
|
+
}
|
|
70
|
+
if (seen.has(cursor))
|
|
71
|
+
throw new Error(`registry corrupt: parent cycle at ${cursor}`);
|
|
72
|
+
seen.add(cursor);
|
|
73
|
+
if ((0, rules_js_1.mustGet)(cursor, byUuid).status !== 'active') {
|
|
74
|
+
throw new Error(`parent ${parentUUID} is not effectively active — restore it before putting entities under it`);
|
|
75
|
+
}
|
|
76
|
+
cursor = postParentOf(cursor);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return moves.map(({ uuid, parentUUID, name }) => {
|
|
80
|
+
const row = rows.get(uuid); // seated in the first pass
|
|
81
|
+
const adoptedWorkspace = row.parentUuid === null && row.type === 'workspace';
|
|
82
|
+
return { uuid, parentUuid: parentUUID, name, ...(adoptedWorkspace ? { type: 'folder' } : {}) };
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=moves.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moves.js","sourceRoot":"","sources":["../../src/entities/moves.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Portable repository state and binary transport.
|
|
4
|
+
*
|
|
5
|
+
* Git object bytes remain a native PACK stream. Amalgm metadata is a short
|
|
6
|
+
* UTF-8 JSON header followed by raw checkpoint cargo; no byte field is ever
|
|
7
|
+
* base64 encoded. Successive transports name their parent and carry an
|
|
8
|
+
* identity-map delta, so one new commit never embeds old repository history
|
|
9
|
+
* or the unchanged per-path identity map again.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.deriveStateId = exports.REPOSITORY_TRANSPORT_CONTRACT = void 0;
|
|
13
|
+
exports.repositoryIdentityHash = repositoryIdentityHash;
|
|
14
|
+
exports.planRepositoryIdentity = planRepositoryIdentity;
|
|
15
|
+
exports.applyRepositoryIdentity = applyRepositoryIdentity;
|
|
16
|
+
exports.encodeRepositoryTransport = encodeRepositoryTransport;
|
|
17
|
+
exports.repositoryTransportMetadataBytes = repositoryTransportMetadataBytes;
|
|
18
|
+
exports.inspectRepositoryTransport = inspectRepositoryTransport;
|
|
19
|
+
exports.decodeRepositoryTransport = decodeRepositoryTransport;
|
|
20
|
+
exports.repositoryTransportSizes = repositoryTransportSizes;
|
|
21
|
+
exports.deriveCardId = deriveCardId;
|
|
22
|
+
exports.deriveCheckpointId = deriveCheckpointId;
|
|
23
|
+
const bytes_js_1 = require("./bytes.js");
|
|
24
|
+
exports.REPOSITORY_TRANSPORT_CONTRACT = 'amalgm.repo-transport.v2';
|
|
25
|
+
const MAGIC = (0, bytes_js_1.utf8Encode)('AMGREPO2');
|
|
26
|
+
const HEADER_BYTES = MAGIC.byteLength + 4;
|
|
27
|
+
const sortedIdentity = (identity) => [...identity].sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
|
|
28
|
+
function repositoryIdentityHash(identity, sha256Hex) {
|
|
29
|
+
return sha256Hex(JSON.stringify(sortedIdentity(identity)));
|
|
30
|
+
}
|
|
31
|
+
/** Derive the smallest path-keyed change from one identity map to the next. */
|
|
32
|
+
function planRepositoryIdentity(current, previous, sha256Hex) {
|
|
33
|
+
const next = sortedIdentity(current);
|
|
34
|
+
if (new Set(next.map((entry) => entry.path)).size !== next.length) {
|
|
35
|
+
throw new Error('repository identity map has duplicate paths');
|
|
36
|
+
}
|
|
37
|
+
if (previous === null) {
|
|
38
|
+
return {
|
|
39
|
+
identityHash: repositoryIdentityHash(next, sha256Hex),
|
|
40
|
+
identityDelta: { reset: true, upsert: next, remove: [] },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const prior = new Map(previous.map((entry) => [entry.path, entry]));
|
|
44
|
+
const currentPaths = new Set(next.map((entry) => entry.path));
|
|
45
|
+
const upsert = next.filter((entry) => {
|
|
46
|
+
const old = prior.get(entry.path);
|
|
47
|
+
return old === undefined || old.uuid !== entry.uuid || old.type !== entry.type
|
|
48
|
+
|| (old.payloadVersion ?? null) !== (entry.payloadVersion ?? null);
|
|
49
|
+
});
|
|
50
|
+
const remove = [...prior.keys()].filter((path) => !currentPaths.has(path)).sort();
|
|
51
|
+
return {
|
|
52
|
+
identityHash: repositoryIdentityHash(next, sha256Hex),
|
|
53
|
+
identityDelta: { reset: false, upsert, remove },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Apply and verify one identity-map chain node. */
|
|
57
|
+
function applyRepositoryIdentity(previous, transport, sha256Hex) {
|
|
58
|
+
if (transport.identityDelta.reset !== (previous === null)) {
|
|
59
|
+
throw new Error('repository identity delta has the wrong chain boundary');
|
|
60
|
+
}
|
|
61
|
+
const entries = new Map((previous ?? []).map((entry) => [entry.path, entry]));
|
|
62
|
+
for (const path of transport.identityDelta.remove)
|
|
63
|
+
entries.delete(path);
|
|
64
|
+
for (const entry of transport.identityDelta.upsert)
|
|
65
|
+
entries.set(entry.path, entry);
|
|
66
|
+
const result = sortedIdentity([...entries.values()]);
|
|
67
|
+
if (repositoryIdentityHash(result, sha256Hex) !== transport.identityHash) {
|
|
68
|
+
throw new Error('repository identity delta does not produce its declared map');
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
const descriptor = (bytes) => ({ bytes: bytes.byteLength });
|
|
73
|
+
/** Encode metadata followed by raw Git/checkpoint bytes. */
|
|
74
|
+
function encodeRepositoryTransport(state, input) {
|
|
75
|
+
const header = {
|
|
76
|
+
contract: exports.REPOSITORY_TRANSPORT_CONTRACT,
|
|
77
|
+
stateId: state.stateId,
|
|
78
|
+
cardId: state.cardId,
|
|
79
|
+
checkpointId: state.checkpointId,
|
|
80
|
+
parentTransportVersion: input.parentTransportVersion,
|
|
81
|
+
identityHash: input.identityHash,
|
|
82
|
+
identityDelta: input.identityDelta,
|
|
83
|
+
card: state.card,
|
|
84
|
+
pack: state.pack ? { sha256: state.pack.sha256, bytes: state.pack.bytes.byteLength } : null,
|
|
85
|
+
checkpoint: {
|
|
86
|
+
baseCommit: state.checkpoint.baseCommit,
|
|
87
|
+
branch: state.checkpoint.branch,
|
|
88
|
+
stagedPatch: descriptor(state.checkpoint.stagedPatch),
|
|
89
|
+
unstagedPatch: descriptor(state.checkpoint.unstagedPatch),
|
|
90
|
+
untracked: state.checkpoint.untracked.map((file) => ({
|
|
91
|
+
path: file.path,
|
|
92
|
+
mode: file.mode,
|
|
93
|
+
sha256: file.sha256,
|
|
94
|
+
...(file.reused === undefined ? {} : { reused: file.reused }),
|
|
95
|
+
content: file.content === null ? null : descriptor(file.content),
|
|
96
|
+
})),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
const metadata = (0, bytes_js_1.utf8Encode)(JSON.stringify(header));
|
|
100
|
+
if (metadata.byteLength > 0xffff_ffff)
|
|
101
|
+
throw new Error('repository transport metadata is too large');
|
|
102
|
+
const cargo = [
|
|
103
|
+
...(state.pack ? [state.pack.bytes] : []),
|
|
104
|
+
state.checkpoint.stagedPatch,
|
|
105
|
+
state.checkpoint.unstagedPatch,
|
|
106
|
+
...state.checkpoint.untracked.flatMap((file) => file.content === null ? [] : [file.content]),
|
|
107
|
+
];
|
|
108
|
+
const cargoBytes = cargo.reduce((total, bytes) => total + bytes.byteLength, 0);
|
|
109
|
+
const output = new Uint8Array(HEADER_BYTES + metadata.byteLength + cargoBytes);
|
|
110
|
+
output.set(MAGIC, 0);
|
|
111
|
+
new DataView(output.buffer).setUint32(MAGIC.byteLength, metadata.byteLength, false);
|
|
112
|
+
output.set(metadata, HEADER_BYTES);
|
|
113
|
+
let cursor = HEADER_BYTES + metadata.byteLength;
|
|
114
|
+
for (const bytes of cargo) {
|
|
115
|
+
output.set(bytes, cursor);
|
|
116
|
+
cursor += bytes.byteLength;
|
|
117
|
+
}
|
|
118
|
+
return output;
|
|
119
|
+
}
|
|
120
|
+
const byteCount = (value, label) => {
|
|
121
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
122
|
+
throw new Error(`repository transport has invalid ${label} byte count`);
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
};
|
|
126
|
+
/** Number of leading bytes needed to decode metadata without reading cargo. */
|
|
127
|
+
function repositoryTransportMetadataBytes(prefix) {
|
|
128
|
+
if (prefix.byteLength < HEADER_BYTES
|
|
129
|
+
|| MAGIC.some((value, index) => prefix[index] !== value)) {
|
|
130
|
+
throw new Error('repository transport has an invalid binary header');
|
|
131
|
+
}
|
|
132
|
+
const metadataBytes = new DataView(prefix.buffer, prefix.byteOffset, prefix.byteLength)
|
|
133
|
+
.getUint32(MAGIC.byteLength, false);
|
|
134
|
+
const total = HEADER_BYTES + metadataBytes;
|
|
135
|
+
if (!Number.isSafeInteger(total))
|
|
136
|
+
throw new Error('repository transport metadata is too large');
|
|
137
|
+
return total;
|
|
138
|
+
}
|
|
139
|
+
/** Decode the small JSON header into seekable cargo ranges. */
|
|
140
|
+
function inspectRepositoryTransport(metadata, totalBytes) {
|
|
141
|
+
const metadataBytes = repositoryTransportMetadataBytes(metadata);
|
|
142
|
+
if (metadata.byteLength < metadataBytes)
|
|
143
|
+
throw new Error('repository transport metadata is truncated');
|
|
144
|
+
if (!Number.isSafeInteger(totalBytes) || totalBytes < metadataBytes) {
|
|
145
|
+
throw new Error('repository transport total byte count is invalid');
|
|
146
|
+
}
|
|
147
|
+
const header = JSON.parse((0, bytes_js_1.utf8Decode)(metadata.subarray(HEADER_BYTES, metadataBytes)));
|
|
148
|
+
if (header.contract !== exports.REPOSITORY_TRANSPORT_CONTRACT) {
|
|
149
|
+
throw new Error('repository transport contract is unsupported');
|
|
150
|
+
}
|
|
151
|
+
let cursor = metadataBytes;
|
|
152
|
+
const range = (count, label) => {
|
|
153
|
+
const bytes = byteCount(count, label);
|
|
154
|
+
const result = { offset: cursor, bytes };
|
|
155
|
+
cursor += bytes;
|
|
156
|
+
if (!Number.isSafeInteger(cursor) || cursor > totalBytes) {
|
|
157
|
+
throw new Error(`repository transport ${label} is truncated`);
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
};
|
|
161
|
+
const pack = header.pack === null ? null : {
|
|
162
|
+
sha256: header.pack.sha256,
|
|
163
|
+
range: range(header.pack.bytes, 'Git pack'),
|
|
164
|
+
};
|
|
165
|
+
const stagedPatch = range(header.checkpoint.stagedPatch.bytes, 'staged patch');
|
|
166
|
+
const unstagedPatch = range(header.checkpoint.unstagedPatch.bytes, 'unstaged patch');
|
|
167
|
+
const untracked = header.checkpoint.untracked.map((file) => ({
|
|
168
|
+
...file,
|
|
169
|
+
content: file.content === null ? null : range(file.content.bytes, `untracked file ${file.path}`),
|
|
170
|
+
}));
|
|
171
|
+
if (cursor !== totalBytes)
|
|
172
|
+
throw new Error('repository transport has trailing cargo');
|
|
173
|
+
return {
|
|
174
|
+
stateId: header.stateId,
|
|
175
|
+
cardId: header.cardId,
|
|
176
|
+
checkpointId: header.checkpointId,
|
|
177
|
+
parentTransportVersion: header.parentTransportVersion,
|
|
178
|
+
identityHash: header.identityHash,
|
|
179
|
+
identityDelta: header.identityDelta,
|
|
180
|
+
card: header.card,
|
|
181
|
+
pack,
|
|
182
|
+
checkpoint: {
|
|
183
|
+
baseCommit: header.checkpoint.baseCommit,
|
|
184
|
+
branch: header.checkpoint.branch,
|
|
185
|
+
stagedPatch,
|
|
186
|
+
unstagedPatch,
|
|
187
|
+
untracked,
|
|
188
|
+
},
|
|
189
|
+
metadataBytes,
|
|
190
|
+
totalBytes,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/** Decode the binary envelope without interpreting Git's native pack bytes. */
|
|
194
|
+
function decodeRepositoryTransport(bytes) {
|
|
195
|
+
const layout = inspectRepositoryTransport(bytes, bytes.byteLength);
|
|
196
|
+
const take = (range) => bytes.slice(range.offset, range.offset + range.bytes);
|
|
197
|
+
return {
|
|
198
|
+
stateId: layout.stateId,
|
|
199
|
+
cardId: layout.cardId,
|
|
200
|
+
checkpointId: layout.checkpointId,
|
|
201
|
+
parentTransportVersion: layout.parentTransportVersion,
|
|
202
|
+
identityHash: layout.identityHash,
|
|
203
|
+
identityDelta: layout.identityDelta,
|
|
204
|
+
card: layout.card,
|
|
205
|
+
pack: layout.pack === null ? null : {
|
|
206
|
+
sha256: layout.pack.sha256,
|
|
207
|
+
bytes: take(layout.pack.range),
|
|
208
|
+
},
|
|
209
|
+
checkpoint: {
|
|
210
|
+
baseCommit: layout.checkpoint.baseCommit,
|
|
211
|
+
branch: layout.checkpoint.branch,
|
|
212
|
+
stagedPatch: take(layout.checkpoint.stagedPatch),
|
|
213
|
+
unstagedPatch: take(layout.checkpoint.unstagedPatch),
|
|
214
|
+
untracked: layout.checkpoint.untracked.map((file) => ({
|
|
215
|
+
...file,
|
|
216
|
+
content: file.content === null ? null : take(file.content),
|
|
217
|
+
})),
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/** Separate Git work from Amalgm metadata/checkpoint overhead in benchmarks. */
|
|
222
|
+
function repositoryTransportSizes(bytes) {
|
|
223
|
+
const transport = decodeRepositoryTransport(bytes);
|
|
224
|
+
const metadataBytes = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
225
|
+
.getUint32(MAGIC.byteLength, false) + HEADER_BYTES;
|
|
226
|
+
const gitPackBytes = transport.pack?.bytes.byteLength ?? 0;
|
|
227
|
+
return {
|
|
228
|
+
totalBytes: bytes.byteLength,
|
|
229
|
+
metadataBytes,
|
|
230
|
+
gitPackBytes,
|
|
231
|
+
checkpointBytes: bytes.byteLength - metadataBytes - gitPackBytes,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/** Card identity from the ledger only. Remotes and transport data are absent. */
|
|
235
|
+
function deriveCardId(card, sha256Hex) {
|
|
236
|
+
return sha256Hex(JSON.stringify({
|
|
237
|
+
version: card.version,
|
|
238
|
+
head: card.head,
|
|
239
|
+
branches: card.branches,
|
|
240
|
+
tags: card.tags,
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
/** Checkpoint identity from its hashes, never duplicated byte encodings. */
|
|
244
|
+
function deriveCheckpointId(checkpoint, sha256Hex) {
|
|
245
|
+
return sha256Hex(JSON.stringify({
|
|
246
|
+
baseCommit: checkpoint.baseCommit,
|
|
247
|
+
stagedPatch: sha256Hex(checkpoint.stagedPatch),
|
|
248
|
+
unstagedPatch: sha256Hex(checkpoint.unstagedPatch),
|
|
249
|
+
untracked: checkpoint.untracked.map((file) => ({
|
|
250
|
+
path: file.path, mode: file.mode, sha256: file.sha256,
|
|
251
|
+
})),
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
254
|
+
const deriveStateId = (cardId, checkpointId, sha256Hex) => sha256Hex(cardId + checkpointId);
|
|
255
|
+
exports.deriveStateId = deriveStateId;
|
|
256
|
+
//# sourceMappingURL=repo-states.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-states.js","sourceRoot":"","sources":["../../src/entities/repo-states.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The registry's pure rule surface — the laws of the entity model (engine
|
|
4
|
+
* docs/entity-model.md) with every store lookup behind the injected
|
|
5
|
+
* {@link EntityReadPort} and every hash behind {@link Sha256Hex}:
|
|
6
|
+
*
|
|
7
|
+
* - the ratified version formula: version = hash(type, parentUUID, name,
|
|
8
|
+
* status, adapterPayloadVersion) — DERIVED, never stored;
|
|
9
|
+
* - container payloads as sorted active direct membership;
|
|
10
|
+
* - lifecycle inheritance DOWN the ancestor chain as derived effective
|
|
11
|
+
* status (deleted > trashed > own stored status);
|
|
12
|
+
* - one active owner per (parentUUID, name) slot; only containers hold
|
|
13
|
+
* active children; the parent graph is acyclic;
|
|
14
|
+
* - what an attestation may say (leaf ground attests bytes; membership and
|
|
15
|
+
* reference identity are never observed);
|
|
16
|
+
* - the record / syncRecord shapes and the cloud-record normalizer.
|
|
17
|
+
*
|
|
18
|
+
* Refusal messages are ported verbatim from the engine registry — they are
|
|
19
|
+
* the ratified refusal text its exams pin.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.mustGet = mustGet;
|
|
23
|
+
exports.attestable = attestable;
|
|
24
|
+
exports.canonicalVersion = canonicalVersion;
|
|
25
|
+
exports.validName = validName;
|
|
26
|
+
exports.mintOrValidateUuid = mintOrValidateUuid;
|
|
27
|
+
exports.ancestorsOf = ancestorsOf;
|
|
28
|
+
exports.effectiveStatusOf = effectiveStatusOf;
|
|
29
|
+
exports.membershipHash = membershipHash;
|
|
30
|
+
exports.entityRecordOf = entityRecordOf;
|
|
31
|
+
exports.syncRecordOf = syncRecordOf;
|
|
32
|
+
exports.normalizeCloudRecord = normalizeCloudRecord;
|
|
33
|
+
exports.sameLogicalRecord = sameLogicalRecord;
|
|
34
|
+
exports.requireActiveContainerParent = requireActiveContainerParent;
|
|
35
|
+
exports.requireFreeSlot = requireFreeSlot;
|
|
36
|
+
const types_js_1 = require("./types.js");
|
|
37
|
+
/** The row a UUID must name; absence is the caller's bug, said plainly. */
|
|
38
|
+
function mustGet(uuid, byUuid) {
|
|
39
|
+
const row = byUuid(uuid);
|
|
40
|
+
if (!row)
|
|
41
|
+
throw new Error(`no entity ${uuid}`);
|
|
42
|
+
return row;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* What an attestation may say — asked of both the type a record wears now
|
|
46
|
+
* and the type its new bytes claim, because an attestation may carry a
|
|
47
|
+
* record across leaf kinds (a pointer replaced by bytes) and both ends
|
|
48
|
+
* must be ground an observation can speak for.
|
|
49
|
+
*/
|
|
50
|
+
function attestable(type) {
|
|
51
|
+
if (types_js_1.DERIVED_PAYLOAD.has(type)) {
|
|
52
|
+
throw new Error(`${type} payload is derived membership, never attested`);
|
|
53
|
+
}
|
|
54
|
+
if (type === 'reference') {
|
|
55
|
+
throw new Error('a reference\'s payload is the target\'s identity, set by the deliberate act that created it — never an attestation; the rendered symlink is derived state, not evidence');
|
|
56
|
+
}
|
|
57
|
+
if (!types_js_1.TYPES.has(type))
|
|
58
|
+
throw new Error(`unknown entity type ${JSON.stringify(type)}`);
|
|
59
|
+
}
|
|
60
|
+
/** The ratified formula: version = hash(type, parentUUID, name, status, payloadVersion). */
|
|
61
|
+
function canonicalVersion({ type, parentUUID = null, name, status, payloadVersion = null }, sha256Hex) {
|
|
62
|
+
return sha256Hex(JSON.stringify([type, parentUUID, name, status, payloadVersion]));
|
|
63
|
+
}
|
|
64
|
+
/** A name is one non-empty path segment: never '', '.', '..', a '/' or NUL. */
|
|
65
|
+
function validName(name) {
|
|
66
|
+
if (typeof name !== 'string' || name === '' || name === '.' || name === '..'
|
|
67
|
+
|| name.includes('/') || name.includes('\0')) {
|
|
68
|
+
throw new Error(`invalid entity name ${JSON.stringify(name)}: a name is one non-empty path segment`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** A UUID may arrive only through a trusted identity binding (for example
|
|
72
|
+
* a cloud user-home bootstrap). The registry still owns the actual insert:
|
|
73
|
+
* accepting a caller-supplied UUID is not accepting a caller-supplied
|
|
74
|
+
* record, parent, status, or version. */
|
|
75
|
+
function mintOrValidateUuid(uuid, ports) {
|
|
76
|
+
if (uuid === undefined || uuid === null)
|
|
77
|
+
return ports.mintUuid();
|
|
78
|
+
if (typeof uuid !== 'string' || !types_js_1.UUID_PATTERN.test(uuid)) {
|
|
79
|
+
throw new Error(`entity identity must be a UUID, got ${JSON.stringify(uuid)}`);
|
|
80
|
+
}
|
|
81
|
+
if (ports.byUuid(uuid))
|
|
82
|
+
throw new Error(`entity identity ${uuid} is already registered`);
|
|
83
|
+
return uuid.toLowerCase();
|
|
84
|
+
}
|
|
85
|
+
/** Ancestor uuids from the given parent up to the root. */
|
|
86
|
+
function ancestorsOf(parentUuid, byUuid) {
|
|
87
|
+
const chain = [];
|
|
88
|
+
const seen = new Set();
|
|
89
|
+
let cursor = parentUuid;
|
|
90
|
+
while (cursor !== null) {
|
|
91
|
+
if (seen.has(cursor))
|
|
92
|
+
throw new Error(`registry corrupt: parent cycle at ${cursor}`);
|
|
93
|
+
seen.add(cursor);
|
|
94
|
+
chain.push(cursor);
|
|
95
|
+
cursor = mustGet(cursor, byUuid).parentUuid;
|
|
96
|
+
}
|
|
97
|
+
return chain;
|
|
98
|
+
}
|
|
99
|
+
/** Lifecycle inherits down: deleted if any ancestor is deleted, trashed if
|
|
100
|
+
* any is trashed, otherwise the entity's own stored status — one flip on a
|
|
101
|
+
* folder, no descendant record rewritten. */
|
|
102
|
+
function effectiveStatusOf(row, byUuid) {
|
|
103
|
+
const statuses = [row.status, ...ancestorsOf(row.parentUuid, byUuid)
|
|
104
|
+
.map((uuid) => mustGet(uuid, byUuid).status)];
|
|
105
|
+
if (statuses.includes('deleted'))
|
|
106
|
+
return 'deleted';
|
|
107
|
+
if (statuses.includes('trashed'))
|
|
108
|
+
return 'trashed';
|
|
109
|
+
return row.status;
|
|
110
|
+
}
|
|
111
|
+
const byUuidOrder = (left, right) => (left < right ? -1 : left > right ? 1 : 0);
|
|
112
|
+
/**
|
|
113
|
+
* Container payload: the sorted active direct membership (childUUID, name).
|
|
114
|
+
* Children are sorted here by uuid, codepoint order — the same order the
|
|
115
|
+
* engine's `ORDER BY uuid` (BINARY collation over lowercase-hex uuids)
|
|
116
|
+
* produces — so the hash input is byte-identical however the port returns
|
|
117
|
+
* them. Membership counts direct children by their STORED status, never
|
|
118
|
+
* effective status: effective-status membership would ripple a version
|
|
119
|
+
* change through the entire subtree and defeat the one-flip lifecycle.
|
|
120
|
+
*/
|
|
121
|
+
function membershipHash(activeChildren, sha256Hex) {
|
|
122
|
+
const pairs = [...activeChildren]
|
|
123
|
+
.sort((left, right) => byUuidOrder(left.uuid, right.uuid))
|
|
124
|
+
.map((child) => [child.uuid, child.name]);
|
|
125
|
+
return sha256Hex(JSON.stringify(pairs));
|
|
126
|
+
}
|
|
127
|
+
const payloadFor = (row, ports) => (types_js_1.DERIVED_PAYLOAD.has(row.type) ? ports.membershipHashOf(row.uuid) : row.payloadVersion);
|
|
128
|
+
/** The public record: exactly the six ratified fields, version derived. */
|
|
129
|
+
function entityRecordOf(row, ports) {
|
|
130
|
+
return {
|
|
131
|
+
uuid: row.uuid,
|
|
132
|
+
type: row.type,
|
|
133
|
+
parentUUID: row.parentUuid,
|
|
134
|
+
name: row.name,
|
|
135
|
+
version: canonicalVersion({
|
|
136
|
+
type: row.type, parentUUID: row.parentUuid, name: row.name,
|
|
137
|
+
status: row.status, payloadVersion: payloadFor(row, ports),
|
|
138
|
+
}, ports.sha256Hex),
|
|
139
|
+
status: row.status,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** The cloud form contains identity and the content/head token, never an
|
|
143
|
+
* address, watcher, inode, or SQLite bytes. `payloadVersion` is the
|
|
144
|
+
* unambiguous current head for leaf types; containers derive theirs from
|
|
145
|
+
* membership and retain null here; a repo.git retains its immutable
|
|
146
|
+
* Card/Checkpoint head. */
|
|
147
|
+
function syncRecordOf(row, ports) {
|
|
148
|
+
return {
|
|
149
|
+
...entityRecordOf(row, ports),
|
|
150
|
+
payloadVersion: row.payloadVersion,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/** Validate and normalize a record arriving from the cloud: six fields plus
|
|
154
|
+
* payloadVersion, UUIDs lowercased, root laws enforced. */
|
|
155
|
+
function normalizeCloudRecord(value) {
|
|
156
|
+
const record = value;
|
|
157
|
+
if (!record || typeof record !== 'object'
|
|
158
|
+
|| typeof record.uuid !== 'string' || !types_js_1.UUID_PATTERN.test(record.uuid)
|
|
159
|
+
|| typeof record.type !== 'string' || !types_js_1.TYPES.has(record.type)
|
|
160
|
+
|| (record.parentUUID !== null && (typeof record.parentUUID !== 'string' || !types_js_1.UUID_PATTERN.test(record.parentUUID)))
|
|
161
|
+
|| typeof record.name !== 'string'
|
|
162
|
+
|| !['active', 'trashed', 'deleted'].includes(record.status)
|
|
163
|
+
|| (record.payloadVersion !== null && typeof record.payloadVersion !== 'string')
|
|
164
|
+
|| typeof record.version !== 'string' || !/^[0-9a-f]{64}$/i.test(record.version)) {
|
|
165
|
+
throw new Error('cloud entity operation has an invalid record');
|
|
166
|
+
}
|
|
167
|
+
validName(record.name);
|
|
168
|
+
if (record.parentUUID === null && !types_js_1.ROOT_TYPES.has(record.type)) {
|
|
169
|
+
throw new Error(`cloud entity ${record.uuid} is not a valid tree root`);
|
|
170
|
+
}
|
|
171
|
+
if (record.parentUUID !== null && record.type === 'workspace') {
|
|
172
|
+
throw new Error('cloud entity workspace is the root type only');
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
uuid: record.uuid.toLowerCase(),
|
|
176
|
+
type: record.type,
|
|
177
|
+
parentUuid: record.parentUUID === null ? null : record.parentUUID.toLowerCase(),
|
|
178
|
+
name: record.name,
|
|
179
|
+
status: record.status,
|
|
180
|
+
payloadVersion: record.payloadVersion,
|
|
181
|
+
expectedVersion: record.version.toLowerCase(),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/** Equality over the five stored facts plus payload — everything the
|
|
185
|
+
* version fingerprints except the fingerprint itself. */
|
|
186
|
+
function sameLogicalRecord(left, right) {
|
|
187
|
+
return left.uuid === right.uuid
|
|
188
|
+
&& left.type === right.type
|
|
189
|
+
&& left.parentUuid === right.parentUuid
|
|
190
|
+
&& left.name === right.name
|
|
191
|
+
&& left.status === right.status
|
|
192
|
+
&& left.payloadVersion === right.payloadVersion;
|
|
193
|
+
}
|
|
194
|
+
/** Only containers — workspace, folder, repo.git — hold active children,
|
|
195
|
+
* and only while effectively active themselves. */
|
|
196
|
+
function requireActiveContainerParent(parentUuid, port) {
|
|
197
|
+
const parent = mustGet(parentUuid, port.byUuid.bind(port));
|
|
198
|
+
if (!types_js_1.CONTAINERS.has(parent.type)) {
|
|
199
|
+
throw new Error(`only containers hold active children: ${parentUuid} is ${parent.type}, not workspace/folder/repo.git`);
|
|
200
|
+
}
|
|
201
|
+
if (effectiveStatusOf(parent, port.byUuid.bind(port)) !== 'active') {
|
|
202
|
+
throw new Error(`parent ${parentUuid} is not effectively active — restore it before putting entities under it`);
|
|
203
|
+
}
|
|
204
|
+
return parent;
|
|
205
|
+
}
|
|
206
|
+
/** One active owner per (parentUUID, name) slot. Parentless records are
|
|
207
|
+
* exempt: a top-level tree is placed by its machine binding, never by name. */
|
|
208
|
+
function requireFreeSlot(parentUuid, name, port, forUuid = null) {
|
|
209
|
+
if (parentUuid === null)
|
|
210
|
+
return; // top level: address places a tree, never its name
|
|
211
|
+
const occupant = port.activeChildByName(parentUuid, name);
|
|
212
|
+
if (occupant && occupant.uuid !== forUuid) {
|
|
213
|
+
throw new Error(`slot taken: active entity ${occupant.uuid} already owns (${parentUuid}, ${name}) — move or trash it first`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/entities/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The entity alphabet and the six-field universal record — the value
|
|
4
|
+
* vocabulary of the entity model (engine docs/entity-model.md, "The entity
|
|
5
|
+
* record"). Every enrolled entity, of every type, is exactly six fields:
|
|
6
|
+
* UUID, type, parentUUID, name, version, status. Paths are derived from the
|
|
7
|
+
* parentUUID + name chain and are never identity; version is derived on
|
|
8
|
+
* read, never stored.
|
|
9
|
+
*
|
|
10
|
+
* The alphabet is PHYSICAL kinds only. Constructs — agents, apps,
|
|
11
|
+
* automations, tools, skills — are folder-and-file ground with a known
|
|
12
|
+
* structure, their meaning layered ABOVE the physical type, never encoded
|
|
13
|
+
* as one.
|
|
14
|
+
*
|
|
15
|
+
* This module also names the two ports the pure rules receive instead of a
|
|
16
|
+
* database or node:crypto: a read port over the host's identity store, and
|
|
17
|
+
* a SHA-256 hex function.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.UUID_PATTERN = exports.isEntityType = exports.ENTITY_TYPES = exports.DERIVED_PAYLOAD = exports.ROOT_TYPES = exports.CONTAINERS = exports.TYPES = void 0;
|
|
21
|
+
const ALPHABET = [
|
|
22
|
+
'workspace', 'folder', 'repo.git', 'file.text', 'file.binary',
|
|
23
|
+
'link', 'reference',
|
|
24
|
+
];
|
|
25
|
+
exports.TYPES = new Set(ALPHABET);
|
|
26
|
+
/** Only containers hold active children. */
|
|
27
|
+
exports.CONTAINERS = new Set(['workspace', 'folder', 'repo.git']);
|
|
28
|
+
/** The types a parentless record (a tree root) may wear. `folder` is
|
|
29
|
+
* deliberately absent: a folder inside no workspace is not a thing amalgm
|
|
30
|
+
* registers. `reference` is absent too — a managed pointer is always
|
|
31
|
+
* created inside a tree. */
|
|
32
|
+
exports.ROOT_TYPES = new Set(['workspace', 'repo.git', 'file.text', 'file.binary', 'link']);
|
|
33
|
+
/** Types whose payload IS their membership: derived from the records
|
|
34
|
+
* beneath them, so no observation may attest one. */
|
|
35
|
+
exports.DERIVED_PAYLOAD = new Set(['workspace', 'folder']);
|
|
36
|
+
/** The one entity alphabet, published sorted for the layers that map onto
|
|
37
|
+
* it — read from here, never restated, so it cannot drift. */
|
|
38
|
+
exports.ENTITY_TYPES = Object.freeze([...ALPHABET].sort());
|
|
39
|
+
const isEntityType = (value) => typeof value === 'string' && exports.TYPES.has(value);
|
|
40
|
+
exports.isEntityType = isEntityType;
|
|
41
|
+
/** RFC-4122 UUID shape (versions 1–8), the permanent identity and realtime
|
|
42
|
+
* channel of every enrolled entity. */
|
|
43
|
+
exports.UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
44
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/entities/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AAiBH,MAAM,QAAQ,GAA0B;IACtC,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa;IAC7D,MAAM,EAAE,WAAW;CACpB,CAAC;AAEW,QAAA,KAAK,GAAwB,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;AAE5D,4CAA4C;AAC/B,QAAA,UAAU,GAAwB,IAAI,GAAG,CACpD,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAA2B,CAC9D,CAAC;AAEF;;;4BAG4B;AACf,QAAA,UAAU,GAAwB,IAAI,GAAG,CACpD,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,CAAwB,CACrF,CAAC;AAEF;qDACqD;AACxC,QAAA,eAAe,GAAwB,IAAI,GAAG,CACzD,CAAC,WAAW,EAAE,QAAQ,CAAwB,CAC/C,CAAC;AAEF;8DAC8D;AACjD,QAAA,YAAY,GAA0B,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAEhF,MAAM,YAAY,GAAG,CAAC,KAAc,EAAuB,EAAE,CAClE,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AADnC,QAAA,YAAY,gBACuB;AAEhD;uCACuC;AAC1B,QAAA,YAAY,GACvB,4EAA4E,CAAC"}
|