@amalgm/live 0.2.30 → 0.2.32

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.
Files changed (87) hide show
  1. package/PURPOSE.md +30 -1
  2. package/README.md +1 -0
  3. package/dist/apply/content-results.d.ts +26 -0
  4. package/dist/apply/content-results.d.ts.map +1 -0
  5. package/dist/apply/content-results.js +52 -0
  6. package/dist/apply/content-results.js.map +1 -0
  7. package/dist/apply/contracts.d.ts +191 -0
  8. package/dist/apply/contracts.d.ts.map +1 -0
  9. package/dist/apply/contracts.js +47 -0
  10. package/dist/apply/contracts.js.map +1 -0
  11. package/dist/apply/index.d.ts +10 -0
  12. package/dist/apply/index.d.ts.map +1 -0
  13. package/dist/apply/index.js +10 -0
  14. package/dist/apply/index.js.map +1 -0
  15. package/dist/apply/local-work.d.ts +10 -0
  16. package/dist/apply/local-work.d.ts.map +1 -0
  17. package/dist/apply/local-work.js +17 -0
  18. package/dist/apply/local-work.js.map +1 -0
  19. package/dist/apply/plans.d.ts +14 -0
  20. package/dist/apply/plans.d.ts.map +1 -0
  21. package/dist/apply/plans.js +183 -0
  22. package/dist/apply/plans.js.map +1 -0
  23. package/dist/apply/rail.d.ts +25 -0
  24. package/dist/apply/rail.d.ts.map +1 -0
  25. package/dist/apply/rail.js +304 -0
  26. package/dist/apply/rail.js.map +1 -0
  27. package/dist/apply/repository-result.d.ts +25 -0
  28. package/dist/apply/repository-result.d.ts.map +1 -0
  29. package/dist/apply/repository-result.js +83 -0
  30. package/dist/apply/repository-result.js.map +1 -0
  31. package/dist/apply/selection.d.ts +14 -0
  32. package/dist/apply/selection.d.ts.map +1 -0
  33. package/dist/apply/selection.js +63 -0
  34. package/dist/apply/selection.js.map +1 -0
  35. package/dist/apply/type-adapters.d.ts +13 -0
  36. package/dist/apply/type-adapters.d.ts.map +1 -0
  37. package/dist/apply/type-adapters.js +37 -0
  38. package/dist/apply/type-adapters.js.map +1 -0
  39. package/dist/detection/adapter-contract.d.ts +11 -8
  40. package/dist/detection/adapter-contract.d.ts.map +1 -1
  41. package/dist/detection/adapter-contract.js +5 -5
  42. package/dist/detection/adapter-contract.js.map +1 -1
  43. package/dist/detection/echo.d.ts +1 -1
  44. package/dist/detection/echo.d.ts.map +1 -1
  45. package/dist/detection/echo.js +8 -1
  46. package/dist/detection/echo.js.map +1 -1
  47. package/dist/detection/territory.d.ts +19 -0
  48. package/dist/detection/territory.d.ts.map +1 -1
  49. package/dist/detection/territory.js +50 -0
  50. package/dist/detection/territory.js.map +1 -1
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +1 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/records/rail.d.ts +2 -0
  56. package/dist/records/rail.d.ts.map +1 -1
  57. package/dist/records/rail.js +6 -0
  58. package/dist/records/rail.js.map +1 -1
  59. package/dist-cjs/apply/content-results.js +57 -0
  60. package/dist-cjs/apply/content-results.js.map +1 -0
  61. package/dist-cjs/apply/contracts.js +53 -0
  62. package/dist-cjs/apply/contracts.js.map +1 -0
  63. package/dist-cjs/apply/index.js +28 -0
  64. package/dist-cjs/apply/index.js.map +1 -0
  65. package/dist-cjs/apply/local-work.js +20 -0
  66. package/dist-cjs/apply/local-work.js.map +1 -0
  67. package/dist-cjs/apply/plans.js +187 -0
  68. package/dist-cjs/apply/plans.js.map +1 -0
  69. package/dist-cjs/apply/rail.js +308 -0
  70. package/dist-cjs/apply/rail.js.map +1 -0
  71. package/dist-cjs/apply/repository-result.js +86 -0
  72. package/dist-cjs/apply/repository-result.js.map +1 -0
  73. package/dist-cjs/apply/selection.js +66 -0
  74. package/dist-cjs/apply/selection.js.map +1 -0
  75. package/dist-cjs/apply/type-adapters.js +41 -0
  76. package/dist-cjs/apply/type-adapters.js.map +1 -0
  77. package/dist-cjs/detection/adapter-contract.js +5 -5
  78. package/dist-cjs/detection/adapter-contract.js.map +1 -1
  79. package/dist-cjs/detection/echo.js +8 -1
  80. package/dist-cjs/detection/echo.js.map +1 -1
  81. package/dist-cjs/detection/territory.js +51 -0
  82. package/dist-cjs/detection/territory.js.map +1 -1
  83. package/dist-cjs/index.js +1 -0
  84. package/dist-cjs/index.js.map +1 -1
  85. package/dist-cjs/records/rail.js +6 -0
  86. package/dist-cjs/records/rail.js.map +1 -1
  87. package/package.json +7 -1
