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