@b00dea/cockpit 0.0.0-bootstrap.0 → 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 (363) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/LICENSE +21 -0
  3. package/README.md +21 -1
  4. package/bin/cockpit.mjs +33 -0
  5. package/cockpit.schema.json +2574 -0
  6. package/dist/autonomy.d.ts +44 -0
  7. package/dist/autonomy.js +156 -0
  8. package/dist/bounded-read.d.ts +14 -0
  9. package/dist/bounded-read.js +42 -0
  10. package/dist/browser/commands.d.ts +62 -0
  11. package/dist/browser/commands.js +349 -0
  12. package/dist/browser/package-paths.d.ts +1 -0
  13. package/dist/browser/package-paths.js +6 -0
  14. package/dist/browser/proxy.d.ts +22 -0
  15. package/dist/browser/proxy.js +37 -0
  16. package/dist/browser/runtime.d.ts +117 -0
  17. package/dist/browser/runtime.js +183 -0
  18. package/dist/browser/surfaces.d.ts +141 -0
  19. package/dist/browser/surfaces.js +556 -0
  20. package/dist/browser/ui-gate.d.ts +15 -0
  21. package/dist/browser/ui-gate.js +18 -0
  22. package/dist/cli-guard.d.ts +5 -0
  23. package/dist/cli-guard.js +71 -0
  24. package/dist/cli-main.d.ts +139 -0
  25. package/dist/cli-main.js +1405 -0
  26. package/dist/cli.d.ts +3 -0
  27. package/dist/cli.js +16 -0
  28. package/dist/command-table.d.ts +113 -0
  29. package/dist/command-table.js +512 -0
  30. package/dist/config/load.d.ts +171 -0
  31. package/dist/config/load.js +345 -0
  32. package/dist/config/sibling-toml.d.ts +48 -0
  33. package/dist/config/sibling-toml.js +160 -0
  34. package/dist/config/surface-tools-toml.d.ts +9 -0
  35. package/dist/config/surface-tools-toml.js +37 -0
  36. package/dist/config/verified-write.d.ts +43 -0
  37. package/dist/config/verified-write.js +89 -0
  38. package/dist/diagnostics.d.ts +26 -0
  39. package/dist/diagnostics.js +335 -0
  40. package/dist/emit.d.ts +22 -0
  41. package/dist/emit.js +43 -0
  42. package/dist/entrypoint-kinds.d.ts +3 -0
  43. package/dist/entrypoint-kinds.js +11 -0
  44. package/dist/environment/application/destructive.d.ts +6 -0
  45. package/dist/environment/application/destructive.js +425 -0
  46. package/dist/environment/application/doctor.d.ts +89 -0
  47. package/dist/environment/application/doctor.js +235 -0
  48. package/dist/environment/application/guard.d.ts +43 -0
  49. package/dist/environment/application/guard.js +622 -0
  50. package/dist/environment/application/health.d.ts +134 -0
  51. package/dist/environment/application/health.js +379 -0
  52. package/dist/environment/application/lifecycle-context.d.ts +228 -0
  53. package/dist/environment/application/lifecycle-context.js +154 -0
  54. package/dist/environment/application/lifecycle-state.d.ts +25 -0
  55. package/dist/environment/application/lifecycle-state.js +201 -0
  56. package/dist/environment/application/lifecycle.d.ts +17 -0
  57. package/dist/environment/application/lifecycle.js +729 -0
  58. package/dist/environment/application/logs.d.ts +45 -0
  59. package/dist/environment/application/logs.js +127 -0
  60. package/dist/environment/application/setup.d.ts +129 -0
  61. package/dist/environment/application/setup.js +741 -0
  62. package/dist/environment/application/shared.d.ts +11 -0
  63. package/dist/environment/application/shared.js +61 -0
  64. package/dist/environment/claims.d.ts +389 -0
  65. package/dist/environment/claims.js +1709 -0
  66. package/dist/environment/codex-hook-trust.d.ts +11 -0
  67. package/dist/environment/codex-hook-trust.js +185 -0
  68. package/dist/environment/compose-environment.d.ts +1 -0
  69. package/dist/environment/compose-environment.js +6 -0
  70. package/dist/environment/compose-ownership.d.ts +21 -0
  71. package/dist/environment/compose-ownership.js +117 -0
  72. package/dist/environment/compose-topology.d.ts +117 -0
  73. package/dist/environment/compose-topology.js +413 -0
  74. package/dist/environment/contract.d.ts +489 -0
  75. package/dist/environment/contract.js +761 -0
  76. package/dist/environment/declaration.d.ts +14 -0
  77. package/dist/environment/declaration.js +39 -0
  78. package/dist/environment/destructive-composition.d.ts +29 -0
  79. package/dist/environment/destructive-composition.js +333 -0
  80. package/dist/environment/docker-daemon.d.ts +30 -0
  81. package/dist/environment/docker-daemon.js +78 -0
  82. package/dist/environment/docker-endpoint.d.ts +10 -0
  83. package/dist/environment/docker-endpoint.js +19 -0
  84. package/dist/environment/env-schema-observation.d.ts +46 -0
  85. package/dist/environment/env-schema-observation.js +241 -0
  86. package/dist/environment/evidence.d.ts +136 -0
  87. package/dist/environment/evidence.js +437 -0
  88. package/dist/environment/executable.d.ts +26 -0
  89. package/dist/environment/executable.js +167 -0
  90. package/dist/environment/generated-application/authorities.d.ts +5 -0
  91. package/dist/environment/generated-application/authorities.js +61 -0
  92. package/dist/environment/generated-application/bootstrap-skill.d.ts +16 -0
  93. package/dist/environment/generated-application/bootstrap-skill.js +328 -0
  94. package/dist/environment/generated-application/check.d.ts +13 -0
  95. package/dist/environment/generated-application/check.js +189 -0
  96. package/dist/environment/generated-application/custom-surface.d.ts +26 -0
  97. package/dist/environment/generated-application/custom-surface.js +289 -0
  98. package/dist/environment/generated-application/prepare.d.ts +29 -0
  99. package/dist/environment/generated-application/prepare.js +276 -0
  100. package/dist/environment/generated-application/publication.d.ts +33 -0
  101. package/dist/environment/generated-application/publication.js +547 -0
  102. package/dist/environment/generated-application/shared.d.ts +484 -0
  103. package/dist/environment/generated-application/shared.js +349 -0
  104. package/dist/environment/generated-application/surface-observation.d.ts +4 -0
  105. package/dist/environment/generated-application/surface-observation.js +69 -0
  106. package/dist/environment/generated-application/surface-outputs.d.ts +71 -0
  107. package/dist/environment/generated-application/surface-outputs.js +389 -0
  108. package/dist/environment/generated-application/surfaces.d.ts +3 -0
  109. package/dist/environment/generated-application/surfaces.js +699 -0
  110. package/dist/environment/generated-application/sync.d.ts +6 -0
  111. package/dist/environment/generated-application/sync.js +109 -0
  112. package/dist/environment/git-observation.d.ts +183 -0
  113. package/dist/environment/git-observation.js +544 -0
  114. package/dist/environment/health-composition.d.ts +11 -0
  115. package/dist/environment/health-composition.js +628 -0
  116. package/dist/environment/host-observation.d.ts +56 -0
  117. package/dist/environment/host-observation.js +52 -0
  118. package/dist/environment/identity.d.ts +48 -0
  119. package/dist/environment/identity.js +85 -0
  120. package/dist/environment/init-application.d.ts +308 -0
  121. package/dist/environment/init-application.js +697 -0
  122. package/dist/environment/install-policy-observation.d.ts +71 -0
  123. package/dist/environment/install-policy-observation.js +284 -0
  124. package/dist/environment/install-policy.d.ts +48 -0
  125. package/dist/environment/install-policy.js +96 -0
  126. package/dist/environment/instance.d.ts +33 -0
  127. package/dist/environment/instance.js +122 -0
  128. package/dist/environment/instruction-pointer.d.ts +19 -0
  129. package/dist/environment/instruction-pointer.js +144 -0
  130. package/dist/environment/lifecycle-composition.d.ts +29 -0
  131. package/dist/environment/lifecycle-composition.js +675 -0
  132. package/dist/environment/lifecycle-stage.d.ts +115 -0
  133. package/dist/environment/lifecycle-stage.js +398 -0
  134. package/dist/environment/lifecycle.d.ts +75 -0
  135. package/dist/environment/lifecycle.js +354 -0
  136. package/dist/environment/logs.d.ts +132 -0
  137. package/dist/environment/logs.js +519 -0
  138. package/dist/environment/observations.d.ts +46 -0
  139. package/dist/environment/observations.js +344 -0
  140. package/dist/environment/operator-application.d.ts +50 -0
  141. package/dist/environment/operator-application.js +155 -0
  142. package/dist/environment/ports.d.ts +182 -0
  143. package/dist/environment/ports.js +1205 -0
  144. package/dist/environment/posture-observation.d.ts +68 -0
  145. package/dist/environment/posture-observation.js +253 -0
  146. package/dist/environment/read-composition.d.ts +27 -0
  147. package/dist/environment/read-composition.js +352 -0
  148. package/dist/environment/readiness-composition.d.ts +38 -0
  149. package/dist/environment/readiness-composition.js +130 -0
  150. package/dist/environment/reclaim.d.ts +333 -0
  151. package/dist/environment/reclaim.js +1835 -0
  152. package/dist/environment/repository-identity.d.ts +13 -0
  153. package/dist/environment/repository-identity.js +108 -0
  154. package/dist/environment/runtime-measurement-record.d.ts +38 -0
  155. package/dist/environment/runtime-measurement-record.js +111 -0
  156. package/dist/environment/runtime-measurement.d.ts +27 -0
  157. package/dist/environment/runtime-measurement.js +224 -0
  158. package/dist/environment/runtime-probe-residue.d.ts +43 -0
  159. package/dist/environment/runtime-probe-residue.js +148 -0
  160. package/dist/environment/runtime-probe.d.ts +72 -0
  161. package/dist/environment/runtime-probe.js +725 -0
  162. package/dist/environment/runtime.d.ts +505 -0
  163. package/dist/environment/runtime.js +2335 -0
  164. package/dist/environment/seed.d.ts +16 -0
  165. package/dist/environment/seed.js +43 -0
  166. package/dist/environment/selftest-application.d.ts +86 -0
  167. package/dist/environment/selftest-application.js +713 -0
  168. package/dist/environment/sensitive.d.ts +3 -0
  169. package/dist/environment/sensitive.js +48 -0
  170. package/dist/environment/setup-observation.d.ts +62 -0
  171. package/dist/environment/setup-observation.js +1473 -0
  172. package/dist/environment/setup.d.ts +43 -0
  173. package/dist/environment/setup.js +176 -0
  174. package/dist/environment/sibling-instructions.d.ts +33 -0
  175. package/dist/environment/sibling-instructions.js +224 -0
  176. package/dist/environment/sibling-registration.d.ts +45 -0
  177. package/dist/environment/sibling-registration.js +538 -0
  178. package/dist/environment/state.d.ts +371 -0
  179. package/dist/environment/state.js +2013 -0
  180. package/dist/environment/templates.d.ts +140 -0
  181. package/dist/environment/templates.js +685 -0
  182. package/dist/environment/tool-registration.d.ts +9 -0
  183. package/dist/environment/tool-registration.js +96 -0
  184. package/dist/environment/upgrade-application.d.ts +19 -0
  185. package/dist/environment/upgrade-application.js +175 -0
  186. package/dist/environment-exec/execute.d.ts +102 -0
  187. package/dist/environment-exec/execute.js +1175 -0
  188. package/dist/environment-exec/libexec-program.d.ts +6 -0
  189. package/dist/environment-exec/libexec-program.js +22 -0
  190. package/dist/environment-exec/verified-digest.d.ts +4 -0
  191. package/dist/environment-exec/verified-digest.js +16 -0
  192. package/dist/exact-keys.d.ts +7 -0
  193. package/dist/exact-keys.js +15 -0
  194. package/dist/fix-catalogue.d.ts +32 -0
  195. package/dist/fix-catalogue.js +60 -0
  196. package/dist/freshness.d.ts +29 -0
  197. package/dist/freshness.js +75 -0
  198. package/dist/generated-environment/adopt.d.ts +16 -0
  199. package/dist/generated-environment/adopt.js +275 -0
  200. package/dist/generated-environment/command.d.ts +47 -0
  201. package/dist/generated-environment/command.js +75 -0
  202. package/dist/generated-environment/transaction.d.ts +186 -0
  203. package/dist/generated-environment/transaction.js +1770 -0
  204. package/dist/grading/evaluate.d.ts +71 -0
  205. package/dist/grading/evaluate.js +403 -0
  206. package/dist/grading/grade.d.ts +33 -0
  207. package/dist/grading/grade.js +57 -0
  208. package/dist/guards/evaluator.d.ts +113 -0
  209. package/dist/guards/evaluator.js +1226 -0
  210. package/dist/guards/harness-adapter.d.ts +17 -0
  211. package/dist/guards/harness-adapter.js +57 -0
  212. package/dist/guards/host.d.ts +8 -0
  213. package/dist/guards/host.js +10 -0
  214. package/dist/guards/invocation-parser.d.ts +66 -0
  215. package/dist/guards/invocation-parser.js +595 -0
  216. package/dist/guards/local-identity.d.ts +40 -0
  217. package/dist/guards/local-identity.js +123 -0
  218. package/dist/guards/policy-pin.d.ts +13 -0
  219. package/dist/guards/policy-pin.js +175 -0
  220. package/dist/guards/protected-locations.d.ts +62 -0
  221. package/dist/guards/protected-locations.js +461 -0
  222. package/dist/guards/read-only.d.ts +37 -0
  223. package/dist/guards/read-only.js +315 -0
  224. package/dist/init/command.d.ts +40 -0
  225. package/dist/init/command.js +310 -0
  226. package/dist/init/derive.d.ts +51 -0
  227. package/dist/init/derive.js +715 -0
  228. package/dist/init/draft.d.ts +138 -0
  229. package/dist/init/draft.js +1205 -0
  230. package/dist/init/render.d.ts +35 -0
  231. package/dist/init/render.js +82 -0
  232. package/dist/init/scaffold.d.ts +53 -0
  233. package/dist/init/scaffold.js +121 -0
  234. package/dist/invocation.d.ts +13 -0
  235. package/dist/invocation.js +20 -0
  236. package/dist/package-metadata.d.ts +9 -0
  237. package/dist/package-metadata.js +19 -0
  238. package/dist/readiness.d.ts +53 -0
  239. package/dist/readiness.js +88 -0
  240. package/dist/references/named.d.ts +24 -0
  241. package/dist/references/named.js +27 -0
  242. package/dist/refusal.d.ts +15 -0
  243. package/dist/refusal.js +7 -0
  244. package/dist/registry-derivation.d.ts +31 -0
  245. package/dist/registry-derivation.js +32 -0
  246. package/dist/registry-resolve/command.d.ts +47 -0
  247. package/dist/registry-resolve/command.js +226 -0
  248. package/dist/registry-resolve/registry.d.ts +68 -0
  249. package/dist/registry-resolve/registry.js +292 -0
  250. package/dist/registry-resolve/render-shell.d.ts +18 -0
  251. package/dist/registry-resolve/render-shell.js +36 -0
  252. package/dist/repair.d.ts +29 -0
  253. package/dist/repair.js +8 -0
  254. package/dist/schema-json.d.ts +1 -0
  255. package/dist/schema-json.js +177 -0
  256. package/dist/schema.d.ts +1322 -0
  257. package/dist/schema.js +934 -0
  258. package/dist/setup/command.d.ts +4 -0
  259. package/dist/setup/command.js +4 -0
  260. package/dist/sha256.d.ts +1 -0
  261. package/dist/sha256.js +4 -0
  262. package/dist/surfaces/adoption.d.ts +41 -0
  263. package/dist/surfaces/adoption.js +217 -0
  264. package/dist/surfaces/consumer-instructions.d.ts +20 -0
  265. package/dist/surfaces/consumer-instructions.js +43 -0
  266. package/dist/surfaces/contract.d.ts +42 -0
  267. package/dist/surfaces/contract.js +169 -0
  268. package/dist/surfaces/core-declarations.d.ts +24 -0
  269. package/dist/surfaces/core-declarations.js +79 -0
  270. package/dist/surfaces/development-markers.d.ts +1 -0
  271. package/dist/surfaces/development-markers.js +18 -0
  272. package/dist/surfaces/generator-adapter.d.ts +71 -0
  273. package/dist/surfaces/generator-adapter.js +809 -0
  274. package/dist/surfaces/harness-registry.d.ts +180 -0
  275. package/dist/surfaces/harness-registry.js +117 -0
  276. package/dist/surfaces/mcp.d.ts +95 -0
  277. package/dist/surfaces/mcp.js +186 -0
  278. package/dist/surfaces/merge.d.ts +30 -0
  279. package/dist/surfaces/merge.js +105 -0
  280. package/dist/surfaces/ownership.d.ts +190 -0
  281. package/dist/surfaces/ownership.js +795 -0
  282. package/dist/surfaces/projection.d.ts +136 -0
  283. package/dist/surfaces/projection.js +681 -0
  284. package/dist/surfaces/render.d.ts +118 -0
  285. package/dist/surfaces/render.js +633 -0
  286. package/dist/surfaces/restrictions.d.ts +130 -0
  287. package/dist/surfaces/restrictions.js +447 -0
  288. package/dist/surfaces/selftest.d.ts +162 -0
  289. package/dist/surfaces/selftest.js +393 -0
  290. package/dist/surfaces/skill-contract.d.ts +85 -0
  291. package/dist/surfaces/skill-contract.js +449 -0
  292. package/dist/surfaces/sync.d.ts +57 -0
  293. package/dist/surfaces/sync.js +164 -0
  294. package/dist/team-metadata.d.ts +41 -0
  295. package/dist/team-metadata.js +512 -0
  296. package/dist/testing/gates.d.ts +91 -0
  297. package/dist/testing/gates.js +182 -0
  298. package/dist/testing/hooks.d.ts +59 -0
  299. package/dist/testing/hooks.js +139 -0
  300. package/dist/testing/verdict.d.ts +29 -0
  301. package/dist/testing/verdict.js +62 -0
  302. package/dist/work-orders/application.d.ts +99 -0
  303. package/dist/work-orders/application.js +383 -0
  304. package/dist/work-orders/composition.d.ts +124 -0
  305. package/dist/work-orders/composition.js +1010 -0
  306. package/dist/work-orders/contract.d.ts +61 -0
  307. package/dist/work-orders/contract.js +122 -0
  308. package/dist/work-orders/store.d.ts +158 -0
  309. package/dist/work-orders/store.js +197 -0
  310. package/docs/README.md +65 -0
  311. package/docs/architecture.md +136 -0
  312. package/docs/capability-matrix.md +50 -0
  313. package/docs/cli-reference.md +599 -0
  314. package/docs/command-list.md +51 -0
  315. package/docs/compose-patterns.md +99 -0
  316. package/docs/concepts.md +171 -0
  317. package/docs/configuration-essentials.md +172 -0
  318. package/docs/configuration-reference.md +621 -0
  319. package/docs/environment.md +760 -0
  320. package/docs/extending.md +43 -0
  321. package/docs/faq.md +111 -0
  322. package/docs/getting-started.md +608 -0
  323. package/docs/harness-surfaces.md +433 -0
  324. package/docs/joining-a-team.md +76 -0
  325. package/docs/release-policy.md +49 -0
  326. package/docs/safety-and-autonomy.md +419 -0
  327. package/docs/troubleshooting.md +361 -0
  328. package/docs/tutorial.md +170 -0
  329. package/docs/work-and-browser.md +254 -0
  330. package/libexec/browser-operation.cjs +186 -0
  331. package/libexec/fence-marker.cjs +101 -0
  332. package/libexec/fence-marker.d.cts +24 -0
  333. package/libexec/fenced-group-runner.cjs +77 -0
  334. package/libexec/fenced-supervisor.cjs +137 -0
  335. package/libexec/generated-filesystem.cjs +731 -0
  336. package/libexec/install-filesystem.cjs +225 -0
  337. package/libexec/rulesync-generator.NOTICE.md +1112 -0
  338. package/libexec/rulesync-generator.cjs +743 -0
  339. package/libexec/surface-generator-worker.cjs +266 -0
  340. package/libexec/surface-output-reader.cjs +99 -0
  341. package/libexec/surface-scratch-cleanup.cjs +14 -0
  342. package/libexec/validate-harness-evidence.d.mts +183 -0
  343. package/libexec/validate-harness-evidence.mjs +1312 -0
  344. package/package.json +76 -1
  345. package/surfaces/README.md +33 -0
  346. package/surfaces/agents/evaluator.agent.md +76 -0
  347. package/surfaces/guards/bash-guard.sh +48 -0
  348. package/surfaces/guards/claude.adapter.json +25 -0
  349. package/surfaces/guards/codex.adapter.json +24 -0
  350. package/surfaces/guards/opencode.adapter.json +25 -0
  351. package/surfaces/references/browser.md +63 -0
  352. package/surfaces/references/test-data-and-personas.md +84 -0
  353. package/surfaces/references/testing-tiers.md +11 -0
  354. package/surfaces/skills/cockpit-browser.skill.md +54 -0
  355. package/surfaces/skills/cockpit-explain.skill.md +32 -0
  356. package/surfaces/skills/cockpit-fix.skill.md +37 -0
  357. package/surfaces/skills/cockpit-setup.skill.md +39 -0
  358. package/surfaces/skills/cockpit-work.skill.md +34 -0
  359. package/surfaces/skills/collection.json +5 -0
  360. package/surfaces/skills/procedures/explain.md +61 -0
  361. package/surfaces/skills/procedures/fix.md +81 -0
  362. package/surfaces/skills/procedures/setup.md +379 -0
  363. package/surfaces/skills/procedures/work.md +105 -0