package/PURPOSE.md CHANGED
@@ -222,7 +222,28 @@ its cutover.
222
222
  reacts immediately and never polls.
223
223
  Startup and reconnect subscribe before reading the durable authority tail,
224
224
  so a delayed, repeated, or missed signal cannot create a gap; Postgres and
225
- the local cursors remain truth, while realtime is only the doorbell.
225
+ the local cursors remain truth, while realtime is only the doorbell. After
226
+ each durable Receive commit, one local payload-free doorbell may wake Apply.
227
+ 39. **Apply is intent-first and type-complete.** Apply consumes only gap-free
228
+ authority-accepted Inbox history, writes one durable target intent before
229
+ any machine effect, either proves ground already equals the target or
230
+ prepares privately, and advances only after the target type rereads exact
231
+ truth. Text uses an exact-base splice with a complete snapshot fallback;
232
+ binary uses its verified block manifest; links use literal target text;
233
+ containers use structure; repositories use one resumable Card + Checkpoint
234
+ transition.
235
+ 40. **Newer local work outranks older materialization.** An unsequenced local
236
+ Outbox row, or an accepted local receipt sequenced after the selected Apply
237
+ target, protects that entity's working ground. The local complete result is
238
+ still accepted normally and wins only when cloud assigns its later
239
+ sequence; Apply never rebases, merges, stale-refuses, or rewrites it. A
240
+ reveal-time disk difference enters Detect and Record before incoming work
241
+ may touch the path.
242
+ 41. **Verify, not a write syscall, commits Apply.** Applied Watch rings are
243
+ retained. Only exact type-specific reread may advance resolved and
244
+ materialized cursors, update the local notebook, mark Inbox history
245
+ resolved, and clear the intent; normal Detect equality then makes the echo
246
+ silent.
226
247
 
227
248
  ## Five surfaces, one behavior
228
249
 
@@ -256,6 +277,9 @@ src/watching/ the Watch pure cores: minimal coverage ownership and
256
277
  src/detection/ the Detect pure submodule: Watch boundary, identity compare,
257
278
  classification, enrollment, repository territory, exact
258
279
  replay proposals, net batches, and echo equality.
280
+ src/apply/ the Apply/Verify pure submodule: durable intent phases,
281
+ gap-free selection, later-local protection, private result
282
+ proof, type-adapter sockets, and crash-resumable orchestration.
259
283
  src/registration/ the login-time user-ground convergence operation and its
260
284
  injected local/cloud effect ports.
261
285
  src/transfer/ type-aware immutable artifact upload/download operations;
@@ -276,3 +300,8 @@ consumes user-ground convergence and the Files commands from this published
276
300
  package with no Engine fallback. Other Live surfaces continue across the
277
301
  extraction boundary independently and must satisfy the same exclusive-cutover
278
302
  axiom before entering a signed release.
303
+
304
+ The portable entity Apply/Verify subsystem exists here. Production filesystem,
305
+ SQLite, immutable-cache, Git-process, and watcher composition remains a Shell
306
+ release step; until that published-package adoption is complete, universal
307
+ cross-machine materialization is not a shipped claim.
package/README.md CHANGED
@@ -20,6 +20,7 @@ normative specifications live in [docs/](docs/):
20
20
  | [realtime-sdk.md](docs/realtime-sdk.md) | the public `bind(surface, channel)` model |
