reploid 0.0.0-stage → 0.1.0

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 (233) hide show
  1. package/apps/poolday/config/chat-files.json +27 -0
  2. package/apps/poolday/config/partition-generation.js +21 -0
  3. package/apps/poolday/config/partition-policy.json +74 -0
  4. package/apps/poolday/config/partition-releases.json +3 -0
  5. package/apps/poolday/config/work-profile.json +122 -0
  6. package/apps/poolday/host/chat-view.js +47 -0
  7. package/apps/poolday/host/earning/client.js +199 -0
  8. package/apps/poolday/host/earning/contribution.js +168 -0
  9. package/apps/poolday/host/partition-release.js +33 -0
  10. package/apps/poolday/host/work-partition-artifact-source.js +37 -0
  11. package/apps/poolday/host/work-partition-capsule.js +39 -0
  12. package/apps/poolday/host/work-partition-plan.js +167 -0
  13. package/apps/poolday/host/work-partition-tokenizer-guard.js +21 -0
  14. package/apps/poolday/infrastructure/model-storage-lock.js +22 -0
  15. package/apps/poolday/infrastructure/pack-release-storage.js +52 -0
  16. package/apps/poolday/pool/pack-operation.js +161 -0
  17. package/apps/poolday/pool/pack-release-policy.js +44 -0
  18. package/apps/poolday/pool/peer-pack-data-channel.js +217 -0
  19. package/apps/poolday/providers/work-adapter.js +67 -0
  20. package/apps/poolday/providers/work-device.js +33 -0
  21. package/apps/poolday/providers/work-generation-completion.js +55 -0
  22. package/apps/poolday/providers/work-provider.js +209 -0
  23. package/apps/poolday/providers/work-resident-provider.js +113 -0
  24. package/deploy/artifacts/doppler-gpu-0.7.1.tgz +0 -0
  25. package/docs/fleet-service.md +214 -0
  26. package/docs/native-participant.md +534 -0
  27. package/native-delivery.json +1174 -0
  28. package/package.json +29 -4
  29. package/packages/reploid/src/artifacts/binary.js +25 -0
  30. package/packages/reploid/src/artifacts/canonical-json.js +23 -0
  31. package/packages/reploid/src/artifacts/custody/exchange.js +402 -0
  32. package/packages/reploid/src/artifacts/custody/piece-acquisition.js +70 -0
  33. package/packages/reploid/src/artifacts/custody/runtime.js +404 -0
  34. package/packages/reploid/src/artifacts/custody/supply-budget.js +19 -0
  35. package/packages/reploid/src/artifacts/custody-certificate.js +123 -0
  36. package/packages/reploid/src/artifacts/delivery-attestation.js +64 -0
  37. package/packages/reploid/src/artifacts/generation-terminal.js +36 -0
  38. package/packages/reploid/src/artifacts/identity.js +91 -0
  39. package/packages/reploid/src/artifacts/participant-proofs.js +159 -0
  40. package/packages/reploid/src/artifacts/receipt.js +131 -0
  41. package/packages/reploid/src/artifacts/signatures.js +94 -0
  42. package/packages/reploid/src/artifacts/whole-model-receipt.js +42 -0
  43. package/packages/reploid/src/cancellation.js +44 -0
  44. package/packages/reploid/src/config/defaults.json +110 -0
  45. package/packages/reploid/src/config/index.js +209 -0
  46. package/packages/reploid/src/config/request-overrides.json +9 -0
  47. package/packages/reploid/src/config/transport-defaults.json +7 -0
  48. package/packages/reploid/src/hashing.js +30 -0
  49. package/packages/reploid/src/measurement/capacity-utilization.js +321 -0
  50. package/packages/reploid/src/measurement/index.js +5 -0
  51. package/packages/reploid/src/measurement/readiness-records.js +310 -0
  52. package/packages/reploid/src/mesh/computer-identity.js +50 -0
  53. package/packages/reploid/src/mesh/computer-identity.policy.json +8 -0
  54. package/packages/reploid/src/mesh/contribution.js +141 -0
  55. package/packages/reploid/src/mesh/generation-recovery.js +58 -0
  56. package/packages/reploid/src/mesh/gpu-signature-shader.js +27 -0
  57. package/packages/reploid/src/mesh/gpu-signature.js +136 -0
  58. package/packages/reploid/src/mesh/gpu-signature.policy.json +11 -0
  59. package/packages/reploid/src/mesh/index.js +66 -0
  60. package/packages/reploid/src/mesh/partitions/automatic-ordered-partitions.js +540 -0
  61. package/packages/reploid/src/mesh/partitions/automatic-partitions.js +298 -0
  62. package/packages/reploid/src/mesh/partitions/partition-attempt-evidence.js +282 -0
  63. package/packages/reploid/src/mesh/partitions/partition-attempt-queue-policy.json +6 -0
  64. package/packages/reploid/src/mesh/partitions/partition-attempt-queue.js +112 -0
  65. package/packages/reploid/src/mesh/partitions/partition-canonical-contract.js +167 -0
  66. package/packages/reploid/src/mesh/partitions/partition-canonical-execution.js +168 -0
  67. package/packages/reploid/src/mesh/partitions/partition-chat-canonical.js +49 -0
  68. package/packages/reploid/src/mesh/partitions/partition-chat.js +125 -0
  69. package/packages/reploid/src/mesh/partitions/partition-contract.js +192 -0
  70. package/packages/reploid/src/mesh/partitions/partition-device-admission.js +96 -0
  71. package/packages/reploid/src/mesh/partitions/partition-discovery.js +96 -0
  72. package/packages/reploid/src/mesh/partitions/partition-entry-publication.js +183 -0
  73. package/packages/reploid/src/mesh/partitions/partition-entry.js +434 -0
  74. package/packages/reploid/src/mesh/partitions/partition-generation-request.js +33 -0
  75. package/packages/reploid/src/mesh/partitions/partition-grants.js +277 -0
  76. package/packages/reploid/src/mesh/partitions/partition-link.js +103 -0
  77. package/packages/reploid/src/mesh/partitions/partition-network.js +109 -0
  78. package/packages/reploid/src/mesh/partitions/partition-ordered-chat.js +290 -0
  79. package/packages/reploid/src/mesh/partitions/partition-ordered-peer.js +415 -0
  80. package/packages/reploid/src/mesh/partitions/partition-ordered-publication.js +100 -0
  81. package/packages/reploid/src/mesh/partitions/partition-peer.js +314 -0
  82. package/packages/reploid/src/mesh/partitions/partition-placement.js +143 -0
  83. package/packages/reploid/src/mesh/partitions/partition-preparation-progress.js +25 -0
  84. package/packages/reploid/src/mesh/partitions/partition-receiver-policy.json +7 -0
  85. package/packages/reploid/src/mesh/partitions/partition-reservations.js +75 -0
  86. package/packages/reploid/src/mesh/partitions/partition-route-envelope-policy.json +16 -0
  87. package/packages/reploid/src/mesh/partitions/partition-route-envelope.js +74 -0
  88. package/packages/reploid/src/mesh/partitions/partition-route-execution.js +409 -0
  89. package/packages/reploid/src/mesh/partitions/partition-route-network.js +179 -0
  90. package/packages/reploid/src/mesh/partitions/partition-route-ranking.js +268 -0
  91. package/packages/reploid/src/mesh/partitions/partition-runner.js +319 -0
  92. package/packages/reploid/src/mesh/partitions/partition-stage-assignment.js +109 -0
  93. package/packages/reploid/src/mesh/partitions/partition-stage-commit.js +103 -0
  94. package/packages/reploid/src/mesh/partitions/partition-step-receiver.js +291 -0
  95. package/packages/reploid/src/mesh/partitions/partition-summary.js +122 -0
  96. package/packages/reploid/src/mesh/partitions/preparation-owner.js +40 -0
  97. package/packages/reploid/src/mesh/partitions/resident-error-codes.json +10 -0
  98. package/packages/reploid/src/mesh/partitions/resident-partition.js +333 -0
  99. package/packages/reploid/src/mesh/partitions/resident-route.js +46 -0
  100. package/packages/reploid/src/mesh/partitions/signed-resident-factory.js +59 -0
  101. package/packages/reploid/src/mesh/peer-generation.js +896 -0
  102. package/packages/reploid/src/mesh/peer-identity.js +87 -0
  103. package/packages/reploid/src/mesh/placement-beliefs.js +107 -0
  104. package/packages/reploid/src/mesh/preparation-progress.js +46 -0
  105. package/packages/reploid/src/mesh/provider-hardware.js +11 -0
  106. package/packages/reploid/src/mesh/remote-generation-requests.js +53 -0
  107. package/packages/reploid/src/mesh/swarm-coordination.js +140 -0
  108. package/packages/reploid/src/mesh/web-access-network.js +112 -0
  109. package/packages/reploid/src/mesh/web-access-policy.json +17 -0
  110. package/packages/reploid/src/retrieval/citations.js +156 -0
  111. package/packages/reploid/src/retrieval/claim-support.js +113 -0
  112. package/packages/reploid/src/retrieval/costs.js +101 -0
  113. package/packages/reploid/src/retrieval/fixed-provider.js +34 -0
  114. package/packages/reploid/src/retrieval/index.js +20 -0
  115. package/packages/reploid/src/retrieval/lexical-support.js +27 -0
  116. package/packages/reploid/src/retrieval/model-reviewer.js +67 -0
  117. package/packages/reploid/src/retrieval/page-fetch.json +10 -0
  118. package/packages/reploid/src/retrieval/page-text.js +182 -0
  119. package/packages/reploid/src/retrieval/passage.js +37 -0
  120. package/packages/reploid/src/retrieval/policy.json +14 -0
  121. package/packages/reploid/src/retrieval/retrieval.js +23 -0
  122. package/packages/reploid/src/retrieval/review-queue.js +76 -0
  123. package/packages/reploid/src/retrieval/sources.js +263 -0
  124. package/packages/reploid/src/retrieval/support-review.js +155 -0
  125. package/packages/reploid/src/retrieval/text.js +21 -0
  126. package/packages/reploid/src/rules/contribution.rules.json +8 -0
  127. package/packages/reploid/src/rules/routing.rules.json +24 -0
  128. package/packages/reploid/src/transport/assignment.js +571 -0
  129. package/packages/reploid/src/transport/bounded-channel-writer.js +46 -0
  130. package/packages/reploid/src/transport/index.js +11 -0
  131. package/packages/reploid/src/transport/introduction-admission.js +24 -0
  132. package/packages/reploid/src/transport/introduction-bootstrap.js +112 -0
  133. package/packages/reploid/src/transport/introduction-policy.json +12 -0
  134. package/packages/reploid/src/transport/introduction-records.js +90 -0
  135. package/packages/reploid/src/transport/introductions.js +209 -0
  136. package/packages/reploid/src/transport/partition-data-channel.js +421 -0
  137. package/packages/reploid/src/transport/partition-errors.json +16 -0
  138. package/packages/reploid/src/transport/retry-policy.js +36 -0
  139. package/packages/reploid/src/transport/room.js +502 -0
  140. package/packages/reploid/src/transport/sdp-fingerprint.js +5 -0
  141. package/packages/reploid/src/transport/signaling.js +571 -0
  142. package/packages/reploid/src/transport/swarm.js +1247 -0
  143. package/packages/reploid/src/transport/tool-offer-channel.js +137 -0
  144. package/server/browser-roots.js +42 -0
  145. package/server/browser-web-worker.js +94 -0
  146. package/server/chat-completions.js +45 -0
  147. package/server/fleet/browser-bridge.js +145 -0
  148. package/server/fleet/contract.js +42 -0
  149. package/server/fleet/credit-evidence.js +103 -0
  150. package/server/fleet/credit-recovery.js +175 -0
  151. package/server/fleet/credits.js +178 -0
  152. package/server/fleet/execution-admission.js +32 -0
  153. package/server/fleet/native-host.js +817 -0
  154. package/server/fleet/placement.js +132 -0
  155. package/server/fleet/requester.js +346 -0
  156. package/server/fleet/service.js +311 -0
  157. package/server/fleet/terminal-policy.js +83 -0
  158. package/server/fleet/text-api.js +94 -0
  159. package/server/hashing.js +35 -0
  160. package/server/http-request-owner.js +49 -0
  161. package/server/messages.js +57 -0
  162. package/server/native-canonical-epochs.js +90 -0
  163. package/server/native-change-log.js +40 -0
  164. package/server/native-earning.js +203 -0
  165. package/server/native-generation-journal.js +46 -0
  166. package/server/native-model-config.js +57 -0
  167. package/server/native-model-files.js +382 -0
  168. package/server/native-model-origin.js +54 -0
  169. package/server/native-model-origins.json +12 -0
  170. package/server/native-node.js +83 -0
  171. package/server/native-owner/controls.js +162 -0
  172. package/server/native-owner/monitor.js +251 -0
  173. package/server/native-owner/policy.js +273 -0
  174. package/server/native-owner/rate.js +92 -0
  175. package/server/native-participant.js +866 -0
  176. package/server/native-readiness-log.js +30 -0
  177. package/server/native-release-storage.js +64 -0
  178. package/server/native-shader-cache.js +369 -0
  179. package/server/native-supply-budget.js +66 -0
  180. package/server/native-whole-earning.js +67 -0
  181. package/server/native-whole-model-fill.js +182 -0
  182. package/server/native-whole-model.js +130 -0
  183. package/server/public-web-worker.js +66 -0
  184. package/server/responses.js +92 -0
  185. package/server/search/errors.js +47 -0
  186. package/server/search/page-fetch.js +185 -0
  187. package/server/text-api.js +83 -0
  188. package/server/text-recovery.js +45 -0
  189. package/server/text-request-options.js +23 -0
  190. package/server/text-requester.js +231 -0
  191. package/server/token-auth.js +9 -0
  192. package/server/whole-model-requester.js +99 -0
  193. package/shared/config/chat-models.json +4685 -0
  194. package/shared/config/doppler-execution-contracts.js +32 -0
  195. package/shared/config/doppler-execution-contracts.json +43 -0
  196. package/shared/config/doppler-generation-contract.js +223 -0
  197. package/shared/config/doppler-local-models.js +79 -0
  198. package/shared/config/doppler-package.json +7 -0
  199. package/shared/config/model-manifests/a0dc69e917133a82780823d17fc771c0f6b882d7c86c571deeaef45be2ff108b.json +6434 -0
  200. package/shared/config/model-manifests/e985e3cdad60d0cb57d84b436161e66ab5b3f6589a168de6f00b4610e5f1fb59.json +16534 -0
  201. package/shared/config/model-manifests/fa6eb7bbc3ba63571f8cede780b877d9272bde948697af93dd3d33837cb46137.json +7175 -0
  202. package/shared/config/model-pieces/qwen-0-8b-pieces.json +1506 -0
  203. package/shared/config/model-pieces/qwen-2b-pieces.json +4800 -0
  204. package/shared/config/model-pieces/qwen35b-q4_0-pieces.json +28880 -0
  205. package/shared/config/reploid-library.json +49 -0
  206. package/shared/config/swarm-bootstrap.json +21 -0
  207. package/shared/infrastructure/doppler-runtime-service.js +261 -0
  208. package/shared/pool/executable-pack.js +87 -0
  209. package/shared/pool/pack-operation-adapters.js +124 -0
  210. package/shared/pool/pack-operation-policy.js +75 -0
  211. package/shared/pool/pool-config.json +2280 -0
  212. package/shared/vendor/reploid/adapters/doppler-session.js +372 -0
  213. package/shared/vendor/reploid/artifacts/binary.js +25 -0
  214. package/shared/vendor/reploid/artifacts/canonical-json.js +23 -0
  215. package/shared/vendor/reploid/artifacts/delivery-attestation.js +64 -0
  216. package/shared/vendor/reploid/artifacts/identity.js +91 -0
  217. package/shared/vendor/reploid/artifacts/manifest-identity.js +17 -0
  218. package/shared/vendor/reploid/artifacts/participant-proofs.js +159 -0
  219. package/shared/vendor/reploid/artifacts/signatures.js +94 -0
  220. package/shared/vendor/reploid/config/defaults.json +110 -0
  221. package/shared/vendor/reploid/config/index.js +209 -0
  222. package/shared/vendor/reploid/config/request-overrides.json +9 -0
  223. package/shared/vendor/reploid/hashing.js +30 -0
  224. package/shared/vendor/reploid/mesh/generation-context-cache.js +97 -0
  225. package/shared/vendor/reploid/mesh/partitions/partition-attempt-evidence.js +282 -0
  226. package/shared/vendor/reploid/mesh/partitions/partition-contract.js +192 -0
  227. package/shared/vendor/reploid/mesh/partitions/partition-receiver-policy.json +7 -0
  228. package/shared/vendor/reploid/mesh/partitions/partition-route-ranking.js +268 -0
  229. package/shared/vendor/reploid/mesh/preparation-progress.js +46 -0
  230. package/shared/vendor/reploid/mesh/provider-hardware.js +11 -0
  231. package/shared/vendor/reploid/rules/routing.rules.json +24 -0
  232. package/shared/vendor/reploid/transport/partition-errors.json +16 -0
  233. package/README.md +0 -3
