@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,692 @@
1
+ # Getting started
2
+
3
+ By the end of chapter 1, one repository has a reviewed `cockpit.toml`, every agent tool you listed
4
+ loads the same instructions and skills, the guard refuses a push to `main` in each of them (in Codex
5
+ once a person trusts its hook), and `cockpit check` fails the moment a generated file drifts. That
6
+ needs one repository, Node.js and Git; no Docker. Chapter 2 adds more repositories and a Compose
7
+ stack each agent can bring up on its own ports.
8
+
9
+ This guide is for developers and for the AI agents they ask to do the setup. To watch cockpit work on
10
+ a throwaway example first, follow the [tutorial](tutorial.md).
11
+
12
+ | Your situation | Go to |
13
+ |---|---|
14
+ | One repository, one agent tool, no Docker | [Chapter 1](#chapter-1-one-repository-one-tool-no-docker) |
15
+ | You want an agent to do the setup | [Set up with an agent](#set-up-with-an-agent) |
16
+ | Several repositories, or a stack to run | [Chapter 2](#chapter-2-several-repositories-and-a-compose-stack) |
17
+ | A setup you already run with scripts or a shell registry | [Adopt an existing setup](#adopt-an-existing-setup) |
18
+ | A teammate's cockpit you are joining | [Joining a team's cockpit](joining-a-team.md) |
19
+
20
+ ## Chapter 1: one repository, one tool, no Docker
21
+
22
+ You need a Node.js release listed in the
23
+ [`engines` field in the package manifest](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/package.json), Git, and macOS or
24
+ Linux. Commands that run a stack also need Docker Compose ([chapter 2](#chapter-2-several-repositories-and-a-compose-stack)).
25
+
26
+ ### Install cockpit
27
+
28
+ Install cockpit as an exact dev dependency of the repository and start `init`:
29
+
30
+ ```sh
31
+ npm install --save-dev --save-exact @b00dea/cockpit
32
+ npx --no cockpit init . --target claudecode
33
+ ```
34
+
35
+ With pnpm or yarn, install with `pnpm add -D -E @b00dea/cockpit` or `yarn add -D -E @b00dea/cockpit`
36
+ and run `pnpm exec cockpit` or `yarn cockpit` wherever this guide runs cockpit through `npx --no`. `init`
37
+ detects `pnpm-lock.yaml` or `yarn.lock` and writes the matching commands into what it proposes.
38
+
39
+ Replace `claudecode` with `codexcli` or `opencode` for those tools, or list several, yours first
40
+ (`--target claudecode,opencode`). `init` records them as `[surfaces] tools` and installs the
41
+ `cockpit-setup` skill for each listed tool. The default tools are `claudecode`, `codexcli` and
42
+ `opencode`; `cursor` and `grokcli` are written only when listed, and nobody has confirmed they load
43
+ the files ([capability matrix](capability-matrix.md)). Change the list later with
44
+ `cockpit tool add|remove <tool>`.
45
+
46
+ A single product repository gets an in-repo cockpit: `cockpit.toml`, the instructions and the guard
47
+ live in the repository itself, with `siblings_root = "."`. `init` previews every file before it
48
+ writes anything and accepts only the exact digest of that preview. Then it asks, one field at a
49
+ time, for each fact it cannot read from the repository: commands, health checks, ports and the
50
+ database and vendor hosts the guard must keep agents away from. Each accepted answer records where
51
+ it came from, and `init` writes a commented `[work.gates]` and `[autonomy]` block showing how to add
52
+ human gates. The details are under [The init interview](#the-init-interview).
53
+
54
+ ### Generate, check and commit
55
+
56
+ ```sh
57
+ npx --no cockpit sync --config ./cockpit.toml --dry-run
58
+ npx --no cockpit sync --config ./cockpit.toml
59
+ npx --no cockpit check --config ./cockpit.toml
60
+ ```
61
+
62
+ `sync` writes the generated files, and `check` reports any that no longer match:
63
+
64
+ - `sync --dry-run` lists every write and removal. Read it.
65
+ - `sync` publishes all generated files as one recoverable transaction. It refuses to remove a stale
66
+ generated file unless `[autonomy] stale_delete` lets it, or a person approves exactly that removal
67
+ with `sync --interactive`.
68
+ - `check` confirms nothing has drifted and never changes a file.
69
+
70
+ Review the output and commit it. From then on an agent started in the repository loads the same
71
+ instructions and skills in every listed tool, and the guard refuses a push to a protected branch, a
72
+ read of a declared secret file and commands against a declared production host. Run
73
+ `npx --no cockpit doctor --config ./cockpit.toml` for what is still missing: it reports each gap
74
+ with why cockpit needs it. If anyone uses Codex, a person must trust its guard hook once per
75
+ machine; `doctor` says so until it is done. Add `npx --no cockpit check --config cockpit.toml` to CI, or use the
76
+ [`cockpit-check` action](harness-surfaces.md).
77
+
78
+ Run every command from the cockpit directory with a path that fails when the dependency is missing
79
+ and never downloads a package: run it as `./node_modules/.bin/cockpit` or through `npx --no`. Once `init`
80
+ has written the `cockpit:*` package scripts, use them. The package ships these guides under
81
+ `./node_modules/@b00dea/cockpit/docs/`, so skills and fix hints cite them offline.
82
+
83
+ ## Set up with an agent
84
+
85
+ Tell the agent: *set up cockpit for this project, following `docs/getting-started.md`*. It can read
86
+ this page from the installed package (`./node_modules/@b00dea/cockpit/docs/getting-started.md`), a
87
+ source checkout, or <https://github.com/b0dea/cockpit/blob/main/docs/getting-started.md>. The
88
+ `adopt-cockpit` skill (`npx skills add b0dea/cockpit --skill adopt-cockpit`) routes an agent to
89
+ this page. After `init`, every listed tool also has the `cockpit-setup` skill, which carries the
90
+ same procedure.
91
+
92
+ ### Safety contract
93
+
94
+ A clean-looking configuration with invented values in it is the failure cockpit exists to prevent.
95
+ The agent follows these rules for the whole setup:
96
+
97
+ 1. **Ask the human first, and wait for a yes,** before creating a Git remote or hosted repository,
98
+ running a destructive command (`reset`, `sync --interactive` removals, deleting files), running
99
+ `cockpit sync --adopt`, accepting an `init` digest, or changing a product repository in any other
100
+ way than the next sentences allow (adopting a test framework or a dependency, for example). A
101
+ person approves or runs staging and the commit of the cockpit: the agent hands them the command.
102
+ A Dockerfile, Compose file or `.env.schema` the product needs goes on a new branch in that
103
+ sibling's checkout, started with no uncommitted changes, and the hand-back shows its diff against
104
+ the branch it started from. Nothing is pushed, so the person reviews it before it reaches anyone
105
+ else.
106
+ 2. **Show the exact preview before asking:** the `sync --dry-run` listing, the `init` preview with its
107
+ `previewSha256`, the answers file or the defaults digest. Consent binds to those bytes, and a
108
+ digest from anything but the latest pending run is refused.
109
+ 3. **Never invent a configuration value.** A port, image, command, health check, purpose or name
110
+ comes from a file the agent read or from the human; otherwise it leaves a named gap and asks.
111
+ 4. **Only what init read exactly is the agent's to accept.** `init` labels each proposal with
112
+ `provenance.kind`: `derived` (the complete answer, read from the named file and line),
113
+ `measured` (observed on this machine) or `inferred` (a hint or guess). A field whose
114
+ `confirmedBy` is `"agent"` may be answered with `"derived"` (below); `init` checks the value
115
+ against what it read, and bring-up proves it. Every other field, and every security boundary
116
+ (the `guards` hosts, protected branches, guard and MCP allow-lists), becomes an answer only on the
117
+ human's word.
118
+ 5. **Ask for every non-local host.** The `guards` answer lists the database and live vendor API hosts
119
+ of production, staging and shared environments. Variable names come from env templates, never
120
+ values; each host comes from the human.
121
+ 6. **Defaults never reach into a product repository.** "Use sensible defaults" covers `init` answers
122
+ only. A pointer in a sibling's **AGENTS.md** or a change to its `package.json` still needs an
123
+ explicit yes to that exact change, and a product file goes on a branch as rule 1 says. Every
124
+ answer the agent chose itself is marked `"agent-default"` (below), and its report ends with each
125
+ default, its field and its value.
126
+ 7. **Confirm a default only by observing it.** The agent clears an `unconfirmed` entry only with
127
+ `cockpit confirm`, which runs the observation that verifies that answer on this machine and
128
+ records it. The trust decisions (`guards`, `testing`, `environment.install_policies`, `sibling`,
129
+ `environment.posture`) and the answers no observation settles (`cockpit.name`, `estate.runnable`,
130
+ `environment.test_data`) stay a person's (below).
131
+
132
+ These rules are instructions, not enforcement. The guard cockpit installs later blocks some commands;
133
+ see [Safety and autonomy](safety-and-autonomy.md).
134
+
135
+ ### Read a cockpit result
136
+
137
+ - Pass `--json` to every command except `session`. Each prints one JSON document with `result`,
138
+ `diagnostics` (each with a `severity` and a `code`) and `invocation.exitCode`.
139
+ - A refusal exits nonzero and names its diagnostic; look the code up in
140
+ [Troubleshooting](troubleshooting.md). Take flags from `cockpit <command> --help` or the
141
+ [CLI reference](cli-reference.md), not from memory.
142
+ - `init` exits 0 when it stops at a question. Read `result.stage`, `result.question` and
143
+ `result.interview.outstanding` for the pending decision.
144
+
145
+ ### Mark the answers you chose
146
+
147
+ When the human delegates a decision ("pick sensible defaults"), say so per field in the answers file
148
+ so the value is never recorded as theirs:
149
+
150
+ ```toml
151
+ [provenance]
152
+ "environment.machine" = "agent-default"
153
+ guards = "agent-default"
154
+ ```
155
+
156
+ Each such field is written under `unconfirmed` at the top of `cockpit.toml`, listed in
157
+ `result.unconfirmed`, and reported by `doctor` as `DECLARATION_UNCONFIRMED` until it is confirmed. An
158
+ `environment.machine` floor the file does not attribute is recorded as unattributed, because no file
159
+ records its free disk or cold start time.
160
+
161
+ Three answers are facts about this machine and the running product, so an agent confirms them by
162
+ observation, one at a time:
163
+
164
+ ```sh
165
+ ./node_modules/.bin/cockpit confirm ports.bases --config cockpit.toml --json
166
+ ```
167
+
168
+ | Answer | The observation that confirms it |
169
+ |---|---|
170
+ | `ports.bases` | `preflight` passes with the stack up and its port family leased on the declared bases |
171
+ | `environment.compose_files` | `check` passes, which parses the Compose files and resolves the stack's topology |
172
+ | `environment.machine` | the runtime measured on this machine meets the declared memory, CPU and free-disk floor |
173
+
174
+ When the observation passes, `confirm` removes that one entry from `unconfirmed` (comments and every
175
+ other byte stay) and records what ran, when, its result and an evidence digest in
176
+ `.cockpit/local/answer-confirmations`. That file is machine-local and ignored, because the evidence is
177
+ about this machine, and the guard denies agent writes to it. The guard treats the removed entry as
178
+ non-widening only while that record matches the configuration on disk, so the agent's own sync
179
+ applies it where `[autonomy] sync = "agent"`; any other edit, or a clone without the record, leaves
180
+ it to a person. A failed observation is refused with `CONFIRM_OBSERVATION_FAILED` beside the
181
+ diagnostics that explain it.
182
+
183
+ Every other answer is refused with `CONFIRM_PERSON_REQUIRED`: the trust decisions, and
184
+ `cockpit.name`, `estate.runnable` and `environment.test_data`, which state what the owner wants rather
185
+ than anything a machine can show. A person confirms the value with whoever owns the product, corrects
186
+ it if it is wrong, deletes its `unconfirmed` entry and runs `cockpit sync` in a terminal.
187
+
188
+ A field whose `interview.outstanding` entry says `confirmedBy = "agent"` can instead be marked
189
+ `"derived"`, with or without a value: `init` answers it with the value it read, refuses
190
+ (`DOCUMENT_CONFIGURATION_ANSWER_NOT_DERIVED`) a value that differs or a field it read no complete value
191
+ for, and writes a `# Derived:` comment naming the source instead of an `unconfirmed` entry:
192
+
193
+ ```toml
194
+ [provenance]
195
+ "cockpit.name" = "derived"
196
+ "ports.bases" = "derived"
197
+ "environment.compose_files" = "derived"
198
+ ```
199
+
200
+ ### Walk through readiness
201
+
202
+ Every `init` stop and `cockpit doctor --config cockpit.toml --json` carry `result.readiness`: the
203
+ prerequisites cockpit depends on, grouped from the diagnostics that run reported. Each entry in `gaps`
204
+ has an `id`, a `level` (a `required` gap is refused by the command that needs it; a `recommended` one
205
+ warns), `needs` (why cockpit needs it) and `findings` (each diagnostic with its message and fix).
206
+ `noFinding` lists the prerequisites no check reported; a check that could not run reports nothing, so
207
+ it is not proof. Take the gaps one at a time, required first: what is missing, why, and the exact change
208
+ you propose.
209
+
210
+ Whether the existing tests prove anything is the agent's judgement, made on evidence. For each
211
+ proposed gate, name the behaviours its tests exercise, then break one of them on purpose, run the
212
+ gate, watch it go red, and restore the file so the checkout is as it was found; that edit needs no
213
+ yes, because it is undone before the step ends. Write the behaviours into the gate's `changes` text
214
+ and report the judgement, with the red run's output, in the hand-back. A gate that stays green on the
215
+ break proves nothing about that behaviour, and the report says so. Adopting a new test framework in a
216
+ product repository stays the human's call.
217
+
218
+ The cockpit directory must be a Git working tree, committed and clean, before `preflight` passes; a
219
+ new one reports `GIT_STATE_UNHEALTHY` until a person stages and commits it.
220
+
221
+ ## The init interview
222
+
223
+ `init` reads the repositories under the directory and asks for every fact it cannot read from them.
224
+ Preview first, then accept in a terminal:
225
+
226
+ ```sh
227
+ ./node_modules/.bin/cockpit init "$(pwd)" --target <tool> --json
228
+ ./node_modules/.bin/cockpit init "$(pwd)" --target <tool> --interactive
229
+ ```
230
+
231
+ The preview writes nothing. It returns the files it would install, a `previewSha256` digest and the
232
+ next step; `--interactive` asks you to type that digest. Re-running the same command resumes where it
233
+ stopped, and a changed repository invalidates earlier answers instead of reusing them. What you get
234
+ depends on what it finds:
235
+
236
+ - **A product repository** (a Git checkout with a language manifest, Dockerfile or Compose file) gets
237
+ an in-repo cockpit and declares only that repository. To put the cockpit in a folder of its own
238
+ beside the repositories, answer `cockpit.root = "dedicated"`
239
+ ([Where the cockpit lives](concepts.md#where-the-cockpit-lives)). Add other repositories afterwards
240
+ with [`sibling add`](#add-or-remove-a-repository); naming them in the answers file is refused with
241
+ `DOCUMENT_ESTATE_TOPOLOGY_MISMATCH`.
242
+ - **Nothing runnable** (an empty directory, or a repository of documents) gets a configuration with
243
+ no `[environment]`; runtime commands refuse with `ENVIRONMENT_NOT_DECLARED`, which is the expected
244
+ result, not a failure. `init` proposes the root itself as the first sibling (`dir = "."`,
245
+ `mount = "none"`).
246
+ - **A declared runtime** adds questions about the machine floor and posture the product needs.
247
+
248
+ Each outstanding field lists its `proposals`, and `confirmedBy` says who settles it: `"agent"` when a
249
+ `derived` proposal answers the whole field (today `cockpit.name`, `ports.bases` and
250
+ `environment.compose_files`, when the files leave no gap), `"person"` otherwise. A source `init`
251
+ could not read, or two that disagree, such as a host port with no default or a memory limit set twice
252
+ with different values, leaves the field to the person. Proposals come only from exact sources: a Dockerfile's `EXPOSE`, `CMD` and `ENTRYPOINT`, a
253
+ `package.json` `start`, `serve` or `dev` script, the `node` toolchain a lockfile names, each
254
+ repository's `origin` remote (a URL carrying credentials is skipped, never shown), variable names
255
+ (never values) in env templates such as `.env.example`, an existing Compose file, the `services:` of
256
+ GitHub workflows, and test entry points such as a Makefile `test` target, a `package.json` test script
257
+ or `go.mod`. A name that suggests a database or vendor endpoint, such as `DATABASE_URL`, becomes a
258
+ `guards` question about its host. For the machine floor, `init` sums the memory and CPU limits of the
259
+ services the Compose file starts by default (`deploy.resources.limits` or `mem_limit` and `cpus`,
260
+ times their replicas), and where no limit records one it measures this machine's container runtime
261
+ (`measured`, which refuses a smaller machine until someone lowers it). Free disk and the cold start
262
+ time have no source and are never proposed. Sources `init` could not use, including a runtime it
263
+ could not measure, are listed in `interview.inferenceSkipped`.
264
+
265
+ ### Without a terminal
266
+
267
+ An agent or CI job has no terminal, so `--interactive` refuses with `INIT_TERMINAL_REQUIRED`. Pass
268
+ consent and answers as arguments instead; there is no blanket `--yes`.
269
+
270
+ 1. Run the `--json` preview. It returns the `previewSha256` and, under `interview.outstanding`, every
271
+ field the interview will still ask, in order, each with a `why`, its `proposals` and `confirmedBy`.
272
+ 2. Write the answers as TOML keyed by field, and show them to the human with the digest.
273
+ 3. Rerun with `--accept-preview <previewSha256>` and `--answers <file>`. The run stops at the first
274
+ unanswered field, or at `configuration.defaults`, where `result.question.document` is the review
275
+ draft (an array of lines). Its provenance comments split the surfaced defaults in two: schema
276
+ defaults and the cockpit's own layout, which the agent accepts, and the security boundaries
277
+ (protected branches, guard allow and deny lists, approved MCP servers, resettable volumes,
278
+ generated host paths), which a person confirms. `result.question.expectedSha256` covers only the
279
+ second group, and the human reads it before accepting that digest.
280
+ 4. Rerun with `--accept-defaults <expectedSha256>` as well. A digest that is not the pending one is
281
+ refused (`INIT_PREVIEW_NOT_ACCEPTED`, `INIT_DEFAULTS_NOT_ACCEPTED`).
282
+
283
+ ```sh
284
+ ./node_modules/.bin/cockpit init "$(pwd)" --target <tool> --accept-preview <previewSha256> --answers ./answers.toml --json
285
+ ./node_modules/.bin/cockpit init "$(pwd)" --target <tool> --accept-preview <previewSha256> --answers ./answers.toml --accept-defaults <expectedSha256> --json
286
+ ```
287
+
288
+ For a directory with one library and nothing runnable, the whole answers file is:
289
+
290
+ ```toml
291
+ [cockpit]
292
+ name = "library"
293
+
294
+ [[sibling]]
295
+ slug = "library"
296
+ dir = "library"
297
+ mount = "always"
298
+ acquire = "none"
299
+ var = "LIBRARY_DIR"
300
+ purpose = "Shared library"
301
+
302
+ [ports]
303
+ bases = {}
304
+
305
+ [guards]
306
+ hosted_db_hosts = []
307
+ vendor_endpoint_hosts = []
308
+ ```
309
+
310
+ | Field | Answer |
311
+ |---|---|
312
+ | `cockpit.root` | `"dedicated"` or `"in-repo"`; asked only where both are possible, and a digest flag takes `"in-repo"` |
313
+ | `cockpit.name` | always asked; the root directory's name is proposed. It scopes Compose projects, state and generated files ([Rename a cockpit](#rename-a-cockpit)) |
314
+ | `sibling` | one `[[sibling]]` table per repository |
315
+ | `estate.runnable` | one table per repository whose run command was unknown, keyed by its slug |
316
+ | `ports.bases` | the host-published base port map; `{}` means none |
317
+ | `environment.install_policies` | the build and test commands per toolchain and lockfile; `[]` for none |
318
+ | `environment.test_data` | exactly the boolean keys `seeded_data` and `signed_in_users`; `false` states it is not needed |
319
+ | `environment.compose_files` | the Compose files that run the product, relative to the cockpit root |
320
+ | `environment.machine` | the runtime floor: `runtime_memory_mb`, `runtime_cpus`, `free_disk_mb`, `cold_start_seconds`; memory and CPUs are proposed, free disk and cold start never |
321
+ | `environment.posture` | `addressing`, `authentication` and `posture_requirements` ([Declare environment postures](environment.md#declare-environment-postures)) |
322
+ | `testing` | the product's `[testing]` stages and gates; `"none"` records that it has no tests yet, so no work can be graded PASS and `doctor` warns (`TESTING_GATE_UNDECLARED`) |
323
+ | `guards` | `hosted_db_hosts` and `vendor_endpoint_hosts` of every non-local environment; `[]` for both records that none exists |
324
+ | `provenance` | optional; `"human"` (the default), `"agent-default"` or `"derived"` per field. An `"agent-default"` answer stays under `unconfirmed` until `cockpit confirm` observes it or a person confirms it ([Mark the answers you chose](#mark-the-answers-you-chose)) |
325
+
326
+ A key that names no field is refused. Recorded answers are kept, so the same file can be passed on every
327
+ run; a different value for a recorded field is refused (`INIT_ANSWER_CONFLICT`) before anything is
328
+ published. Preview resetting one, and every later dependent answer, with
329
+ `cockpit init <root> --target <tool> --reset-answer <field> --json`, then repeat with
330
+ `--accept-reset <previewSha256>`. Once `cockpit.toml` is written, recorded answers can no longer be reset:
331
+ edit the value in `cockpit.toml` and rerun `init` with `--accept-preview`.
332
+
333
+ ## Chapter 2: several repositories and a Compose stack
334
+
335
+ cockpit runs your own Compose files; it does not generate them. Add each further repository with
336
+ [`sibling add`](#add-or-remove-a-repository), and put the cockpit in a folder beside them
337
+ (`cockpit.root = "dedicated"`, `siblings_root = ".."`) when it should own several neutrally.
338
+
339
+ **Compose.** Declare `environment.compose_files` with the files that run the product, inside the
340
+ cockpit root:
341
+
342
+ ```toml
343
+ [environment]
344
+ install_policies = []
345
+ compose_files = ["compose.yml"]
346
+ ```
347
+
348
+ | Compose files | Layout |
349
+ |---|---|
350
+ | One, inside a product repository checked out under the cockpit root (`siblings_root = "."`) | Declare the repository as a sibling and point at its file in place, as in `compose_files = ["shop/compose.yml"]`. Relative paths such as `build: ./api` resolve against `shop/`, so the file needs no change. |
351
+ | In two or more repositories, or outside the cockpit root | A `compose.yml` of your own at the cockpit root that reaches each checkout through its sibling variable (`build: ${SHOP_DIR}/api`) and publishes ports from `[ports.bases]` variables. A Compose `include` of the product's file is refused. |
352
+ | None yet | `cockpit init . --scaffold-compose <app dir> --port <port>` writes one plain `compose.yml` once, which the product then owns ([Scaffold a Compose file](environment.md#scaffold-a-compose-file)). |
353
+
354
+ `check` reads the topology with `docker compose config`: every published host port must come from a
355
+ `[ports.bases]` variable, and a service without a healthcheck warns. The rules are in
356
+ [Environment lifecycle](environment.md#environment-modes); a working layout is
357
+ [examples/compose-first](https://github.com/b0dea/cockpit/blob/main/examples/compose-first/README.md). Changing a product's Compose file is a
358
+ product change: an agent makes it on a branch, as the [safety contract](#safety-contract) says.
359
+
360
+ **Data.** `seed` and `resettable_volumes` fill and wipe the stack's data
361
+ ([Demo data, test users and roles](environment.md#demo-data-test-users-and-roles)). `cockpit reset` previews the change and needs a person
362
+ to approve it unless `[autonomy] reset` says otherwise.
363
+
364
+ **Docker.** Commands that run the stack need Docker Compose and a local runtime that has passed
365
+ `cockpit runtime measure --image <local-image>`; [Measure the container runtime](environment.md#measure-the-container-runtime)
366
+ lists the supported runtimes. Configuration, generation and `check` need no runtime, though validating
367
+ declared Compose files needs Docker Compose.
368
+
369
+ ### Bring the product up
370
+
371
+ ```sh
372
+ ./node_modules/.bin/cockpit setup --config ./cockpit.toml
373
+ ./node_modules/.bin/cockpit sync --config ./cockpit.toml
374
+ ./node_modules/.bin/cockpit check --config ./cockpit.toml
375
+ ./node_modules/.bin/cockpit up --config ./cockpit.toml
376
+ ./node_modules/.bin/cockpit preflight --config ./cockpit.toml
377
+ ```
378
+
379
+ `setup` clones or verifies each declared repository and checks its remote. `up` starts or resumes the
380
+ stack, but only `preflight` says it is healthy; it also fails with `GIT_STATE_UNHEALTHY` while the
381
+ cockpit has uncommitted changes. With `--json`, `up` reports the stack identifier, whether it
382
+ `started`, `resumed` or was `unchanged`, the leased port for each `[ports.bases]` name and the cold-start
383
+ time of the services it started.
384
+
385
+ ## Other situations
386
+
387
+ | On disk | Do |
388
+ |---|---|
389
+ | Repositories scattered across the disk | Moving them is the human's call. Otherwise `sibling add <slug> --from <path> --purpose "<purpose>"` records each checkout's `origin` with `acquire = "auto"`, and `setup` clones a fresh copy into the cockpit. It never moves, changes or deletes the original. |
390
+ | A service that has only ever run in CI, staging or a cluster | Follow **Create a local setup** in the shipped [setup procedure](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/surfaces/skills/procedures/setup.md#create-a-local-setup): derive each value from manifests, CI workflows and deployment files, record it as inferred with its source, and keep every unknown a named gap. |
391
+ | Committed `.claude/settings.json`, `.codex/config.toml` or `.codex/hooks.json` | [Adopt existing agent settings](#adopt-existing-agent-settings), after the human agrees. |
392
+ | A sibling with a `.env.schema` (Varlock) | `preflight` and `doctor` check each schema through Varlock and report key names and validity, never values. Follow **Secret handling** in the [setup procedure](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/surfaces/skills/procedures/setup.md#secret-handling) and [Secret sources and environment schemas](environment.md#secret-sources-and-environment-schemas). `varlock init`, provider login, encryption and moving secrets are the human's actions. |
393
+
394
+ ## Adopt an existing setup
395
+
396
+ For teams that already run a multi-repository product with their own scripts or a shell-registry
397
+ cockpit, and want to move to cockpit one layer at a time. Keep the old path runnable until the
398
+ cockpit path passes the same checks.
399
+
400
+ ### Bootstrap from the registry
401
+
402
+ Preview for one harness, then accept. Replace `<tool>` with its target, listed in
403
+ [chapter 1](#install-cockpit):
404
+
405
+ ```sh
406
+ ./node_modules/.bin/cockpit init . --target <tool> --registry ./env/lib/instance.sh --json
407
+ ./node_modules/.bin/cockpit init . --target <tool> --registry ./env/lib/instance.sh --interactive
408
+ ```
409
+
410
+ The first command writes nothing; the second needs a terminal and the exact preview digest. init
411
+ reads the registry's repositories, marks every value the registry did not state with its source and
412
+ the reason it was inferred or defaulted, and asks for the rest, such as
413
+ <!-- cockpit:ref schema=ports.bases --> `ports.bases`, which no registry dialect records. A missing
414
+ registry file is refused with `REGISTRY_NOT_FOUND`. Accepted answers keep their source, and
415
+ re-running resumes where it stopped. When `init` finds
416
+ repositories directly beneath the cockpit root instead of reading a registry, it records
417
+ `siblings_root = "."` as an inference for you to confirm.
418
+
419
+ ### Adopt in layers
420
+
421
+ Keep each layer's old path until the new one passes:
422
+
423
+ 1. **Registry.** Get the reviewed configuration to validate.
424
+ 2. **Surfaces.** Run `sync --dry-run`, `sync` and `check` (chapter 1), and read the dry run before
425
+ every `sync`.
426
+ 3. **Runtime.** Run `up` and `preflight` against the same configuration
427
+ ([chapter 2](#chapter-2-several-repositories-and-a-compose-stack)).
428
+ 4. **Guards, grading and more harnesses.** Add them once the earlier layers are stable. The
429
+ [capability matrix](capability-matrix.md) shows each harness feature's
430
+ [Cockpit harness capability state](concepts.md#cockpit-harness-capability-state); an
431
+ `instructed` feature should not yet replace a legacy control that is enforced.
432
+
433
+ Two rules matter in the surfaces layer:
434
+
435
+ - **cockpit never takes over an unmanaged file.** If a file already exists where cockpit wants to
436
+ generate one, `sync` refuses; move the existing file deliberately. The one supported exception
437
+ is a team's agent settings file, which you can [adopt](#adopt-existing-agent-settings).
438
+ [Cockpit generated ownership](concepts.md#cockpit-generated-ownership) covers only cockpit's own
439
+ output and never permits removing a file cockpit did not write.
440
+ - **Secrets after the ignore boundary.** Let `sync` create the ignore boundary before adopting
441
+ environment credentials, then follow
442
+ [Secret sources and environment schemas](environment.md#secret-sources-and-environment-schemas).
443
+
444
+ ### Keep shell scripts on the registry while you migrate
445
+
446
+ While old scripts still read the shell registry, `registry-resolve` validates it and prints the
447
+ same rows as data a script can `source`, so the scripts and cockpit read one checked copy. It
448
+ takes three required flags:
449
+
450
+ ```sh
451
+ ./node_modules/.bin/cockpit registry-resolve \
452
+ --registry ./env/lib/instance.sh --siblings-root .. --adoption ./adoption.state > resolved.sh
453
+ ```
454
+
455
+ `--adoption` names a five-line file that records how far each layer has moved to cockpit. The
456
+ lines name the layers in this order, each set to `migrated` or `documented-only`, and the migrated
457
+ layers come first:
458
+
459
+ ```text
460
+ registry=migrated
461
+ environment=documented-only
462
+ surfaces=documented-only
463
+ guards=documented-only
464
+ grading=documented-only
465
+ ```
466
+
467
+ The output assigns `COCKPIT_REGISTRY_ROWS`, `COCKPIT_SIBLING_PATHS`, `COCKPIT_SIBLING_VARIABLES`
468
+ and `COCKPIT_ADOPTION_STATES`, exports one `*_DIR` variable per sibling, and records the registry
469
+ digest in `COCKPIT_REGISTRY_SHA256`. `COCKPIT_SOURCE_REVISION` is the cockpit commit that produced
470
+ the data. A cockpit installed from a tarball packed from source has no release commit, so the
471
+ value is `development` and the command warns with `COCKPIT_REVISION_UNSTAMPED`. Nothing is printed
472
+ unless every input passed validation.
473
+
474
+ ### Adopt existing agent settings
475
+
476
+ For a repository that already commits its own `.claude/settings.json`, `.codex/config.toml` or
477
+ `.codex/hooks.json`. cockpit writes those files whole, so a plain `sync` refuses with
478
+ `SURFACE_STATE_CONFLICT` and names the command that keeps the team's settings:
479
+
480
+ ```sh
481
+ ./node_modules/.bin/cockpit sync --config cockpit.toml
482
+ ./node_modules/.bin/cockpit sync --config cockpit.toml --adopt .claude/settings.json
483
+ ./node_modules/.bin/cockpit check --config cockpit.toml
484
+ ```
485
+
486
+ `--adopt <path>` can be repeated, once per file. It moves the file to `cockpit/adopted/<path>`,
487
+ records a <!-- cockpit:ref schema=surfaces.adopted --> `surfaces.adopted` row in cockpit.toml (path, source, SHA-256 of the moved bytes, date,
488
+ provenance), and syncs. The file at `<path>` becomes cockpit's merge of the adopted copy and its
489
+ own generated version:
490
+
491
+ - **Hooks:** the team's hooks are kept beside cockpit's guard hook. `PreToolUse` entries are
492
+ combined; any other hook event both sides define must be identical.
493
+ - **Claude permissions:** `allow`, `ask` and `deny` rules are combined. A rule cockpit denies is
494
+ never kept as a team `allow` or `ask`.
495
+ - **Every other key** is the team's, unless cockpit writes the same key; then the two values must
496
+ match.
497
+
498
+ Commit `cockpit/adopted/` with cockpit.toml: it is the team's copy and, from now on, the place to
499
+ change those settings. To change them, edit the adopted copy, delete the merged file and run
500
+ `sync`; `check` reports a hand-edited merged file, or an adopted copy changed since the last
501
+ merge, and `sync` refuses the former. The recorded SHA-256 says which bytes were moved; it is not
502
+ a lock.
503
+
504
+ Adoption is refused with `SURFACE_ADOPTION_REFUSED`, naming the key, when the file would switch off
505
+ or route around the guard, or carries a setting cockpit declares elsewhere:
506
+
507
+ - `disableAllHooks`, `permissions.defaultMode = "bypassPermissions"`, or any hook that names a
508
+ `.cockpit/guards/` transport;
509
+ - `permissions.additionalDirectories` and `enabledMcpjsonServers` (declare a sibling or approve
510
+ the MCP server instead);
511
+ - in `.codex/config.toml`, `mcp_servers` and `features.codex_hooks = false`.
512
+
513
+ Adoption reads and moves only regular files inside the cockpit root, so it also refuses redirected
514
+ ancestors, links, special files and files that change while being read; replace them with plain
515
+ files and re-run. A refusal is rolled back, leaving the file in place and cockpit.toml unchanged. If
516
+ a concurrent replacement prevents a safe rollback, the refusal names every private recovery path
517
+ that may still hold the original bytes, with their SHA-256; keep those paths until the source is
518
+ restored. Because adoption changes cockpit.toml, it has no dry run or `--interactive` form, and an
519
+ agent's guard never treats it as an ordinary command.
520
+
521
+ `opencode.jsonc` needs no adoption: cockpit writes only its `$schema`, `instructions`, `mcp` and
522
+ `permission` keys and keeps the team's other keys as they are.
523
+
524
+ ### Complete the cutover
525
+
526
+ Retire the old path only when everything it did passes under cockpit (`check`, `up` and
527
+ `preflight` for the same configuration and runtime) and you know how to roll back. Destructive
528
+ environment commands, stale-output removal, changes to external services and publication stay
529
+ explicit human decisions. For recovery, see [Environment](environment.md) and
530
+ [Troubleshooting](troubleshooting.md).
531
+ ## Add or remove a repository
532
+
533
+ `sibling add` and `sibling remove` edit the `[[sibling]]` tables of `cockpit.toml` for you. They
534
+ append or delete only that table, keep every other line and comment, and refuse rather than write
535
+ anything that is not exactly the intended change. Pick the form for where the repository is:
536
+
537
+ ```sh
538
+ # a directory that already exists under the siblings root (acquire = "none")
539
+ ./node_modules/.bin/cockpit sibling add api --config ./cockpit.toml --purpose "HTTP API for orders"
540
+
541
+ # a repository that does not exist yet: runs `git init` on an empty or missing path
542
+ ./node_modules/.bin/cockpit sibling add api --config ./cockpit.toml --create --purpose "HTTP API for orders"
543
+
544
+ # a checkout elsewhere on disk: records its origin so `setup` clones a fresh copy
545
+ ./node_modules/.bin/cockpit sibling add api --config ./cockpit.toml --from ~/code/api --purpose "HTTP API for orders"
546
+
547
+ # a known remote (acquire = "auto"); also records a remote for an existing acquire = "none" sibling
548
+ ./node_modules/.bin/cockpit sibling add api --config ./cockpit.toml --remote git@example.com:team/api.git --purpose "HTTP API for orders"
549
+ ```
550
+
551
+ | Option | Meaning |
552
+ |---|---|
553
+ | `--purpose "<text>"` | what the repository is for; required for a new sibling, never defaulted |
554
+ | `--dir <relative dir>` | directory under the siblings root; defaults to the slug |
555
+ | `--var <NAME>` | exported variable; defaults to the slug as `API_DIR`. A default that would start with a Docker, Compose or host-process control prefix gets `SIBLING_` prepended, and an explicit control variable is refused, because handing it to Compose could change the runtime plan |
556
+ | `--mount <always\|none\|profile:NAME>` | how the stack uses the checkout. Defaults to `always`, except in a compose-first cockpit, where it defaults to `none`: cockpit never edits your Compose files, and `check` and `up` refuse a `mount = "always"` sibling no service bind-mounts. Pass `--mount always` once a service mounts the sibling's variable |
557
+
558
+ A duplicate slug, directory or variable is refused by name. `--create` never creates a GitHub
559
+ repository: it prints the `gh repo create` command to run and the `--remote` call that records the
560
+ result (with `--json`, `result.publish.command` and `result.publish.recordRemote`). `--from` never
561
+ moves, modifies or deletes the original checkout, and refuses one with no `origin` remote.
562
+
563
+ `--instruction-pointer` opts a separate sibling into a marked link from its **AGENTS.md** to the
564
+ cockpit instructions. That changes what agents in that repository load, so `setup` reports the
565
+ proposal first and writes it only when asked:
566
+
567
+ ```sh
568
+ ./node_modules/.bin/cockpit sibling add api --config ./cockpit.toml --from ~/code/api \
569
+ --purpose "HTTP API for orders" --instruction-pointer
570
+ ./node_modules/.bin/cockpit setup --config ./cockpit.toml --json
571
+ # after a human approves the exact AGENTS.md block
572
+ ./node_modules/.bin/cockpit setup --config ./cockpit.toml --write-instruction-pointers
573
+ ```
574
+
575
+ The link targets the **AGENTS.md** beside the selected **cockpit.toml**. The write appends only the
576
+ marked block and keeps existing team text (a missing **AGENTS.md** becomes a new guide); an edited,
577
+ partial or duplicate pointer is refused. The root sibling (`dir = "."`) cannot opt in: its guide
578
+ is the cockpit guide.
579
+
580
+ Plain `setup` also proposes the **AGENTS.md** or **CLAUDE.md** a sibling needs so every agent tool
581
+ started there loads its instructions, and `setup --write-instruction-files` writes it after review;
582
+ [Lifecycle and ownership](environment.md#lifecycle-and-ownership) has the cases.
583
+
584
+ ```sh
585
+ ./node_modules/.bin/cockpit sibling remove api --config ./cockpit.toml
586
+ ```
587
+
588
+ `remove` drops the table only if nothing refers to the sibling (generated services, vendor
589
+ endpoints, mounts, its exported variable, or a declared Compose file using that variable);
590
+ otherwise it lists every reference and changes nothing. It never deletes the checkout or a
591
+ generated file. After either command, run `cockpit sync --config ./cockpit.toml --dry-run` to see
592
+ what changes.
593
+
594
+ While a stack is up or asleep, both commands act at once only on a repository the stack does not
595
+ use (`mount = "none"`, named by none of its Compose files); for any other they refuse and ask for
596
+ `./node_modules/.bin/cockpit down --config ./cockpit.toml` first. Hand edits follow the same rule:
597
+ a change that never reaches a container (a `purpose`, guards, MCP, skills, surfaces, comments,
598
+ the `[environment.machine]` floor and cold-start budget, the reset volumes and the seed command)
599
+ needs only `sync`, and the next `up` resumes the same stack. A change to a Compose file, ports,
600
+ mounts or anything else the containers receive makes `up` refuse with `LIFECYCLE_PROGRESS_INVALID`,
601
+ because `up` never replaces a running stack in place; run the `down` it prints, then `up`.
602
+
603
+ ## Rename a cockpit
604
+
605
+ `cockpit.name` is part of every identity cockpit records: owner markers in generated files, the
606
+ ownership ledger, the Compose project and the stack's saved state. A running stack keeps the name
607
+ it started under, and only `down` under that name removes its containers, so take the stack down
608
+ before renaming:
609
+
610
+ ```sh
611
+ ./node_modules/.bin/cockpit down --config ./cockpit.toml
612
+ # edit name under [cockpit] in cockpit.toml, then:
613
+ ./node_modules/.bin/cockpit sync --config ./cockpit.toml
614
+ ./node_modules/.bin/cockpit check --config ./cockpit.toml
615
+ ```
616
+
617
+ `sync` rewrites the generated files and the ledger under the new name and keeps your own text
618
+ around cockpit's regions. If you renamed while a stack was recorded, `sync`, `check`, `up` and
619
+ `down` refuse with `STACK_RECORDED_UNDER_EARLIER_NAME` and print the earlier name: put it back, run
620
+ `down`, then rename again. Never delete or hand-edit cockpit's ownership files to get past a
621
+ refusal; they are how `sync` knows which files are its own.
622
+ ## Run an agent inside the environment
623
+
624
+ `session` is the everyday command. It runs `up`, holds the stack while your agent runs, and
625
+ releases it when the agent exits:
626
+
627
+ ```sh
628
+ ./node_modules/.bin/cockpit session --config ./cockpit.toml -- codex
629
+ ```
630
+
631
+ Put the agent command and its arguments after `--`. It starts with each `[ports.bases]` name set
632
+ to the stack's leased port and each entrypoint under `COCKPIT_ENTRYPOINT_`
633
+ ([Environment lifecycle](environment.md#lifecycle-and-ownership)). When the command's process
634
+ group stops, `session` calls `sleep`, which stops the stack only if no other checkout still holds
635
+ it. Interrupting `session` stops only the process group it started, and a `session` inside another
636
+ is refused. Use plain `up` only when the stack should outlive one command.
637
+
638
+ While it runs, `ps` shows each service, and `restart`, `rebuild` and `exec` act on one of them by its
639
+ `--service` name; `up --profile <name>` adds a Compose profile. To work on a sibling in a worktree,
640
+ `use <slug> <checkout>` points this cockpit checkout's stack at it, `pull` fast-forwards every
641
+ checkout, and `stacks prune` removes the stack a deleted worktree left behind. All of them are in
642
+ [Environment lifecycle](environment.md#serve-a-sibling-from-a-worktree).
643
+
644
+ To remove the stack and its containers, run `down`. It reads the active Docker context once,
645
+ refuses one that is not local, and deletes only from that daemon, so a deletion never lands on a
646
+ remote daemon or on a context switched mid-command
647
+ ([Choose the Docker daemon](environment.md#choose-the-docker-daemon)):
648
+
649
+ ```sh
650
+ ./node_modules/.bin/cockpit down --config ./cockpit.toml
651
+ ```
652
+
653
+ ## Upgrade cockpit
654
+
655
+ ```sh
656
+ ./node_modules/.bin/cockpit upgrade --config ./cockpit.toml --dry-run
657
+ ./node_modules/.bin/cockpit upgrade --config ./cockpit.toml
658
+ ```
659
+
660
+ `upgrade [<version>]` moves the exact pin to a newer version and re-runs `sync`; `--dry-run` prints
661
+ the commands and runs nothing. Until `sync` finishes, the guard holds every agent tool call, because
662
+ it trusts only the cockpit, Node and `cockpit.toml` it was generated for. Review and commit the
663
+ regenerated files. [Upgrade cockpit](harness-surfaces.md#upgrade-cockpit) has the details.
664
+
665
+ ## Install from source
666
+
667
+ To run an unreleased build, pack the package and install the tarball. That exercises the same files,
668
+ lifecycle scripts, dependencies and binary entry point as a registry install; `npm link` does not.
669
+
670
+ ```sh
671
+ git clone https://github.com/b0dea/cockpit.git
672
+ cd cockpit
673
+ npm ci --ignore-scripts
674
+ npm run build
675
+ COCKPIT_PACKAGE_DIR="$(mktemp -d)"
676
+ npm pack --workspace @b00dea/cockpit --pack-destination "$COCKPIT_PACKAGE_DIR"
677
+ cd /path/to/your/repository
678
+ npm install -D "$COCKPIT_PACKAGE_DIR"/*.tgz
679
+ ./node_modules/.bin/cockpit --help
680
+ ```
681
+
682
+ If `npm pack` or `npm install` fails, stop: a command run from the source checkout does not prove the
683
+ package works. Keep the tarball while the lockfile resolves cockpit from it.
684
+
685
+ ## Next steps
686
+
687
+ - [Environment lifecycle](environment.md): who holds the stack, resources, cold-start limits and recovery.
688
+ - [Harness surfaces](harness-surfaces.md): what `sync` writes for each agent tool.
689
+ - [Safety and autonomy](safety-and-autonomy.md): what the guards allow, ask about and deny.
690
+ - [Work and browser](work-and-browser.md): work orders, grading and browser checks.
691
+ - [Troubleshooting](troubleshooting.md): every diagnostic code and its remedy.
692
+ - [FAQ](faq.md): short answers to common questions.