@@ -0,0 +1,183 @@
1
+ import { lstatSync, realpathSync } from 'node:fs';
2
+ import { isIP } from 'node:net';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { BROWSER_DRIVER_VERSION, browserDriversCompatible, GeneratedHostPath, parseBrowserNetworkExposure } from '../schema.js';
5
+ import { authenticateObservationPostureContext } from '../environment/posture-observation.js';
6
+ import { authenticateStateNamespace } from '../environment/state.js';
7
+ import { browserHostAllowed, resolveBrowserProxy } from './proxy.js';
8
+ import { RefusalError } from '../environment/contract.js';
9
+ const issuedRuntimes = new WeakMap();
10
+ function storageIdentity(path) {
11
+ const metadata = lstatSync(path);
12
+ if (metadata.isFile() && !metadata.isSymbolicLink() && metadata.nlink === 1
13
+ && (metadata.mode & 0o7777) === 0o600 && realpathSync(path) === path) {
14
+ return JSON.stringify([metadata.dev, metadata.ino, metadata.mode, metadata.size, metadata.mtimeMs, metadata.ctimeMs]);
15
+ }
16
+ throw new RefusalError('browser seeded storage state must be a confined mode-600 regular file');
17
+ }
18
+ function browserClientLimit(maxClients, policy) {
19
+ return policy === 'serialized' ? 1 : maxClients;
20
+ }
21
+ export function resolveBrowserRuntime(input, coordinationNamespace) {
22
+ // The existing owner authenticates source, freshness and both directions of the catalog.
23
+ const checked = authenticateObservationPostureContext(input.postures);
24
+ const checks = checked.checks;
25
+ if (input.postures.authorities.length !== 1 || checks.length !== 2 || checks.some(({ verdict }) => verdict !== 'pass')) {
26
+ throw new RefusalError('browser posture requirements must match the selected declarations');
27
+ }
28
+ const authority = checked.authorities.values().next().value;
29
+ const namespace = coordinationNamespace === undefined ? undefined : authenticateStateNamespace(coordinationNamespace);
30
+ if (coordinationNamespace !== undefined && !namespace)
31
+ throw new RefusalError('browser runtime coordination namespace must be an issued canonical state namespace');
32
+ const { addressing, authentication } = authority.environmentPostures;
33
+ const proxy = resolveBrowserProxy(input.proxy);
34
+ if (!Number.isSafeInteger(input.maxClients) || input.maxClients < 1 || input.maxClients > 64) {
35
+ throw new RefusalError('browser client cap must be an integer from 1 through 64');
36
+ }
37
+ const projectKeys = ['lockfile', 'sha256', 'driverVersion', ...(input.project.manifest === undefined ? [] : ['manifest', 'manifestSha256'])];
38
+ if (Object.keys(input.project).length !== projectKeys.length || !projectKeys.every((key) => Object.hasOwn(input.project, key))
39
+ || !GeneratedHostPath.safeParse(input.project.lockfile).success || !/^[a-f0-9]{64}$/.test(input.project.sha256)
40
+ || input.project.manifest !== undefined && (!GeneratedHostPath.safeParse(input.project.manifest).success
41
+ || !/^[a-f0-9]{64}$/.test(input.project.manifestSha256 ?? ''))
42
+ || input.project.manifest === undefined && input.project.manifestSha256 !== undefined) {
43
+ throw new RefusalError('browser project lockfile identity is invalid');
44
+ }
45
+ if (!BROWSER_DRIVER_VERSION.test(input.project.driverVersion))
46
+ throw new RefusalError('browser project driver version must be exact');
47
+ if (!/^[a-z0-9][a-z0-9./:_-]*@sha256:[a-f0-9]{64}$/.test(input.images.mcp.reference))
48
+ throw new RefusalError('browser images must be digest-pinned');
49
+ if (typeof input.images.mcp.driverVersion !== 'string' || !BROWSER_DRIVER_VERSION.test(input.images.mcp.driverVersion)
50
+ || !browserDriversCompatible(input.images.mcp.driverVersion, input.project.driverVersion)) {
51
+ throw new RefusalError('browser MCP image driver does not share major.minor with the project driver');
52
+ }
53
+ const engine = input.engine ?? 'chromium';
54
+ if (!['chromium', 'firefox', 'webkit'].includes(engine))
55
+ throw new RefusalError('browser engine must be chromium, firefox or webkit');
56
+ const networkExposure = parseBrowserNetworkExposure(input.networkExposure, input.networkExposureReason);
57
+ if (input.hostVariable !== undefined && !/^[A-Z][A-Z0-9_]{0,127}$/.test(input.hostVariable)) {
58
+ throw new RefusalError('browser proxy host variable must be a canonical environment name');
59
+ }
60
+ let connection;
61
+ if (!Object.hasOwn(input, 'endpoint')) {
62
+ connection = { kind: 'local-fallback', reason: 'endpoint-absent', launchLocal: true };
63
+ }
64
+ else {
65
+ let endpoint;
66
+ try {
67
+ const parsed = new URL(input.endpoint);
68
+ const spelling = /^ws:\/\/([^/?#]+)(\/[^?#]*)$/.exec(input.endpoint);
69
+ if (parsed.protocol !== 'ws:' || parsed.username || parsed.password || parsed.search || parsed.hash
70
+ || !spelling || spelling[2] !== parsed.pathname || !browserHostAllowed(proxy, spelling[1]))
71
+ throw Error('invalid');
72
+ endpoint = input.endpoint;
73
+ }
74
+ catch {
75
+ throw new RefusalError('configured browser endpoint must use ws:// with the exact credential-free checking proxy authority; TLS termination is unavailable');
76
+ }
77
+ connection = { kind: 'remote', endpoint, launchLocal: false };
78
+ }
79
+ if (!Array.isArray(input.resolver) || input.resolver.length > 64
80
+ || (addressing === 'hostname' ? input.resolver.length === 0 : input.resolver.length !== 0)
81
+ || new Set(input.resolver.map(({ hostname }) => hostname)).size !== input.resolver.length
82
+ || input.resolver.some(({ hostname, address }) => !/^(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z][a-z0-9-]*$/.test(hostname) || isIP(address) === 0)) {
83
+ throw new RefusalError('browser resolver rules must match the selected addressing posture');
84
+ }
85
+ if (connection.kind === 'local-fallback' && addressing === 'hostname' && engine !== 'chromium') {
86
+ throw new RefusalError('local hostname resolver rules require chromium');
87
+ }
88
+ const artifactKeys = ['mcp', 'cli', 'auth'];
89
+ const paths = artifactKeys.map((key) => input.artifacts[key]);
90
+ if (Object.keys(input.artifacts).length !== artifactKeys.length
91
+ || paths.some((path) => !GeneratedHostPath.safeParse(path).success)
92
+ || paths.some((path, index) => paths.some((other, otherIndex) => index !== otherIndex && (path === other || path.startsWith(`${other}/`))))) {
93
+ throw new RefusalError('browser artifact roots must be confined, distinct and non-overlapping');
94
+ }
95
+ const states = input.authentication.states;
96
+ const storage = [];
97
+ if (!Array.isArray(states) || states.length > 64)
98
+ throw new RefusalError('browser authentication states are invalid');
99
+ const signedOut = authentication === 'bypassed' || authentication === 'none' ? authentication : undefined;
100
+ if (signedOut) {
101
+ if (input.authentication.policy !== 'none' || states.length !== 0)
102
+ throw new RefusalError(`${signedOut} authentication cannot declare persona state or login`);
103
+ }
104
+ else {
105
+ if (input.authentication.policy !== 'serialized' && input.authentication.policy !== 'per-worker'
106
+ || states.length !== (input.authentication.policy === 'serialized' ? 1 : input.maxClients)) {
107
+ throw new RefusalError('real browser authentication requires serialized or per-worker seeded state');
108
+ }
109
+ if (new Set(states.map(({ worker }) => worker)).size !== states.length || new Set(states.map(({ path }) => path)).size !== states.length) {
110
+ throw new RefusalError('per-worker browser state must have distinct workers and paths');
111
+ }
112
+ const root = dirname(authority.source);
113
+ for (const state of states) {
114
+ if (!/^[a-z0-9][a-z0-9_-]{0,63}$/.test(state.worker)
115
+ || !GeneratedHostPath.safeParse(state.path).success || !state.path.startsWith(`${input.artifacts.auth}/`)) {
116
+ throw new RefusalError('browser storage state must name a worker and a path inside the auth artifact root');
117
+ }
118
+ const path = resolve(root, state.path);
119
+ storage.push({ path, identity: storageIdentity(path) });
120
+ }
121
+ }
122
+ if (!['empty', 'seeded', 'restored'].includes(input.data.mode) || typeof input.data.isolated !== 'boolean'
123
+ || typeof input.data.reachesProduction !== 'boolean' || typeof input.requestPreapproval !== 'boolean') {
124
+ throw new RefusalError('browser data posture must be explicit');
125
+ }
126
+ if (input.requestPreapproval && (input.data.mode === 'restored' || !input.data.isolated || input.data.reachesProduction)) {
127
+ throw new RefusalError('browser preapproval requires isolated empty or seeded data with no production reach');
128
+ }
129
+ const projection = {
130
+ configurationPath: authority.source,
131
+ connection,
132
+ project: {
133
+ lockfile: input.project.lockfile, sha256: input.project.sha256, driverVersion: input.project.driverVersion,
134
+ ...(input.project.manifest === undefined ? {} : { manifest: input.project.manifest, manifestSha256: input.project.manifestSha256 }),
135
+ },
136
+ mcp: { image: input.images.mcp.reference, ...(connection.kind === 'remote' ? { endpoint: connection.endpoint } : {}) },
137
+ server: { ...proxy.server, maxClients: browserClientLimit(input.maxClients, input.authentication.policy), engine, headless: true },
138
+ proxy: proxy.proxy,
139
+ addressing: { posture: addressing, resolverRules: addressing === 'hostname' ? input.resolver.map(({ hostname, address }) => `MAP ${hostname} ${address}`) : null },
140
+ requirements: authority.postureRequirements,
141
+ authentication: signedOut
142
+ ? { posture: signedOut, policy: 'none', states: [] }
143
+ : { posture: 'real', policy: input.authentication.policy, states: states.map((state) => ({ ...state })), claim: input.authentication.policy === 'serialized' ? 'exclusive' : 'per-worker' },
144
+ preapproval: input.requestPreapproval ? 'eligible' : 'not-requested',
145
+ networkExposure: networkExposure.value,
146
+ ...(networkExposure.reason ? { networkExposureReason: networkExposure.reason } : {}),
147
+ generatedHostPaths: paths,
148
+ cliArtifactRoot: input.artifacts.cli,
149
+ };
150
+ issuedRuntimes.set(projection, Object.freeze({ storage: Object.freeze(storage), stackId: authority.stackId,
151
+ ...(namespace ? { coordination: Object.freeze({ namespace, stackId: authority.stackId }) } : {}) }));
152
+ return projection;
153
+ }
154
+ function controlAuthority(value, defaultPort) {
155
+ const parsed = new URL(value.includes('://') ? value : `http://${value}`);
156
+ return `${parsed.hostname}:${parsed.port || defaultPort}`;
157
+ }
158
+ export function browserRuntimeControlAuthorities(runtime) {
159
+ if (!issuedRuntimes.has(runtime))
160
+ return undefined;
161
+ return [...new Set([
162
+ ...(runtime.connection.kind === 'remote' ? [controlAuthority(runtime.connection.endpoint, 80),
163
+ `127.0.0.1:${runtime.server.port}`, `localhost:${runtime.server.port}`] : []),
164
+ ...runtime.proxy.allowedHosts.map(value => controlAuthority(value, 80)),
165
+ ])];
166
+ }
167
+ export function browserRuntimeControlPorts(runtime) {
168
+ if (!issuedRuntimes.has(runtime))
169
+ return undefined;
170
+ return runtime.connection.kind === 'remote' ? [runtime.server.port] : [];
171
+ }
172
+ export function browserRuntimeCoordination(runtime) {
173
+ return issuedRuntimes.get(runtime)?.coordination;
174
+ }
175
+ export function assertBrowserStorageStateCurrent(runtime) {
176
+ const binding = issuedRuntimes.get(runtime);
177
+ if (!binding)
178
+ throw new RefusalError('browser storage state revalidation requires an issued runtime');
179
+ for (const state of binding.storage) {
180
+ if (storageIdentity(state.path) !== state.identity)
181
+ throw new RefusalError('browser seeded storage state changed after resolution');
182
+ }
183
+ }
@@ -0,0 +1,141 @@
1
+ import { type HolderId, type StackId } from '../environment/contract.js';
2
+ import { type ExecuteProbeOutcome } from '../environment-exec/execute.js';
3
+ import { type StateNamespace } from '../environment/state.js';
4
+ import type { RenderedSurfaceFile } from '../surfaces/contract.js';
5
+ import { type GuardSurfaceTarget } from '../surfaces/harness-registry.js';
6
+ import { type McpDeclaration } from '../surfaces/mcp.js';
7
+ import { type BrowserRuntimeProjection } from './runtime.js';
8
+ export type BrowserTestPackage = Readonly<{
9
+ directory: string;
10
+ manifest: {
11
+ readonly bytes: string;
12
+ readonly sha256: string;
13
+ };
14
+ cli: {
15
+ readonly path: string;
16
+ readonly bytes: string;
17
+ readonly sha256: string;
18
+ };
19
+ }> & (Readonly<{
20
+ artifactRoot?: never;
21
+ module?: never;
22
+ }> | Readonly<{
23
+ artifactRoot: string;
24
+ module: {
25
+ readonly path: string;
26
+ readonly bytes: string;
27
+ readonly sha256: string;
28
+ };
29
+ }>);
30
+ export interface BrowserSurfaceInput {
31
+ readonly runtime: BrowserRuntimeProjection;
32
+ readonly cockpitDirectory: string;
33
+ readonly harnesses: readonly {
34
+ readonly target: GuardSurfaceTarget;
35
+ readonly version: string;
36
+ }[];
37
+ readonly mcp: McpDeclaration;
38
+ readonly approved: boolean;
39
+ readonly testPackage: BrowserTestPackage | null;
40
+ readonly skillTemplate: string;
41
+ }
42
+ export interface BrowserTransportRow {
43
+ readonly target: GuardSurfaceTarget;
44
+ readonly version: string;
45
+ readonly transport: 'mcp' | 'cli';
46
+ readonly measuredOn: string;
47
+ readonly measuredVersion: string;
48
+ readonly declaration: 'instructed' | 'unavailable';
49
+ readonly callable: 'human_needed' | 'unavailable';
50
+ readonly productState: 'instructed';
51
+ readonly reason: string;
52
+ readonly tool: string | null;
53
+ readonly cli: Readonly<{
54
+ package: '@playwright/test';
55
+ version: string;
56
+ argv: readonly string[];
57
+ sha256: string;
58
+ }> | null;
59
+ }
60
+ export interface BrowserProjectClient {
61
+ readonly package: '@playwright/test';
62
+ readonly target: GuardSurfaceTarget;
63
+ readonly version: string;
64
+ readonly cwd: string;
65
+ readonly artifactRoot: string;
66
+ readonly node: Readonly<{
67
+ path: string;
68
+ sha256: string;
69
+ maxBytes: number;
70
+ }>;
71
+ readonly module: Readonly<{
72
+ path: string;
73
+ sha256: string;
74
+ maxBytes: number;
75
+ }>;
76
+ readonly manifest: Readonly<{
77
+ path: string;
78
+ sha256: string;
79
+ maxBytes: number;
80
+ }>;
81
+ readonly lock: Readonly<{
82
+ path: string;
83
+ sha256: string;
84
+ maxBytes: number;
85
+ }>;
86
+ }
87
+ export interface BrowserProjectOperation {
88
+ readonly kind: 'drive' | 'screenshot';
89
+ readonly surface: Readonly<{
90
+ name: string;
91
+ url: string;
92
+ }>;
93
+ readonly deadline: number;
94
+ readonly role?: string;
95
+ readonly output?: string;
96
+ }
97
+ export interface BrowserProjectOperationAuthorization {
98
+ readonly kind: 'browser-project-operation-authorization';
99
+ }
100
+ export interface BrowserProjectOperationAdmissionInput {
101
+ readonly origin: string;
102
+ readonly role?: string;
103
+ readonly state?: Readonly<{
104
+ namespace: StateNamespace;
105
+ stackId: StackId;
106
+ ownerId: HolderId;
107
+ }>;
108
+ }
109
+ /** The harness version each target's browser transport spelling was measured at, for diagnostics. */
110
+ export declare function measuredBrowserHarnessVersions(): Readonly<Record<GuardSurfaceTarget, string>>;
111
+ export declare function observeBrowserProjectPackage(input: Readonly<{
112
+ runtime: BrowserRuntimeProjection;
113
+ cockpitDirectory: string;
114
+ artifactRoot: string;
115
+ }>): BrowserTestPackage;
116
+ export declare function authenticateBrowserProjectClient(value: unknown, runtime: BrowserRuntimeProjection): BrowserProjectClient | undefined;
117
+ export type BrowserProjectOperationNotAdmitted = Readonly<{
118
+ kind: 'unadmitted';
119
+ cause: string;
120
+ }>;
121
+ export declare function executeBrowserProjectOperation(client: BrowserProjectClient, runtime: BrowserRuntimeProjection, input: BrowserProjectOperation, authorization?: BrowserProjectOperationAuthorization): Promise<ExecuteProbeOutcome | BrowserProjectOperationNotAdmitted | undefined>;
122
+ type BrowserProjectOperationAdmissionResult<T> = Readonly<{
123
+ kind: 'admitted';
124
+ value: T;
125
+ }> | Readonly<{
126
+ kind: 'refusal';
127
+ reason: string;
128
+ }>;
129
+ export declare function withBrowserProjectOperationAdmission<T>(client: BrowserProjectClient, runtime: BrowserRuntimeProjection, input: BrowserProjectOperationAdmissionInput, operation: (authorization: BrowserProjectOperationAuthorization) => Promise<T>): Promise<BrowserProjectOperationAdmissionResult<T>>;
130
+ export declare function renderBrowserSurfaces(input: BrowserSurfaceInput): {
131
+ rows: BrowserTransportRow[];
132
+ files: RenderedSurfaceFile[];
133
+ mcp: Readonly<{
134
+ kind: 'complete';
135
+ result: import("../surfaces/mcp.js").McpCollection;
136
+ diagnostics: readonly import("../surfaces/mcp.js").McpDiagnostic[];
137
+ }>;
138
+ clients: BrowserProjectClient[];
139
+ graderBrowserAccess: 'retained';
140
+ };
141
+ export {};