@@ -0,0 +1,333 @@
1
+ import { createResidentRouteBinding } from './resident-route.js';
2
+ import residentErrorCodes from './resident-error-codes.json' with { type: 'json' };
3
+ import failureMessages from '../../transport/partition-errors.json' with { type: 'json' };
4
+ import { createPartitionReservations } from './partition-reservations.js';
5
+ import { assertPartition as assert, assertCapacity, canonicalPartitionJson } from './partition-contract.js';
6
+ import { verifyPartitionStageCommit } from './partition-stage-commit.js';
7
+ import { openStageReceipts } from './partition-attempt-evidence.js';
8
+
9
+ /** Owns an explicitly contributed runtime session; never implements model computation. An optional
10
+ * shared `device` admission (Launch 3, ordered only) charges this resident's weights once and every
11
+ * admitted attempt's `attemptBytes` and slot against one budget for the whole device. An optional
12
+ * `evidence` signer (createAttemptEvidenceSigner over the host's participant identity, ordered only)
13
+ * signs cumulative receipts for attempts that arrive with the requester's charge binding. */
14
+ export function createResidentPartition({ runtime, model, plan, planId, index, participantId, limits,
15
+ canonicalGeneration, canonicalRuntime, canonicalCommitAuthority, ordered = null, device = null, attemptBytes, evidence = null, onEvidence = null, onChange = () => {} }) {
16
+ assert(evidence === null || ordered && typeof evidence.sign === 'function' && evidence.participantId === participantId,
17
+ 'Stage receipts need an ordered resident and this participant\'s signing identity');
18
+ assert(typeof runtime?.openResidentPartition === 'function', 'Doppler resident partition API is unavailable');
19
+ assert((ordered ? Number.isSafeInteger(index) && index >= 0 && index < plan?.stageCount : [0, 1].includes(index)) && plan?.partitions?.[index] && model?.id === plan.modelId
20
+ && /^sha256:[a-f0-9]{64}$/.test(model.identity) && typeof planId === 'string' && planId
21
+ && typeof participantId === 'string' && participantId, 'Explicit resident partition allocation required');
22
+ assert(canonicalGeneration === undefined || typeof canonicalRuntime?.canonicalGenerationIdentity === 'function',
23
+ 'Explicit canonical Doppler capability required');
24
+ const canonical = canonicalGeneration === undefined ? null : canonicalRuntime.canonicalGenerationIdentity(
25
+ canonicalGeneration.policy, canonicalGeneration.executionIdentity, plan.vocabSize);
26
+ const allocation = structuredClone({ model, plan, planId, index, participantId, limits,
27
+ ...(canonicalGeneration === undefined ? {} : { canonicalGeneration }) });
28
+ assert(!ordered || canonicalGeneration === undefined && canonicalCommitAuthority === undefined, 'Ordered canonical execution is not supported');
29
+ const routeBinding = ordered ? createResidentRouteBinding({ ordered, allocation }) : null;
30
+ assert(device === null || ordered && ['admitResident', 'admit', 'release', 'releaseResident', 'available', 'getState']
31
+ .every(method => typeof device[method] === 'function') && Number.isSafeInteger(attemptBytes) && attemptBytes > 0,
32
+ 'Shared device admission requires an ordered resident and an explicit attempt allocation');
33
+ const deviceOwner = Object.freeze({ participantId, index });
34
+ const canonicalStage = canonicalCommitAuthority?.getStage();
35
+ if (canonicalCommitAuthority !== undefined) {
36
+ assert(canonical && typeof canonicalCommitAuthority?.sign === 'function'
37
+ && ['metadataDigest', 'validateResidentAttemptIdentity', 'residentAttemptDigest', 'residentPublicationDecisionDigest']
38
+ .every(method => typeof canonicalRuntime?.[method] === 'function')
39
+ && canonicalStage?.participantId === participantId && canonicalStage.partitionIndex === index
40
+ && canonicalStage.executionId === canonical.executionIdentity, 'Canonical signing stage differs from allocation');
41
+ }
42
+ const lifetime = new AbortController(), operations = new Set(), listeners = new Set([onChange]);
43
+ const attempts = new Set();
44
+ const reservations = createPartitionReservations({ limits, participantId, index });
45
+ // Charged attempts' receipt tallies, bounded like reservation history.
46
+ const tallies = new Map();
47
+ const bound = identity => routeBinding ? routeBinding.identity(identity) : identity;
48
+ const openTally = async request => {
49
+ if (!evidence || request.charge === undefined || request.charge === null) return;
50
+ const binding = routeBinding.identity(request.identity);
51
+ if (tallies.has(binding.attemptId)) return;
52
+ const opening = openStageReceipts({ signer: evidence, identity: binding, partitionIndex: index, charge: request.charge });
53
+ tallies.set(binding.attemptId, opening);
54
+ try { await opening; } catch (cause) { tallies.delete(binding.attemptId); throw cause; }
55
+ };
56
+ // Before computing a charged step: the requester's verified acknowledgments must be within K outputs of it.
57
+ const authorizeStep = async input => {
58
+ const tally = await tallies.get(input.identity?.attemptId);
59
+ if (tally) await tally.authorizeStep({ step: input.step, acknowledged: input.acknowledged ?? null });
60
+ };
61
+ const recordStep = async (result, input) => {
62
+ const tally = await tallies.get(result?.identity?.attemptId ?? input.identity?.attemptId);
63
+ if (!tally) return result;
64
+ // A receipt that cannot be signed leaves the step unreceipted; it never fails the computation.
65
+ const receipt = await tally.step({ step: input.step, inputTokenCount: input.inputTokenCount,
66
+ delta: result.delta, done: result.done, stopReason: result.stopReason }).catch(() => null);
67
+ reservations.attachEvidence(bound(input.identity), tally.evidence());
68
+ return receipt ? { ...result, receipt } : result;
69
+ };
70
+ const closeTally = async (identity, acknowledged) => {
71
+ const tally = await tallies.get(identity?.attemptId)?.catch(() => null);
72
+ if (!tally) return;
73
+ if (acknowledged) await tally.acknowledge(acknowledged);
74
+ const receipt = await tally.close({ failed: reservations.failureOf(identity) != null });
75
+ const bundle = tally.evidence();
76
+ reservations.attachEvidence(identity, bundle);
77
+ if (onEvidence) await Promise.resolve().then(() => onEvidence(structuredClone(bundle))).catch(() => {});
78
+ return receipt;
79
+ };
80
+ let draining = null, finishDrain = null;
81
+ let phase = 'idle', error = null, session = null, preparing = null, closing = null, disposal = null, descriptor = null;
82
+ let tail = Promise.resolve(), generationDigest = null, recovery = null;
83
+ // With a shared device, advertised slots are what both this resident and the device can admit.
84
+ const reservationState = () => {
85
+ const local = reservations.getState();
86
+ return device ? { ...local, availableSlots: Math.min(local.availableSlots, device.available(attemptBytes)), device: device.getState() } : local;
87
+ };
88
+ const state = () => ({ phase, ready: phase === 'ready' && !lifetime.signal.aborted,
89
+ activeAttempts: attempts.size, reservations: reservationState(),
90
+ error, descriptor: structuredClone(descriptor), recovery: structuredClone(recovery), index, participantId,
91
+ modelId: allocation.model.id, modelIdentity: allocation.model.identity, planId });
92
+ const notify = () => { for (const listener of listeners) { try { listener(state()); } catch {} } };
93
+ const dispose = () => disposal ||= Promise.resolve().then(() => session?.close()).then(async () => {
94
+ reservations.close(); reservations.settleAll(); attempts.clear(); device?.releaseResident(deviceOwner); finishDrain?.();
95
+ // Device/session cleanup also closes proofs for attempts whose coordinator disappeared.
96
+ for (const opening of tallies.values()) {
97
+ const tally = await opening.catch(() => null), bundle = tally?.evidence();
98
+ if (bundle && !bundle.receipts[0]?.timing.closedAt) await closeTally(bundle.identity).catch(() => {});
99
+ }
100
+ }).catch(cause => {
101
+ // A rejection is not settlement. Retain the session and charged attempts,
102
+ // but allow the owner to explicitly retry a transient cleanup failure.
103
+ disposal = null; throw cause;
104
+ });
105
+ const check = () => {
106
+ const actual = session?.getDescriptor();
107
+ assert(actual?.schema === (ordered ? 'doppler.resident-partition/v2' : 'doppler.resident-partition/v1')
108
+ && (!ordered || actual.stageCount === allocation.plan.stageCount) && actual.ready === true
109
+ && actual.modelId === allocation.model.id && actual.modelIdentity === allocation.model.identity
110
+ && actual.generationDigest === generationDigest
111
+ && (actual.canonicalGenerationId ?? null) === (canonical?.generationId ?? null)
112
+ && actual.planId === allocation.planId && actual.index === allocation.index
113
+ && canonicalPartitionJson(actual.layerRange) === canonicalPartitionJson(allocation.plan.partitions[index].layerRange)
114
+ && Number.isSafeInteger(actual.residentWeightBytes) && actual.residentWeightBytes > 0,
115
+ 'Doppler resident partition identity or readiness mismatch');
116
+ return structuredClone(actual);
117
+ };
118
+ const reserve = identity => {
119
+ // A resident that is not offering admission refuses as unavailable capacity, never as a generic failure.
120
+ assertCapacity((phase === 'ready' || phase === 'draining' && attempts.has(identity?.attemptId)) && !lifetime.signal.aborted);
121
+ if (routeBinding) identity = routeBinding.identity(identity);
122
+ const record = reservations.reserve(identity);
123
+ attempts.add(identity.attemptId); notify(); return record;
124
+ };
125
+ const invoke = (method, request, finish = result => result, before = null) => {
126
+ reserve(request.identity);
127
+ const { signal, ...input } = request;
128
+ const snapshot = structuredClone(input);
129
+ const combined = signal ? AbortSignal.any([signal, lifetime.signal]) : lifetime.signal;
130
+ const operation = tail.then(async () => {
131
+ combined.throwIfAborted(); check();
132
+ if (before) { await before(snapshot); combined.throwIfAborted(); }
133
+ const result = await session[method]({ ...snapshot, signal: combined });
134
+ combined.throwIfAborted(); check();
135
+ const finished = await finish(result, snapshot);
136
+ combined.throwIfAborted(); check();
137
+ return structuredClone(finished);
138
+ }).catch(async cause => {
139
+ reservations.fail(snapshot.identity, cause);
140
+ if (!combined.aborted) {
141
+ try {
142
+ check();
143
+ reservations.settling(snapshot.identity);
144
+ await session.closeAttempt({ identity: snapshot.identity });
145
+ reservations.settled(snapshot.identity);
146
+ attempts.delete(snapshot.identity.attemptId); device?.release(deviceOwner, snapshot.identity.attemptId);
147
+ if (!attempts.size) finishDrain?.();
148
+ await closeTally(bound(snapshot.identity)).catch(() => {});
149
+ } catch {
150
+ phase = 'failed'; error = String(cause.message || cause);
151
+ lifetime.abort(cause); notify(); await dispose();
152
+ }
153
+ }
154
+ // The pinned 0.6.27 resident emits this exact untyped allocation error.
155
+ // This local compatibility allowlist never forwards exception text.
156
+ const code = Object.hasOwn(residentErrorCodes.codes, cause?.code) ? residentErrorCodes.codes[cause.code]
157
+ : !cause?.code && Object.hasOwn(residentErrorCodes.legacyMessages, cause?.message)
158
+ ? residentErrorCodes.legacyMessages[cause.message] : null;
159
+ if (code) {
160
+ throw Object.assign(new Error(failureMessages[code], { cause }), { code });
161
+ }
162
+ throw cause;
163
+ });
164
+ tail = operation.catch(() => {}); operations.add(operation);
165
+ operation.finally(() => operations.delete(operation)).catch(() => {});
166
+ return operation;
167
+ };
168
+ const canonicalInvoke = (method, request) => {
169
+ assert(canonical, 'Canonical resident execution was not allocated');
170
+ return invoke(method, request);
171
+ };
172
+ const committed = (method, request) => {
173
+ assert(canonical, 'Canonical resident execution was not allocated');
174
+ if (!canonicalCommitAuthority) return canonicalInvoke(method, request);
175
+ const { signal, ...data } = request;
176
+ const input = { ...structuredClone(data), signal };
177
+ const attempt = canonicalRuntime.validateResidentAttemptIdentity(input.canonicalAttempt);
178
+ assert(attempt.attemptId === input.identity.attemptId && attempt.generationId === canonical.generationId
179
+ && attempt.routeKind === 'two-stage-layer' && attempt.stages[0].participantId === input.identity.participantA
180
+ && attempt.stages[1].participantId === input.identity.participantB
181
+ && canonicalPartitionJson(attempt.stages[index]) === canonicalPartitionJson(canonicalStage),
182
+ 'Canonical attempt differs from contributor binding');
183
+ assert(Number.isSafeInteger(input.sequence) && input.sequence >= 0
184
+ && (index === 1 ? input.sequence === input.step : input.sequence === input.transition.successor.revision),
185
+ 'Canonical sequence differs from actual ordinary step');
186
+ return invoke(method, input, async result => {
187
+ const transition = index === 1 ? result.transition : result;
188
+ const commit = await canonicalCommitAuthority.sign({ attempt, sequence: input.sequence,
189
+ baseCursorId: input.baseCursorId, transition });
190
+ return index === 1 ? { ...result, commit } : { transition: result, commit };
191
+ });
192
+ };
193
+ return Object.freeze({
194
+ id: participantId, index, getState: state,
195
+ ...(routeBinding ? { transportId: routeBinding.stage.transportId, residentId: routeBinding.stage.residentId,
196
+ executionId: routeBinding.stage.executionId } : {}),
197
+ reserve: routeBinding ? async request => {
198
+ request.signal?.throwIfAborted();
199
+ assert(request.partitionIndex === index, 'Ordered reservation stage mismatch');
200
+ await openTally(request);
201
+ request.signal?.throwIfAborted();
202
+ if (device && !attempts.has(request.identity?.attemptId)) {
203
+ assertCapacity(phase === 'ready' && !lifetime.signal.aborted);
204
+ const binding = routeBinding.identity(request.identity);
205
+ // A bounded wait in the device queue ends when this resident closes or the caller cancels.
206
+ await device.admit({ owner: deviceOwner, attemptId: binding.attemptId, bytes: attemptBytes,
207
+ requesterId: binding.requesterId, routeKey: binding.route.stages[0].participantId,
208
+ signal: request.signal ? AbortSignal.any([request.signal, lifetime.signal]) : lifetime.signal });
209
+ try { return { ...reserve(request.identity), partitionIndex: index, status: 'reserved' }; }
210
+ catch (cause) { if (!attempts.has(binding.attemptId)) device.release(deviceOwner, binding.attemptId); throw cause; }
211
+ }
212
+ const record = reserve(request.identity);
213
+ return { ...record, partitionIndex: index, status: 'reserved' };
214
+ } : reserve,
215
+ getCanonicalGeneration: () => structuredClone(canonical),
216
+ getCanonicalStage: () => structuredClone(canonicalStage ?? null),
217
+ canAccept(identity) { return !lifetime.signal.aborted && ((phase === 'ready' || phase === 'draining')
218
+ && attempts.has(identity?.attemptId) || phase === 'ready' && reservationState().availableSlots > 0); },
219
+ subscribe(listener) { listeners.add(listener); listener(state()); return () => listeners.delete(listener); },
220
+ prepare({ approved, signal } = {}) {
221
+ assert(approved === true, 'Explicit partition contribution approval required');
222
+ assert(!lifetime.signal.aborted, 'Partition contribution closed');
223
+ if (preparing) return preparing;
224
+ if (phase === 'ready') return Promise.resolve(state());
225
+ assert(phase === 'idle', 'Retired partition contribution requires a new owner');
226
+ phase = 'loading'; notify();
227
+ const combined = signal ? AbortSignal.any([signal, lifetime.signal]) : lifetime.signal;
228
+ preparing = (async () => {
229
+ try {
230
+ combined.throwIfAborted();
231
+ if (routeBinding) {
232
+ await routeBinding.prepare();
233
+ generationDigest = await routeBinding.generationDigest(allocation.model.generation);
234
+ } else {
235
+ const bytes = new TextEncoder().encode(canonicalPartitionJson(allocation.model.generation));
236
+ generationDigest = 'sha256:' + [...new Uint8Array(await crypto.subtle.digest('SHA-256', bytes))]
237
+ .map(byte => byte.toString(16).padStart(2, '0')).join('');
238
+ }
239
+ combined.throwIfAborted();
240
+ session = await runtime.openResidentPartition({ ...structuredClone(allocation), signal: combined });
241
+ assert(['getDescriptor', 'getRecoveryCapabilities', 'tokenize', ...(ordered ? ['executeStage'] : ['executeGroup0', 'executeGroup1']),
242
+ 'closeAttempt', 'close'].every(method => typeof session?.[method] === 'function'),
243
+ 'Incomplete Doppler resident partition API');
244
+ if (routeBinding) session = routeBinding.wrap(session);
245
+ if (canonical) {
246
+ assert(['getCanonicalGeneration', 'admitCanonicalPrompt', 'executeCanonicalGroup0',
247
+ 'executeCanonicalGroup1', 'commitCanonicalTransition'].every(method => typeof session?.[method] === 'function'),
248
+ 'Incomplete canonical Doppler resident capability');
249
+ assert(canonicalPartitionJson(session.getCanonicalGeneration()) === canonicalPartitionJson(canonical),
250
+ 'Canonical Doppler generation differs from admitted allocation');
251
+ }
252
+ const capabilities = session.getRecoveryCapabilities();
253
+ assert(capabilities?.schema === 'doppler.resident-recovery/v1'
254
+ && ['inputReplay', 'checkpointExport', 'checkpointImport'].every(key => capabilities[key] === false),
255
+ 'Unsupported Doppler resident recovery contract');
256
+ recovery = structuredClone(capabilities);
257
+ combined.throwIfAborted(); descriptor = check();
258
+ // Weights are charged once to the shared device before this stage can be offered.
259
+ device?.admitResident(deviceOwner, descriptor.residentWeightBytes);
260
+ phase = 'ready'; notify(); return state();
261
+ } catch (cause) {
262
+ phase = 'failed'; error = String(cause.message || cause);
263
+ await dispose(); notify(); throw cause;
264
+ }
265
+ })();
266
+ return preparing;
267
+ },
268
+ tokenize(request) { assert(index === 0, 'Only partition A tokenizes'); return invoke('tokenize', request); },
269
+ executeStage(request) {
270
+ assert(routeBinding, 'Ordered resident execution was not allocated');
271
+ return invoke('executeStage', request, evidence ? recordStep : undefined, evidence ? authorizeStep : null);
272
+ },
273
+ executeGroup0(request) { assert(!ordered, 'Ordered resident requires executeStage'); assert(!canonical, 'Canonical resident requires canonical execution'); assert(index === 0, 'This contributor is partition B'); return invoke('executeGroup0', request); },
274
+ executeGroup1(request) { assert(!ordered, 'Ordered resident requires executeStage'); assert(!canonical, 'Canonical resident requires canonical execution'); assert(index === 1, 'This contributor is partition A'); return invoke('executeGroup1', request); },
275
+ admitCanonicalPrompt(request) { return canonicalInvoke('admitCanonicalPrompt', request); },
276
+ executeCanonicalGroup0(request) { assert(index === 0, 'This contributor is partition B'); return canonicalInvoke('executeCanonicalGroup0', request); },
277
+ executeCanonicalGroup1(request) { assert(index === 1, 'This contributor is partition A'); return committed('executeCanonicalGroup1', request); },
278
+ async commitCanonicalTransition(request) {
279
+ assert(index === 0, 'Only partition A commits the remote transition');
280
+ const { signal, ...data } = request;
281
+ request = { ...structuredClone(data), signal };
282
+ if (canonicalCommitAuthority) {
283
+ const attempt = canonicalRuntime.validateResidentAttemptIdentity(request.canonicalAttempt);
284
+ assert(await verifyPartitionStageCommit({ runtime: canonicalRuntime, attempt, stage: attempt.stages[1],
285
+ acknowledgment: request.targetCommit?.acknowledgment, evidence: request.targetCommit?.evidence,
286
+ transition: request.transition, sequence: request.sequence, baseCursorId: request.baseCursorId }),
287
+ 'Target commitment is not authenticated');
288
+ }
289
+ return committed('commitCanonicalTransition', request);
290
+ },
291
+ async closeAttempt({ identity, acknowledged = null }) {
292
+ if (routeBinding) identity = routeBinding.identity(identity);
293
+ // Never free admission capacity before the runtime confirms cleanup.
294
+ reservations.settling(identity);
295
+ try {
296
+ if (session) await session.closeAttempt({ identity: structuredClone(identity) });
297
+ reservations.settled(identity); attempts.delete(identity.attemptId); device?.release(deviceOwner, identity.attemptId);
298
+ if (!attempts.size) finishDrain?.();
299
+ } catch (cause) {
300
+ reservations.fail(identity, cause);
301
+ throw Object.assign(new Error(failureMessages.CLEANUP_FAILED, { cause }), { code: 'CLEANUP_FAILED' });
302
+ }
303
+ // The closing receipt is signed only after the runtime confirmed cleanup; signing never unsettles it.
304
+ try {
305
+ const receipt = await closeTally(identity, acknowledged);
306
+ return receipt ? { receipt } : undefined;
307
+ } catch {} finally { notify(); }
308
+ },
309
+ drain() {
310
+ if (draining) return draining;
311
+ assert(phase === 'ready', 'Only a ready contributor can drain');
312
+ phase = 'draining'; notify();
313
+ draining = (async () => {
314
+ if (attempts.size) await new Promise(resolve => { finishDrain = resolve; });
315
+ await Promise.allSettled([...operations]);
316
+ await dispose(); phase = 'closed'; notify();
317
+ })();
318
+ return draining;
319
+ },
320
+ close() {
321
+ if (closing) return closing;
322
+ reservations.close();
323
+ lifetime.abort(new Error('Partition contribution stopped')); phase = 'stopping'; notify();
324
+ closing = (async () => {
325
+ await preparing?.catch(() => {});
326
+ await Promise.allSettled([...operations]);
327
+ try { await dispose(); phase = 'closed'; error = null; } catch (cause) { phase = 'failed'; error = String(cause.message || cause); throw cause; }
328
+ finally { finishDrain?.(); notify(); }
329
+ })().catch(cause => { closing = null; throw cause; });
330
+ return closing;
331
+ }
332
+ });
333
+ }
@@ -0,0 +1,46 @@
1
+ import { assertPartition as assert, canonicalRouteAttemptBinding, canonicalPartitionJson } from './partition-contract.js';
2
+
3
+ /** One host-owned route identity mapped consistently across the provider session lifecycle. */
4
+ export function createResidentRouteBinding({ ordered, allocation }) {
5
+ const stage = structuredClone(ordered.stage), runtime = ordered.runtime;
6
+ assert(allocation.plan?.schema === 'doppler.layer-partition-contract/v3'
7
+ && stage?.index === allocation.index && stage.participantId === allocation.participantId
8
+ && ['transportId', 'residentId', 'executionId'].every(key => typeof stage[key] === 'string' && stage[key].length > 0)
9
+ && ['hashLayerPartitionPlan', 'hashPartitionGeneration', 'getPartitionActivationContract'].every(key => typeof runtime?.[key] === 'function'),
10
+ 'Explicit ordered resident provider and stage binding required');
11
+ const activation = structuredClone(runtime.getPartitionActivationContract(allocation.plan));
12
+ const identity = input => {
13
+ const binding = canonicalRouteAttemptBinding(input), route = binding.route;
14
+ assert(route.modelId === allocation.model.id && route.modelIdentity === allocation.model.identity
15
+ && route.planId === allocation.planId && route.stages.length === allocation.plan.stageCount
16
+ && canonicalPartitionJson(route.stages[allocation.index]) === canonicalPartitionJson(stage)
17
+ && canonicalPartitionJson(route.activation) === canonicalPartitionJson(activation), 'Ordered resident route differs from allocation');
18
+ return binding;
19
+ };
20
+ const providerIdentity = input => {
21
+ const binding = identity(input);
22
+ return { schema: 'doppler.resident-partition-attempt/v2', modelId: binding.route.modelId,
23
+ modelIdentity: binding.route.modelIdentity, planId: binding.route.planId, threadId: binding.threadId,
24
+ attemptId: binding.attemptId, requesterId: binding.requesterId, placementGeneration: binding.placementGeneration,
25
+ stages: structuredClone(binding.route.stages) };
26
+ };
27
+ return Object.freeze({ stage: Object.freeze(stage), identity,
28
+ async prepare() { assert(await runtime.hashLayerPartitionPlan(allocation.plan) === allocation.planId, 'Ordered resident plan identity mismatch'); },
29
+ generationDigest: generation => runtime.hashPartitionGeneration(generation),
30
+ wrap(session) {
31
+ const request = input => ({ ...input, identity: providerIdentity(input.identity) });
32
+ return Object.freeze({ ...session,
33
+ tokenize: input => session.tokenize(request(input)),
34
+ closeAttempt: input => session.closeAttempt(request(input)),
35
+ async executeStage(input) {
36
+ assert(input.partitionIndex === allocation.index, 'Ordered resident stage mismatch');
37
+ const binding = identity(input.identity), mapped = request(input);
38
+ const output = await session.executeStage(mapped);
39
+ assert(output?.partitionIndex === allocation.index && output.step === input.step && output.tokenPosition === input.tokenPosition
40
+ && canonicalPartitionJson(output.identity) === canonicalPartitionJson(mapped.identity), 'Ordered runtime result identity mismatch');
41
+ return { ...output, identity: binding };
42
+ }
43
+ });
44
+ }
45
+ });
46
+ }
@@ -0,0 +1,59 @@
1
+ /** Shared signed resident lifecycle. Hosts supply admission, release policy and Doppler. */
2
+ export function createSignedResidentFactory({ createFactory, openCapsule, model, artifactStore,
3
+ release, assertSession, closeSources, trackSession, canonical = false, onVerification = () => {}, onLoadProgress = null }) {
4
+ if (typeof canonical !== 'boolean') throw new Error('Explicit canonical signed factory mode required');
5
+ if (typeof trackSession !== 'function') throw new Error('Signed resident requires an explicit session cleanup owner');
6
+ if (onLoadProgress !== null && typeof onLoadProgress !== 'function') throw new Error('Signed resident load progress must be a function');
7
+ // Doppler reports byte acquisition and, before readiness, GPU pipeline preparation here.
8
+ return createFactory({ capsuleOptions: { ...release.options, artifactStore, ...(onLoadProgress ? { onLoadProgress } : {}) },
9
+ async openCapsule(capsule, options) {
10
+ const session = await openCapsule(capsule, options);
11
+ const settled = trackSession(session);
12
+ try {
13
+ await assertSession(model, session);
14
+ await release.assertCurrent(session);
15
+ onVerification(session.verification);
16
+ const partition = session.residentPartition;
17
+ if (!partition) throw new Error('Capsule opener did not return a qualified resident');
18
+ const canonicalMethods = ['admitCanonicalPrompt', 'executeCanonicalGroup0', 'executeCanonicalGroup1', 'commitCanonicalTransition'];
19
+ if (canonical && (typeof partition.getCanonicalGeneration !== 'function'
20
+ || canonicalMethods.some(name => typeof partition[name] !== 'function'))) {
21
+ throw new Error('Signed resident lacks declared canonical execution methods');
22
+ }
23
+ let closing = null, sessionSettled = false;
24
+ const invoke = async (method, request) => {
25
+ await release.assertCurrent(session);
26
+ const failures = []; let result;
27
+ try { result = await partition[method](request); } catch (error) { failures.push(error); }
28
+ try { await release.assertCurrent(session); } catch (error) { failures.push(error); }
29
+ if (failures.length === 1) throw failures[0];
30
+ if (failures.length) throw new AggregateError(failures, 'Resident computation and authorization failed');
31
+ return result;
32
+ };
33
+ return { ...session, residentPartition: Object.freeze({ ...partition,
34
+ ...(canonical ? Object.fromEntries(canonicalMethods.map(name => [name, request => invoke(name, request)])) : {}),
35
+ ...(typeof partition.executeStage === 'function' ? { executeStage: request => invoke('executeStage', request) } : {}),
36
+ tokenize: request => invoke('tokenize', request),
37
+ executeGroup0: request => invoke('executeGroup0', request),
38
+ executeGroup1: request => invoke('executeGroup1', request),
39
+ close() {
40
+ if (!closing) closing = (async () => {
41
+ const failures = [];
42
+ if (!sessionSettled) {
43
+ try { await session.close(); sessionSettled = true; settled(); } catch (error) { failures.push(error); }
44
+ }
45
+ await closeSources(failures);
46
+ if (failures.length) throw new AggregateError(failures, 'Signed resident cleanup failed');
47
+ })().catch(error => { closing = null; throw error; });
48
+ return closing;
49
+ }
50
+ }) };
51
+ } catch (error) {
52
+ try { await session.close(); settled(); } catch (cleanup) {
53
+ throw new AggregateError([error, cleanup], 'Signed resident admission and cleanup failed');
54
+ }
55
+ throw error;
56
+ }
57
+ }
58
+ });
59
+ }