reploid 0.0.0-stage → 0.1.1

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 +542 -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 +85 -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,113 @@
1
+ /** One prepared model, reusable across requests until explicitly retired. */
2
+ import { createPreparationProgressObserver } from '../../../shared/vendor/reploid/mesh/preparation-progress.js';
3
+ import { openWorkProvider } from './work-provider.js';
4
+ import { retainModelStorage } from '../infrastructure/model-storage-lock.js';
5
+ import { withWorkDevice } from './work-device.js';
6
+
7
+ export function createWorkResidentProvider({ service, model, generation, maxOutcomeCharacters,
8
+ onChange = () => {}, onComplete = () => {}, scope = 'work-resident:' + crypto.randomUUID(), resolveAdapter, resolveSource, source, loadOptions }) {
9
+ model = structuredClone(model);
10
+ generation = structuredClone(generation);
11
+ const lifetime = new AbortController(), operations = new Set();
12
+ let adapter = null, identity = null, preparing = null, closing = null, cleanup = null, releaseStorage = null;
13
+ let closed = false, phase = 'idle', error = null, progress = null, completed = 0;
14
+ const production = { outputTokens: 0, missingTokenCounts: 0 };
15
+ let adapterIdentities = [];
16
+ const getState = () => ({ phase, error, progress: structuredClone(progress), completed, production: { ...production },
17
+ modelId: model.id, modelIdentity: identity?.modelIdentity || null,
18
+ adapterIdentities: [...adapterIdentities],
19
+ hardware: adapter?.getHardware() || null,
20
+ contextCache: adapter?.getContextCacheStats?.() || null,
21
+ ready: !closed && !!adapter && adapter.isReady() && ['ready', 'executing'].includes(phase) });
22
+ const notify = () => {
23
+ try { onChange(getState()); } catch (cause) { console.error('[Resident] state observer failed', cause); }
24
+ };
25
+ const dispose = () => {
26
+ adapter?.close();
27
+ adapter = null;
28
+ cleanup ||= Promise.resolve().then(() => service.close(scope)).then(async () => { await releaseStorage?.(); releaseStorage = null; }).catch(cause => { cleanup = null; throw cause; });
29
+ return cleanup;
30
+ };
31
+ const fail = async cause => {
32
+ error = cause?.message || String(cause); phase = 'failed';
33
+ try { await dispose(); }
34
+ catch (cleanupError) { error = new AggregateError([cause, cleanupError], 'Execution and cleanup failed').message; }
35
+ notify();
36
+ };
37
+ const prepare = () => {
38
+ if (closed) return Promise.reject(new Error('Contribution stopped'));
39
+ if (preparing) return preparing;
40
+ if (adapter) return Promise.resolve(getState());
41
+ if (error) return Promise.reject(new Error(error));
42
+ phase = 'loading';
43
+ const observeProgress = createPreparationProgressObserver();
44
+ let observingPreparation = true;
45
+ preparing = Promise.resolve().then(() => withWorkDevice(service, lifetime.signal, async () => {
46
+ const reportProgress = value => { if (observingPreparation) { progress = observeProgress(structuredClone(value)); notify(); } };
47
+ releaseStorage = await retainModelStorage({ signal: lifetime.signal });
48
+ const resolvedSource = resolveSource ? await resolveSource(model, { signal: lifetime.signal, onProgress: reportProgress }) : source;
49
+ const loaded = await openWorkProvider({ model, service, scope, signal: lifetime.signal,
50
+ generation, maxOutcomeCharacters, resolveAdapter, source: resolvedSource, loadOptions, onProgress: reportProgress });
51
+ lifetime.signal.throwIfAborted();
52
+ await loaded.reset();
53
+ if (model.adapters?.length) adapterIdentities = await loaded.prepareAdapters(model.adapters);
54
+ lifetime.signal.throwIfAborted();
55
+ identity = loaded.getIdentity(); adapter = loaded; phase = 'ready'; notify();
56
+ return getState();
57
+ })).catch(async cause => {
58
+ await fail(cause); throw cause;
59
+ }).finally(() => { observingPreparation = false; preparing = null; });
60
+ notify();
61
+ return preparing;
62
+ };
63
+ const generate = (messages, onUpdate, { signal, adapters = [], maxOutputTokens, contextOwner, contextId }) => {
64
+ if (!getState().ready) return Promise.reject(new Error('Contributor model is not ready'));
65
+ const input = structuredClone(messages);
66
+ const selectedAdapters = structuredClone(adapters);
67
+ const current = adapter, combined = AbortSignal.any([lifetime.signal, signal]);
68
+ const operation = withWorkDevice(service, combined, async () => {
69
+ combined.throwIfAborted();
70
+ if (adapter !== current || error) throw new Error('Resident session was retired before execution');
71
+ phase = 'executing'; notify();
72
+ try {
73
+ const result = await current.generate(input, onUpdate, { signal: combined, adapters: selectedAdapters,
74
+ maxOutputTokens, contextOwner, contextId });
75
+ combined.throwIfAborted(); completed++;
76
+ // Count runtime-reported tokens, never text deltas or estimated words.
77
+ const tokens = result.completion?.generatedTokenCount ?? result.timing?.generatedTokenCount;
78
+ if (Number.isSafeInteger(tokens) && tokens >= 0) production.outputTokens += tokens;
79
+ else production.missingTokenCounts++;
80
+ // Retain only completed, identity-checked execution metadata. Reporting
81
+ // failure must not turn a completed answer into an inference failure.
82
+ try { onComplete({ modelId: model.id, modelIdentity: identity.modelIdentity,
83
+ outputTokens: Number.isSafeInteger(tokens) && tokens >= 0 ? tokens : null }); }
84
+ catch (cause) { console.error('[Resident] completion observer failed', cause); }
85
+ return result;
86
+ } catch (cause) {
87
+ // Cancellation or pre-execution admission rejection may reuse a clean session; runtime or reset failures may not.
88
+ if ((!combined.aborted && cause?.recoverableSession !== true) || !current.isReady()) await fail(cause);
89
+ throw cause;
90
+ } finally {
91
+ if (!closed && adapter) phase = 'ready';
92
+ notify();
93
+ }
94
+ });
95
+ operations.add(operation);
96
+ operation.finally(() => operations.delete(operation)).catch(() => {});
97
+ return operation;
98
+ };
99
+ const close = () => {
100
+ if (closing) return closing;
101
+ closed = true; phase = 'stopping'; lifetime.abort(new Error('Contribution stopped'));
102
+ closing = (async () => {
103
+ await preparing?.catch(() => {});
104
+ await Promise.allSettled([...operations]);
105
+ try { await dispose(); phase = 'idle'; }
106
+ catch (cause) { phase = 'failed'; error = cause?.message || String(cause); throw cause; }
107
+ finally { notify(); }
108
+ })().catch(cause => { closing = null; throw cause; });
109
+ notify();
110
+ return closing;
111
+ };
112
+ return Object.freeze({ getState, prepare, generate, close });
113
+ }
@@ -0,0 +1,214 @@
1
+ # Native fleet service
2
+
3
+ `server/fleet/` adds enrolled computer identities, non-cash service credits and
4
+ placement to the existing native participant. It uses the existing WebRTC,
5
+ whole-model and ordered-partition execution paths. It does not change Doppler's
6
+ model arithmetic or qualification rules.
7
+
8
+ This is an operator-configured private fleet. A paired browser can use it from the
9
+ normal chat workspace; unpaired public-network chats do not use this coordinator.
10
+ Purchased credits and payouts are separate.
11
+
12
+ ## Computer identity
13
+
14
+ An owner-only `identityFile` retains an Ed25519 signing identity across launches.
15
+ The coordinator enrollment maps its public key to the computer ID, display name
16
+ and owner. Several provider keys may belong to one computer account. Generate
17
+ enrollment from the workspace fleet registry; do not maintain another static
18
+ machine inventory in this repository.
19
+
20
+ GPU adapter information, buffer limits and live memory observations describe
21
+ capacity. They are not unique hardware identifiers or remote attestation. A
22
+ copied signing key can impersonate its enrolled computer.
23
+
24
+ ## Credits
25
+
26
+ Before sending a prompt, the requester reserves its maximum charge and records
27
+ dispatch. Providers independently check that admission before executing. The
28
+ credit policy explicitly sets the integer rate, debt limit, output limit,
29
+ pending-request limit and whether computers belonging to one owner may trade.
30
+ Negative balances are permitted within the configured debt limit.
31
+
32
+ Completed whole-model work requires a provider-signed, requester-countersigned
33
+ receipt. Partitioned work requires the ordered stages' signed closing receipts
34
+ and the requester's signed output acknowledgment. Exact model, adapter, route,
35
+ request and participant identities must match. Duplicate settlement has one
36
+ economic effect. Every credit has an equal debit. A requester's own partition
37
+ share is unbilled; there is no reward for paying itself.
38
+
39
+ SQLite retains balances, reservations, the complete signed evidence, provider
40
+ admissions, and the journal. Requester and provider outboxes retry proofs after
41
+ process restart without generating another answer. Partition acknowledgments
42
+ are retained before they return to the coordinator; each contributor independently
43
+ submits its signed closing receipt. Invalid proof is retained as a rejected record
44
+ rather than retried forever.
45
+
46
+ Cancellation can settle an acknowledged prefix. All admitted stages must prove
47
+ cleanup, and a signed final-stage receipt must match that prefix's output chain.
48
+ Unacknowledged work is not billed. A signed `failed` receipt proves cleanup only
49
+ with its closing timestamp; it does not turn a failed answer into a completed one.
50
+ Equivalent verified re-signatures retain the original economic outcome.
51
+
52
+ For whole-model cancellation or failure, the provider retains and submits
53
+ `reploid.generation-terminal/v1` only after its execution owner confirms cleanup.
54
+ Usage remains unknown. Setting `creditPolicy.wholeModelTerminalCharge` to `0`
55
+ accepts zero non-cash terminal charge, frozen into each reservation; omission
56
+ keeps the hold pending. This does not change purchased-credit accounting.
57
+ `acceptFleetTerminalPolicy` in `server/fleet/terminal-policy.js` records an
58
+ operator-approved zero-charge policy migration and an explicit list of unresolved
59
+ whole-model reservations to which it applies. It cannot change metered rates,
60
+ completed balances, or release work without verified cleanup.
61
+
62
+ Admission closes atomically before recovery. A never-dispatched reservation can
63
+ expire. A dispatched request with no admitted providers can release after that
64
+ fence; one with admitted providers still needs their signed closing receipts.
65
+ Deadline expiry closes admission but never proves remote cleanup. Old reservations
66
+ without the admission journal cannot use the zero-admission release rule.
67
+ A request whose dispatch or completion is uncertain retains its hold. Cancellation
68
+ alone does not establish that work was never performed. There is no automatic
69
+ hold forgiveness or cash conversion. Enrollment or policy changes require an
70
+ explicit migration; editing a JSON file cannot reinterpret existing balances.
71
+
72
+ ## Placement
73
+
74
+ Each computer submits owner preferences and measured execution envelopes. The
75
+ planner checks the exact model, installed delivery digest, measurement age,
76
+ observation age, input/output limits, GPU/host budgets and single-buffer binding
77
+ limit before ranking a candidate. Costs use measured loading, prefill and decode
78
+ rates. They are scheduling estimates, not throughput guarantees or billing meters.
79
+
80
+ It prefers feasible whole-model capacity, retains warm residents, and adds replicas
81
+ when queue demand warrants them. Otherwise it requires a complete ordered
82
+ partition route across distinct computers and measured links. Search is bounded.
83
+ Missing measurements produce an unavailable result, never an invented estimate.
84
+ Owner opt-out stops idle contribution; active work drains before replacement.
85
+ An opted-out provider cannot admit new credited work.
86
+
87
+ The host reads an operator observation file, refreshes live memory and hardware
88
+ limits, binds it to `native-delivery.json`, and applies plans at idle boundaries.
89
+ `followPlacement` publishes bounded demand while a request waits for an exact
90
+ ready model. Its UTF-8-byte input estimate is labeled as such and is not a token
91
+ charge. Conservative estimates can reject capacity outside the measured envelope.
92
+
93
+ ## Running
94
+
95
+ Use Node 22.13 or newer and the packaged native delivery, with its locked Doppler,
96
+ WebRTC and GPU dependencies. The package must retain `native-delivery.json`.
97
+
98
+ ```sh
99
+ npm run package:native
100
+ node server/fleet/service.js /absolute/operator/service.json
101
+ node server/fleet/native-host.js /absolute/operator/host.json
102
+ ```
103
+
104
+ The service configuration uses schema `reploid.fleet-service/v1` and declares
105
+ `enrollmentFile`, `modelsFile`, `databaseFile`, `creditPolicy`, `placementPolicy`,
106
+ `listenHost`, `port`, and optional `tls: {keyFile, certFile}`. Non-loopback binding
107
+ requires TLS. Pin a private CA for the service processes rather than disabling
108
+ certificate checks. Requests are authenticated with enrolled signing keys.
109
+
110
+ Host configuration uses schema `reploid.fleet-native/v1`, explicit `computerId`,
111
+ `name`, `identityFile`, private `roomId`, `roomTokenFile`, `signalingUrl`,
112
+ `serviceUrl`, `maxOutputTokens` and `models`. Each model entry supplies the exact
113
+ catalog `model`, local artifact `directory`, `mode`, and, for ordered shards,
114
+ `ordered` stage configuration. Doppler's public partition API owns the layer plan.
115
+ The model manifest digest is checked before preparation.
116
+
117
+ `observationFile`, `auto: true` and `pollMs` enable reconciliation. `daemon: true`
118
+ keeps the host running after standard input closes. `initialModel` and
119
+ `initialContribution` explicitly choose startup behavior. A requester using
120
+ `followPlacement: true` must supply a bounded `capacityWaitMs`.
121
+
122
+ The JSON-lines control interface accepts `select`, `state`, `reconcile`,
123
+ `balances`, `generate` and `cancel`. Every command has an `id`; generation emits
124
+ `delta` events followed by the result. `state` includes computer identity,
125
+ execution state, adapter information and owned GPU-buffer accounting. The
126
+ identity file, private room token, database and operator configuration stay out
127
+ of source control.
128
+
129
+ ## Evidence
130
+
131
+ Focused tests cover admission, credit conservation, restart/replay, missing or
132
+ forged evidence, cancellation/completion races, partial settlement, remote retirement,
133
+ requester/provider restarts, token caps, admission fencing, local-stage exclusion, placement bounds,
134
+ clock skew and owner opt-out. The opt-in physical fixture is
135
+ `tests/fixtures/fleet-native-physical.js`; it consumes private operator paths and
136
+ an installed package receipt, verifies the remote delivery digest, runs real
137
+ WebRTC requests and retains settlement and cleanup results.
138
+
139
+ ```sh
140
+ REPLOID_FLEET_PHYSICAL=1 node tests/fixtures/fleet-native-physical.js /absolute/operator/physical.json
141
+ ```
142
+
143
+ Physical receipts establish only the recorded devices, prompts, package and
144
+ route. They do not establish general model quality, a speed advantage for
145
+ sharding, Flash-Next readiness, or public-site deployment.
146
+
147
+ ## Browser workspace
148
+
149
+ The existing Computers panel can pair with a native requester on the same computer.
150
+ Add `browserBridge` to its private `reploid.fleet-native/v1` configuration:
151
+
152
+ ```json
153
+ {
154
+ "browserBridge": {
155
+ "port": 18784,
156
+ "tokenFile": "/absolute/owner-only/browser-pairing-secret",
157
+ "origins": ["https://replo.id", "http://localhost:8000"]
158
+ },
159
+ "daemon": true
160
+ }
161
+ ```
162
+
163
+ Use at least 32 random bytes encoded as text for the pairing secret, with an
164
+ owner-only file. Run the existing `server/fleet/native-host.js` entry point with
165
+ that configuration. The bridge binds only 127.0.0.1. Every request checks the exact
166
+ browser origin and bearer secret. A browser may separately request permission to
167
+ access the local network. No signing key, private room token or model-file path
168
+ is returned to the browser.
169
+
170
+ In Computers, choose **Connect a native host**, enter its local address and secret,
171
+ and review the enrolled computer names. The pairing is stored only in that tab's
172
+ session storage. Choose a model under **Your private computers**. This authorizes
173
+ your native requester to serve the exact model through its reviewed private pool;
174
+ its existing per-provider disclosure, admission, spending limits and settlement
175
+ remain mandatory. It is delegation to the paired host, not browser-side hardware
176
+ attestation. A changed enrollment requires reconnection. Private selections never
177
+ fall back to public capacity or a local weight download.
178
+
179
+ The answer retains actual whole-model or ordered-stage execution and service-credit
180
+ records. Computers shows fresh observed capacity separately from execution receipts;
181
+ expired observations are offline, not ready. Service credits and receipt export are
182
+ on demand. Stop requests cancellation; a lost stream leaves a pending outcome until
183
+ the native owners reconcile. There is no automatic resend after interruption.
184
+ Browser history, drafts and reload use the existing conversation store; the bridge
185
+ does not retain prompt text. Signing keys and durable accounting remain native.
186
+
187
+ Local model downloads remain a separate reviewed action. Send does not acquire
188
+ weights, even if an older automatic-download preference was stored.
189
+
190
+ ## Authenticated HTTP text API
191
+
192
+ An enrolled native requester can also serve `/v1/models`, `/v1/chat/completions`
193
+ and `/v1/responses` over its private pool by adding `textApi` to its
194
+ `reploid.fleet-native/v1` configuration:
195
+
196
+ ```json
197
+ {
198
+ "textApi": {
199
+ "listenHost": "127.0.0.1",
200
+ "port": 18785,
201
+ "tokenFile": "/absolute/owner-only/fleet-api-secret",
202
+ "allowedRecipients": ["peer:5c0ecd2fd5fd8a105a4f8068"]
203
+ }
204
+ }
205
+ ```
206
+
207
+ Use at least 32 random bytes encoded as text for `tokenFile` with mode `0600`.
208
+ Non-loopback `listenHost` values require `tls: { "keyFile": "...", "certFile": "..." }`.
209
+ Every request checks the bearer secret in constant time, verifies that the
210
+ requester remains in `private-pool` scope, checks disclosed provider signing
211
+ identities against the coordinator's enrolled computers (and optional
212
+ `allowedRecipients`), and reserves and settles non-cash service credits before
213
+ publishing `reploid.http-execution/v1`. Signing keys and room tokens remain on
214
+ the native host.