@b00dea/cockpit 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 (426) hide show
  1. package/CHANGELOG.md +474 -0
  2. package/LICENSE +21 -0
  3. package/README.md +25 -2
  4. package/bin/cockpit.mjs +33 -0
  5. package/cockpit.schema.json +2644 -0
  6. package/dist/autonomy.d.ts +45 -0
  7. package/dist/autonomy.js +173 -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 +117 -0
  11. package/dist/browser/commands.js +453 -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 +118 -0
  17. package/dist/browser/runtime.js +186 -0
  18. package/dist/browser/surfaces.d.ts +141 -0
  19. package/dist/browser/surfaces.js +561 -0
  20. package/dist/browser/ui-gate.d.ts +15 -0
  21. package/dist/browser/ui-gate.js +18 -0
  22. package/dist/canonical-json.d.ts +2 -0
  23. package/dist/canonical-json.js +5 -0
  24. package/dist/cli-guard.d.ts +5 -0
  25. package/dist/cli-guard.js +71 -0
  26. package/dist/cli-main.d.ts +176 -0
  27. package/dist/cli-main.js +1584 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.js +16 -0
  30. package/dist/command-table.d.ts +121 -0
  31. package/dist/command-table.js +664 -0
  32. package/dist/config/load.d.ts +183 -0
  33. package/dist/config/load.js +367 -0
  34. package/dist/config/sibling-toml.d.ts +48 -0
  35. package/dist/config/sibling-toml.js +160 -0
  36. package/dist/config/surface-tools-toml.d.ts +9 -0
  37. package/dist/config/surface-tools-toml.js +37 -0
  38. package/dist/config/unconfirmed-toml.d.ts +9 -0
  39. package/dist/config/unconfirmed-toml.js +29 -0
  40. package/dist/config/verified-write.d.ts +43 -0
  41. package/dist/config/verified-write.js +89 -0
  42. package/dist/diagnostics.d.ts +26 -0
  43. package/dist/diagnostics.js +344 -0
  44. package/dist/docs/check.d.ts +16 -0
  45. package/dist/docs/check.js +197 -0
  46. package/dist/docs/decision-record.d.ts +34 -0
  47. package/dist/docs/decision-record.js +135 -0
  48. package/dist/docs/decisions.d.ts +16 -0
  49. package/dist/docs/decisions.js +103 -0
  50. package/dist/docs/markdown.d.ts +36 -0
  51. package/dist/docs/markdown.js +88 -0
  52. package/dist/docs/references.d.ts +32 -0
  53. package/dist/docs/references.js +148 -0
  54. package/dist/emit.d.ts +22 -0
  55. package/dist/emit.js +43 -0
  56. package/dist/entrypoint-kinds.d.ts +3 -0
  57. package/dist/entrypoint-kinds.js +11 -0
  58. package/dist/environment/application/confirm.d.ts +35 -0
  59. package/dist/environment/application/confirm.js +122 -0
  60. package/dist/environment/application/destructive.d.ts +6 -0
  61. package/dist/environment/application/destructive.js +429 -0
  62. package/dist/environment/application/doctor.d.ts +94 -0
  63. package/dist/environment/application/doctor.js +247 -0
  64. package/dist/environment/application/guard.d.ts +49 -0
  65. package/dist/environment/application/guard.js +677 -0
  66. package/dist/environment/application/health.d.ts +143 -0
  67. package/dist/environment/application/health.js +385 -0
  68. package/dist/environment/application/lifecycle-context.d.ts +235 -0
  69. package/dist/environment/application/lifecycle-context.js +154 -0
  70. package/dist/environment/application/lifecycle-state.d.ts +25 -0
  71. package/dist/environment/application/lifecycle-state.js +202 -0
  72. package/dist/environment/application/lifecycle.d.ts +18 -0
  73. package/dist/environment/application/lifecycle.js +737 -0
  74. package/dist/environment/application/logs.d.ts +45 -0
  75. package/dist/environment/application/logs.js +127 -0
  76. package/dist/environment/application/services.d.ts +60 -0
  77. package/dist/environment/application/services.js +89 -0
  78. package/dist/environment/application/setup.d.ts +129 -0
  79. package/dist/environment/application/setup.js +741 -0
  80. package/dist/environment/application/shared.d.ts +11 -0
  81. package/dist/environment/application/shared.js +61 -0
  82. package/dist/environment/application/siblings.d.ts +43 -0
  83. package/dist/environment/application/siblings.js +269 -0
  84. package/dist/environment/claims.d.ts +389 -0
  85. package/dist/environment/claims.js +1701 -0
  86. package/dist/environment/codex-hook-trust.d.ts +11 -0
  87. package/dist/environment/codex-hook-trust.js +185 -0
  88. package/dist/environment/compose-environment.d.ts +1 -0
  89. package/dist/environment/compose-environment.js +6 -0
  90. package/dist/environment/compose-ownership.d.ts +21 -0
  91. package/dist/environment/compose-ownership.js +117 -0
  92. package/dist/environment/compose-topology.d.ts +125 -0
  93. package/dist/environment/compose-topology.js +490 -0
  94. package/dist/environment/contract.d.ts +522 -0
  95. package/dist/environment/contract.js +794 -0
  96. package/dist/environment/declaration.d.ts +14 -0
  97. package/dist/environment/declaration.js +39 -0
  98. package/dist/environment/destructive-composition.d.ts +29 -0
  99. package/dist/environment/destructive-composition.js +333 -0
  100. package/dist/environment/docker-daemon.d.ts +30 -0
  101. package/dist/environment/docker-daemon.js +78 -0
  102. package/dist/environment/docker-endpoint.d.ts +10 -0
  103. package/dist/environment/docker-endpoint.js +19 -0
  104. package/dist/environment/env-schema-observation.d.ts +46 -0
  105. package/dist/environment/env-schema-observation.js +241 -0
  106. package/dist/environment/evidence.d.ts +136 -0
  107. package/dist/environment/evidence.js +437 -0
  108. package/dist/environment/executable.d.ts +38 -0
  109. package/dist/environment/executable.js +190 -0
  110. package/dist/environment/generated-application/authorities.d.ts +5 -0
  111. package/dist/environment/generated-application/authorities.js +61 -0
  112. package/dist/environment/generated-application/bootstrap-skill.d.ts +16 -0
  113. package/dist/environment/generated-application/bootstrap-skill.js +328 -0
  114. package/dist/environment/generated-application/check.d.ts +13 -0
  115. package/dist/environment/generated-application/check.js +191 -0
  116. package/dist/environment/generated-application/custom-surface.d.ts +26 -0
  117. package/dist/environment/generated-application/custom-surface.js +289 -0
  118. package/dist/environment/generated-application/prepare.d.ts +29 -0
  119. package/dist/environment/generated-application/prepare.js +278 -0
  120. package/dist/environment/generated-application/publication.d.ts +33 -0
  121. package/dist/environment/generated-application/publication.js +547 -0
  122. package/dist/environment/generated-application/shared.d.ts +492 -0
  123. package/dist/environment/generated-application/shared.js +354 -0
  124. package/dist/environment/generated-application/surface-observation.d.ts +4 -0
  125. package/dist/environment/generated-application/surface-observation.js +69 -0
  126. package/dist/environment/generated-application/surface-outputs.d.ts +71 -0
  127. package/dist/environment/generated-application/surface-outputs.js +400 -0
  128. package/dist/environment/generated-application/surfaces.d.ts +3 -0
  129. package/dist/environment/generated-application/surfaces.js +704 -0
  130. package/dist/environment/generated-application/sync.d.ts +6 -0
  131. package/dist/environment/generated-application/sync.js +124 -0
  132. package/dist/environment/git-observation.d.ts +202 -0
  133. package/dist/environment/git-observation.js +553 -0
  134. package/dist/environment/health-composition.d.ts +12 -0
  135. package/dist/environment/health-composition.js +645 -0
  136. package/dist/environment/host-observation.d.ts +56 -0
  137. package/dist/environment/host-observation.js +52 -0
  138. package/dist/environment/identity.d.ts +48 -0
  139. package/dist/environment/identity.js +85 -0
  140. package/dist/environment/init-application.d.ts +333 -0
  141. package/dist/environment/init-application.js +726 -0
  142. package/dist/environment/install-policy-observation.d.ts +71 -0
  143. package/dist/environment/install-policy-observation.js +284 -0
  144. package/dist/environment/install-policy.d.ts +48 -0
  145. package/dist/environment/install-policy.js +96 -0
  146. package/dist/environment/instance.d.ts +33 -0
  147. package/dist/environment/instance.js +122 -0
  148. package/dist/environment/instruction-pointer.d.ts +19 -0
  149. package/dist/environment/instruction-pointer.js +144 -0
  150. package/dist/environment/lifecycle-composition.d.ts +31 -0
  151. package/dist/environment/lifecycle-composition.js +742 -0
  152. package/dist/environment/lifecycle-stage.d.ts +120 -0
  153. package/dist/environment/lifecycle-stage.js +408 -0
  154. package/dist/environment/lifecycle.d.ts +75 -0
  155. package/dist/environment/lifecycle.js +354 -0
  156. package/dist/environment/logs.d.ts +132 -0
  157. package/dist/environment/logs.js +519 -0
  158. package/dist/environment/map-limit.d.ts +2 -0
  159. package/dist/environment/map-limit.js +13 -0
  160. package/dist/environment/mcp-observation.d.ts +9 -0
  161. package/dist/environment/mcp-observation.js +46 -0
  162. package/dist/environment/observations.d.ts +46 -0
  163. package/dist/environment/observations.js +346 -0
  164. package/dist/environment/operator-application.d.ts +79 -0
  165. package/dist/environment/operator-application.js +197 -0
  166. package/dist/environment/ports.d.ts +182 -0
  167. package/dist/environment/ports.js +1205 -0
  168. package/dist/environment/posture-observation.d.ts +68 -0
  169. package/dist/environment/posture-observation.js +253 -0
  170. package/dist/environment/presence.d.ts +4 -0
  171. package/dist/environment/presence.js +26 -0
  172. package/dist/environment/read-composition.d.ts +32 -0
  173. package/dist/environment/read-composition.js +397 -0
  174. package/dist/environment/readiness-composition.d.ts +57 -0
  175. package/dist/environment/readiness-composition.js +151 -0
  176. package/dist/environment/reclaim.d.ts +370 -0
  177. package/dist/environment/reclaim.js +1940 -0
  178. package/dist/environment/repository-identity.d.ts +13 -0
  179. package/dist/environment/repository-identity.js +108 -0
  180. package/dist/environment/runtime-measurement-record.d.ts +38 -0
  181. package/dist/environment/runtime-measurement-record.js +111 -0
  182. package/dist/environment/runtime-measurement.d.ts +27 -0
  183. package/dist/environment/runtime-measurement.js +224 -0
  184. package/dist/environment/runtime-probe-residue.d.ts +43 -0
  185. package/dist/environment/runtime-probe-residue.js +148 -0
  186. package/dist/environment/runtime-probe.d.ts +72 -0
  187. package/dist/environment/runtime-probe.js +725 -0
  188. package/dist/environment/runtime.d.ts +551 -0
  189. package/dist/environment/runtime.js +2405 -0
  190. package/dist/environment/seed.d.ts +16 -0
  191. package/dist/environment/seed.js +43 -0
  192. package/dist/environment/selftest-application.d.ts +86 -0
  193. package/dist/environment/selftest-application.js +713 -0
  194. package/dist/environment/sensitive.d.ts +3 -0
  195. package/dist/environment/sensitive.js +48 -0
  196. package/dist/environment/served-checkout-grants.d.ts +53 -0
  197. package/dist/environment/served-checkout-grants.js +182 -0
  198. package/dist/environment/setup-observation.d.ts +62 -0
  199. package/dist/environment/setup-observation.js +1473 -0
  200. package/dist/environment/setup.d.ts +43 -0
  201. package/dist/environment/setup.js +176 -0
  202. package/dist/environment/sibling-checkouts.d.ts +119 -0
  203. package/dist/environment/sibling-checkouts.js +254 -0
  204. package/dist/environment/sibling-instructions.d.ts +33 -0
  205. package/dist/environment/sibling-instructions.js +224 -0
  206. package/dist/environment/sibling-observation.d.ts +27 -0
  207. package/dist/environment/sibling-observation.js +45 -0
  208. package/dist/environment/sibling-pull.d.ts +23 -0
  209. package/dist/environment/sibling-pull.js +95 -0
  210. package/dist/environment/sibling-registration.d.ts +45 -0
  211. package/dist/environment/sibling-registration.js +538 -0
  212. package/dist/environment/stack-inputs.d.ts +18 -0
  213. package/dist/environment/stack-inputs.js +210 -0
  214. package/dist/environment/stack-inventory-prune.d.ts +31 -0
  215. package/dist/environment/stack-inventory-prune.js +129 -0
  216. package/dist/environment/stack-inventory-report.d.ts +44 -0
  217. package/dist/environment/stack-inventory-report.js +78 -0
  218. package/dist/environment/stack-inventory.d.ts +94 -0
  219. package/dist/environment/stack-inventory.js +418 -0
  220. package/dist/environment/state.d.ts +410 -0
  221. package/dist/environment/state.js +2153 -0
  222. package/dist/environment/templates.d.ts +140 -0
  223. package/dist/environment/templates.js +685 -0
  224. package/dist/environment/tool-registration.d.ts +9 -0
  225. package/dist/environment/tool-registration.js +92 -0
  226. package/dist/environment/upgrade-application.d.ts +19 -0
  227. package/dist/environment/upgrade-application.js +175 -0
  228. package/dist/environment-exec/execute.d.ts +105 -0
  229. package/dist/environment-exec/execute.js +1179 -0
  230. package/dist/environment-exec/libexec-program.d.ts +6 -0
  231. package/dist/environment-exec/libexec-program.js +22 -0
  232. package/dist/environment-exec/verified-digest.d.ts +4 -0
  233. package/dist/environment-exec/verified-digest.js +16 -0
  234. package/dist/exact-keys.d.ts +7 -0
  235. package/dist/exact-keys.js +15 -0
  236. package/dist/fix-catalogue.d.ts +32 -0
  237. package/dist/fix-catalogue.js +60 -0
  238. package/dist/freshness.d.ts +29 -0
  239. package/dist/freshness.js +75 -0
  240. package/dist/generated-environment/adopt.d.ts +16 -0
  241. package/dist/generated-environment/adopt.js +271 -0
  242. package/dist/generated-environment/command.d.ts +47 -0
  243. package/dist/generated-environment/command.js +75 -0
  244. package/dist/generated-environment/transaction.d.ts +186 -0
  245. package/dist/generated-environment/transaction.js +1770 -0
  246. package/dist/grading/evaluate.d.ts +71 -0
  247. package/dist/grading/evaluate.js +403 -0
  248. package/dist/grading/grade.d.ts +33 -0
  249. package/dist/grading/grade.js +57 -0
  250. package/dist/guards/answer-confirmation.d.ts +41 -0
  251. package/dist/guards/answer-confirmation.js +109 -0
  252. package/dist/guards/evaluator.d.ts +130 -0
  253. package/dist/guards/evaluator.js +1258 -0
  254. package/dist/guards/harness-adapter.d.ts +17 -0
  255. package/dist/guards/harness-adapter.js +57 -0
  256. package/dist/guards/host.d.ts +8 -0
  257. package/dist/guards/host.js +10 -0
  258. package/dist/guards/invocation-parser.d.ts +66 -0
  259. package/dist/guards/invocation-parser.js +595 -0
  260. package/dist/guards/local-identity.d.ts +44 -0
  261. package/dist/guards/local-identity.js +129 -0
  262. package/dist/guards/policy-change.d.ts +43 -0
  263. package/dist/guards/policy-change.js +159 -0
  264. package/dist/guards/policy-pin.d.ts +13 -0
  265. package/dist/guards/policy-pin.js +177 -0
  266. package/dist/guards/protected-locations.d.ts +62 -0
  267. package/dist/guards/protected-locations.js +461 -0
  268. package/dist/guards/read-only.d.ts +37 -0
  269. package/dist/guards/read-only.js +315 -0
  270. package/dist/init/command.d.ts +41 -0
  271. package/dist/init/command.js +330 -0
  272. package/dist/init/derive.d.ts +53 -0
  273. package/dist/init/derive.js +819 -0
  274. package/dist/init/draft.d.ts +140 -0
  275. package/dist/init/draft.js +1228 -0
  276. package/dist/init/render.d.ts +47 -0
  277. package/dist/init/render.js +104 -0
  278. package/dist/init/scaffold.d.ts +53 -0
  279. package/dist/init/scaffold.js +121 -0
  280. package/dist/invocation.d.ts +13 -0
  281. package/dist/invocation.js +20 -0
  282. package/dist/package-metadata.d.ts +9 -0
  283. package/dist/package-metadata.js +19 -0
  284. package/dist/readiness.d.ts +53 -0
  285. package/dist/readiness.js +88 -0
  286. package/dist/references/named.d.ts +24 -0
  287. package/dist/references/named.js +27 -0
  288. package/dist/refusal.d.ts +15 -0
  289. package/dist/refusal.js +7 -0
  290. package/dist/registry-derivation.d.ts +31 -0
  291. package/dist/registry-derivation.js +32 -0
  292. package/dist/registry-resolve/command.d.ts +47 -0
  293. package/dist/registry-resolve/command.js +226 -0
  294. package/dist/registry-resolve/registry.d.ts +68 -0
  295. package/dist/registry-resolve/registry.js +292 -0
  296. package/dist/registry-resolve/render-shell.d.ts +18 -0
  297. package/dist/registry-resolve/render-shell.js +36 -0
  298. package/dist/repair.d.ts +29 -0
  299. package/dist/repair.js +8 -0
  300. package/dist/repository-path.d.ts +9 -0
  301. package/dist/repository-path.js +16 -0
  302. package/dist/schema-json.d.ts +1 -0
  303. package/dist/schema-json.js +177 -0
  304. package/dist/schema.d.ts +1289 -0
  305. package/dist/schema.js +985 -0
  306. package/dist/setup/command.d.ts +4 -0
  307. package/dist/setup/command.js +4 -0
  308. package/dist/sha256.d.ts +1 -0
  309. package/dist/sha256.js +4 -0
  310. package/dist/surfaces/adoption.d.ts +41 -0
  311. package/dist/surfaces/adoption.js +217 -0
  312. package/dist/surfaces/consumer-instructions.d.ts +20 -0
  313. package/dist/surfaces/consumer-instructions.js +43 -0
  314. package/dist/surfaces/contract.d.ts +42 -0
  315. package/dist/surfaces/contract.js +169 -0
  316. package/dist/surfaces/core-declarations.d.ts +24 -0
  317. package/dist/surfaces/core-declarations.js +79 -0
  318. package/dist/surfaces/development-markers.d.ts +1 -0
  319. package/dist/surfaces/development-markers.js +18 -0
  320. package/dist/surfaces/generator-adapter.d.ts +71 -0
  321. package/dist/surfaces/generator-adapter.js +809 -0
  322. package/dist/surfaces/harness-registry.d.ts +260 -0
  323. package/dist/surfaces/harness-registry.js +146 -0
  324. package/dist/surfaces/mcp.d.ts +145 -0
  325. package/dist/surfaces/mcp.js +349 -0
  326. package/dist/surfaces/merge.d.ts +30 -0
  327. package/dist/surfaces/merge.js +105 -0
  328. package/dist/surfaces/ownership.d.ts +190 -0
  329. package/dist/surfaces/ownership.js +795 -0
  330. package/dist/surfaces/projection.d.ts +136 -0
  331. package/dist/surfaces/projection.js +716 -0
  332. package/dist/surfaces/render.d.ts +79 -0
  333. package/dist/surfaces/render.js +636 -0
  334. package/dist/surfaces/restrictions.d.ts +130 -0
  335. package/dist/surfaces/restrictions.js +447 -0
  336. package/dist/surfaces/selftest.d.ts +162 -0
  337. package/dist/surfaces/selftest.js +393 -0
  338. package/dist/surfaces/skill-contract.d.ts +85 -0
  339. package/dist/surfaces/skill-contract.js +449 -0
  340. package/dist/surfaces/sync.d.ts +57 -0
  341. package/dist/surfaces/sync.js +164 -0
  342. package/dist/team-metadata.d.ts +41 -0
  343. package/dist/team-metadata.js +513 -0
  344. package/dist/testing/gates.d.ts +91 -0
  345. package/dist/testing/gates.js +182 -0
  346. package/dist/testing/hooks.d.ts +59 -0
  347. package/dist/testing/hooks.js +139 -0
  348. package/dist/testing/test-protection.d.ts +34 -0
  349. package/dist/testing/test-protection.js +137 -0
  350. package/dist/testing/verdict.d.ts +29 -0
  351. package/dist/testing/verdict.js +62 -0
  352. package/dist/testing/weakening.d.ts +15 -0
  353. package/dist/testing/weakening.js +30 -0
  354. package/dist/work-orders/application-closure.d.ts +7 -0
  355. package/dist/work-orders/application-closure.js +76 -0
  356. package/dist/work-orders/application-context.d.ts +162 -0
  357. package/dist/work-orders/application-context.js +137 -0
  358. package/dist/work-orders/application-decisions.d.ts +27 -0
  359. package/dist/work-orders/application-decisions.js +121 -0
  360. package/dist/work-orders/application-grading.d.ts +11 -0
  361. package/dist/work-orders/application-grading.js +212 -0
  362. package/dist/work-orders/application.d.ts +6 -0
  363. package/dist/work-orders/application.js +223 -0
  364. package/dist/work-orders/composition.d.ts +101 -0
  365. package/dist/work-orders/composition.js +1202 -0
  366. package/dist/work-orders/contract.d.ts +77 -0
  367. package/dist/work-orders/contract.js +140 -0
  368. package/dist/work-orders/decisions.d.ts +23 -0
  369. package/dist/work-orders/decisions.js +55 -0
  370. package/dist/work-orders/store.d.ts +207 -0
  371. package/dist/work-orders/store.js +291 -0
  372. package/docs/README.md +68 -0
  373. package/docs/architecture.md +136 -0
  374. package/docs/capability-matrix.md +58 -0
  375. package/docs/cli-reference.md +807 -0
  376. package/docs/command-list.md +62 -0
  377. package/docs/compose-patterns.md +99 -0
  378. package/docs/concepts.md +173 -0
  379. package/docs/configuration-essentials.md +177 -0
  380. package/docs/configuration-reference.md +636 -0
  381. package/docs/docs-check.md +76 -0
  382. package/docs/environment.md +948 -0
  383. package/docs/extending.md +43 -0
  384. package/docs/faq.md +113 -0
  385. package/docs/getting-started.md +692 -0
  386. package/docs/harness-surfaces.md +500 -0
  387. package/docs/joining-a-team.md +76 -0
  388. package/docs/release-policy.md +49 -0
  389. package/docs/safety-and-autonomy.md +463 -0
  390. package/docs/troubleshooting.md +382 -0
  391. package/docs/tutorial.md +171 -0
  392. package/docs/work-and-browser.md +420 -0
  393. package/libexec/browser-operation.cjs +270 -0
  394. package/libexec/fence-marker.cjs +101 -0
  395. package/libexec/fence-marker.d.cts +24 -0
  396. package/libexec/fenced-group-runner.cjs +77 -0
  397. package/libexec/fenced-supervisor.cjs +137 -0
  398. package/libexec/generated-filesystem.cjs +731 -0
  399. package/libexec/install-filesystem.cjs +225 -0
  400. package/libexec/rulesync-generator.NOTICE.md +1112 -0
  401. package/libexec/rulesync-generator.cjs +743 -0
  402. package/libexec/surface-generator-worker.cjs +266 -0
  403. package/libexec/surface-output-reader.cjs +99 -0
  404. package/libexec/surface-scratch-cleanup.cjs +14 -0
  405. package/libexec/validate-harness-evidence.d.mts +183 -0
  406. package/libexec/validate-harness-evidence.mjs +1312 -0
  407. package/package.json +74 -4
  408. package/surfaces/README.md +33 -0
  409. package/surfaces/agents/evaluator.agent.md +76 -0
  410. package/surfaces/guards/bash-guard.sh +48 -0
  411. package/surfaces/guards/claude.adapter.json +25 -0
  412. package/surfaces/guards/codex.adapter.json +24 -0
  413. package/surfaces/guards/opencode.adapter.json +25 -0
  414. package/surfaces/references/browser.md +63 -0
  415. package/surfaces/references/test-data-and-personas.md +84 -0
  416. package/surfaces/references/testing-tiers.md +11 -0
  417. package/surfaces/skills/cockpit-browser.skill.md +59 -0
  418. package/surfaces/skills/cockpit-explain.skill.md +32 -0
  419. package/surfaces/skills/cockpit-fix.skill.md +37 -0
  420. package/surfaces/skills/cockpit-setup.skill.md +39 -0
  421. package/surfaces/skills/cockpit-work.skill.md +34 -0
  422. package/surfaces/skills/collection.json +5 -0
  423. package/surfaces/skills/procedures/explain.md +66 -0
  424. package/surfaces/skills/procedures/fix.md +95 -0
  425. package/surfaces/skills/procedures/setup.md +452 -0
  426. package/surfaces/skills/procedures/work.md +134 -0
