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,534 @@
1
+ # Run a native Reploid participant
2
+
3
+ This is the same application host and participant protocol as the browser.
4
+ The generated delivery copies canonical source and catalog bytes; it does not
5
+ maintain another runtime. Linux/Vulkan native computation has physical evidence
6
+ under [native files](https://github.com/clocksmith/reploid/tree/main/artifacts/native-files-20261012). Signed opening and
7
+ whole-model numerical and document-quality acceptance remain separate gates.
8
+
9
+ Use Node 22.13 or newer. From the checkout, run `npm ci`, then
10
+ `npm run start:native -- --help`. WebRTC and WebGPU dependencies are declared
11
+ optional at the application root so browser development can omit them.
12
+
13
+ ## One command
14
+
15
+ The delivered package has a short command that stands for the full one:
16
+
17
+ ```sh
18
+ reploid qwen-3-5-2b-q4k-ehaf16
19
+ ```
20
+
21
+ It runs `reploid-participant --contribute --execution-mode whole-model` for that
22
+ catalog model with state under `~/.reploid` (`weights/<model id>/` and
23
+ `identity.json`) and the supported transport and GPU packages, and prints what
24
+ it chose. One machine then holds the whole model and serves requests alone. Any
25
+ participant option may follow and replaces the chosen value:
26
+ `--execution-mode partition` (or a partition-only option such as
27
+ `--partition-index`, `--ordered-config`, `--canonical` or `--readiness-log`)
28
+ keeps partition execution, which needs another contributor for the same model;
29
+ `--connect-only` or `--share-files` choose another mode.
30
+
31
+ Whole-model contribution with an incomplete model directory first fills it
32
+ (`model-fill` status lines: `start`, `waiting-for-supplier`, `source`,
33
+ `source-failed`, `piece`, `file`, `complete`; piece lines and the per-source
34
+ `sources` totals name where bytes came from). Sources are tried in order: the
35
+ verified piece cache and pieces already written, authorized custody peers, then
36
+ the model's pinned public origin when
37
+ [`server/native-model-origins.json`](../server/native-model-origins.json) pins
38
+ one. A pin binds the exact model identity to a Hugging Face repository, an
39
+ immutable 40-hex revision and a path; nothing from peers or requests can name
40
+ an origin, requests carry no credentials, and shards are read by HTTP range per
41
+ pinned piece. The manifest always comes from the delivery's pinned copy, never
42
+ an origin. With a pin, the fill gives peers a 15 s grace to announce and then
43
+ uses the origin for pieces no peer offers or that peers fail to deliver, so it
44
+ also completes with no peer online. Partition acquisition uses the same pinned
45
+ origin as its last source. Only `qwen-3-5-2b-q4k-ehaf16` is pinned
46
+ (`clocksmith/rdrr` at `3a05b346b1c86abf02c7620f2369a9a7b82cb62f`,
47
+ `models/qwen-3-5-2b-q4k-ehaf16`); its 32 shard hashes there equal the pinned
48
+ manifest's. Each piece is checked
49
+ against the catalog's pinned piece index, each assembled shard against the
50
+ manifest's SHA-256 and each other file against the catalog. A file is written as
51
+ `<name>.partial` and renamed only after its whole hash matches; the manifest is
52
+ written last. A restart reuses verified pieces already written. The fill needs
53
+ free space for the missing files, follows the owner policy's admission and rates,
54
+ and drops its cached piece copies once a shard is in place. Without a pinned
55
+ origin it waits while no supplier is online; once one has delivered, a piece no
56
+ connected supplier offers within one channel timeout stops contribution with
57
+ that piece named. A directory
58
+ holding another model's manifest is refused, never overwritten. A complete
59
+ directory is used unchanged, as before.
60
+
61
+ `npm run package:native -- --publishable` builds the same delivery with a
62
+ manifest npm accepts. Published under the name `reploid`, the command above
63
+ becomes `npx reploid qwen-3-5-2b-q4k-ehaf16` with no checkout. The example names
64
+ 2B because the fleet supplies it; a model with no supplier online starts and
65
+ waits. `--omit-model <catalog id>` (repeatable) leaves a model and its bundled
66
+ files out of a delivery; the publishable build omits
67
+ `qwen3-8-27b-text-q4k-ehaf16`, whose content-addressed manifest names a home
68
+ directory and whose identity a live provider uses, so it cannot be re-issued
69
+ in place. The package
70
+ is not published; that is an owner decision. Checked: the built package
71
+ installs, and its three commands start through npm's links (help text and
72
+ argument expansion). A whole-model contribution through the short command has
73
+ not been run against the fleet.
74
+
75
+ ## Delivery archive
76
+
77
+ To create an installable native delivery without a source checkout on its host:
78
+
79
+ ```sh
80
+ npm run package:native
81
+ ```
82
+
83
+ The output reports an archive path and its SHA-256. Copy that archive to the
84
+ native host, verify its reported hash, extract it, and enter the `reploid`
85
+ directory. Its `native-delivery.json` binds the source files, catalog, lockfile
86
+ and unchanged accepted Doppler archive. No model weights are included.
87
+
88
+ ```sh
89
+ npm ci --no-audit --no-fund
90
+ npm start -- --help
91
+ mkdir -p weights
92
+ npm start -- --connect-only \
93
+ --model qwen-3-5-0-8b-q4k-ehaf16 \
94
+ --model-directory ./weights \
95
+ --identity-file ./state/identity.json \
96
+ --rtc-module @roamhq/wrtc --ws-module ws
97
+ ```
98
+
99
+ `--connect-only` authenticates and discovers participants without starting the
100
+ GPU or offering files. The model directory may start empty. Use `--contribute`
101
+ and `--gpu-module webgpu` to authorize compute: the existing coordinator chooses
102
+ the assigned partition and obtains its missing verified pieces from authorized
103
+ suppliers. Use `--share-files` to authorize file supply independently, or combine
104
+ it with `--contribute`. Neither mode grants disclosure of requester messages.
105
+
106
+ The native delivery requires `@roamhq/wrtc` and `ws`; `webgpu` is optional for
107
+ connections and file supply. For a host with no compute, installation may use
108
+ `npm ci --omit=optional`. Compute must have an installed compatible WebGPU
109
+ provider, Vulkan driver and adapter. Optional dependency installation failure
110
+ does not qualify compute; selecting an unavailable provider fails explicitly.
111
+
112
+ Public discovery uses the application's existing bootstrap configuration.
113
+ Private deployments can supply `--signaling-url`, `--room`, `--room-token-file`
114
+ and `--origin` explicitly. `--room-token-file` takes an absolute path to a
115
+ regular file owned by the participant's user with mode `0600`; the token is read
116
+ once at startup and one trailing newline is removed. Any other path, owner or
117
+ mode stops startup before the identity, modules or network are touched.
118
+
119
+ ### Model and split JSON
120
+
121
+ `--model-config /absolute/model.json` adds an operator-local model or replaces a
122
+ catalog model's cuts in a private room. It is rejected in public discovery before
123
+ identity creation or provider startup. This is configuration authority, not a
124
+ public model release or signed partition qualification. It requires the matching
125
+ Doppler package (0.6.36 or newer with the manifest-driven plan API).
126
+
127
+ ```json
128
+ {
129
+ "schema": "reploid.native-model/v1",
130
+ "model": "qwen3-8-27b-text-q4k-ehaf16",
131
+ "partition": {
132
+ "splitLayers": [32],
133
+ "activationDtype": "f32",
134
+ "activationPrecision": "f32"
135
+ },
136
+ "partitionRuntime": {
137
+ "maxGpuBufferBytes": [17179869184, 17179869184],
138
+ "runtimeConfig": "model"
139
+ }
140
+ }
141
+ ```
142
+
143
+ `model` can be a catalog ID or a complete model descriptor with `id`, `name`,
144
+ `provider: "doppler"`, exact manifest `identity`, explicit `generation`,
145
+ `executionModes`, and the ordinary pinned `source.files` metadata. Local source
146
+ files include the manifest and SHA-256-bound verified piece index; creating a
147
+ descriptor does not download or copy weights. The actual manifest bytes and
148
+ model ID must match before the runtime is imported. Geometry comes from that
149
+ manifest, not an operator-supplied hidden width or layer count.
150
+
151
+ `partitionRuntime.runtimeConfig` is a complete runtime overlay object, or the
152
+ explicit string `"model"` to reuse `model.loadOptions.runtimeConfig`. One positive
153
+ `maxGpuBufferBytes` value is required for each stage. A profile that runs
154
+ whole-model warm generation must be copied and set
155
+ `shared.kernelWarmup.warmGeneration` to `null` for partition execution. Unsupported
156
+ precision, fusion or generator modes fail; selecting a split never changes them
157
+ silently.
158
+
159
+ Use the same model JSON on every contributor and requester. Supply a separate
160
+ `--ordered-config /absolute/host.json` for each host's placement and limits:
161
+
162
+ ```json
163
+ {
164
+ "stage": {
165
+ "modelId": "qwen3-8-27b-text-q4k-ehaf16",
166
+ "index": 0,
167
+ "residentId": "operator-stage-zero",
168
+ "executionId": "operator-program-zero"
169
+ },
170
+ "maxStages": 4,
171
+ "maxStageOffersPerPeer": 4,
172
+ "maxRouteBytes": 32768,
173
+ "maxSelectionSteps": 2000,
174
+ "maxRoutes": 4
175
+ }
176
+ ```
177
+
178
+ The next host uses index 1 and its own allocation identities; a weightless
179
+ requester uses `"stage": null`. For contributor-chosen placement use
180
+ `"stage": { "modelId": "...", "assignment": "auto" }` together with
181
+ `"orchestration": { "autoStage": { "dwellMs": 60000 } }`.
182
+ [Additional orchestration controls](launch-3-orchestration.md) remain opt-in.
183
+ Automatic assignment, replica demand and timing hints match the exact plan
184
+ identity, so peers with different cuts of the same model are excluded. Byte
185
+ admission cannot exceed the configured stage budget; an automatic contributor
186
+ uses the smallest of its authorized stage budgets. Owner limits can reduce it.
187
+
188
+ Qwen 35B can request `[10, 20, 30]` and Flash-Next `[16, 32]`, with matching
189
+ runtime configuration, budgets and source metadata. Doppler's
190
+ [retained AMD component checks](https://github.com/clocksmith/doppler/tree/main/reports/ordered-qwen-partitions-20261109)
191
+ compare those splits against their unsplit GPU programs. They do not qualify
192
+ cross-machine numerics or public availability. Flash-Next boundaries retain all
193
+ four residual streams. Cuts cannot change during an active attempt; idle
194
+ placement and new-request routing do not migrate conversation state.
195
+
196
+ ```sh
197
+ umask 077 # new files are owner-only (0600)
198
+ cat > /srv/reploid/state/room-token # paste the token, then Ctrl-D
199
+ npm start -- --contribute ... --room reploid-swarm-<name> \
200
+ --room-token-file /srv/reploid/state/room-token
201
+ ```
202
+
203
+ `--room-token <token>` still works for compatibility, but the token is then
204
+ visible in process arguments and in any service journal that records them; the
205
+ CLI prints a warning on stderr. The two options cannot be combined. Protect the identity file and its parent directory;
206
+ they contain the contributor's signing key. SIGINT or SIGTERM settles work,
207
+ closes authenticated channels and releases owned resources before natural exit.
208
+
209
+ The retained development runs used absolute temporary module paths; ordinary
210
+ installation uses the named packages above. Installing or connecting alone
211
+ does not establish useful distributed answers, numerical accuracy or release
212
+ qualification. No package publication or deployment occurs during packaging.
213
+
214
+ ## GPU shader cache
215
+
216
+ On Linux, `--contribute` gives the Vulkan driver a private Mesa shader cache and
217
+ never reuses one that an unfinished preparation wrote. Mesa ANV 24.2.8 stores a
218
+ shader's intermediate form before its compiled binary; a process stopped
219
+ mid-compile leaves an entry that can crash every later process needing that
220
+ pipeline ([investigation](https://github.com/clocksmith/reploid/tree/main/artifacts/native-crash-20261014)).
221
+
222
+ - The cache is keyed by the installed Doppler runtime and its pinned archive, the
223
+ WebGPU provider, the Vulkan driver files and render devices, driver environment
224
+ variables, and the model, Capsule, catalog entry, partition policy and stage.
225
+ - Without a sealed cache for its key, a start compiles into its own new staging
226
+ directory. Once the stage reports complete pipeline preparation and Mesa's cache
227
+ writers are idle, a hashed, read-only snapshot becomes the sealed cache.
228
+ - With a sealed cache, a start verifies every file and works on a private copy;
229
+ the sealed directory is never given to the driver. A sealed cache that fails
230
+ verification is removed and the start compiles cold.
231
+ - Each start removes staging left by a process that has exited.
232
+
233
+ The root defaults to `shader-cache` beside the identity file; choose another with
234
+ `--shader-cache-root <absolute directory>`. Startup fails if
235
+ `MESA_SHADER_CACHE_DIR` or `MESA_SHADER_CACHE_DISABLE` is already set.
236
+ `shader-cache` status lines report the binding, discarded or rejected caches and
237
+ the seal outcome. A driver that does not use `MESA_SHADER_CACHE_DIR` is reported
238
+ and never sealed. A cold start always compiles every pipeline the stage needs;
239
+ the protocol does not reduce that cost.
240
+
241
+ ## Owner limits
242
+
243
+ `--owner-policy <absolute JSON path>` applies the owner's approved contribution
244
+ limits. Without it, behavior is unchanged and status lines report
245
+ `"owner":{"status":"no owner policy"}`. The file is read once at startup, so a
246
+ restart with the same file restores the same limits.
247
+
248
+ ```json
249
+ {
250
+ "schema": "reploid.native-owner-policy/v1",
251
+ "authorization": {
252
+ "equipment": { "granted": true, "ownership": "workplace", "grantedBy": "A. Owner", "workplaceApproval": "IT ticket 1234" },
253
+ "network": { "granted": true, "ownership": "personal", "grantedBy": "A. Owner" }
254
+ },
255
+ "sampleIntervalMs": 5000,
256
+ "schedule": { "timeZone": "America/New_York",
257
+ "windows": [{ "days": ["mon", "tue", "wed", "thu", "fri"], "start": "22:00", "end": "07:00" }] },
258
+ "memory": { "maxProcessResidentBytes": 8589934592, "maxGpuBufferBytes": 1073741824 },
259
+ "bandwidth": { "uploadBytesPerSecond": 1048576, "downloadBytesPerSecond": 4194304 },
260
+ "temperature": { "sensors": ["amdgpu"], "reduceAboveCelsius": 80, "deferAboveCelsius": 90 },
261
+ "power": { "requireExternalPower": true, "gpuSensors": ["amdgpu"], "deferAboveWatts": 150 },
262
+ "foreground": { "source": "owner-signal", "signalFile": "/run/user/1000/reploid-foreground", "action": "defer" },
263
+ "reduced": { "maxConcurrentAttempts": 1, "maxSupplyTransfers": 1 }
264
+ }
265
+ ```
266
+
267
+ - Equipment and network grants are required; workplace resources also need
268
+ `workplaceApproval`. Unknown keys fail startup. No limit has a built-in
269
+ default; an omitted section requests no control.
270
+ - Schedule windows use local wall time in `timeZone`; a window that ends before
271
+ it starts continues into the next day.
272
+ - `defer` admits no new stage attempt, contribution preparation or piece supply;
273
+ `reduce` lowers new admission to the `reduced` limits. Admitted attempts and
274
+ granted transfers finish or settle. Nothing cancels conversations, and the
275
+ process takes no wake lock.
276
+ - Rates pace custody piece and file bytes, not execution activations. Each rate
277
+ must be at least the custody deadline floor (74,566 bytes per second with the
278
+ current file policy). Cumulative file allowances are unchanged.
279
+ - `maxGpuBufferBytes` lowers Doppler's GPU buffer budget (application
280
+ allocations, not physical VRAM); `maxProcessResidentBytes` defers new work
281
+ while the process exceeds it.
282
+ - A requested control without a readable source rejects new work; missing or
283
+ stale readings defer it.
284
+ - With `owner-signal`, new work defers or reduces while `signalFile` exists.
285
+ - `power.gpuSensors` without watt thresholds only measures GPU energy.
286
+
287
+ | Control | Linux | macOS | Windows |
288
+ | --- | --- | --- | --- |
289
+ | Schedule, process memory, GPU buffer budget, rates, owner signal | Supported | Supported | Supported |
290
+ | Temperature | Named hwmon sensors (`temp*_input`) | Unsupported (needs root) | Unsupported |
291
+ | GPU power | Named hwmon sensors (`power*`, `energy*`); component estimate | Unsupported (needs root) | Unsupported |
292
+ | External power | `power_supply` | `pmset -g batt` | Unsupported |
293
+ | Input idle | Unsupported; use `owner-signal` | `ioreg` `HIDIdleTime` | Unsupported |
294
+ | Wall power | Unsupported (external meter) | Unsupported | Unsupported |
295
+
296
+ `native-initialized` declares the policy and every control. `network` lines
297
+ report the decision, readings and measured CPU, memory, transfer and GPU energy;
298
+ `partition-state` lines carry the current decision and `at`, the observation
299
+ time in ISO 8601 UTC. These are source controls; installed and physical
300
+ qualification are separate.
301
+
302
+ ## Readiness records
303
+
304
+ `--readiness-log <absolute JSONL path>` (with `--contribute`) appends the
305
+ records `scripts/capacity-utilization.js` measures. There is no default path;
306
+ without the flag nothing is written. The file is created owner-only (`0600`).
307
+
308
+ - `reploid.readiness-span/v1`: one stage of this participant (`participantId`,
309
+ `modelIdentity`, `planId`, `stageIndex`) was `ready` with `capacity`
310
+ (`attempt-slots` it holds or admits, after any owner limit) or `unready` from
311
+ `from` to `to` (epoch ms). A span is written when it opens (`to: null`),
312
+ re-written every 60 s while open and closed with `end` (for example `stopped`,
313
+ `failed`, `capacity-changed`, `observation-gap`, `shutdown`). A stage is ready
314
+ only while offered, Doppler reports it ready and it admits at least one slot.
315
+ - `reploid.stage-admission/v1`: one admitted attempt's identities, reservation
316
+ and settlement times and slot count, written when reserved, while held and
317
+ when settled.
318
+
319
+ Records hold no conversation text, thread or requester identities, or error
320
+ text. SIGINT/SIGTERM closes every span when shutdown starts. After a crash the
321
+ last span stays open: the CLI counts it only through its last observation, lists
322
+ it, and treats the time until the next start as unknown. A start writes nothing
323
+ for a stage until it is prepared; the stage is then recorded unready back to the
324
+ start. More than 60 s without an observation ends a ready span (a suspended
325
+ machine serves nothing). Pass the log and the requester's exports to the CLI
326
+ with an explicit interval:
327
+
328
+ ```sh
329
+ node scripts/capacity-utilization.js readiness.jsonl attempts.json \
330
+ --from 2026-10-15T22:00:00Z --to 2026-10-16T07:00:00Z
331
+ ```
332
+
333
+ ## Opt-in text HTTP APIs
334
+
335
+ The installed native entry exports `createChatCompletions`, `createResponses` and `createMessages`. Each borrows an ordinary
336
+ participant's existing requester; it neither loads a fallback model nor grants
337
+ permission. No HTTP endpoint is mounted by the CLI or standalone signaling server
338
+ by default. A host application can mount the adapter explicitly:
339
+
340
+ ```js
341
+ import http from 'node:http';
342
+ import { createNativeParticipant, createChatCompletions, createResponses, createMessages } from './server/native-participant.js';
343
+ import { nativeOptions, authenticate, authorize } from './api-host.js';
344
+
345
+ const participant = await createNativeParticipant(nativeOptions);
346
+ const api = createChatCompletions({ participant, authenticate, authorize });
347
+ const responses = createResponses({ participant, authenticate, authorize });
348
+ const messages = createMessages({ participant, authenticate, authorize });
349
+ const server = http.createServer((req, res) => {
350
+ const path = new URL(req.url, 'http://localhost').pathname;
351
+ return (path === '/v1/messages' ? messages : path === '/v1/responses' ? responses : api).handle(req, res);
352
+ });
353
+ server.listen(8788, '127.0.0.1');
354
+ // On host shutdown: await Promise.all([api.close(), responses.close(), messages.close()]), close the HTTP server,
355
+ // then await participant.close(). Failed settlement must remain retryable.
356
+ ```
357
+
358
+ `api-host.js` is the application's credential and consent owner. It must provide
359
+ `authenticate(request, {signal})`, returning a verified `{subject}` or rejecting,
360
+ and `authorize({action, principal, request, preview?, signal})`, returning `true`
361
+ only for approved actions. `chat.execute` covers the immutable request;
362
+ `chat.disclose` separately presents the actual route, recipients and input chosen
363
+ by the existing requester. Approval of execution does not approve disclosure.
364
+ Use a separately qualified prepared route; connection alone is not readiness.
365
+
366
+ An ordinary native requester now projects ready whole-model peers as well as its
367
+ partition routes. It prefers a ready whole-model route for the exact base model;
368
+ adapter variants use their catalog `selectionId`. Artifact and adapter identities
369
+ remain bound through disclosure and completion. A whole-model contributor and an
370
+ ordinary requester remain separate roles: the requester does not load weights.
371
+ The current whole-model mesh does not support caller-selected token ceilings, so
372
+ it refuses Responses `max_output_tokens` and cannot serve Messages' required
373
+ `max_tokens`. Completion metadata is provider-reported, not validated billing evidence.
374
+
375
+ The application server can mount `/v1/models`, `/v1/chat/completions` and
376
+ `/v1/responses` before the earning router by setting
377
+ `REPLOID_TEXT_API_COMPOSITION` to an absolute module outside this repository.
378
+ That module exports `createTextApiComposition({env, production})`, returning
379
+ `participant`, `authenticate`, `authorize`, an `accounting.run(request, controls,
380
+ execute)` port, and optional `close()`. `controls.principal` is the authenticated
381
+ caller. Model listing additionally requires authorization for `models.list`.
382
+ Production refuses a `testOnly` composition and requires accounted execution.
383
+ Controlled tests may explicitly opt into `allowUnbilledTest` outside production.
384
+ Without the environment setting, these routes remain unmounted. Hosting rewrites
385
+ and deployment of the configured server remain separate release actions.
386
+
387
+ `server/trial-admission.js` supplies an exposure gate over the existing
388
+ transactional backend interface, using `TRIAL_COLLECTIONS`. It creates no
389
+ credits or prices. The accounting owner supplies an accepted reservation reader
390
+ returning `{reservationId, accountId, quoteIdentity, accepted, currency,
391
+ maxSubsidyMinor, expiresAt}` and a settlement reader returning
392
+ `{reservationId, accountId, settlementId, currency, subsidyMinor,
393
+ executionSettled}`. Amounts must come from the bound, approved ledger conversion
394
+ and settlement; they must not come from client-supplied prices or text estimates.
395
+ The gate reserves global and lifetime-account exposure atomically, admits a
396
+ reservation once, and retains the slot across restarts until both execution and
397
+ ledger settlement are confirmed. Cancellation or an expired quote does not
398
+ release uncertain execution. Production requires shared Firestore storage.
399
+
400
+ Evidence: [HTTP composition tests](../tests/integration/text-api.test.js),
401
+ [whole-model requester tests](../tests/unit/whole-model-requester.test.js) and
402
+ [trial admission tests](../tests/unit/trial-admission.test.js). These use controlled
403
+ execution and ledger fixtures; they do not qualify live inference, contributor
404
+ rewards, cash accounting, or a production earn-and-redeem loop. A production
405
+ composition must still supply approved terms and those ledger/execution projections.
406
+
407
+ | Surface | Implemented contract |
408
+ | --- | --- |
409
+ | `POST /v1/chat/completions` | `model`, `messages`, optional boolean `stream`; one text choice |
410
+ | Messages | `system`, `user`, `assistant` with string `content` only |
411
+ | Streaming | SSE deltas, stable completion identity, actual terminal reason and `[DONE]` only on success |
412
+ | Termination | Stop token/sequence/EOS maps to `stop`; token/context limit maps to `length`; unknown reason fails |
413
+ | Cancellation | HTTP disconnect aborts the existing requester; unresolved HTTP calls remain charged until their promises settle |
414
+ | Unsupported parameters | Explicit 400 for sampling overrides including `temperature`, `top_p`, `seed`, `max_tokens`, `n`, tools, structured outputs and other unrecognized fields |
415
+ | `POST /v1/responses` | Explicit `store:false`, `model`, string `input` or an array of the text messages above; optional string `instructions`, boolean `stream`, caller `max_output_tokens`, and `text.format.type=json_object` |
416
+ | Responses streaming | Typed SSE events with contiguous sequence numbers, stable response/item identities, and one completed or incomplete response |
417
+ | Responses termination | Stop/EOS completes; output-token limit is `incomplete/max_output_tokens` with `completed_at:null`; context-limit and unknown termination fail explicitly |
418
+ | Responses unsupported state | Rejects omitted/true `store`, previous response IDs, conversations, background, tools, `json_schema`, sampling and unknown fields; no lookup or response persistence |
419
+ | `POST /v1/messages` | Text Messages wire adapter: `model`, alternating user/assistant string `messages` ending in user, optional string `system`, positive `max_tokens`, optional `stream` |
420
+ | Messages limits | Requires a route advertising caller-limit and raw-token usage support; the requested ceiling must fit its prepared allocation. Zero/cache-only, prefill, content blocks, tools, thinking, structured output, sampling and custom stop sequences are rejected |
421
+ | Messages streaming | Actual tokenization observation produces `message_start` before numerical dispatch; typed content deltas and final cumulative sampled count end with `message_stop` |
422
+ | Messages termination | EOS/stop token → `end_turn`; output ceiling → `max_tokens`; context-limit or unmatched stop-sequence metadata fails explicitly |
423
+ | Other paths | Unimplemented routes return 404 |
424
+ | Usage | Chat Completions omits counts. Responses with a caller ceiling and Messages use actual `raw-model-tokens/v1` local accounting described below; missing counts remain absent |
425
+
426
+ The adapter uses existing input/output/admission limits from
427
+ `apps/poolday/config/partition-policy.json`. Adapters borrowing the same participant share
428
+ the HTTP admission limit; closing one adapter aborts only its own requests.
429
+ `getState().active` counts that adapter's HTTP requests,
430
+ not GPU ownership; remote cleanup debt remains with participant/resident owners.
431
+ This ordinary streamed execution path does not claim canonical durable publication.
432
+
433
+ The [installed consumer evidence](https://github.com/clocksmith/reploid/tree/main/artifacts/text-chat-completions-20261013)
434
+ uses the official OpenAI JavaScript SDK against loopback, with injected numerical
435
+ text and no cloud or GPU calls. Separate source controls reach the real automatic
436
+ requester, signed grants and ordered peer owners through a mounted HTTP handler.
437
+ Neither establishes physical model correctness or coding quality. Wire fields
438
+ follow the official [Chat Completions reference](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create).
439
+
440
+ Stateless Responses requires the caller to resend its intended text history.
441
+ Instructions are included in the exact messages presented for authorization and
442
+ disclosure. There is no prior-response lookup or hidden continuation state, and
443
+ no token counts are invented. Generation
444
+ uses the prepared route's declared policy. Responses `max_output_tokens` and
445
+ Messages `max_tokens` enter the existing signed generation request and must fit
446
+ the prepared allocation and policy ceiling. A route without caller-limit/usage
447
+ capability rejects the request. General sampling overrides remain unsupported.
448
+
449
+ Responses JSON-object mode adds an explicit JSON instruction to the authorized
450
+ messages and validates that final text parses as an object. It does not supply
451
+ constrained decoding or JSON-schema guarantees. Invalid output cannot publish a
452
+ successful terminal event; streamed text remains provisional.
453
+
454
+ An optional namespaced `reploid` field narrows, without replacing, the host's
455
+ existing authorization:
456
+
457
+ ```json
458
+ {
459
+ "pool_id": "valera-private-pool-v1",
460
+ "expected_model_identity": "sha256:REPLACE-WITH-READY-MODEL-IDENTITY",
461
+ "expected_adapter_identities": [],
462
+ "expected_plan_identity": null,
463
+ "allowed_recipients": ["REPLACE-WITH-ADMITTED-PEER-THUMBPRINT"],
464
+ "include_execution": true
465
+ }
466
+ ```
467
+
468
+ The native host exposes its authoritative `roomId` and `executionClass`. Public-pool
469
+ or unknown classes, changed pools, model/adapter/plan mismatches and undeclared
470
+ recipients fail closed. Checks span execution authorization, disclosure authorization
471
+ and completion. Actual recipients include `preview.input.recipients`, route stage
472
+ participant IDs and pair participants; a room name is not a recipient identity.
473
+ Expected adapters must be active on the selected route, not merely available.
474
+
475
+ The completed Responses object then includes `reploid.http-execution/v1` metadata:
476
+ thread/attempt, model, pool/class, selected adapters/plan, approved recipients and
477
+ the existing native execution result. Headers retain request/attempt/model identity
478
+ and the raw-token usage schema when admitted. This is provider-reported evidence;
479
+ HTTP compatibility does not independently attest remote hardware or model quality.
480
+ The request field grants neither admission nor disclosure rights. Source integration
481
+ tests cover these bindings with injected computation; no physical inference is
482
+ implied by those tests. Mounting remains an explicit host operation.
483
+
484
+ The [Responses installed consumer evidence](https://github.com/clocksmith/reploid/tree/main/artifacts/stateless-responses-20261013)
485
+ uses OpenAI SDK 7.32.0 for nonstreaming, streaming, terminal errors and cancellation
486
+ against an installed native adapter with injected computation. Source HTTP tests
487
+ add the actual automatic requester, grants and ordered peers. This proves protocol
488
+ composition, not physical inference. Event shapes follow the official
489
+ [Responses streaming guide](https://developers.openai.com/api/docs/guides/streaming-responses)
490
+ and [conversation state guide](https://developers.openai.com/api/docs/guides/conversation-state).
491
+
492
+ The text Messages adapter reports `x-reploid-token-usage: raw-model-tokens/v1`.
493
+ `usage.input_tokens` is the selected model's actual templated prompt token count;
494
+ `usage.output_tokens` counts actual sampled tokens, including a terminal token
495
+ that decodes to no visible text. These are local execution counts, not Claude
496
+ tokenizer equivalence, Anthropic billing, cache usage or visible-text estimates.
497
+ No cache/billing fields are fabricated. A caller limit enters the existing signed
498
+ generation digest, and cannot change mid-attempt. Input-usage or text publication
499
+ prevents automatic retry from splicing a fresh attempt into the same response.
500
+ The host must authenticate `x-api-key` or other credentials through its existing
501
+ authentication port; the adapter itself grants no identity or disclosure rights.
502
+
503
+ The [Messages compatibility evidence](https://github.com/clocksmith/reploid/tree/main/artifacts/text-messages-20261013)
504
+ uses the official Anthropic SDK against an installed, explicit loopback mount with
505
+ injected numerical output. Source tests exercise real request/grant/entry/peer
506
+ owners, smaller caller caps, cancellation and actual token arrays. Neither proves
507
+ physical model quality. The supported wire subset follows the official
508
+ [Messages reference](https://platform.claude.com/docs/en/api/messages/create) and
509
+ [streaming events](https://platform.claude.com/docs/en/build-with-claude/streaming);
510
+ unsupported features fail explicitly.
511
+
512
+ ## Contributor browser search
513
+
514
+ `--browser-search-profile /absolute/path/to/new-dedicated-profile` opts this
515
+ participant into Google search through an owned, visible Chrome session. It can
516
+ run with `--connect-only`: neither model preparation nor file sharing is needed.
517
+ The host needs Chrome and Playwright (`npm install --no-save playwright` in a
518
+ native delivery; the source checkout already includes it for browser tests).
519
+ Do not point this option at a personal Chrome profile or sign into this profile.
520
+ Existing non-Reploid profiles are refused. Keep its local browser state private;
521
+ it can retain search queries and Google's verification cookies.
522
+
523
+ Human verification remains manual in the contributor window. Closing the browser
524
+ withdraws its offer; a verification challenge suspends it until resolved. Search
525
+ runs one query at a time and refuses overlap; cancellation closes its search tab
526
+ and waits for bounded outstanding redirect requests. Only search-engine redirects
527
+ use the browser session. Source pages go through the existing DNS-guarded public
528
+ fetcher without browser cookies. Individual extraction failures remain recorded.
529
+
530
+ The browser application waits for a browser-Google contributor for new searches;
531
+ it does not automatically fall back to the unreliable legacy Bing RSS service. Each attempt binds its exact contributor, service and version;
532
+ there is no silent mid-request switch. A new Send or Retry authorizes the query
533
+ under the existing settings without adding a popup. Search quality and continued
534
+ availability still depend on the external search engine and source sites.