@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.
Files changed (197) hide show
  1. package/PURPOSE.md +52 -29
  2. package/README.md +1 -2
  3. package/dist/contracts/index.d.ts +0 -1
  4. package/dist/contracts/index.d.ts.map +1 -1
  5. package/dist/contracts/index.js +0 -1
  6. package/dist/contracts/index.js.map +1 -1
  7. package/dist/detection/record-proposal.d.ts +3 -2
  8. package/dist/detection/record-proposal.d.ts.map +1 -1
  9. package/dist/detection/record-proposal.js +9 -7
  10. package/dist/detection/record-proposal.js.map +1 -1
  11. package/dist/index.d.ts +3 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/machines/index.d.ts +0 -2
  16. package/dist/machines/index.d.ts.map +1 -1
  17. package/dist/machines/index.js +0 -2
  18. package/dist/machines/index.js.map +1 -1
  19. package/dist/records/authority.d.ts +23 -0
  20. package/dist/records/authority.d.ts.map +1 -0
  21. package/dist/records/authority.js +28 -0
  22. package/dist/records/authority.js.map +1 -0
  23. package/dist/records/codec.d.ts +6 -0
  24. package/dist/records/codec.d.ts.map +1 -0
  25. package/dist/records/codec.js +42 -0
  26. package/dist/records/codec.js.map +1 -0
  27. package/dist/records/contracts.d.ts +46 -0
  28. package/dist/records/contracts.d.ts.map +1 -0
  29. package/dist/records/contracts.js +114 -0
  30. package/dist/records/contracts.js.map +1 -0
  31. package/dist/records/inbox.d.ts +18 -0
  32. package/dist/records/inbox.d.ts.map +1 -0
  33. package/dist/records/inbox.js +34 -0
  34. package/dist/records/inbox.js.map +1 -0
  35. package/dist/records/index.d.ts +7 -0
  36. package/dist/records/index.d.ts.map +1 -0
  37. package/dist/records/index.js +7 -0
  38. package/dist/records/index.js.map +1 -0
  39. package/dist/records/outbox.d.ts +20 -0
  40. package/dist/records/outbox.d.ts.map +1 -0
  41. package/dist/records/outbox.js +44 -0
  42. package/dist/records/outbox.js.map +1 -0
  43. package/dist/registration/user-ground.d.ts +5 -2
  44. package/dist/registration/user-ground.d.ts.map +1 -1
  45. package/dist/registration/user-ground.js +14 -3
  46. package/dist/registration/user-ground.js.map +1 -1
  47. package/dist/watching/suspicion.d.ts.map +1 -1
  48. package/dist/watching/suspicion.js +29 -1
  49. package/dist/watching/suspicion.js.map +1 -1
  50. package/dist-cjs/contracts/binding.js +26 -0
  51. package/dist-cjs/contracts/binding.js.map +1 -0
  52. package/dist-cjs/contracts/content.js +99 -0
  53. package/dist-cjs/contracts/content.js.map +1 -0
  54. package/dist-cjs/contracts/docs.js +56 -0
  55. package/dist-cjs/contracts/docs.js.map +1 -0
  56. package/dist-cjs/contracts/events.js +44 -0
  57. package/dist-cjs/contracts/events.js.map +1 -0
  58. package/dist-cjs/contracts/frames/gateway.js +39 -0
  59. package/dist-cjs/contracts/frames/gateway.js.map +1 -0
  60. package/dist-cjs/contracts/frames/stream.js +20 -0
  61. package/dist-cjs/contracts/frames/stream.js.map +1 -0
  62. package/dist-cjs/contracts/frames/tunnel.js +60 -0
  63. package/dist-cjs/contracts/frames/tunnel.js.map +1 -0
  64. package/dist-cjs/contracts/index.js +34 -0
  65. package/dist-cjs/contracts/index.js.map +1 -0
  66. package/dist-cjs/contracts/presence.js +38 -0
  67. package/dist-cjs/contracts/presence.js.map +1 -0
  68. package/dist-cjs/contracts/resources.js +114 -0
  69. package/dist-cjs/contracts/resources.js.map +1 -0
  70. package/dist-cjs/contracts/snapshot.js +31 -0
  71. package/dist-cjs/contracts/snapshot.js.map +1 -0
  72. package/dist-cjs/contracts/validate.js +34 -0
  73. package/dist-cjs/contracts/validate.js.map +1 -0
  74. package/dist-cjs/detection/adapter-contract.js +168 -0
  75. package/dist-cjs/detection/adapter-contract.js.map +1 -0
  76. package/dist-cjs/detection/batch.js +71 -0
  77. package/dist-cjs/detection/batch.js.map +1 -0
  78. package/dist-cjs/detection/classify.js +48 -0
  79. package/dist-cjs/detection/classify.js.map +1 -0
  80. package/dist-cjs/detection/content.js +122 -0
  81. package/dist-cjs/detection/content.js.map +1 -0
  82. package/dist-cjs/detection/continuity.js +88 -0
  83. package/dist-cjs/detection/continuity.js.map +1 -0
  84. package/dist-cjs/detection/diff.js +193 -0
  85. package/dist-cjs/detection/diff.js.map +1 -0
  86. package/dist-cjs/detection/echo.js +25 -0
  87. package/dist-cjs/detection/echo.js.map +1 -0
  88. package/dist-cjs/detection/enrollment.js +189 -0
  89. package/dist-cjs/detection/enrollment.js.map +1 -0
  90. package/dist-cjs/detection/index.js +57 -0
  91. package/dist-cjs/detection/index.js.map +1 -0
  92. package/dist-cjs/detection/record-proposal.js +170 -0
  93. package/dist-cjs/detection/record-proposal.js.map +1 -0
  94. package/dist-cjs/detection/refusal.js +44 -0
  95. package/dist-cjs/detection/refusal.js.map +1 -0
  96. package/dist-cjs/detection/repository.js +67 -0
  97. package/dist-cjs/detection/repository.js.map +1 -0
  98. package/dist-cjs/detection/territory.js +82 -0
  99. package/dist-cjs/detection/territory.js.map +1 -0
  100. package/dist-cjs/detection/watch-boundary.js +51 -0
  101. package/dist-cjs/detection/watch-boundary.js.map +1 -0
  102. package/dist-cjs/entities/bytes.js +92 -0
  103. package/dist-cjs/entities/bytes.js.map +1 -0
  104. package/dist-cjs/entities/cloud.js +171 -0
  105. package/dist-cjs/entities/cloud.js.map +1 -0
  106. package/dist-cjs/entities/index.js +39 -0
  107. package/dist-cjs/entities/index.js.map +1 -0
  108. package/dist-cjs/entities/moves.js +85 -0
  109. package/dist-cjs/entities/moves.js.map +1 -0
  110. package/dist-cjs/entities/repo-states.js +256 -0
  111. package/dist-cjs/entities/repo-states.js.map +1 -0
  112. package/dist-cjs/entities/rules.js +216 -0
  113. package/dist-cjs/entities/rules.js.map +1 -0
  114. package/dist-cjs/entities/types.js +44 -0
  115. package/dist-cjs/entities/types.js.map +1 -0
  116. package/dist-cjs/files/commands.js +120 -0
  117. package/dist-cjs/files/commands.js.map +1 -0
  118. package/dist-cjs/files/index.js +19 -0
  119. package/dist-cjs/files/index.js.map +1 -0
  120. package/dist-cjs/index.js +39 -0
  121. package/dist-cjs/index.js.map +1 -0
  122. package/dist-cjs/machines/arbitration.js +41 -0
  123. package/dist-cjs/machines/arbitration.js.map +1 -0
  124. package/dist-cjs/machines/backoff.js +38 -0
  125. package/dist-cjs/machines/backoff.js.map +1 -0
  126. package/dist-cjs/machines/bootstrap.js +110 -0
  127. package/dist-cjs/machines/bootstrap.js.map +1 -0
  128. package/dist-cjs/machines/chunks.js +72 -0
  129. package/dist-cjs/machines/chunks.js.map +1 -0
  130. package/dist-cjs/machines/index.js +28 -0
  131. package/dist-cjs/machines/index.js.map +1 -0
  132. package/dist-cjs/machines/presence.js +53 -0
  133. package/dist-cjs/machines/presence.js.map +1 -0
  134. package/dist-cjs/merge/index.js +25 -0
  135. package/dist-cjs/merge/index.js.map +1 -0
  136. package/dist-cjs/merge/merge3.js +191 -0
  137. package/dist-cjs/merge/merge3.js.map +1 -0
  138. package/dist-cjs/package.json +1 -0
  139. package/dist-cjs/records/authority.js +31 -0
  140. package/dist-cjs/records/authority.js.map +1 -0
  141. package/dist-cjs/records/codec.js +48 -0
  142. package/dist-cjs/records/codec.js.map +1 -0
  143. package/dist-cjs/records/contracts.js +121 -0
  144. package/dist-cjs/records/contracts.js.map +1 -0
  145. package/dist-cjs/records/inbox.js +37 -0
  146. package/dist-cjs/records/inbox.js.map +1 -0
  147. package/dist-cjs/records/index.js +23 -0
  148. package/dist-cjs/records/index.js.map +1 -0
  149. package/dist-cjs/records/outbox.js +48 -0
  150. package/dist-cjs/records/outbox.js.map +1 -0
  151. package/dist-cjs/registration/index.js +19 -0
  152. package/dist-cjs/registration/index.js.map +1 -0
  153. package/dist-cjs/registration/user-ground.js +183 -0
  154. package/dist-cjs/registration/user-ground.js.map +1 -0
  155. package/dist-cjs/transfer/artifacts.js +75 -0
  156. package/dist-cjs/transfer/artifacts.js.map +1 -0
  157. package/dist-cjs/transfer/batches.js +44 -0
  158. package/dist-cjs/transfer/batches.js.map +1 -0
  159. package/dist-cjs/transfer/download.js +88 -0
  160. package/dist-cjs/transfer/download.js.map +1 -0
  161. package/dist-cjs/transfer/index.js +21 -0
  162. package/dist-cjs/transfer/index.js.map +1 -0
  163. package/dist-cjs/transfer/parallel.js +35 -0
  164. package/dist-cjs/transfer/parallel.js.map +1 -0
  165. package/dist-cjs/transfer/upload.js +161 -0
  166. package/dist-cjs/transfer/upload.js.map +1 -0
  167. package/dist-cjs/watching/coverage.js +54 -0
  168. package/dist-cjs/watching/coverage.js.map +1 -0
  169. package/dist-cjs/watching/index.js +24 -0
  170. package/dist-cjs/watching/index.js.map +1 -0
  171. package/dist-cjs/watching/suspicion.js +105 -0
  172. package/dist-cjs/watching/suspicion.js.map +1 -0
  173. package/dist-cjs/workspace/api.js +66 -0
  174. package/dist-cjs/workspace/api.js.map +1 -0
  175. package/dist-cjs/workspace/identity.js +32 -0
  176. package/dist-cjs/workspace/identity.js.map +1 -0
  177. package/dist-cjs/workspace/index.js +14 -0
  178. package/dist-cjs/workspace/index.js.map +1 -0
  179. package/dist-cjs/workspace/memory-store.js +21 -0
  180. package/dist-cjs/workspace/memory-store.js.map +1 -0
  181. package/dist-cjs/workspace/registry.js +98 -0
  182. package/dist-cjs/workspace/registry.js.map +1 -0
  183. package/dist-cjs/workspace/types.js +3 -0
  184. package/dist-cjs/workspace/types.js.map +1 -0
  185. package/package.json +30 -8
  186. package/dist/contracts/mutation.d.ts +0 -51
  187. package/dist/contracts/mutation.d.ts.map +0 -1
  188. package/dist/contracts/mutation.js +0 -55
  189. package/dist/contracts/mutation.js.map +0 -1
  190. package/dist/machines/journal.d.ts +0 -63
  191. package/dist/machines/journal.d.ts.map +0 -1
  192. package/dist/machines/journal.js +0 -71
  193. package/dist/machines/journal.js.map +0 -1
  194. package/dist/machines/ordering.d.ts +0 -53
  195. package/dist/machines/ordering.d.ts.map +0 -1
  196. package/dist/machines/ordering.js +0 -87
  197. package/dist/machines/ordering.js.map +0 -1
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ /**
3
+ * The adapter contract: what it means to serve an entity type.
4
+ *
5
+ * An adapter is how a KIND of entity rides the seven realtime rails —
6
+ * watch, detect, record, send, receive, apply, verify. The entity's
7
+ * `type` selects its adapter; the rails themselves never change shape
8
+ * per type. Ratified by entity-model.md ("Type selects the complete
9
+ * adapter cycle") and entity-implementation.md.
10
+ *
11
+ * Axioms:
12
+ *
13
+ * 1. ONE ADAPTER PER TYPE, EVERY TYPE ASSIGNED. The alphabet belongs
14
+ * to the registry; the adapter map covers it exactly — no type
15
+ * unassigned, no type claimed twice. Assigned is not yet
16
+ * operational: operational is earned rail by rail, and absence is
17
+ * honest.
18
+ * 2. ADAPTERS OWN BEHAVIOR; THE REGISTRY OWNS IDENTITY. A lawful type
19
+ * transition that crosses adapters is a handoff on the same UUID,
20
+ * never a rebirth.
21
+ * 3. ONE SOCKET PER RAIL. A rail's callable surfaces are ratified
22
+ * HERE, once, for every adapter (`SOCKETS`). An adapter binds a
23
+ * rail's whole socket or binds the rail not at all; a rail whose
24
+ * socket is not yet ratified cannot be bound by anyone.
25
+ * 4. A TRUTH READ NEVER LIES. Every assigned type names its source of
26
+ * truth in one sentence, and reading it produces exactly one of
27
+ * three honest answers: present, absent, or unsettled.
28
+ * 5. RAILS ARE HONEST. An unbound rail is absent — never stubbed,
29
+ * never defaulted.
30
+ * 6. THE CONTRACT IS FROZEN GROUND. A descriptor is immutable from
31
+ * the moment it loads.
32
+ * 7. THE BASE ORCHESTRATES; THE ADAPTER SUPPLIES TYPE BEHAVIOR. A
33
+ * rail earns a socket only when a real consumer proves that
34
+ * behavior differs by type — never for symmetry.
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.referenceAdapter = exports.lookFailed = exports.SOCKETS = exports.RAILS = void 0;
38
+ exports.assertAdapter = assertAdapter;
39
+ exports.buildTypeMap = buildTypeMap;
40
+ /** The seven rails, declared once, frozen, in journey order. */
41
+ exports.RAILS = Object.freeze([
42
+ 'watch', 'detect', 'record', 'send', 'receive', 'apply', 'verify',
43
+ ]);
44
+ /**
45
+ * The ratified sockets — for each rail that has one, the exact surfaces
46
+ * every binding adapter implements. Same names, same shapes, every
47
+ * type. ONE socket is ratified today (detect), derived from what
48
+ * production detection actually asks of a type. Watch and record earn
49
+ * none at this bar (adjudicated 2026-08-03 under axiom 7); apply and
50
+ * verify join only when the Send/Receive rails exist to derive their
51
+ * socket from. A socket is ratified from a real consumer or it is not
52
+ * ratified at all.
53
+ */
54
+ exports.SOCKETS = Object.freeze({
55
+ detect: Object.freeze(['truth']),
56
+ });
57
+ /**
58
+ * Convict a malformed adapter descriptor loudly; return it (typed)
59
+ * unchanged when lawful.
60
+ */
61
+ function assertAdapter(adapter) {
62
+ const isRecord = (value) => typeof value === 'object' && value !== null;
63
+ const where = isRecord(adapter) && typeof adapter['name'] === 'string' && adapter['name']
64
+ ? `adapter ${JSON.stringify(adapter['name'])}` : 'adapter';
65
+ if (!isRecord(adapter) || !Object.isFrozen(adapter)) {
66
+ throw new Error(`${where}: a descriptor is a frozen object`);
67
+ }
68
+ if (typeof adapter['name'] !== 'string' || adapter['name'].length === 0) {
69
+ throw new Error('adapter: name is a non-empty string');
70
+ }
71
+ const { types, rails } = adapter;
72
+ if (!isRecord(types) || !Object.isFrozen(types) || Object.keys(types).length === 0) {
73
+ throw new Error(`${where}: types is a frozen, non-empty map of entity type → declared truth`);
74
+ }
75
+ for (const [type, truth] of Object.entries(types)) {
76
+ if (typeof truth !== 'string' || truth.length === 0) {
77
+ throw new Error(`${where}: type ${JSON.stringify(type)} must declare its source of truth in one sentence`);
78
+ }
79
+ }
80
+ if (!isRecord(rails) || !Object.isFrozen(rails)) {
81
+ throw new Error(`${where}: rails is a frozen map (empty is honest; a stub is not)`);
82
+ }
83
+ for (const [rail, surfaces] of Object.entries(rails)) {
84
+ if (!exports.RAILS.includes(rail)) {
85
+ throw new Error(`${where}: ${JSON.stringify(rail)} is not a rail — the rails are ${exports.RAILS.join(', ')}`);
86
+ }
87
+ const socket = exports.SOCKETS[rail];
88
+ if (!socket) {
89
+ throw new Error(`${where}: rail ${rail} has no ratified socket yet — a socket is ratified in the contract before anyone binds it`);
90
+ }
91
+ if (!isRecord(surfaces) || !Object.isFrozen(surfaces)) {
92
+ throw new Error(`${where}: rail ${rail} must bind a frozen map of its socket's surfaces`);
93
+ }
94
+ const bound = Object.keys(surfaces).sort();
95
+ if (bound.join(',') !== [...socket].sort().join(',')) {
96
+ throw new Error(`${where}: rail ${rail} binds [${bound.join(', ')}] but its socket is [${socket.join(', ')}] — an adapter implements a rail's whole socket or binds the rail not at all`);
97
+ }
98
+ for (const [surface, fn] of Object.entries(surfaces)) {
99
+ if (typeof fn !== 'function') {
100
+ throw new Error(`${where}: ${rail}.${surface} must be a function — an unbuilt surface is left absent, never stubbed`);
101
+ }
102
+ }
103
+ }
104
+ return adapter;
105
+ }
106
+ /**
107
+ * Build the one type → adapter map, convicting every violation of
108
+ * axiom 1: an adapter claiming a type outside the alphabet, two
109
+ * adapters claiming one type, or an alphabet type left unassigned.
110
+ * Pure — callers own where the alphabet and adapters come from.
111
+ */
112
+ function buildTypeMap(adapters, alphabet) {
113
+ const known = new Set(alphabet);
114
+ const byType = new Map();
115
+ for (const candidate of adapters) {
116
+ const adapter = assertAdapter(candidate);
117
+ for (const type of Object.keys(adapter.types)) {
118
+ if (!known.has(type)) {
119
+ throw new Error(`adapter ${adapter.name} claims ${JSON.stringify(type)}, which is not in the registry's alphabet`);
120
+ }
121
+ const holder = byType.get(type);
122
+ if (holder) {
123
+ throw new Error(`entity type ${JSON.stringify(type)} is claimed by both ${holder.name} and ${adapter.name} — one adapter per type`);
124
+ }
125
+ byType.set(type, adapter);
126
+ }
127
+ }
128
+ for (const type of known) {
129
+ if (!byType.has(type)) {
130
+ throw new Error(`entity type ${JSON.stringify(type)} has no adapter — every type is assigned`);
131
+ }
132
+ }
133
+ return byType;
134
+ }
135
+ /**
136
+ * The three-state vocabulary's one shared judgment: what a FAILED look
137
+ * at ground means. ENOENT and ENOTDIR are the filesystem itself saying
138
+ * "not there" — honest ABSENCE, a fact. Every other failure means the
139
+ * LOOK failed, not the ground — UNSETTLED: no conclusion, read again.
140
+ *
141
+ * Every truth reader classifies through this one function so no reader
142
+ * can invent its own idea of absence: mistaking "could not look" for
143
+ * "not there" is the exact lie axiom 4 forbids. Only present or absent
144
+ * may produce a conclusion.
145
+ */
146
+ const lookFailed = (error) => error.code === 'ENOENT' || error.code === 'ENOTDIR'
147
+ ? { truth: 'absent' }
148
+ : { truth: 'unsettled', reason: error.code };
149
+ exports.lookFailed = lookFailed;
150
+ /**
151
+ * The managed-reference adapter: Amalgm's OWN link kind, never
152
+ * conflated with a filesystem symlink. Its payload is the target
153
+ * entity's UUID — identity, not an address — and its local rendering as
154
+ * an ordinary symlink is DERIVED state (entity-model.md, symlink
155
+ * section). ASSIGNED, NOT YET OPERATIONAL — and that absence is the
156
+ * honest truth: no rail is bound because the projection lives inside
157
+ * the registration boundary today; its detect socket is ratified from
158
+ * that seam when the projection is extracted, never invented ahead of
159
+ * it.
160
+ */
161
+ exports.referenceAdapter = Object.freeze({
162
+ name: 'reference',
163
+ types: Object.freeze({
164
+ reference: "its target entity's UUID — identity, not an address; the rendered symlink is derived state",
165
+ }),
166
+ rails: Object.freeze({}),
167
+ });
168
+ //# sourceMappingURL=adapter-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-contract.js","sourceRoot":"","sources":["../../src/detection/adapter-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Net-difference planning for one settled Watch batch.
4
+ *
5
+ * Identity reconciliation and type-specific capture happen before this seam.
6
+ * This seam makes cancellation, unsettled truth, lifecycle authority, coverage
7
+ * requests, and Watch settlement one total decision.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.planDetectionBatch = planDetectionBatch;
11
+ const types_js_1 = require("../entities/types.js");
12
+ const record_proposal_js_1 = require("./record-proposal.js");
13
+ const watch_boundary_js_1 = require("./watch-boundary.js");
14
+ const newlyDirectoryGround = (transition) => transition.relPath !== ''
15
+ &&
16
+ types_js_1.CONTAINERS.has(transition.result.type)
17
+ && (transition.base === null || !types_js_1.CONTAINERS.has(transition.base.type));
18
+ /** Plan the complete net difference. No partial proposals escape an unsettled batch. */
19
+ function planDetectionBatch(batch, transitions) {
20
+ const unsettled = transitions.filter((transition) => transition.truth === 'unsettled');
21
+ if (unsettled.length > 0) {
22
+ return Object.freeze({
23
+ kind: 'retry',
24
+ reasons: Object.freeze(unsettled.map((transition) => transition.reason ?? 'truth is unsettled')),
25
+ });
26
+ }
27
+ const proposals = [];
28
+ const missing = [];
29
+ const createdDirectories = [];
30
+ for (const transition of transitions) {
31
+ if (transition.truth === 'present') {
32
+ const proposal = (0, record_proposal_js_1.detectedChangeProposal)(transition);
33
+ if (proposal)
34
+ proposals.push(proposal);
35
+ if (newlyDirectoryGround(transition)) {
36
+ createdDirectories.push(transition.relPath);
37
+ }
38
+ continue;
39
+ }
40
+ if (transition.truth !== 'absent') {
41
+ throw new Error('unsettled truth escaped the batch retry gate');
42
+ }
43
+ if (transition.base === null)
44
+ continue; // absent before and after: no entity existed
45
+ if (transition.base.status !== 'active')
46
+ continue;
47
+ if (transition.lifecycleAuthorization !== 'trash') {
48
+ missing.push(transition.base);
49
+ continue;
50
+ }
51
+ if (!transition.trashedResult) {
52
+ throw new Error('authorized Trash requires the entity law\'s exact trashed result');
53
+ }
54
+ const proposal = (0, record_proposal_js_1.detectedChangeProposal)({
55
+ base: transition.base,
56
+ result: transition.trashedResult,
57
+ replay: { kind: 'structure' },
58
+ lifecycleAuthorization: 'trash',
59
+ });
60
+ if (proposal)
61
+ proposals.push(proposal);
62
+ }
63
+ return Object.freeze({
64
+ kind: 'ready',
65
+ proposals: Object.freeze(proposals),
66
+ missing: Object.freeze(missing),
67
+ coverage: (0, watch_boundary_js_1.directoryCoverageRequests)(batch, createdDirectories),
68
+ settle: batch,
69
+ });
70
+ }
71
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/detection/batch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Amalgm's file-type policy: which physical type a piece of file ground
4
+ * takes. Ratified by entity-model.md ("Formats live underneath the file
5
+ * types"; text versus binary is an adapter difference, never an
6
+ * identity difference).
7
+ *
8
+ * Classification is an INJECTED policy everywhere it is used — the
9
+ * registration boundary and its lenses refuse to construct without one
10
+ * — so it lives in its own file with no other job: one definition,
11
+ * replaceable whole.
12
+ *
13
+ * The rule is the oldest one there is: bytes holding a NUL are not
14
+ * text. What matters is WHERE that fact comes from. It is not read
15
+ * here. Detect's single read of a file produces its fingerprint and
16
+ * this report together, and this policy only names the type that report
17
+ * implies.
18
+ *
19
+ * That is the whole law: A FILE'S HASH AND ITS TYPE DESCRIBE THE SAME
20
+ * OBSERVED BYTES. A policy that opened the ground itself would be a
21
+ * second look — and a second look can meet different bytes, or none at
22
+ * all, leaving a record whose type contradicts the payload beside it.
23
+ * So this function takes evidence, never a path; it is total, and it
24
+ * cannot fail.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.classifyFile = classifyFile;
28
+ exports.classifyDirectory = classifyDirectory;
29
+ exports.classifyRegisteredRoot = classifyRegisteredRoot;
30
+ exports.isRepositoryMetadataEntry = isRepositoryMetadataEntry;
31
+ function classifyFile({ binary }) {
32
+ return binary ? 'file.binary' : 'file.text';
33
+ }
34
+ function classifyDirectory({ repository }) {
35
+ return repository ? 'repo.git' : 'folder';
36
+ }
37
+ /** A deliberately registered external directory remains a tree root. A Git
38
+ * root wears `repo.git`; an ordinary root wears `workspace`. */
39
+ function classifyRegisteredRoot({ repository }) {
40
+ return repository ? 'repo.git' : 'workspace';
41
+ }
42
+ /** `.git` is cargo of a repository entity, never one of its worktree
43
+ * children. Marker presence makes the parent a repository before this rule is
44
+ * asked, regardless of whether Git can currently consume that marker. */
45
+ function isRepositoryMetadataEntry(parentType, name) {
46
+ return parentType === 'repo.git' && name === '.git';
47
+ }
48
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/detection/classify.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;;AAWH,oCAEC;AASD,8CAEC;AAID,wDAEC;AAKD,8DAEC;AA1BD,SAAgB,YAAY,CAAC,EAAE,MAAM,EAAoB;IACvD,OAAO,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;AAC9C,CAAC;AASD,SAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAsB;IAClE,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5C,CAAC;AAED;gEACgE;AAChE,SAAgB,sBAAsB,CAAC,EAAE,UAAU,EAAsB;IACvE,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;AAC/C,CAAC;AAED;;yEAEyE;AACzE,SAAgB,yBAAyB,CAAC,UAA8C,EAAE,IAAY;IACpG,OAAO,UAAU,KAAK,UAAU,IAAI,IAAI,KAAK,MAAM,CAAC;AACtD,CAAC"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /** Type-sensitive content capture from Detection's one settled byte read. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.textSplice = textSplice;
5
+ exports.captureTextChange = captureTextChange;
6
+ exports.reproduceTextChange = reproduceTextChange;
7
+ exports.captureBinaryChange = captureBinaryChange;
8
+ exports.captureLinkChange = captureLinkChange;
9
+ const content_js_1 = require("../contracts/content.js");
10
+ const bytes_js_1 = require("../entities/bytes.js");
11
+ const upload_js_1 = require("../transfer/upload.js");
12
+ const capturedArtifact = (entityId, entityType, kind, input, sha256Hex) => {
13
+ const bytes = input.slice();
14
+ const artifact = {
15
+ entityId,
16
+ entityType,
17
+ kind,
18
+ contentHash: sha256Hex(bytes),
19
+ };
20
+ return Object.freeze({
21
+ artifact: Object.freeze(artifact),
22
+ bytes,
23
+ manifest: (0, upload_js_1.deriveUploadManifest)(artifact, bytes, sha256Hex),
24
+ });
25
+ };
26
+ /** The smallest single replacement span that transforms base bytes to result. */
27
+ function textSplice(base, result) {
28
+ let prefix = 0;
29
+ const shared = Math.min(base.byteLength, result.byteLength);
30
+ while (prefix < shared && base[prefix] === result[prefix])
31
+ prefix += 1;
32
+ let suffix = 0;
33
+ while (suffix < shared - prefix
34
+ && base[base.byteLength - suffix - 1] === result[result.byteLength - suffix - 1]) {
35
+ suffix += 1;
36
+ }
37
+ return Object.freeze({
38
+ offset: prefix,
39
+ deleteBytes: base.byteLength - prefix - suffix,
40
+ insert: result.slice(prefix, result.byteLength - suffix),
41
+ });
42
+ }
43
+ /**
44
+ * Capture text as one verified byte splice when that instruction is smaller
45
+ * than the result bytes. The immutable snapshot is always sealed as repair and
46
+ * cold-materialization truth.
47
+ */
48
+ function captureTextChange(entityId, base, result, sha256Hex) {
49
+ const cargo = capturedArtifact(entityId, 'file.text', 'file', result, sha256Hex);
50
+ const basePayloadVersion = base === null ? null : sha256Hex(base);
51
+ if (basePayloadVersion === cargo.artifact.contentHash)
52
+ return null;
53
+ const delta = base === null ? null : textSplice(base, result);
54
+ // Two numeric fields are fixed overhead on the wire. This conservative
55
+ // estimate keeps a replace-all operation on the snapshot path.
56
+ const useDelta = delta !== null && delta.insert.byteLength + 16 < result.byteLength;
57
+ return Object.freeze({
58
+ replay: Object.freeze({
59
+ kind: 'file.text',
60
+ mode: useDelta ? 'delta' : 'snapshot',
61
+ basePayloadVersion,
62
+ resultPayloadVersion: cargo.artifact.contentHash,
63
+ delta: useDelta ? delta : null,
64
+ }),
65
+ cargo,
66
+ });
67
+ }
68
+ /** Apply a text replay and verify its exact result, falling back to snapshot. */
69
+ function reproduceTextChange(base, replay, snapshot, sha256Hex) {
70
+ const verifiedSnapshot = () => {
71
+ if (sha256Hex(snapshot) !== replay.resultPayloadVersion) {
72
+ throw new Error('text snapshot does not match its declared result');
73
+ }
74
+ return snapshot.slice();
75
+ };
76
+ if (replay.mode !== 'delta' || replay.delta === null || base === null
77
+ || sha256Hex(base) !== replay.basePayloadVersion) {
78
+ return verifiedSnapshot();
79
+ }
80
+ const { offset, deleteBytes, insert } = replay.delta;
81
+ if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(deleteBytes)
82
+ || offset < 0 || deleteBytes < 0 || offset + deleteBytes > base.byteLength) {
83
+ return verifiedSnapshot();
84
+ }
85
+ const result = new Uint8Array(base.byteLength - deleteBytes + insert.byteLength);
86
+ result.set(base.subarray(0, offset), 0);
87
+ result.set(insert, offset);
88
+ result.set(base.subarray(offset + deleteBytes), offset + insert.byteLength);
89
+ return sha256Hex(result) === replay.resultPayloadVersion ? result : verifiedSnapshot();
90
+ }
91
+ /** Binary replay is the existing exact content manifest; Transfer moves gaps. */
92
+ function captureBinaryChange(entityId, previous, result, sha256Hex) {
93
+ if (previous !== null && !(0, content_js_1.checkContentManifest)(previous).ok) {
94
+ throw new Error('previous binary content manifest is invalid');
95
+ }
96
+ const cargo = capturedArtifact(entityId, 'file.binary', 'file', result, sha256Hex);
97
+ if (previous?.contentHash === cargo.artifact.contentHash)
98
+ return null;
99
+ return Object.freeze({
100
+ replay: Object.freeze({
101
+ kind: 'file.binary',
102
+ resultPayloadVersion: cargo.artifact.contentHash,
103
+ manifest: cargo.manifest,
104
+ }),
105
+ cargo,
106
+ });
107
+ }
108
+ /** A symlink's portable content is the literal target text, never its target. */
109
+ function captureLinkChange(entityId, previousTarget, target, sha256Hex) {
110
+ if (previousTarget === target)
111
+ return null;
112
+ const cargo = capturedArtifact(entityId, 'link', 'link', (0, bytes_js_1.utf8Encode)(target), sha256Hex);
113
+ return Object.freeze({
114
+ replay: Object.freeze({
115
+ kind: 'link',
116
+ resultPayloadVersion: cargo.artifact.contentHash,
117
+ target,
118
+ }),
119
+ cargo,
120
+ });
121
+ }
122
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/detection/content.ts"],"names":[],"mappings":";AAAA,6EAA6E;;AAgD7E,gCAcC;AAOD,8CAuBC;AAGD,kDA0BC;AAGD,kDAmBC;AAGD,8CAgBC;AAhKD,wDAAqF;AACrF,mDAAkD;AAGlD,qDAA6D;AAoB7D,MAAM,gBAAgB,GAAG,CACvB,QAAgB,EAChB,UAAgD,EAChD,IAAqB,EACrB,KAAiB,EACjB,SAAoB,EACF,EAAE;IACpB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG;QACf,QAAQ;QACR,UAAU;QACV,IAAI;QACJ,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC;KACrB,CAAC;IACX,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACjC,KAAK;QACL,QAAQ,EAAE,IAAA,gCAAoB,EAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC;KAC3D,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,iFAAiF;AACjF,SAAgB,UAAU,CAAC,IAAgB,EAAE,MAAkB;IAC7D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5D,OAAO,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,CAAC,CAAC;IACvE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,GAAG,MAAM,GAAG,MAAM;WAC1B,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,CAAC,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM;QACd,WAAW,EAAE,IAAI,CAAC,UAAU,GAAG,MAAM,GAAG,MAAM;QAC9C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC;KACzD,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,QAAgB,EAChB,IAAuB,EACvB,MAAkB,EAClB,SAAoB;IAEpB,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACjF,MAAM,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,kBAAkB,KAAK,KAAK,CAAC,QAAQ,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9D,uEAAuE;IACvE,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;IACpF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,WAAoB;YAC1B,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC,UAAmB;YACvD,kBAAkB;YAClB,oBAAoB,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW;YAChD,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;SAC/B,CAAC;QACF,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AACjF,SAAgB,mBAAmB,CACjC,IAAuB,EACvB,MAAkB,EAClB,QAAoB,EACpB,SAAoB;IAEpB,MAAM,gBAAgB,GAAG,GAAe,EAAE;QACxC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;WAChE,SAAS,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACnD,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC;WAClE,MAAM,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,IAAI,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7E,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACjF,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5E,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;AACzF,CAAC;AAED,iFAAiF;AACjF,SAAgB,mBAAmB,CACjC,QAAgB,EAChB,QAAgC,EAChC,MAAkB,EAClB,SAAoB;IAEpB,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,IAAA,iCAAoB,EAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACnF,IAAI,QAAQ,EAAE,WAAW,KAAK,KAAK,CAAC,QAAQ,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,aAAsB;YAC5B,oBAAoB,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW;YAChD,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC;QACF,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AACjF,SAAgB,iBAAiB,CAC/B,QAAgB,EAChB,cAA6B,EAC7B,MAAc,EACd,SAAoB;IAEpB,IAAI,cAAc,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAA,qBAAU,EAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,MAAe;YACrB,oBAAoB,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW;YAChD,MAAM;SACP,CAAC;QACF,KAAK;KACN,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * Root continuity verdicts: what a root's WITNESSED physical identity
4
+ * is, whether its recorded address still holds its ground, and whether
5
+ * a piece of ground rescues a moved root. Ratified by entity-model.md
6
+ * ("Ground that moves is rescued by continuity" — the directory law
7
+ * lifted to roots; "the follow rides witnessed continuity, never
8
+ * clairvoyance").
9
+ *
10
+ * Pure verdicts over injected answers — the host supplies the one look
11
+ * at an address (`statAt`) and the store's witnessed channel row
12
+ * (`channelIdentity`); the ACTIONS a verdict triggers (rebind, presence
13
+ * transitions, the undecided-address decision) stay in the host's
14
+ * wiring, because they re-aim watchers and scans.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createContinuity = createContinuity;
18
+ function createContinuity({ statAt, channelIdentity }) {
19
+ /**
20
+ * A root's WITNESSED physical identity, for continuity rescue.
21
+ * Directory roots carry their own device:inode (nothing replaces a
22
+ * directory's inode in place). A single-ground root's identity lives
23
+ * in its one channel row. Ground that changed inodes inside a
24
+ * still-open settle window is unwitnessed — no evidence, no claim.
25
+ */
26
+ function rootIdentity(root) {
27
+ if (root.kind !== 'file') {
28
+ const { device, inode } = root;
29
+ return device == null || inode == null ? null : { device, inode };
30
+ }
31
+ return channelIdentity(root.rootId);
32
+ }
33
+ /** Orphaned means the recorded address no longer holds this ground. */
34
+ function orphanedAtAddress(root) {
35
+ const identity = rootIdentity(root);
36
+ if (!identity)
37
+ return false;
38
+ const stat = statAt(root.path);
39
+ if (!stat)
40
+ return true;
41
+ return stat.device !== identity.device || stat.inode !== identity.inode;
42
+ }
43
+ /**
44
+ * Continuity claims a root exactly like it claims the directories
45
+ * inside one: unique device:inode match, exactly one candidate, and
46
+ * only for a path-orphan — a root whose recorded address still holds
47
+ * its ground is never stolen by a lookalike.
48
+ */
49
+ function findMovedRoot(stat, roots) {
50
+ const wantDir = stat.kind === 'dir';
51
+ const matches = roots.filter((root) => {
52
+ if (wantDir !== (root.kind !== 'file'))
53
+ return false;
54
+ const identity = rootIdentity(root);
55
+ return identity !== null && identity.device === stat.device && identity.inode === stat.inode;
56
+ });
57
+ const only = matches.length === 1 ? matches[0] : null;
58
+ return only && orphanedAtAddress(only) ? only : null;
59
+ }
60
+ /**
61
+ * A scan's evidence horizon is the root's ground; the root's own
62
+ * address is the horizon's edge. Ground missing there — or a
63
+ * directory root's address wearing a different physical identity — is
64
+ * UNDECIDABLE from here: moved away, deleted, or replaced by a
65
+ * lookalike all present the same address, and concluding "deleted"
66
+ * would end every channel a rescue could have saved. So the scan
67
+ * concludes nothing: beliefs freeze, the referee convicts the
68
+ * divergence, and the next enrollment moment decides — naming the new
69
+ * address rescues, re-naming this one adopts, and explicit removal is
70
+ * the only deletion (an external filesystem change is never
71
+ * permission to end identity). A single-ground root's address
72
+ * lawfully churns inodes (atomic saves, retargets), so only absence —
73
+ * or foreign directory ground — freezes it; presence is the file
74
+ * laws' business.
75
+ */
76
+ function addressUndecided(root) {
77
+ const stat = statAt(root.path);
78
+ if (!stat)
79
+ return true;
80
+ if (root.kind === 'file')
81
+ return stat.kind !== 'file' && stat.kind !== 'link';
82
+ if (stat.kind !== 'dir')
83
+ return true;
84
+ return root.device != null && (stat.device !== root.device || stat.inode !== root.inode);
85
+ }
86
+ return { rootIdentity, findMovedRoot, addressUndecided };
87
+ }
88
+ //# sourceMappingURL=continuity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuity.js","sourceRoot":"","sources":["../../src/detection/continuity.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;AA8CH,4CAmEC;AAnED,SAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAmB;IAC3E;;;;;;OAMG;IACH,SAAS,YAAY,CAAC,IAAoB;QACxC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YAC/B,OAAO,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACpE,CAAC;QACD,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,uEAAuE;IACvE,SAAS,iBAAiB,CAAC,IAAoB;QAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC;IAC1E,CAAC;IAED;;;;;OAKG;IACH,SAAS,aAAa,CAAC,IAAgB,EAAE,KAAgC;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC;QACpC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACpC,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;YACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;QAC/F,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,OAAO,IAAI,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,SAAS,gBAAgB,CAAC,IAAoB;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;QAC9E,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3F,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;AAC3D,CAAC"}