@@ -0,0 +1,183 @@
1
+ import { type ConfigSourceSnapshot, type EnvironmentCommandOutcome, type EnvironmentDiagnostic, type SourceProvenance } from '../environment/contract.js';
2
+ import { type EffectivePolicy } from '../autonomy.js';
3
+ import { browserDataQualifies, CockpitConfig, type EvaluatorTool } from '../schema.js';
4
+ /** An explicit request_preapproval wins; otherwise preapproval follows the declared data posture. */
5
+ export declare const browserPreapprovalRequested: (browser: Readonly<{
6
+ request_preapproval?: boolean | undefined;
7
+ data: Parameters<typeof browserDataQualifies>[0];
8
+ }>) => boolean;
9
+ import { type BoundedRead } from '../bounded-read.js';
10
+ export declare const STRUCTURED_INPUT_BYTE_LIMIT = 1048576;
11
+ type BoundedInputRead = BoundedRead;
12
+ export declare function readBoundedInput(path: string): Promise<BoundedInputRead>;
13
+ declare const loadedConfigProjectionBrand: unique symbol;
14
+ export type LoadedConfigProjection = LoadedCockpitConfig;
15
+ export interface ConsumedLoadedConfig {
16
+ readonly config: CockpitConfig;
17
+ readonly source: SourceProvenance;
18
+ /** Identifies the stack this configuration runs; `source.sha256` identifies the file that was read. */
19
+ readonly runtimeSha256: string;
20
+ readonly guardHostsStated: boolean;
21
+ }
22
+ export interface LoadedCockpitConfig {
23
+ readonly config: CockpitConfig;
24
+ readonly source: SourceProvenance;
25
+ /** Identifies the stack this configuration runs; `source.sha256` identifies the file that was read. */
26
+ readonly runtimeSha256: string;
27
+ /**
28
+ * Both guard host keys are written in the file. The schema defaults an absent key to the same
29
+ * empty list, so only the parsed source can tell "none exists" from "never answered".
30
+ */
31
+ readonly guardHostsStated: boolean;
32
+ readonly [loadedConfigProjectionBrand]: never;
33
+ }
34
+ export interface MachineFloorConfigProjection {
35
+ readonly kind: 'machine-floor-config-projection';
36
+ }
37
+ interface ConsumedMachineFloorConfig {
38
+ readonly cockpitName: string;
39
+ readonly source: SourceProvenance;
40
+ readonly runtimeSha256: string;
41
+ readonly floor: Readonly<{
42
+ runtimeMemoryMb: number;
43
+ runtimeCpus: number;
44
+ freeDiskMb: number;
45
+ }>;
46
+ }
47
+ interface WorkEnvironmentConfigProjection {
48
+ readonly kind: 'work-environment-config-projection';
49
+ }
50
+ export interface ConsumedWorkEnvironmentConfig {
51
+ readonly cockpitName: string;
52
+ readonly cockpitRoot: string;
53
+ readonly siblingsRoot: string;
54
+ readonly source: SourceProvenance;
55
+ readonly siblings: readonly Readonly<{
56
+ slug: string;
57
+ dir: string;
58
+ environmentFiles: readonly Readonly<{
59
+ template: string;
60
+ instance: string;
61
+ }>[];
62
+ }>[];
63
+ readonly policy: EffectivePolicy;
64
+ readonly wipCap: number;
65
+ readonly attemptCap: number;
66
+ readonly verificationTimeoutSeconds: number;
67
+ readonly evaluatorTimeoutSeconds: number;
68
+ readonly evaluators: readonly EvaluatorTool[];
69
+ /** False when the order is the surfaces.tools default, which the command may reorder for the tool running it. */
70
+ readonly evaluatorsDeclared: boolean;
71
+ readonly generatedHostPaths: readonly string[];
72
+ readonly browser?: ReturnType<typeof projectBrowserConfig>;
73
+ readonly testing?: ReturnType<typeof projectTestingConfig>;
74
+ readonly docs?: Readonly<{
75
+ decisions?: string;
76
+ decisionsIndex?: string;
77
+ }>;
78
+ }
79
+ declare function projectBrowserConfig(declaredBrowser: NonNullable<CockpitConfig['browser']>): {
80
+ engine: "chromium" | "firefox" | "webkit";
81
+ networkExposure: string;
82
+ networkExposureReason?: string | undefined;
83
+ harnesses: {
84
+ target: "claudecode" | "codexcli" | "opencode";
85
+ version: string;
86
+ }[];
87
+ images: {
88
+ mcp: {
89
+ reference: string;
90
+ driverVersion: string;
91
+ };
92
+ };
93
+ project: {
94
+ lockfile: string;
95
+ sha256: string;
96
+ driverVersion: string;
97
+ manifest?: string | undefined;
98
+ manifestSha256?: string | undefined;
99
+ };
100
+ endpoint?: string | undefined;
101
+ maxClients: number;
102
+ proxy: {
103
+ hostVariable?: string | undefined;
104
+ serverPort: number;
105
+ proxyPort: number;
106
+ allowedHosts: string[];
107
+ bind: "127.0.0.1" | "::1";
108
+ };
109
+ resolver: {
110
+ hostname: string;
111
+ address: string;
112
+ }[];
113
+ authentication: {
114
+ policy: "none" | "per-worker" | "serialized";
115
+ states: {
116
+ worker: string;
117
+ path: string;
118
+ }[];
119
+ };
120
+ data: {
121
+ mode: "empty" | "restored" | "seeded";
122
+ isolated: boolean;
123
+ reachesProduction: boolean;
124
+ };
125
+ requestPreapproval: boolean;
126
+ artifacts: {
127
+ mcp: string;
128
+ cli: string;
129
+ auth: string;
130
+ };
131
+ };
132
+ declare function projectTestingConfig(declaredTesting: NonNullable<CockpitConfig['testing']>): {
133
+ declarations: {
134
+ stages: {
135
+ id: string;
136
+ command: [string, ...string[]];
137
+ requiresStack: boolean;
138
+ timeoutSeconds: number;
139
+ select?: {
140
+ [k: string]: string[];
141
+ } | undefined;
142
+ }[];
143
+ gates: {
144
+ id: string;
145
+ tier: "full" | "targeted";
146
+ stages: string[];
147
+ changes: string;
148
+ }[];
149
+ };
150
+ nativeHookInstall: "explicit-native" | "inspect";
151
+ testFiles?: string[] | undefined;
152
+ nativeHookPolicy?: {
153
+ path: string;
154
+ sha256: string;
155
+ } | undefined;
156
+ };
157
+ export declare function projectWorkEnvironmentConfig(configuration: LoadedConfigProjection): WorkEnvironmentConfigProjection | undefined;
158
+ export declare function consumeWorkEnvironmentConfigProjection(projection: WorkEnvironmentConfigProjection): ConsumedWorkEnvironmentConfig | undefined;
159
+ export declare function projectMachineFloorConfig(projection: LoadedConfigProjection): MachineFloorConfigProjection | undefined;
160
+ export declare function consumeMachineFloorConfigProjection(projection: MachineFloorConfigProjection): ConsumedMachineFloorConfig | undefined;
161
+ export declare function consumeLoadedConfigProjection(projection: LoadedConfigProjection): ConsumedLoadedConfig | undefined;
162
+ export declare function observeConfigSource(inputPath: string): Promise<ConfigSourceSnapshot>;
163
+ export declare function schemaIssueSummary(issues: readonly {
164
+ path: readonly PropertyKey[];
165
+ message: string;
166
+ }[], limit?: number): string;
167
+ /** The policy cockpit.toml declares now and the one the last sync recorded, for a command that gates a decision. */
168
+ export declare function loadAutonomyPolicy(configPath: string): Promise<Readonly<{
169
+ root: string;
170
+ current: EffectivePolicy;
171
+ recorded?: EffectivePolicy;
172
+ }> | Readonly<{
173
+ refusal: EnvironmentDiagnostic;
174
+ }>>;
175
+ /** The configuration `bytes` declare, or undefined when they are not UTF-8 TOML the schema accepts. */
176
+ export declare function parseCockpitConfigBytes(bytes: Uint8Array): CockpitConfig | undefined;
177
+ export declare function loadCockpitConfig(inputPath: string): Promise<EnvironmentCommandOutcome<LoadedCockpitConfig>>;
178
+ /**
179
+ * The evaluators work grade and cockpit grade try, in order. Left unset, they are the listed agent
180
+ * tools that can evaluate, so a team on one tool is never told to install another to grade.
181
+ */
182
+ export declare function evaluatorTools(config: Pick<CockpitConfig, 'work' | 'surfaces'>): readonly EvaluatorTool[];
183
+ export {};
@@ -0,0 +1,367 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { realpath } from 'node:fs/promises';
3
+ import { basename, dirname, join, resolve } from 'node:path';
4
+ import { parse, TomlError } from 'smol-toml';
5
+ import { RefusalError, ENVIRONMENT_CODES, snapshotJson, } from '../environment/contract.js';
6
+ import { effectivePolicy, readRecordedPolicy } from '../autonomy.js';
7
+ import { browserDataQualifies, CockpitConfig, EVALUATOR_COMMANDS, runtimeDeclarationSha256 } from '../schema.js';
8
+ /** An explicit request_preapproval wins; otherwise preapproval follows the declared data posture. */
9
+ export const browserPreapprovalRequested = (browser) => browser.request_preapproval ?? browserDataQualifies(browser.data);
10
+ import { formatShellCommand } from '../fix-catalogue.js';
11
+ import { readBoundedFile } from '../bounded-read.js';
12
+ export const STRUCTURED_INPUT_BYTE_LIMIT = 1_048_576;
13
+ export async function readBoundedInput(path) {
14
+ return readBoundedFile(path, STRUCTURED_INPUT_BYTE_LIMIT);
15
+ }
16
+ const issuedConfigProjections = new WeakMap();
17
+ const issuedMachineFloorConfigProjections = new WeakMap();
18
+ const issuedWorkEnvironmentConfigProjections = new WeakMap();
19
+ function projectBrowserConfig(declaredBrowser) {
20
+ return {
21
+ engine: declaredBrowser.engine,
22
+ networkExposure: declaredBrowser.network_exposure,
23
+ ...(declaredBrowser.network_exposure_reason === undefined ? {} : { networkExposureReason: declaredBrowser.network_exposure_reason }),
24
+ harnesses: declaredBrowser.harnesses.map((row) => ({ ...row })),
25
+ images: { mcp: { reference: declaredBrowser.images.mcp.reference, driverVersion: declaredBrowser.images.mcp.driver_version } },
26
+ project: { lockfile: declaredBrowser.project.lockfile, sha256: declaredBrowser.project.sha256, driverVersion: declaredBrowser.project.driver_version,
27
+ ...(declaredBrowser.project.manifest === undefined ? {} : { manifest: declaredBrowser.project.manifest, manifestSha256: declaredBrowser.project.manifest_sha256 }) },
28
+ ...(declaredBrowser.endpoint === undefined ? {} : { endpoint: declaredBrowser.endpoint }),
29
+ maxClients: declaredBrowser.max_clients,
30
+ proxy: {
31
+ ...(declaredBrowser.proxy.host_variable === undefined ? {} : { hostVariable: declaredBrowser.proxy.host_variable }),
32
+ serverPort: declaredBrowser.proxy.server_port,
33
+ proxyPort: declaredBrowser.proxy.proxy_port,
34
+ allowedHosts: [...declaredBrowser.proxy.allowed_hosts],
35
+ bind: declaredBrowser.proxy.bind,
36
+ },
37
+ resolver: declaredBrowser.resolver.map((row) => ({ ...row })),
38
+ authentication: {
39
+ policy: declaredBrowser.authentication.policy,
40
+ states: declaredBrowser.authentication.states.map((row) => ({ ...row })),
41
+ },
42
+ data: {
43
+ mode: declaredBrowser.data.mode,
44
+ isolated: declaredBrowser.data.isolated,
45
+ reachesProduction: declaredBrowser.data.reaches_production,
46
+ },
47
+ requestPreapproval: browserPreapprovalRequested(declaredBrowser),
48
+ artifacts: { ...declaredBrowser.artifacts },
49
+ };
50
+ }
51
+ function projectTestingConfig(declaredTesting) {
52
+ return {
53
+ declarations: {
54
+ stages: declaredTesting.stages.map((stage) => ({
55
+ id: stage.id,
56
+ command: [...stage.command],
57
+ requiresStack: stage.requires_stack,
58
+ timeoutSeconds: stage.timeout_seconds,
59
+ ...(stage.select === undefined ? {} : { select: Object.fromEntries(Object.entries(stage.select)
60
+ .map(([kind, argv]) => [kind, [...argv]])) }),
61
+ })),
62
+ gates: declaredTesting.gates.map((gate) => ({
63
+ id: gate.id,
64
+ tier: gate.tier,
65
+ stages: [...gate.stages],
66
+ changes: gate.changes,
67
+ })),
68
+ },
69
+ nativeHookInstall: declaredTesting.native_hooks.install,
70
+ ...(declaredTesting.test_files === undefined ? {} : { testFiles: [...declaredTesting.test_files] }),
71
+ ...(declaredTesting.native_hook_policy === undefined ? {} : {
72
+ nativeHookPolicy: { ...declaredTesting.native_hook_policy },
73
+ }),
74
+ };
75
+ }
76
+ export function projectWorkEnvironmentConfig(configuration) {
77
+ const loaded = configuration && typeof configuration === 'object' ? issuedConfigProjections.get(configuration) : undefined;
78
+ if (!loaded)
79
+ return undefined;
80
+ const declaredBrowser = loaded.config.browser;
81
+ const browser = declaredBrowser === undefined ? undefined : projectBrowserConfig(declaredBrowser);
82
+ if (browser && (new Set(Object.values(browser.artifacts)).size !== loaded.config.environment.generated_host_paths.length
83
+ || loaded.config.environment.generated_host_paths.some((path) => !Object.values(browser.artifacts).includes(path))))
84
+ return undefined;
85
+ const testing = loaded.config.testing === undefined ? undefined : projectTestingConfig(loaded.config.testing);
86
+ const result = { kind: 'work-environment-config-projection' };
87
+ issuedWorkEnvironmentConfigProjections.set(result, Object.freeze({
88
+ cockpitName: loaded.config.cockpit.name,
89
+ cockpitRoot: dirname(loaded.source.path),
90
+ siblingsRoot: loaded.config.cockpit.siblings_root,
91
+ source: Object.freeze({ ...loaded.source }),
92
+ siblings: Object.freeze(loaded.config.sibling.map(({ slug, dir, environment_files }) => ({ slug, dir,
93
+ environmentFiles: (environment_files ?? []).map(row => ({ template: row.template, instance: row.instance })),
94
+ }))),
95
+ policy: effectivePolicy(loaded.config),
96
+ wipCap: loaded.config.work.wip_cap,
97
+ attemptCap: loaded.config.work.attempt_cap,
98
+ verificationTimeoutSeconds: loaded.config.work.verification_timeout_seconds,
99
+ evaluatorTimeoutSeconds: loaded.config.work.evaluator_timeout_seconds,
100
+ evaluators: Object.freeze([...evaluatorTools(loaded.config)]),
101
+ evaluatorsDeclared: loaded.config.work.evaluators !== undefined,
102
+ generatedHostPaths: Object.freeze([...loaded.config.environment.generated_host_paths]),
103
+ ...(browser === undefined ? {} : { browser }),
104
+ ...(testing === undefined ? {} : { testing }),
105
+ ...(loaded.config.docs === undefined ? {} : { docs: Object.freeze({
106
+ ...(loaded.config.docs.decisions === undefined ? {} : { decisions: loaded.config.docs.decisions }),
107
+ ...(loaded.config.docs.decisions_index === undefined ? {} : { decisionsIndex: loaded.config.docs.decisions_index })
108
+ }) }),
109
+ }));
110
+ return result;
111
+ }
112
+ export function consumeWorkEnvironmentConfigProjection(projection) {
113
+ if (!projection || typeof projection !== 'object')
114
+ return undefined;
115
+ const loaded = issuedWorkEnvironmentConfigProjections.get(projection);
116
+ issuedWorkEnvironmentConfigProjections.delete(projection);
117
+ return loaded;
118
+ }
119
+ export function projectMachineFloorConfig(projection) {
120
+ const loaded = projection && typeof projection === 'object' ? issuedConfigProjections.get(projection) : undefined;
121
+ const machine = loaded?.config.environment.machine;
122
+ if (!loaded || !machine)
123
+ return undefined;
124
+ const result = { kind: 'machine-floor-config-projection' };
125
+ issuedMachineFloorConfigProjections.set(result, Object.freeze({
126
+ cockpitName: loaded.config.cockpit.name,
127
+ source: Object.freeze({ ...loaded.source }),
128
+ runtimeSha256: loaded.runtimeSha256,
129
+ floor: Object.freeze({
130
+ runtimeMemoryMb: machine.runtime_memory_mb,
131
+ runtimeCpus: machine.runtime_cpus,
132
+ freeDiskMb: machine.free_disk_mb,
133
+ }),
134
+ }));
135
+ return result;
136
+ }
137
+ export function consumeMachineFloorConfigProjection(projection) {
138
+ if (!projection || typeof projection !== 'object')
139
+ return undefined;
140
+ const loaded = issuedMachineFloorConfigProjections.get(projection);
141
+ issuedMachineFloorConfigProjections.delete(projection);
142
+ return loaded;
143
+ }
144
+ export function consumeLoadedConfigProjection(projection) {
145
+ try {
146
+ if (projection === null || typeof projection !== 'object')
147
+ return undefined;
148
+ const loaded = issuedConfigProjections.get(projection);
149
+ issuedConfigProjections.delete(projection);
150
+ return loaded;
151
+ }
152
+ catch { // A throwing accessor or proxy trap makes the projection malformed; the caller refuses it.
153
+ return undefined;
154
+ }
155
+ }
156
+ async function readConfigSource(inputPath) {
157
+ const requestedPath = resolve(inputPath);
158
+ let path;
159
+ try {
160
+ path = await realpath(requestedPath);
161
+ }
162
+ catch (error) {
163
+ const code = error.code;
164
+ return {
165
+ kind: 'unavailable',
166
+ source: {
167
+ state: 'unavailable',
168
+ path: requestedPath,
169
+ code: code === 'ENOENT' ? ENVIRONMENT_CODES.CONFIG_NOT_FOUND : ENVIRONMENT_CODES.CONFIG_UNREADABLE,
170
+ },
171
+ };
172
+ }
173
+ try {
174
+ const read = await readBoundedInput(path);
175
+ if (read.kind === 'too-large')
176
+ return {
177
+ kind: 'unavailable', tooLarge: true,
178
+ source: { state: 'unavailable', path, code: ENVIRONMENT_CODES.CONFIG_UNREADABLE },
179
+ };
180
+ const bytes = read.bytes;
181
+ return {
182
+ kind: 'available',
183
+ bytes,
184
+ source: {
185
+ path,
186
+ byteLength: bytes.length,
187
+ sha256: createHash('sha256').update(bytes).digest('hex'),
188
+ },
189
+ };
190
+ }
191
+ catch (error) {
192
+ const code = error.code;
193
+ return {
194
+ kind: 'unavailable',
195
+ source: {
196
+ state: 'unavailable',
197
+ path,
198
+ code: code === 'ENOENT' ? ENVIRONMENT_CODES.CONFIG_NOT_FOUND : ENVIRONMENT_CODES.CONFIG_UNREADABLE,
199
+ },
200
+ };
201
+ }
202
+ }
203
+ export async function observeConfigSource(inputPath) {
204
+ const observed = await readConfigSource(inputPath);
205
+ return observed.kind === 'available'
206
+ ? { state: 'available', ...observed.source }
207
+ : observed.source;
208
+ }
209
+ // smol-toml's message embeds a source excerpt; keep only the reason and position so file content is not echoed.
210
+ function tomlErrorSummary(error) {
211
+ if (!(error instanceof Error))
212
+ return 'unknown parse failure';
213
+ const reason = error.message.split('\n', 1)[0];
214
+ const { line, column } = error;
215
+ return typeof line === 'number' && typeof column === 'number' ? `${reason} (line ${line}, column ${column})` : reason;
216
+ }
217
+ const SCHEMA_ISSUES_SHOWN = 3;
218
+ export function schemaIssueSummary(issues, limit = SCHEMA_ISSUES_SHOWN) {
219
+ const shown = issues.slice(0, limit)
220
+ .map(issue => `${issue.path.length === 0 ? '(root)' : issue.path.map(String).join('.')}: ${issue.message}`);
221
+ const more = issues.length - shown.length;
222
+ return `${shown.join('; ')}${more > 0 ? `; and ${more} more` : ''}`;
223
+ }
224
+ // The schema lets a declared provenance omit observed_on only when the configuration file is
225
+ // its own source; only the loader knows that file's name, so it closes the rule here.
226
+ function undatedForeignProvenance(value, configName, path = []) {
227
+ if (value === null || typeof value !== 'object')
228
+ return undefined;
229
+ for (const [key, item] of Object.entries(value)) {
230
+ const itemPath = [...path, key];
231
+ if (key === 'provenance' && item !== null && typeof item === 'object' && !Array.isArray(item)
232
+ && !Object.hasOwn(item, 'observed_on') && item.source !== configName)
233
+ return itemPath.join('.');
234
+ const nested = undatedForeignProvenance(item, configName, itemPath);
235
+ if (nested !== undefined)
236
+ return nested;
237
+ }
238
+ return undefined;
239
+ }
240
+ function refusal(code, message, target, fix) {
241
+ const diagnostic = { severity: 'error', code, message, target, ...(fix ? { fix } : {}) };
242
+ return { kind: 'refusal', status: 2, diagnostics: [diagnostic], result: null };
243
+ }
244
+ // A `.cockpit/` directory beside the missing file means it was deleted from a cockpit checkout
245
+ // rather than mistyped, and every cockpit command and guarded agent call is stranded until it
246
+ // comes back; the committed copy is the fastest way back.
247
+ // sync records the configuration it read in the ownership manifest, and only that file is known to
248
+ // be committed. A mistyped --config beside it was never tracked, so restoring it from git fails.
249
+ // The manifest only chooses which remedy to print: one that cannot be read gives the plain refusal,
250
+ // and sync and check report the manifest itself.
251
+ async function syncedConfigName(directory) {
252
+ let manifest;
253
+ try {
254
+ const read = await readBoundedInput(join(directory, '.cockpit', 'generated-environment-ownership.json'));
255
+ if (read.kind !== 'complete')
256
+ return undefined;
257
+ manifest = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(read.bytes));
258
+ }
259
+ catch (error) {
260
+ // Absent, unreadable, changing under a concurrent sync, or not JSON: no remedy can be chosen.
261
+ if (error instanceof Error)
262
+ return undefined;
263
+ throw error;
264
+ }
265
+ const record = manifest;
266
+ const name = record?.format === 'cockpit-generated-ownership/v3' ? record.source?.path : undefined;
267
+ return typeof name === 'string' && name !== '' && basename(name) === name ? name : undefined;
268
+ }
269
+ /** The policy cockpit.toml declares now and the one the last sync recorded, for a command that gates a decision. */
270
+ export async function loadAutonomyPolicy(configPath) {
271
+ const loaded = await loadCockpitConfig(configPath);
272
+ if (loaded.kind !== 'complete')
273
+ return { refusal: loaded.diagnostics[0] };
274
+ const root = dirname(loaded.result.source.path);
275
+ const recorded = await readRecordedPolicy(root);
276
+ return { root, current: effectivePolicy(loaded.result.config), ...recorded ? { recorded } : {} };
277
+ }
278
+ /** The configuration `bytes` declare, or undefined when they are not UTF-8 TOML the schema accepts. */
279
+ export function parseCockpitConfigBytes(bytes) {
280
+ let parsed;
281
+ try {
282
+ parsed = parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
283
+ }
284
+ catch (error) {
285
+ // Invalid UTF-8 or TOML is the answer; anything else is a fault to surface.
286
+ if (error instanceof TypeError || error instanceof TomlError)
287
+ return undefined;
288
+ throw error;
289
+ }
290
+ const validated = CockpitConfig.safeParse(parsed);
291
+ return validated.success ? validated.data : undefined;
292
+ }
293
+ export async function loadCockpitConfig(inputPath) {
294
+ const observed = await readConfigSource(inputPath);
295
+ if (observed.kind === 'unavailable') {
296
+ // Each branch names its code literally so the diagnostic index reads the fix beside it.
297
+ const synced = observed.source.code === ENVIRONMENT_CODES.CONFIG_NOT_FOUND
298
+ ? await syncedConfigName(dirname(observed.source.path)) : undefined;
299
+ if (synced === basename(observed.source.path)) {
300
+ return refusal(ENVIRONMENT_CODES.CONFIG_NOT_FOUND, `${basename(observed.source.path)} is missing from a cockpit checkout (.cockpit/ is present); every cockpit command and guarded agent call reads it`, observed.source.path, `${formatShellCommand(['git', '-C', dirname(observed.source.path), 'restore', '--', basename(observed.source.path)])} (it is committed), then retry`);
301
+ }
302
+ if (synced !== undefined) {
303
+ return refusal(ENVIRONMENT_CODES.CONFIG_NOT_FOUND, `${basename(observed.source.path)} does not exist; this cockpit checkout was synced from ${join(dirname(observed.source.path), synced)}`, observed.source.path, 'check the --config path, then retry');
304
+ }
305
+ if (observed.source.code === ENVIRONMENT_CODES.CONFIG_NOT_FOUND) {
306
+ return refusal(ENVIRONMENT_CODES.CONFIG_NOT_FOUND, 'cockpit configuration was not found', observed.source.path, 'pass --config the path of an existing cockpit.toml, or create one with npx --no cockpit init <cockpit root> --target <target>');
307
+ }
308
+ if (observed.tooLarge) {
309
+ return refusal(ENVIRONMENT_CODES.CONFIG_UNREADABLE, `cockpit configuration exceeds the ${STRUCTURED_INPUT_BYTE_LIMIT}-byte input limit`, observed.source.path, 'cut the configuration below the input limit; it holds declarations, so move any embedded data into the files it names, then retry');
310
+ }
311
+ return refusal(ENVIRONMENT_CODES.CONFIG_UNREADABLE, 'cockpit configuration could not be read', observed.source.path, 'make --config name a regular file the user running cockpit can read, then retry');
312
+ }
313
+ const { bytes, source: provenance } = observed;
314
+ const { path } = provenance;
315
+ let source;
316
+ try {
317
+ source = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
318
+ }
319
+ catch { // Fatal decoding throws only for invalid UTF-8, which the refusal names.
320
+ return refusal(ENVIRONMENT_CODES.CONFIG_ENCODING_INVALID, 'cockpit configuration is not valid UTF-8', path, 'save the configuration as UTF-8, then retry');
321
+ }
322
+ let parsed;
323
+ try {
324
+ parsed = parse(source);
325
+ }
326
+ catch (error) {
327
+ return refusal(ENVIRONMENT_CODES.CONFIG_PARSE_INVALID, `cockpit configuration is not valid TOML: ${tomlErrorSummary(error)}`, path, 'correct the TOML at the line and column named, then retry');
328
+ }
329
+ const validated = CockpitConfig.safeParse(parsed);
330
+ if (!validated.success) {
331
+ return refusal(ENVIRONMENT_CODES.CONFIG_SCHEMA_INVALID, `cockpit configuration does not match the schema: ${schemaIssueSummary(validated.error.issues)}`, path, 'correct each named key to the shape and values ./node_modules/@b00dea/cockpit/docs/configuration-reference.md gives for it, then retry');
332
+ }
333
+ const undated = undatedForeignProvenance(validated.data, basename(path));
334
+ if (undated !== undefined) {
335
+ return refusal(ENVIRONMENT_CODES.CONFIG_SCHEMA_INVALID, `cockpit configuration does not match the schema: ${undated}: provenance without observed_on must name this configuration file (${basename(path)}) as its source`, path, 'add observed_on with the date the source was read, or name this configuration file as the source, then retry');
336
+ }
337
+ const reconstructed = CockpitConfig.safeParse(snapshotJson(validated.data));
338
+ if (!reconstructed.success) {
339
+ return refusal(ENVIRONMENT_CODES.CONFIG_SCHEMA_INVALID, 'cockpit configuration does not match the schema', path, 'correct each named key to the shape and values ./node_modules/@b00dea/cockpit/docs/configuration-reference.md gives for it, then retry');
340
+ }
341
+ const writtenGuards = parsed.guards;
342
+ const guardHostsStated = writtenGuards !== null && typeof writtenGuards === 'object'
343
+ && Object.hasOwn(writtenGuards, 'hosted_db_hosts') && Object.hasOwn(writtenGuards, 'vendor_endpoint_hosts');
344
+ const immutableConfig = snapshotJson(reconstructed.data);
345
+ const runtimeSha256 = runtimeDeclarationSha256(immutableConfig);
346
+ const bound = {
347
+ config: immutableConfig,
348
+ source: { ...provenance },
349
+ runtimeSha256,
350
+ guardHostsStated,
351
+ };
352
+ const result = { config: validated.data, source: provenance, runtimeSha256, guardHostsStated };
353
+ issuedConfigProjections.set(result, bound);
354
+ return {
355
+ kind: 'complete',
356
+ status: 0,
357
+ diagnostics: [],
358
+ result,
359
+ };
360
+ }
361
+ /**
362
+ * The evaluators work grade and cockpit grade try, in order. Left unset, they are the listed agent
363
+ * tools that can evaluate, so a team on one tool is never told to install another to grade.
364
+ */
365
+ export function evaluatorTools(config) {
366
+ return config.work.evaluators ?? config.surfaces.tools.filter((tool) => Object.hasOwn(EVALUATOR_COMMANDS, tool));
367
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Owns the text edits `sibling add` and `sibling remove` make to cockpit.toml: append one
3
+ * `[[sibling]]` table, delete one table with its sub-tables, or switch one `acquire = "none"`
4
+ * row to a recorded remote.
5
+ *
6
+ * It edits lines and leaves every other byte alone, so comments and formatting elsewhere in the
7
+ * file survive. It does not judge the result: `verified-write.ts` re-parses the edited file through
8
+ * the real schema and refuses anything that is not exactly the intended change. A layout this
9
+ * module cannot locate rows in (an inline `sibling = [...]` array, dotted keys) is refused by name
10
+ * rather than guessed at.
11
+ */
12
+ export interface SiblingTableRow {
13
+ readonly slug: string;
14
+ readonly dir: string;
15
+ readonly remote?: string;
16
+ readonly mount: string;
17
+ readonly acquire: string;
18
+ readonly var: string;
19
+ readonly toolchain: string;
20
+ readonly instruction_pointer?: boolean;
21
+ readonly purpose: string;
22
+ }
23
+ export interface SiblingTableLocation {
24
+ /** Zero-based line of the `[[sibling]]` header. */
25
+ readonly start: number;
26
+ /** Zero-based line of the last content line owned by the row, sub-tables included. */
27
+ readonly end: number;
28
+ /** First sub-table header after the row's own keys, or `end + 1` when it has none. */
29
+ readonly ownKeysEnd: number;
30
+ }
31
+ export type SiblingEdit = Readonly<{
32
+ kind: 'edited';
33
+ text: string;
34
+ }> | Readonly<{
35
+ kind: 'unsupported';
36
+ reason: string;
37
+ }>;
38
+ export interface Header {
39
+ readonly line: number;
40
+ readonly array: boolean;
41
+ readonly path: string;
42
+ }
43
+ /** Every table header outside multi-line strings and open arrays, by zero-based line. */
44
+ export declare function scanHeaders(lines: readonly string[]): Header[];
45
+ /** Placed after the last sibling row so the siblings stay together; the first row when the file has none. */
46
+ export declare function appendSiblingTable(text: string, row: SiblingTableRow, existingRows: number): SiblingEdit;
47
+ export declare function removeSiblingTable(text: string, index: number, existingRows: number): SiblingEdit;
48
+ export declare function recordSiblingRemote(text: string, index: number, existingRows: number, remote: string): SiblingEdit;