21
21
  | [local-live-protocol.md](docs/local-live-protocol.md) | the shipped local wire protocol (v1/v2) |
22
22
  | [entity-record-queues.md](docs/entity-record-queues.md) | filesystem Record, local Outbox, per-UUID cloud order, and local Inbox |
23
+ | [entity-apply.md](docs/entity-apply.md) | intent-first, type-sensitive Apply and exact Verify |
23
24
  | [shared-realtime-wave-3.md](docs/shared-realtime-wave-3.md) | the multi-user cloud-authority design |
24
25
  | [extraction-boundary.md](docs/extraction-boundary.md) | what moves here from the engine runtime, and in what order |
25
26
  | [user-ground-login.md](docs/user-ground-login.md) | first-login publication, later-device materialization, and Watch readiness |
@@ -0,0 +1,26 @@
1
+ /** Portable private-result construction for file and link adapters. */
2
+ import type { Sha256Hex } from '../entities/types.js';
3
+ import type { BinaryApplyPlan, LinkApplyPlan, TextApplyPlan } from './contracts.js';
4
+ /**
5
+ * Construct text privately. The snapshot is mandatory truth. A delta is only
6
+ * a shortcut over the exact immutable base; reproduceTextChange falls back to
7
+ * the already-verified snapshot on every base or result mismatch. The returned
8
+ * snapshot reference remains caller-owned immutable input; Apply never mutates
9
+ * it and the host streams it into private staging.
10
+ */
11
+ export declare function prepareTextResult(plan: TextApplyPlan, snapshot: Uint8Array, exactBase: Uint8Array | null, sha256Hex: Sha256Hex): Uint8Array;
12
+ export interface BinaryApplySinkReceipt {
13
+ readonly bytes: number;
14
+ readonly contentHash: string;
15
+ }
16
+ export interface BinaryApplySink {
17
+ /** Persist one verified block at its manifest position in private staging. */
18
+ write(index: number, bytes: Uint8Array): Promise<void>;
19
+ /** Fsync/close and verify the staged whole without returning its bytes. */
20
+ seal(): Promise<BinaryApplySinkReceipt>;
21
+ }
22
+ /** Verify reusable binary blocks while streaming them into private staging. */
23
+ export declare function prepareBinaryResult(plan: BinaryApplyPlan, read: (index: number) => Promise<Uint8Array>, sink: BinaryApplySink, sha256Hex: Sha256Hex): Promise<BinaryApplySinkReceipt>;
24
+ /** A link result is only its literal UTF-8 target bytes. */
25
+ export declare function prepareLinkResult(plan: LinkApplyPlan, sha256Hex: Sha256Hex): string;
26
+ //# sourceMappingURL=content-results.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-results.d.ts","sourceRoot":"","sources":["../../src/apply/content-results.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAIvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAcpF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,UAAU,EACpB,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,SAAS,EAAE,SAAS,GACnB,UAAU,CAYZ;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,2EAA2E;IAC3E,IAAI,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACzC;AAED,+EAA+E;AAC/E,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,EAC5C,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAgBjC;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAKnF"}
@@ -0,0 +1,52 @@
1
+ /** Portable private-result construction for file and link adapters. */
2
+ import { reproduceTextChange } from '../detection/content.js';
3
+ import { utf8Encode } from '../entities/bytes.js';
4
+ const exactResult = (bytes, expected, sha256Hex, label) => {
5
+ if (sha256Hex(bytes) !== expected) {
6
+ throw new Error(`${label} does not match its accepted complete result`);
7
+ }
8
+ return bytes;
9
+ };
10
+ /**
11
+ * Construct text privately. The snapshot is mandatory truth. A delta is only
12
+ * a shortcut over the exact immutable base; reproduceTextChange falls back to
13
+ * the already-verified snapshot on every base or result mismatch. The returned
14
+ * snapshot reference remains caller-owned immutable input; Apply never mutates
15
+ * it and the host streams it into private staging.
16
+ */
17
+ export function prepareTextResult(plan, snapshot, exactBase, sha256Hex) {
18
+ const verifiedSnapshot = exactResult(snapshot, plan.artifact.contentHash, sha256Hex, 'text Apply snapshot');
19
+ if (plan.strategy.kind === 'snapshot')
20
+ return verifiedSnapshot;
21
+ return reproduceTextChange(exactBase, {
22
+ kind: 'file.text',
23
+ mode: 'delta',
24
+ basePayloadVersion: plan.strategy.basePayloadVersion,
25
+ resultPayloadVersion: plan.artifact.contentHash,
26
+ delta: plan.strategy.delta,
27
+ }, verifiedSnapshot, sha256Hex);
28
+ }
29
+ /** Verify reusable binary blocks while streaming them into private staging. */
30
+ export async function prepareBinaryResult(plan, read, sink, sha256Hex) {
31
+ for (const [index, expected] of plan.manifest.chunks.entries()) {
32
+ const chunk = await read(index);
33
+ if (!(chunk instanceof Uint8Array)
34
+ || chunk.byteLength !== expected.bytes
35
+ || sha256Hex(chunk) !== expected.sha256) {
36
+ throw new Error(`binary Apply block ${index} failed verification`);
37
+ }
38
+ await sink.write(index, chunk);
39
+ }
40
+ const receipt = await sink.seal();
41
+ if (receipt.bytes !== plan.manifest.bytes
42
+ || receipt.contentHash !== plan.artifact.contentHash) {
43
+ throw new Error('binary Apply staged result failed complete verification');
44
+ }
45
+ return Object.freeze({ ...receipt });
46
+ }
47
+ /** A link result is only its literal UTF-8 target bytes. */
48
+ export function prepareLinkResult(plan, sha256Hex) {
49
+ exactResult(utf8Encode(plan.targetText), plan.artifact.contentHash, sha256Hex, 'link Apply target');
50
+ return plan.targetText;
51
+ }
52
+ //# sourceMappingURL=content-results.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-results.js","sourceRoot":"","sources":["../../src/apply/content-results.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAIlD,MAAM,WAAW,GAAG,CAClB,KAAiB,EACjB,QAAgB,EAChB,SAAoB,EACpB,KAAa,EACD,EAAE;IACd,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8CAA8C,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAmB,EACnB,QAAoB,EACpB,SAA4B,EAC5B,SAAoB;IAEpB,MAAM,gBAAgB,GAAG,WAAW,CAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,qBAAqB,CACtE,CAAC;IACF,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,gBAAgB,CAAC;IAC/D,OAAO,mBAAmB,CAAC,SAAS,EAAE;QACpC,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,OAAO;QACb,kBAAkB,EAAE,IAAI,CAAC,QAAQ,CAAC,kBAAkB;QACpD,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW;QAC/C,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;KAC3B,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC;AAClC,CAAC;AAcD,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAqB,EACrB,IAA4C,EAC5C,IAAqB,EACrB,SAAoB;IAEpB,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC;eAC7B,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,KAAK;eACnC,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,sBAAsB,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK;WACpC,OAAO,CAAC,WAAW,KAAK,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,iBAAiB,CAAC,IAAmB,EAAE,SAAoB;IACzE,WAAW,CACT,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,mBAAmB,CACvF,CAAC;IACF,OAAO,IAAI,CAAC,UAAU,CAAC;AACzB,CAAC"}
@@ -0,0 +1,191 @@
1
+ /** Portable contracts at the Inbox -> Apply -> Verify boundary. */
2
+ import type { CloudEntityRecord } from '../entities/cloud.js';
3
+ import { type EntityType, type Sha256Hex } from '../entities/types.js';
4
+ import type { ChangeFacet, TextSplice } from '../detection/record-proposal.js';
5
+ import type { AcceptedEntityRecord } from '../records/contracts.js';
6
+ import type { ContentManifest } from '../contracts/content.js';
7
+ import type { TransferArtifact } from '../transfer/artifacts.js';
8
+ export declare const ENTITY_APPLY_INTENT_CONTRACT = "amalgm.entity-apply-intent@1";
9
+ export type ApplyIntentPhase = 'declared' | 'prepared' | 'revealed';
10
+ /** One crash-recovery responsibility. It is written before any machine effect. */
11
+ export interface EntityApplyIntent {
12
+ readonly contract: typeof ENTITY_APPLY_INTENT_CONTRACT;
13
+ readonly authorityId: string;
14
+ readonly entityId: string;
15
+ readonly fromSequence: number;
16
+ readonly throughSequence: number;
17
+ readonly targetMutationId: string;
18
+ readonly targetState: string;
19
+ readonly targetType: EntityType;
20
+ readonly phase: ApplyIntentPhase;
21
+ readonly createdAt: number;
22
+ }
23
+ /** The exact official state disk most recently proved, if any. */
24
+ export interface MaterializedOfficialState {
25
+ readonly globalSequence: number;
26
+ readonly record: CloudEntityRecord;
27
+ }
28
+ /** One entity's contiguous unresolved Inbox range. */
29
+ export interface EntityApplyWork {
30
+ readonly authorityId: string;
31
+ readonly entityId: string;
32
+ readonly resolvedThrough: number;
33
+ readonly materialized: MaterializedOfficialState | null;
34
+ readonly records: readonly AcceptedEntityRecord[];
35
+ readonly intent: EntityApplyIntent | null;
36
+ }
37
+ /** One stable page of unresolved entities. The cursor is opaque to Live. */
38
+ export interface EntityApplyWorkPage {
39
+ readonly work: readonly EntityApplyWork[];
40
+ readonly nextCursor: string | null;
41
+ }
42
+ interface ApplyPlanBase {
43
+ readonly entityId: string;
44
+ readonly fromSequence: number;
45
+ readonly throughSequence: number;
46
+ readonly targetMutationId: string;
47
+ readonly target: CloudEntityRecord;
48
+ readonly facets: readonly ChangeFacet[];
49
+ }
50
+ export interface TextApplyPlan extends ApplyPlanBase {
51
+ readonly kind: 'file.text';
52
+ readonly artifact: TransferArtifact;
53
+ readonly strategy: {
54
+ readonly kind: 'snapshot';
55
+ } | {
56
+ readonly kind: 'delta';
57
+ readonly basePayloadVersion: string;
58
+ readonly delta: TextSplice;
59
+ };
60
+ }
61
+ export interface BinaryApplyPlan extends ApplyPlanBase {
62
+ readonly kind: 'file.binary';
63
+ readonly artifact: TransferArtifact;
64
+ readonly manifest: ContentManifest;
65
+ }
66
+ export interface LinkApplyPlan extends ApplyPlanBase {
67
+ readonly kind: 'link';
68
+ readonly artifact: TransferArtifact;
69
+ readonly targetText: string;
70
+ }
71
+ /** Structure replay changes address/type/status without shipping new bytes. */
72
+ export interface StructureApplyPlan extends ApplyPlanBase {
73
+ readonly kind: 'structure';
74
+ /** Repair truth when active leaf ground is unexpectedly absent. */
75
+ readonly repairArtifact: TransferArtifact | null;
76
+ }
77
+ export interface ReferenceApplyPlan extends ApplyPlanBase {
78
+ readonly kind: 'reference';
79
+ readonly targetEntityId: string;
80
+ }
81
+ export interface RepositoryApplyPlan extends ApplyPlanBase {
82
+ readonly kind: 'repo.git';
83
+ readonly artifact: TransferArtifact;
84
+ readonly stateId: string;
85
+ readonly cardId: string;
86
+ readonly checkpointId: string;
87
+ readonly parentTransportVersion: string | null;
88
+ readonly transportVersion: string;
89
+ readonly cardChanged: boolean;
90
+ readonly checkpointChanged: boolean;
91
+ }
92
+ export interface LifecycleApplyPlan extends ApplyPlanBase {
93
+ readonly kind: 'lifecycle';
94
+ readonly status: 'trashed' | 'deleted';
95
+ }
96
+ export type EntityApplyPlan = TextApplyPlan | BinaryApplyPlan | LinkApplyPlan | StructureApplyPlan | ReferenceApplyPlan | RepositoryApplyPlan | LifecycleApplyPlan;
97
+ export type ApplyGuard = {
98
+ readonly kind: 'safe';
99
+ } | {
100
+ readonly kind: 'already-target';
101
+ } | {
102
+ readonly kind: 'local-change';
103
+ } | {
104
+ readonly kind: 'retry';
105
+ readonly reason?: string;
106
+ };
107
+ export type ApplyVerification = {
108
+ readonly kind: 'match';
109
+ } | {
110
+ readonly kind: 'local-change';
111
+ } | {
112
+ readonly kind: 'retry';
113
+ readonly reason?: string;
114
+ };
115
+ export type ApplyCompletion = {
116
+ readonly kind: 'materialized';
117
+ } | {
118
+ readonly kind: 'superseded-by-local';
119
+ };
120
+ type MaybePromise<T> = T | Promise<T>;
121
+ /** One prepared SQLite owner supplies these transactions for the rail lifetime. */
122
+ export interface EntityApplyStorePort {
123
+ /** At most one item per entity across a stable cursor scan, existing intents
124
+ * first. Pagination prevents blocked UUIDs from starving unrelated work. */
125
+ readApplyWork(limit: number, afterCursor: string | null): MaybePromise<EntityApplyWorkPage>;
126
+ /** True when a local Outbox row is still unsequenced or was accepted after
127
+ * `targetSequence`. An accepted local receipt remains protective until its
128
+ * own official position is selected by Apply. */
129
+ hasLocalWorkAfter(authorityId: string, entityId: string, targetSequence: number): MaybePromise<boolean>;
130
+ beginIntent(intent: EntityApplyIntent): MaybePromise<void>;
131
+ setIntentPhase(intent: EntityApplyIntent): MaybePromise<void>;
132
+ cancelIntent(intent: EntityApplyIntent): MaybePromise<void>;
133
+ /** One transaction resolves Inbox rows, advances proof, updates the notebook,
134
+ * and clears the exact intent. */
135
+ completeIntent(intent: EntityApplyIntent, completion: ApplyCompletion): MaybePromise<void>;
136
+ }
137
+ /** Type-owned Apply behavior. Every operation is idempotent for the exact intent. */
138
+ export interface EntityApplySocket {
139
+ prepare(intent: EntityApplyIntent, plan: EntityApplyPlan): Promise<void>;
140
+ /** Compare ground with the last local observation before preparation and again before reveal. */
141
+ guard(intent: EntityApplyIntent, plan: EntityApplyPlan): Promise<ApplyGuard>;
142
+ reveal(intent: EntityApplyIntent, plan: EntityApplyPlan): Promise<void>;
143
+ /** Remove only disposable private preparation; recovery bytes remain host-owned. */
144
+ discard(intent: EntityApplyIntent, plan: EntityApplyPlan): Promise<void>;
145
+ }
146
+ /** Type-owned reread of real ground after reveal. */
147
+ export interface EntityVerifySocket {
148
+ verify(intent: EntityApplyIntent, plan: EntityApplyPlan): Promise<ApplyVerification>;
149
+ }
150
+ export interface OperationalEntityApplyAdapter {
151
+ readonly name: string;
152
+ readonly apply: EntityApplySocket;
153
+ readonly verify: EntityVerifySocket;
154
+ }
155
+ /**
156
+ * Machine seam for the common rail. Type dispatch is explicit: the coordinator
157
+ * cannot perform a filesystem effect until it obtains the target type's full
158
+ * Apply + Verify adapter. Detect + Record remains the one common capture path.
159
+ */
160
+ export interface EntityApplyEffectsPort {
161
+ adapterFor(type: EntityType): OperationalEntityApplyAdapter;
162
+ /** Await Detect + Record so the observed local result is durable before return. */
163
+ captureLocal(intent: EntityApplyIntent, plan: EntityApplyPlan, position: 'before-reveal' | 'after-reveal'): Promise<void>;
164
+ }
165
+ export interface EntityApplySchedulePort {
166
+ schedule(delayMs: number, callback: () => void): {
167
+ cancel(): void;
168
+ };
169
+ random(): number;
170
+ }
171
+ export interface EntityApplyRailOptions {
172
+ readonly store: EntityApplyStorePort;
173
+ readonly effects: EntityApplyEffectsPort;
174
+ readonly schedule: EntityApplySchedulePort;
175
+ readonly sha256Hex: Sha256Hex;
176
+ readonly now: () => number;
177
+ readonly concurrency?: number;
178
+ readonly workLimit?: number;
179
+ readonly onBackgroundError?: (error: unknown) => void;
180
+ }
181
+ export declare function assertApplyIntent(intent: EntityApplyIntent): void;
182
+ export declare function createApplyIntent(input: {
183
+ readonly authorityId: string;
184
+ readonly entityId: string;
185
+ readonly fromSequence: number;
186
+ readonly target: AcceptedEntityRecord;
187
+ readonly createdAt: number;
188
+ }): EntityApplyIntent;
189
+ export declare function advanceApplyIntent(intent: EntityApplyIntent, phase: Exclude<ApplyIntentPhase, 'declared'>): EntityApplyIntent;
190
+ export {};
191
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/apply/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** Portable contracts at the Inbox -> Apply -> Verify boundary. */
2
+ import { isEntityType, UUID_PATTERN } from '../entities/types.js';
3
+ export const ENTITY_APPLY_INTENT_CONTRACT = 'amalgm.entity-apply-intent@1';
4
+ const HASH = /^[0-9a-f]{64}$/;
5
+ const PHASES = new Set(['declared', 'prepared', 'revealed']);
6
+ const sequence = (value, positive = false) => Number.isSafeInteger(value) && value >= (positive ? 1 : 0);
7
+ export function assertApplyIntent(intent) {
8
+ if (intent.contract !== ENTITY_APPLY_INTENT_CONTRACT
9
+ || !intent.authorityId
10
+ || !UUID_PATTERN.test(intent.entityId)
11
+ || !sequence(intent.fromSequence)
12
+ || !sequence(intent.throughSequence, true)
13
+ || intent.throughSequence < intent.fromSequence + 1
14
+ || !intent.targetMutationId
15
+ || !HASH.test(intent.targetState)
16
+ || !isEntityType(intent.targetType)
17
+ || !PHASES.has(intent.phase)
18
+ || !sequence(intent.createdAt)) {
19
+ throw new Error('entity Apply intent is invalid');
20
+ }
21
+ }
22
+ export function createApplyIntent(input) {
23
+ const intent = Object.freeze({
24
+ contract: ENTITY_APPLY_INTENT_CONTRACT,
25
+ authorityId: input.authorityId,
26
+ entityId: input.entityId,
27
+ fromSequence: input.fromSequence,
28
+ throughSequence: input.target.globalSequence,
29
+ targetMutationId: input.target.mutationId,
30
+ targetState: input.target.resultState,
31
+ targetType: input.target.change.result.type,
32
+ phase: 'declared',
33
+ createdAt: input.createdAt,
34
+ });
35
+ assertApplyIntent(intent);
36
+ return intent;
37
+ }
38
+ export function advanceApplyIntent(intent, phase) {
39
+ assertApplyIntent(intent);
40
+ const legal = intent.phase === phase
41
+ || (intent.phase === 'declared' && phase === 'prepared')
42
+ || (intent.phase === 'prepared' && phase === 'revealed');
43
+ if (!legal)
44
+ throw new Error(`entity Apply intent cannot move from ${intent.phase} to ${phase}`);
45
+ return Object.freeze({ ...intent, phase });
46
+ }
47
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/apply/contracts.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAGnE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAmC,MAAM,sBAAsB,CAAC;AAMnG,MAAM,CAAC,MAAM,4BAA4B,GAAG,8BAA8B,CAAC;AA4M3E,MAAM,IAAI,GAAG,gBAAgB,CAAC;AAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;AAE/E,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,QAAQ,GAAG,KAAK,EAAW,EAAE,CAC5D,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7D,MAAM,UAAU,iBAAiB,CAAC,MAAyB;IACzD,IAAI,MAAM,CAAC,QAAQ,KAAK,4BAA4B;WAC/C,CAAC,MAAM,CAAC,WAAW;WACnB,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;WACnC,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC;WAC9B,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC;WACvC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,YAAY,GAAG,CAAC;WAChD,CAAC,MAAM,CAAC,gBAAgB;WACxB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;WAC9B,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC;WAChC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;WACzB,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAMjC;IACC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3B,QAAQ,EAAE,4BAA4B;QACtC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;QAC5C,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;QACzC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW;QACrC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI;QAC3C,KAAK,EAAE,UAAmB;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC,CAAC;IACH,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAAyB,EACzB,KAA4C;IAE5C,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,KAAK;WAC/B,CAAC,MAAM,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,CAAC;WACrD,CAAC,MAAM,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,CAAC,CAAC;IAC3D,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,MAAM,CAAC,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC;IAChG,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,10 @@
1
+ /** Entity Apply and Verify subsystem. */
2
+ export * from './contracts.js';
3
+ export * from './content-results.js';
4
+ export * from './local-work.js';
5
+ export { planEntityApply } from './plans.js';
6
+ export * from './rail.js';
7
+ export * from './repository-result.js';
8
+ export * from './selection.js';
9
+ export * from './type-adapters.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/apply/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /** Entity Apply and Verify subsystem. */
2
+ export * from './contracts.js';
3
+ export * from './content-results.js';
4
+ export * from './local-work.js';
5
+ export { planEntityApply } from './plans.js';
6
+ export * from './rail.js';
7
+ export * from './repository-result.js';
8
+ export * from './selection.js';
9
+ export * from './type-adapters.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/apply/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /** Pure form of the Outbox gate used by the Apply store transaction. */
2
+ import type { OutboxRow } from '../records/outbox.js';
3
+ /**
4
+ * A local result protects working ground when cloud has not sequenced it yet,
5
+ * or when its accepted sequence is later than the incoming target. An
6
+ * accepted local row at the target is no longer a blocker: that is the
7
+ * official position Apply should Verify against the already-equal disk.
8
+ */
9
+ export declare function hasLocalWorkAfter(rows: readonly OutboxRow[], authorityId: string, entityId: string, targetSequence: number): boolean;
10
+ //# sourceMappingURL=local-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-work.d.ts","sourceRoot":"","sources":["../../src/apply/local-work.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,OAAO,CAQT"}
@@ -0,0 +1,17 @@
1
+ /** Pure form of the Outbox gate used by the Apply store transaction. */
2
+ /**
3
+ * A local result protects working ground when cloud has not sequenced it yet,
4
+ * or when its accepted sequence is later than the incoming target. An
5
+ * accepted local row at the target is no longer a blocker: that is the
6
+ * official position Apply should Verify against the already-equal disk.
7
+ */
8
+ export function hasLocalWorkAfter(rows, authorityId, entityId, targetSequence) {
9
+ if (!authorityId || !entityId
10
+ || !Number.isSafeInteger(targetSequence) || targetSequence < 1) {
11
+ throw new Error('Apply local-work target is invalid');
12
+ }
13
+ return rows.some((row) => row.record.authorityId === authorityId
14
+ && row.record.entityId === entityId
15
+ && (row.status === 'pending' || row.globalSequence > targetSequence));
16
+ }
17
+ //# sourceMappingURL=local-work.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-work.js","sourceRoot":"","sources":["../../src/apply/local-work.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAIxE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAA0B,EAC1B,WAAmB,EACnB,QAAgB,EAChB,cAAsB;IAEtB,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ;WACxB,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,WAAW;WAC3D,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ;WAChC,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,14 @@
1
+ /** Type-sensitive Apply plan derivation from one accepted complete result. */
2
+ import { type Sha256Hex } from '../entities/types.js';
3
+ import type { EntityApplyPlan, EntityApplyWork } from './contracts.js';
4
+ import { type SelectedEntityApply } from './selection.js';
5
+ /**
6
+ * Validate the target's replay/cargo seam and derive the one plan a host may
7
+ * execute. Type is never rediscovered from path, extension, or downloaded
8
+ * bytes. A structural-only record stays structural even when its target is a
9
+ * leaf; its existing immutable head is only repair fallback.
10
+ */
11
+ export declare function planEntityApply(work: EntityApplyWork, sha256Hex: Sha256Hex): EntityApplyPlan;
12
+ /** Derive a plan from the exact selection this coordinator already validated. */
13
+ export declare function planSelectedEntityApply(work: EntityApplyWork, selected: SelectedEntityApply, sha256Hex: Sha256Hex): EntityApplyPlan;
14
+ //# sourceMappingURL=plans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../../src/apply/plans.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAK9E,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQpE,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EAIhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AA6I7E;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,GAAG,eAAe,CAE5F;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,eAAe,EACrB,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,SAAS,GACnB,eAAe,CAyDjB"}