@b00dea/cockpit 0.0.0-bootstrap.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/LICENSE +21 -0
  3. package/README.md +21 -1
  4. package/bin/cockpit.mjs +33 -0
  5. package/cockpit.schema.json +2574 -0
  6. package/dist/autonomy.d.ts +44 -0
  7. package/dist/autonomy.js +156 -0
  8. package/dist/bounded-read.d.ts +14 -0
  9. package/dist/bounded-read.js +42 -0
  10. package/dist/browser/commands.d.ts +62 -0
  11. package/dist/browser/commands.js +349 -0
  12. package/dist/browser/package-paths.d.ts +1 -0
  13. package/dist/browser/package-paths.js +6 -0
  14. package/dist/browser/proxy.d.ts +22 -0
  15. package/dist/browser/proxy.js +37 -0
  16. package/dist/browser/runtime.d.ts +117 -0
  17. package/dist/browser/runtime.js +183 -0
  18. package/dist/browser/surfaces.d.ts +141 -0
  19. package/dist/browser/surfaces.js +556 -0
  20. package/dist/browser/ui-gate.d.ts +15 -0
  21. package/dist/browser/ui-gate.js +18 -0
  22. package/dist/cli-guard.d.ts +5 -0
  23. package/dist/cli-guard.js +71 -0
  24. package/dist/cli-main.d.ts +139 -0
  25. package/dist/cli-main.js +1405 -0
  26. package/dist/cli.d.ts +3 -0
  27. package/dist/cli.js +16 -0
  28. package/dist/command-table.d.ts +113 -0
  29. package/dist/command-table.js +512 -0
  30. package/dist/config/load.d.ts +171 -0
  31. package/dist/config/load.js +345 -0
  32. package/dist/config/sibling-toml.d.ts +48 -0
  33. package/dist/config/sibling-toml.js +160 -0
  34. package/dist/config/surface-tools-toml.d.ts +9 -0
  35. package/dist/config/surface-tools-toml.js +37 -0
  36. package/dist/config/verified-write.d.ts +43 -0
  37. package/dist/config/verified-write.js +89 -0
  38. package/dist/diagnostics.d.ts +26 -0
  39. package/dist/diagnostics.js +335 -0
  40. package/dist/emit.d.ts +22 -0
  41. package/dist/emit.js +43 -0
  42. package/dist/entrypoint-kinds.d.ts +3 -0
  43. package/dist/entrypoint-kinds.js +11 -0
  44. package/dist/environment/application/destructive.d.ts +6 -0
  45. package/dist/environment/application/destructive.js +425 -0
  46. package/dist/environment/application/doctor.d.ts +89 -0
  47. package/dist/environment/application/doctor.js +235 -0
  48. package/dist/environment/application/guard.d.ts +43 -0
  49. package/dist/environment/application/guard.js +622 -0
  50. package/dist/environment/application/health.d.ts +134 -0
  51. package/dist/environment/application/health.js +379 -0
  52. package/dist/environment/application/lifecycle-context.d.ts +228 -0
  53. package/dist/environment/application/lifecycle-context.js +154 -0
  54. package/dist/environment/application/lifecycle-state.d.ts +25 -0
  55. package/dist/environment/application/lifecycle-state.js +201 -0
  56. package/dist/environment/application/lifecycle.d.ts +17 -0
  57. package/dist/environment/application/lifecycle.js +729 -0
  58. package/dist/environment/application/logs.d.ts +45 -0
  59. package/dist/environment/application/logs.js +127 -0
  60. package/dist/environment/application/setup.d.ts +129 -0
  61. package/dist/environment/application/setup.js +741 -0
  62. package/dist/environment/application/shared.d.ts +11 -0
  63. package/dist/environment/application/shared.js +61 -0
  64. package/dist/environment/claims.d.ts +389 -0
  65. package/dist/environment/claims.js +1709 -0
  66. package/dist/environment/codex-hook-trust.d.ts +11 -0
  67. package/dist/environment/codex-hook-trust.js +185 -0
  68. package/dist/environment/compose-environment.d.ts +1 -0
  69. package/dist/environment/compose-environment.js +6 -0
  70. package/dist/environment/compose-ownership.d.ts +21 -0
  71. package/dist/environment/compose-ownership.js +117 -0
  72. package/dist/environment/compose-topology.d.ts +117 -0
  73. package/dist/environment/compose-topology.js +413 -0
  74. package/dist/environment/contract.d.ts +489 -0
  75. package/dist/environment/contract.js +761 -0
  76. package/dist/environment/declaration.d.ts +14 -0
  77. package/dist/environment/declaration.js +39 -0
  78. package/dist/environment/destructive-composition.d.ts +29 -0
  79. package/dist/environment/destructive-composition.js +333 -0
  80. package/dist/environment/docker-daemon.d.ts +30 -0
  81. package/dist/environment/docker-daemon.js +78 -0
  82. package/dist/environment/docker-endpoint.d.ts +10 -0
  83. package/dist/environment/docker-endpoint.js +19 -0
  84. package/dist/environment/env-schema-observation.d.ts +46 -0
  85. package/dist/environment/env-schema-observation.js +241 -0
  86. package/dist/environment/evidence.d.ts +136 -0
  87. package/dist/environment/evidence.js +437 -0
  88. package/dist/environment/executable.d.ts +26 -0
  89. package/dist/environment/executable.js +167 -0
  90. package/dist/environment/generated-application/authorities.d.ts +5 -0
  91. package/dist/environment/generated-application/authorities.js +61 -0
  92. package/dist/environment/generated-application/bootstrap-skill.d.ts +16 -0
  93. package/dist/environment/generated-application/bootstrap-skill.js +328 -0
  94. package/dist/environment/generated-application/check.d.ts +13 -0
  95. package/dist/environment/generated-application/check.js +189 -0
  96. package/dist/environment/generated-application/custom-surface.d.ts +26 -0
  97. package/dist/environment/generated-application/custom-surface.js +289 -0
  98. package/dist/environment/generated-application/prepare.d.ts +29 -0
  99. package/dist/environment/generated-application/prepare.js +276 -0
  100. package/dist/environment/generated-application/publication.d.ts +33 -0
  101. package/dist/environment/generated-application/publication.js +547 -0
  102. package/dist/environment/generated-application/shared.d.ts +484 -0
  103. package/dist/environment/generated-application/shared.js +349 -0
  104. package/dist/environment/generated-application/surface-observation.d.ts +4 -0
  105. package/dist/environment/generated-application/surface-observation.js +69 -0
  106. package/dist/environment/generated-application/surface-outputs.d.ts +71 -0
  107. package/dist/environment/generated-application/surface-outputs.js +389 -0
  108. package/dist/environment/generated-application/surfaces.d.ts +3 -0
  109. package/dist/environment/generated-application/surfaces.js +699 -0
  110. package/dist/environment/generated-application/sync.d.ts +6 -0
  111. package/dist/environment/generated-application/sync.js +109 -0
  112. package/dist/environment/git-observation.d.ts +183 -0
  113. package/dist/environment/git-observation.js +544 -0
  114. package/dist/environment/health-composition.d.ts +11 -0
  115. package/dist/environment/health-composition.js +628 -0
  116. package/dist/environment/host-observation.d.ts +56 -0
  117. package/dist/environment/host-observation.js +52 -0
  118. package/dist/environment/identity.d.ts +48 -0
  119. package/dist/environment/identity.js +85 -0
  120. package/dist/environment/init-application.d.ts +308 -0
  121. package/dist/environment/init-application.js +697 -0
  122. package/dist/environment/install-policy-observation.d.ts +71 -0
  123. package/dist/environment/install-policy-observation.js +284 -0
  124. package/dist/environment/install-policy.d.ts +48 -0
  125. package/dist/environment/install-policy.js +96 -0
  126. package/dist/environment/instance.d.ts +33 -0
  127. package/dist/environment/instance.js +122 -0
  128. package/dist/environment/instruction-pointer.d.ts +19 -0
  129. package/dist/environment/instruction-pointer.js +144 -0
  130. package/dist/environment/lifecycle-composition.d.ts +29 -0
  131. package/dist/environment/lifecycle-composition.js +675 -0
  132. package/dist/environment/lifecycle-stage.d.ts +115 -0
  133. package/dist/environment/lifecycle-stage.js +398 -0
  134. package/dist/environment/lifecycle.d.ts +75 -0
  135. package/dist/environment/lifecycle.js +354 -0
  136. package/dist/environment/logs.d.ts +132 -0
  137. package/dist/environment/logs.js +519 -0
  138. package/dist/environment/observations.d.ts +46 -0
  139. package/dist/environment/observations.js +344 -0
  140. package/dist/environment/operator-application.d.ts +50 -0
  141. package/dist/environment/operator-application.js +155 -0
  142. package/dist/environment/ports.d.ts +182 -0
  143. package/dist/environment/ports.js +1205 -0
  144. package/dist/environment/posture-observation.d.ts +68 -0
  145. package/dist/environment/posture-observation.js +253 -0
  146. package/dist/environment/read-composition.d.ts +27 -0
  147. package/dist/environment/read-composition.js +352 -0
  148. package/dist/environment/readiness-composition.d.ts +38 -0
  149. package/dist/environment/readiness-composition.js +130 -0
  150. package/dist/environment/reclaim.d.ts +333 -0
  151. package/dist/environment/reclaim.js +1835 -0
  152. package/dist/environment/repository-identity.d.ts +13 -0
  153. package/dist/environment/repository-identity.js +108 -0
  154. package/dist/environment/runtime-measurement-record.d.ts +38 -0
  155. package/dist/environment/runtime-measurement-record.js +111 -0
  156. package/dist/environment/runtime-measurement.d.ts +27 -0
  157. package/dist/environment/runtime-measurement.js +224 -0
  158. package/dist/environment/runtime-probe-residue.d.ts +43 -0
  159. package/dist/environment/runtime-probe-residue.js +148 -0
  160. package/dist/environment/runtime-probe.d.ts +72 -0
  161. package/dist/environment/runtime-probe.js +725 -0
  162. package/dist/environment/runtime.d.ts +505 -0
  163. package/dist/environment/runtime.js +2335 -0
  164. package/dist/environment/seed.d.ts +16 -0
  165. package/dist/environment/seed.js +43 -0
  166. package/dist/environment/selftest-application.d.ts +86 -0
  167. package/dist/environment/selftest-application.js +713 -0
  168. package/dist/environment/sensitive.d.ts +3 -0
  169. package/dist/environment/sensitive.js +48 -0
  170. package/dist/environment/setup-observation.d.ts +62 -0
  171. package/dist/environment/setup-observation.js +1473 -0
  172. package/dist/environment/setup.d.ts +43 -0
  173. package/dist/environment/setup.js +176 -0
  174. package/dist/environment/sibling-instructions.d.ts +33 -0
  175. package/dist/environment/sibling-instructions.js +224 -0
  176. package/dist/environment/sibling-registration.d.ts +45 -0
  177. package/dist/environment/sibling-registration.js +538 -0
  178. package/dist/environment/state.d.ts +371 -0
  179. package/dist/environment/state.js +2013 -0
  180. package/dist/environment/templates.d.ts +140 -0
  181. package/dist/environment/templates.js +685 -0
  182. package/dist/environment/tool-registration.d.ts +9 -0
  183. package/dist/environment/tool-registration.js +96 -0
  184. package/dist/environment/upgrade-application.d.ts +19 -0
  185. package/dist/environment/upgrade-application.js +175 -0
  186. package/dist/environment-exec/execute.d.ts +102 -0
  187. package/dist/environment-exec/execute.js +1175 -0
  188. package/dist/environment-exec/libexec-program.d.ts +6 -0
  189. package/dist/environment-exec/libexec-program.js +22 -0
  190. package/dist/environment-exec/verified-digest.d.ts +4 -0
  191. package/dist/environment-exec/verified-digest.js +16 -0
  192. package/dist/exact-keys.d.ts +7 -0
  193. package/dist/exact-keys.js +15 -0
  194. package/dist/fix-catalogue.d.ts +32 -0
  195. package/dist/fix-catalogue.js +60 -0
  196. package/dist/freshness.d.ts +29 -0
  197. package/dist/freshness.js +75 -0
  198. package/dist/generated-environment/adopt.d.ts +16 -0
  199. package/dist/generated-environment/adopt.js +275 -0
  200. package/dist/generated-environment/command.d.ts +47 -0
  201. package/dist/generated-environment/command.js +75 -0
  202. package/dist/generated-environment/transaction.d.ts +186 -0
  203. package/dist/generated-environment/transaction.js +1770 -0
  204. package/dist/grading/evaluate.d.ts +71 -0
  205. package/dist/grading/evaluate.js +403 -0
  206. package/dist/grading/grade.d.ts +33 -0
  207. package/dist/grading/grade.js +57 -0
  208. package/dist/guards/evaluator.d.ts +113 -0
  209. package/dist/guards/evaluator.js +1226 -0
  210. package/dist/guards/harness-adapter.d.ts +17 -0
  211. package/dist/guards/harness-adapter.js +57 -0
  212. package/dist/guards/host.d.ts +8 -0
  213. package/dist/guards/host.js +10 -0
  214. package/dist/guards/invocation-parser.d.ts +66 -0
  215. package/dist/guards/invocation-parser.js +595 -0
  216. package/dist/guards/local-identity.d.ts +40 -0
  217. package/dist/guards/local-identity.js +123 -0
  218. package/dist/guards/policy-pin.d.ts +13 -0
  219. package/dist/guards/policy-pin.js +175 -0
  220. package/dist/guards/protected-locations.d.ts +62 -0
  221. package/dist/guards/protected-locations.js +461 -0
  222. package/dist/guards/read-only.d.ts +37 -0
  223. package/dist/guards/read-only.js +315 -0
  224. package/dist/init/command.d.ts +40 -0
  225. package/dist/init/command.js +310 -0
  226. package/dist/init/derive.d.ts +51 -0
  227. package/dist/init/derive.js +715 -0
  228. package/dist/init/draft.d.ts +138 -0
  229. package/dist/init/draft.js +1205 -0
  230. package/dist/init/render.d.ts +35 -0
  231. package/dist/init/render.js +82 -0
  232. package/dist/init/scaffold.d.ts +53 -0
  233. package/dist/init/scaffold.js +121 -0
  234. package/dist/invocation.d.ts +13 -0
  235. package/dist/invocation.js +20 -0
  236. package/dist/package-metadata.d.ts +9 -0
  237. package/dist/package-metadata.js +19 -0
  238. package/dist/readiness.d.ts +53 -0
  239. package/dist/readiness.js +88 -0
  240. package/dist/references/named.d.ts +24 -0
  241. package/dist/references/named.js +27 -0
  242. package/dist/refusal.d.ts +15 -0
  243. package/dist/refusal.js +7 -0
  244. package/dist/registry-derivation.d.ts +31 -0
  245. package/dist/registry-derivation.js +32 -0
  246. package/dist/registry-resolve/command.d.ts +47 -0
  247. package/dist/registry-resolve/command.js +226 -0
  248. package/dist/registry-resolve/registry.d.ts +68 -0
  249. package/dist/registry-resolve/registry.js +292 -0
  250. package/dist/registry-resolve/render-shell.d.ts +18 -0
  251. package/dist/registry-resolve/render-shell.js +36 -0
  252. package/dist/repair.d.ts +29 -0
  253. package/dist/repair.js +8 -0
  254. package/dist/schema-json.d.ts +1 -0
  255. package/dist/schema-json.js +177 -0
  256. package/dist/schema.d.ts +1322 -0
  257. package/dist/schema.js +934 -0
  258. package/dist/setup/command.d.ts +4 -0
  259. package/dist/setup/command.js +4 -0
  260. package/dist/sha256.d.ts +1 -0
  261. package/dist/sha256.js +4 -0
  262. package/dist/surfaces/adoption.d.ts +41 -0
  263. package/dist/surfaces/adoption.js +217 -0
  264. package/dist/surfaces/consumer-instructions.d.ts +20 -0
  265. package/dist/surfaces/consumer-instructions.js +43 -0
  266. package/dist/surfaces/contract.d.ts +42 -0
  267. package/dist/surfaces/contract.js +169 -0
  268. package/dist/surfaces/core-declarations.d.ts +24 -0
  269. package/dist/surfaces/core-declarations.js +79 -0
  270. package/dist/surfaces/development-markers.d.ts +1 -0
  271. package/dist/surfaces/development-markers.js +18 -0
  272. package/dist/surfaces/generator-adapter.d.ts +71 -0
  273. package/dist/surfaces/generator-adapter.js +809 -0
  274. package/dist/surfaces/harness-registry.d.ts +180 -0
  275. package/dist/surfaces/harness-registry.js +117 -0
  276. package/dist/surfaces/mcp.d.ts +95 -0
  277. package/dist/surfaces/mcp.js +186 -0
  278. package/dist/surfaces/merge.d.ts +30 -0
  279. package/dist/surfaces/merge.js +105 -0
  280. package/dist/surfaces/ownership.d.ts +190 -0
  281. package/dist/surfaces/ownership.js +795 -0
  282. package/dist/surfaces/projection.d.ts +136 -0
  283. package/dist/surfaces/projection.js +681 -0
  284. package/dist/surfaces/render.d.ts +118 -0
  285. package/dist/surfaces/render.js +633 -0
  286. package/dist/surfaces/restrictions.d.ts +130 -0
  287. package/dist/surfaces/restrictions.js +447 -0
  288. package/dist/surfaces/selftest.d.ts +162 -0
  289. package/dist/surfaces/selftest.js +393 -0
  290. package/dist/surfaces/skill-contract.d.ts +85 -0
  291. package/dist/surfaces/skill-contract.js +449 -0
  292. package/dist/surfaces/sync.d.ts +57 -0
  293. package/dist/surfaces/sync.js +164 -0
  294. package/dist/team-metadata.d.ts +41 -0
  295. package/dist/team-metadata.js +512 -0
  296. package/dist/testing/gates.d.ts +91 -0
  297. package/dist/testing/gates.js +182 -0
  298. package/dist/testing/hooks.d.ts +59 -0
  299. package/dist/testing/hooks.js +139 -0
  300. package/dist/testing/verdict.d.ts +29 -0
  301. package/dist/testing/verdict.js +62 -0
  302. package/dist/work-orders/application.d.ts +99 -0
  303. package/dist/work-orders/application.js +383 -0
  304. package/dist/work-orders/composition.d.ts +124 -0
  305. package/dist/work-orders/composition.js +1010 -0
  306. package/dist/work-orders/contract.d.ts +61 -0
  307. package/dist/work-orders/contract.js +122 -0
  308. package/dist/work-orders/store.d.ts +158 -0
  309. package/dist/work-orders/store.js +197 -0
  310. package/docs/README.md +65 -0
  311. package/docs/architecture.md +136 -0
  312. package/docs/capability-matrix.md +50 -0
  313. package/docs/cli-reference.md +599 -0
  314. package/docs/command-list.md +51 -0
  315. package/docs/compose-patterns.md +99 -0
  316. package/docs/concepts.md +171 -0
  317. package/docs/configuration-essentials.md +172 -0
  318. package/docs/configuration-reference.md +621 -0
  319. package/docs/environment.md +760 -0
  320. package/docs/extending.md +43 -0
  321. package/docs/faq.md +111 -0
  322. package/docs/getting-started.md +608 -0
  323. package/docs/harness-surfaces.md +433 -0
  324. package/docs/joining-a-team.md +76 -0
  325. package/docs/release-policy.md +49 -0
  326. package/docs/safety-and-autonomy.md +419 -0
  327. package/docs/troubleshooting.md +361 -0
  328. package/docs/tutorial.md +170 -0
  329. package/docs/work-and-browser.md +254 -0
  330. package/libexec/browser-operation.cjs +186 -0
  331. package/libexec/fence-marker.cjs +101 -0
  332. package/libexec/fence-marker.d.cts +24 -0
  333. package/libexec/fenced-group-runner.cjs +77 -0
  334. package/libexec/fenced-supervisor.cjs +137 -0
  335. package/libexec/generated-filesystem.cjs +731 -0
  336. package/libexec/install-filesystem.cjs +225 -0
  337. package/libexec/rulesync-generator.NOTICE.md +1112 -0
  338. package/libexec/rulesync-generator.cjs +743 -0
  339. package/libexec/surface-generator-worker.cjs +266 -0
  340. package/libexec/surface-output-reader.cjs +99 -0
  341. package/libexec/surface-scratch-cleanup.cjs +14 -0
  342. package/libexec/validate-harness-evidence.d.mts +183 -0
  343. package/libexec/validate-harness-evidence.mjs +1312 -0
  344. package/package.json +76 -1
  345. package/surfaces/README.md +33 -0
  346. package/surfaces/agents/evaluator.agent.md +76 -0
  347. package/surfaces/guards/bash-guard.sh +48 -0
  348. package/surfaces/guards/claude.adapter.json +25 -0
  349. package/surfaces/guards/codex.adapter.json +24 -0
  350. package/surfaces/guards/opencode.adapter.json +25 -0
  351. package/surfaces/references/browser.md +63 -0
  352. package/surfaces/references/test-data-and-personas.md +84 -0
  353. package/surfaces/references/testing-tiers.md +11 -0
  354. package/surfaces/skills/cockpit-browser.skill.md +54 -0
  355. package/surfaces/skills/cockpit-explain.skill.md +32 -0
  356. package/surfaces/skills/cockpit-fix.skill.md +37 -0
  357. package/surfaces/skills/cockpit-setup.skill.md +39 -0
  358. package/surfaces/skills/cockpit-work.skill.md +34 -0
  359. package/surfaces/skills/collection.json +5 -0
  360. package/surfaces/skills/procedures/explain.md +61 -0
  361. package/surfaces/skills/procedures/fix.md +81 -0
  362. package/surfaces/skills/procedures/setup.md +379 -0
  363. package/surfaces/skills/procedures/work.md +105 -0
@@ -0,0 +1,419 @@
1
+ # Safety and autonomy
2
+
3
+ This page is for people reviewing the controls cockpit generates and for agents working within
4
+ them. It says what the guard allows, asks about, denies or cannot evaluate, and why. A permission
5
+ always applies to one exact command and declared resources, never a whole command family.
6
+
7
+ The [command table](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/src/command-table.ts) and
8
+ [guard evaluator](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/src/guards/evaluator.ts) own these decisions; the generated
9
+ [CLI reference](cli-reference.md), [command list](command-list.md) and
10
+ [configuration reference](configuration-reference.md) describe their public inputs.
11
+
12
+ ## Outcome vocabulary
13
+
14
+ | Outcome | Meaning |
15
+ | --- | --- |
16
+ | `allow` | Evaluation completed without a harder boundary; executable invocations match exact permitted profiles or the built-in read-only profile. |
17
+ | `ask` | A person must decide. An `ask` result permits nothing by itself. |
18
+ | `deny` | A hard boundary forbids the request, even with an exact grant. |
19
+ | `unavailable` | Cockpit could not verify or safely evaluate the request, so it permits nothing. |
20
+
21
+ The evaluator scans the whole captured command for hard denials before returning `unavailable` or
22
+ `ask`, so a softer result found earlier cannot hide a later forbidden operation. Malformed input or
23
+ an incomplete policy is `unavailable` before that scan can begin.
24
+
25
+ ## Cockpit and project commands
26
+
27
+ A cockpit command is allowed only when it matches an exact available public command profile. The
28
+ application verifies the executable and working root; the command resolver checks the bounded
29
+ complete argument vector, resolved configuration path, declared services, permitted option roles
30
+ and inspected paths. Internal guard transport and public commands marked unavailable are excluded.
31
+ Declared project build and test commands are allowed only as their exact argument vectors in their
32
+ own checkout. A wildcard over a command family never grants permission.
33
+
34
+ ## Hard controls and prompts
35
+
36
+ Evaluation runs in this order: built-in hard denials, declared denials, checks cockpit could not
37
+ complete, declared allows, the built-in read-only profile, then `ask`. A declared allow therefore
38
+ cannot bypass any boundary below.
39
+
40
+ ### Instances, secrets and hosted endpoints
41
+
42
+ The guard denies mutation or staging of a declared environment instance, and mutation below a
43
+ secrets directory. That covers command and patch removals as well as writes, removing a directory
44
+ that contains an instance or the secrets directory, and staging a containing directory that could
45
+ include an instance.
46
+
47
+ Every `.env` and `.env.*` file at any depth is treated as holding secrets, declared or not: reading,
48
+ writing, removing, staging or linking one is a hard denial through every guarded tool. The
49
+ conventional documentation names `.env.example`, `.env.sample`, `.env.template` and `.env.schema`
50
+ are exempt, and so is every declared environment `template`. The refusal says what to do instead:
51
+ run what needs the values as `varlock run -- <cmd>`, which never prints them, or read the variable
52
+ names from the `.env.schema`. Another name that starts with `.env`, such as `.envrc`, is not denied,
53
+ but reading it prompts.
54
+
55
+ Executable use of a declared hosted database or vendor host is denied at hostname boundaries.
56
+ Matching examines executable, argument and environment-assignment-value roles; redirects,
57
+ heredocs, comments and definitions do not count as executable host use. Host names are compared
58
+ after Unicode compatibility normalization, so fullwidth letters and ideographic full stops, which
59
+ resolvers fold to ASCII, do not hide a declared host.
60
+
61
+ ### Configuration, Git and guard controls
62
+
63
+ Every guarded call reads the configuration file and
64
+ `.cockpit/generated-environment-ownership.json`, so losing either holds the agent until a human
65
+ restores it. Deleting, renaming, truncating, relinking or making either unreadable is a hard
66
+ denial, and so is removing a directory that contains either. The guard recognises this through
67
+ `rm`, `unlink`, `mv`, `git rm`, `git mv`, `find -delete`, `truncate`, `git archive` output,
68
+ truncating `dd` or `tee` writes, `ln` onto either file, a `chmod` mode that drops the owner's read
69
+ permission or is copied with `--reference`, a patch delete or move, a Write tool call with empty
70
+ content, and a `>` redirect. Editing the configuration in place stays permitted, including bounded
71
+ `dd conv=notrunc` and `tee` append forms under the normal write checks; the edit takes effect only
72
+ after a human runs `sync`.
73
+
74
+ Writing anywhere under a `.git` directory is a hard denial, because Git configuration chooses
75
+ programs that read-only Git commands run. For the same reason, so is every `git config` form other
76
+ than a proven read (`--get`, `--get-all`, `--get-regexp`, `--list`, `get`, `list`, or a lone
77
+ `section.key`), whatever its scope: a global `core.pager` or `core.hooksPath` reaches every
78
+ repository.
79
+
80
+ Removing, renaming or directly overwriting a guard control is a hard denial, as is removing a
81
+ directory that contains one or an executable control below a protected plugin directory. Otherwise
82
+ an exact command allow could disable a hook, or change a program a harness starts, before the next
83
+ guarded call. The protected files include every harness's native MCP and permission outputs derived
84
+ from the shipped harness registry, the MCP wrapper scripts under `.cockpit/mcp/` that those
85
+ outputs start, the work-order records under `.cockpit/work-orders/`, which carry no key, so one an
86
+ agent wrote would read as a person's to the next `cockpit work` command, and `.cockpit/policy.json`,
87
+ the [autonomy policy](#who-decides) the last sync accepted. This boundary follows folded path
88
+ spellings and verified filesystem identities, so alternate case and aliases do not bypass it.
89
+
90
+ The installed code the guard runs is a control too. The guard checks its entry point's digest, but
91
+ an edited module it loads could turn every hard denial into an allow. So these are hard denials:
92
+
93
+ - writing, linking, changing the mode of, or removing anything inside the running cockpit package
94
+ or any package it loads, under both its installed path and its real path, or removing a
95
+ directory that contains one;
96
+ - writing into any `node_modules/.bin` directory of a configured root, where package scripts and
97
+ `npx` find their commands;
98
+ - creating, replacing or linking a file directly inside a directory on the harness's command
99
+ search path (`PATH`) that lies within a configured root, where a planted `ls`, `git` or `rg`
100
+ would run in place of a permitted read-only command.
101
+
102
+ Only absolute search path entries can be protected: a relative entry such as `.`, `./node_modules/.bin`
103
+ or an empty one names whatever directory a command runs in, so a file the agent wrote anywhere could
104
+ run in place of a permitted command, or as the interpreter a path-spelled script such as
105
+ `./node_modules/.bin/cockpit` starts through `#!/usr/bin/env node`. While the harness's `PATH` holds
106
+ one, no command is allowed without a prompt, whatever profile or declared rule matches it, and the
107
+ reason names the entry. Keep relative entries off the `PATH` an agent harness starts with; `doctor`
108
+ reports one in the `PATH` it runs with as `GUARD_SEARCH_PATH_RELATIVE`.
109
+
110
+ The Claude Code registration includes `NotebookEdit`, so notebook cell changes get the same
111
+ protected-path checks as text edits. For a configuration in a repository subdirectory, these
112
+ controls belong to the configuration's directory. Start Codex in that directory: its generated hook
113
+ resolves the guard from the canonical session directory, not from an enclosing Git repository.
114
+ Generating a hook does not establish that the harness runs it; see
115
+ [Capability states](harness-surfaces.md#capability-states).
116
+
117
+ ### Destinations, sources and links
118
+
119
+ The evaluator resolves visible destinations for bounded `cp`, `install`, `mv`, `ln`, `git mv`,
120
+ `git archive`, `tee`, `dd`, `touch`, `truncate` and `chmod` forms, and the destination of bounded
121
+ `tar` extraction forms. Git paths use the directory selected by `git -C`. Extraction without an
122
+ explicit destination writes to the invocation's working directory. Visible source files for bounded
123
+ `cp`, `install`, `dd` and `tar` forms get the same protected read check as built-in read-only
124
+ commands.
125
+
126
+ A hard or symbolic `ln` whose target is, contains or lies inside a secrets directory, a declared
127
+ instance, a guard control or the installed cockpit is a hard denial, because the link would reach
128
+ it under a name the guard does not protect. A symbolic link's target is checked from both the
129
+ working directory and the link's own directory.
130
+
131
+ These are `unavailable`: every unsupported `tar` or `ln` mode or option, and a command whose
132
+ visible operand names a control, a protected plugin subtree or a directory containing either
133
+ and that the guard cannot classify. These checks run before declared allows. They do not inspect archive
134
+ member paths or the bodies of approved scripts, and classifying an extraction directory does not
135
+ prove that an archive cannot traverse outside it. An exact command rule permits that command; it is
136
+ not a filesystem sandbox. To restore or intentionally replace generated controls, stop the guarded
137
+ session and have a human run `cockpit sync --config cockpit.toml` in a terminal.
138
+
139
+ ### Protected branches and prompts
140
+
141
+ Pushes to declared protected branches are hard denials, including explicit protected destinations
142
+ and `git push --all` or `git push --mirror` when protected branches are declared. Missing or
143
+ unresolved destinations, including ambiguous source-only revisions, symbolic aliases and wildcards,
144
+ need a human decision. An exact grant cannot override either boundary.
145
+
146
+ These produce `ask`: unresolved Git execution context, destructive Git reset or clean forms,
147
+ staging by explicit path (a person approves or runs it), staging without explicit paths, wrapped or environment-modifying commands, unmatched invocation
148
+ profiles, and any removal without a grant. An explicit removal outside configured roots stays at
149
+ `ask` even when a declared allow matches, because cockpit cannot verify a target outside the roots
150
+ it manages; review the exact path and approve it, or move the work under a configured root. `git add -A`, `git add .` or a
151
+ directory operand that covers a secrets directory or an environment instance is a hard denial:
152
+ stage the changed files by name. Unsupported staging options or unproven pathspec grammar produce
153
+ `unavailable`. Any other refused command gets an `ask` that names the command and gives three ways
154
+ forward: a person approves it, a person runs it in a terminal, or a person admits it under
155
+ `[guards] allow`; for tests it points to `cockpit test-run`.
156
+
157
+ ### Declared rules
158
+
159
+ Declared rules refine the final prompt boundary. Each vector starts with the executable.
160
+ `[[guards.deny]]` matches a command-vector prefix or a contiguous command-vector sequence and may
161
+ name a safe fix. `[[guards.allow]]` matches a command-vector prefix, optionally only at one
162
+ checkout-relative working directory. An allow cannot bypass a hosted endpoint, protected branch,
163
+ secret path, malformed capture or unavailable filesystem evidence. Wrapped and
164
+ environment-modifying invocations are never allowed by a declared rule, because wrappers can change
165
+ which program actually runs. A rule that admits an interpreter, such as `["node"]`, `["python3"]` or
166
+ `["perl"]`, admits whatever code it is given, inline (`node -e`) or in a file, and the guard cannot
167
+ see what that code writes, guard controls included; without such a rule those invocations ask.
168
+
169
+ Malformed or oversized input, incomplete policy, escaped or symlinked path evidence, inspection
170
+ failure and exceeded limits produce `unavailable`. The
171
+ [invocation parser](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/src/guards/invocation-parser.ts) captures bounded input
172
+ once; the evaluator accepts only input that parser produced, so a hand-built lookalike is refused.
173
+
174
+ ### Read-only commands
175
+
176
+ A built-in read-only profile lets agents inspect the checkout without a prompt, which matters most
177
+ on Codex and OpenCode, where a prompt becomes a denial. It covers exact argument shapes of `ls`,
178
+ `pwd`, `cat`, `head`, `tail`, `wc`, `rg`, `grep`, `fd`, `find`, `echo`, `printf`, `sed`,
179
+ `git status`, `git diff`, `git log`, `git show`, `git rev-parse`, `git branch` listing flags, and the
180
+ cockpit commands in
181
+ [Cockpit commands an agent can run](#cockpit-commands-an-agent-can-run). The
182
+ [read-only profile](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/src/guards/read-only.ts) lists each permitted option.
183
+
184
+ - Any other option falls back to the ordinary rules, including options that run programs or write
185
+ files: `rg --pre`, `find -exec`, `find -delete`, `fd --exec`, `git -c`, `git --output`,
186
+ `git --ext-diff` and `git diff --no-index`.
187
+ - Options whose value is optional, such as `grep --context` on macOS, are accepted only in their
188
+ attached `--option=value` form, so the next word can never be misread.
189
+ - `printf` is read-only only without options, because `printf -v` assigns a variable. `sed` only
190
+ prints: `sed -n '5p'` or `sed -n '1,$p'` with numeric or `$` addresses and the `p` command, since
191
+ other commands can write or run programs. `git rev-parse` is read-only except `--git-path`,
192
+ `--resolve-git-dir`, `--parseopt` and `--sq-quote`. `git branch` is read-only with no argument or
193
+ with `--list`, `-a`, `-r`, `-v`, `-vv` or `--show-current` (and their long forms), never with a
194
+ branch name.
195
+ - `$?` is allowed as an argument only to a read-only command, where it cannot name a path, and
196
+ never as the directory of `env -C`.
197
+ - A command may follow `cd ./dir`, `cd ../dir` or `cd /abs/dir` joined by `&&` or `;`, with the
198
+ directory then judged as the command's working directory. A bare `cd name` is refused, because
199
+ `CDPATH` can send it elsewhere the guard cannot see: write `cd ./name`, or use `git -C name` for
200
+ Git. A `..` after a directory name, as in `cd ./a/../b` or `env -C a/..`, is refused too: `env`
201
+ resolves it from wherever a link named `a` leads, and so does a shell set to follow links.
202
+ `pushd`, `popd` and zsh's `chdir` are refused, because only `cd` is followed. A `cd`
203
+ may fail, and one after `||` may not run at all, so each later command is judged from every
204
+ directory it may run in: `&&` and `||` group left to right, so in `pwd || cd ./dir && cat x` the
205
+ `cat` is judged from both directories. A newline after `&&`, `||` or `|` continues the list. A
206
+ `cd` in a pipeline is refused, and a list ending in `&` runs in a subshell, so its `cd` moves no
207
+ later command.
208
+ - Git runs read-only only in a directory with its own `.git`, because Git otherwise treats a
209
+ directory holding `HEAD`, `objects` and `refs` as a repository and honours its configuration.
210
+ Git operands are inspected as files whose content may be printed.
211
+ - `rg` is read-only only when `RIPGREP_CONFIG_PATH` is absent, because an ambient ripgrep
212
+ configuration can inject options such as a preprocessor. Its `-g`, `--glob` and `--iglob` are
213
+ read-only only as `!` exclusions: any other glob overrides the hidden and ignore filters, so
214
+ `rg -g '.env*'` would print a hidden environment file.
215
+ - A pipeline or chain is permitted only when every segment is. Redirecting output to `/dev/null`,
216
+ `/dev/stdout` or `/dev/stderr`, or input from `/dev/null`, touches no file and does not change the
217
+ decision.
218
+
219
+ ### Cockpit commands an agent can run
220
+
221
+ | Command | Decision | Why |
222
+ | --- | --- | --- |
223
+ | `npx --no cockpit check --config cockpit.toml`, and likewise `doctor`, `preflight`, `logs --service <service>` and `sync --dry-run` | allowed | They read and report; nothing they do changes a file the guard relies on. |
224
+ | `npx --no -- cockpit --help`, `npx --no cockpit up --help`, and the version | allowed | They print and exit before any command runs. |
225
+ | `npx --no cockpit up --config cockpit.toml`, and likewise `sleep` and `down` | allowed | They act only on the stack cockpit declared and owns; `down` keeps data volumes, and deletes only from the local Docker daemon it fixes at the start of the run. |
226
+ | `npx --no cockpit runtime measure --config cockpit.toml --image <local-image>` | allowed | The probe runs a disposable stack under its own project, removes it, and records the result only in this machine's git-ignored state; `cockpit.toml` never changes. |
227
+ | `npx --no cockpit session --config cockpit.toml -- <command>` | the decision for `<command>` | A session runs its command as the agent could run it directly, so it never admits more. |
228
+ | `npx --no cockpit test-run --config cockpit.toml --gate <gate>`, with an optional `--mode` and a `--select <kind>:<value>` whose value does not start with `-` | allowed for a gate `cockpit.toml` declares | The gate runs only the stages a person declared in the reviewed configuration, the trust `up` already has. |
229
+ | `npx --no cockpit work status --config cockpit.toml`, `work accept`, `work check`, `work note`, `work answer`, `work grade`, `work signoff`, `work recover` without `--apply`, `work verify` and `cockpit grade --criteria <file>`, each with its own options | allowed | They report, or take a step [`[work.gates]`](#who-decides) gives the agent; a step it gives a person waits for the digest typed after `--interactive`, which no agent invocation carries. Grading runs in a separate evaluator. |
230
+ | `npx --no cockpit sync --config cockpit.toml`, and `upgrade`, whose sync child writes | allowed where `[autonomy] sync = "agent"`, otherwise a prompt | It regenerates the files the configuration already declares; the guard holds every call after `cockpit.toml` changes until a person syncs, so an agent's sync never publishes an edit of its own. |
231
+ | `npx --no cockpit reset --config cockpit.toml --apply` | allowed where `[autonomy] reset = "agent"`, otherwise a prompt | It deletes stack data. |
232
+ | `npx --no cockpit browser drive --config cockpit.toml`, and likewise `screenshot`, with an optional `--role` | allowed where `browser.request_preapproval` is set, otherwise a prompt | They sign in and capture the declared application, so they run unprompted only on the isolated, non-production data the configuration must declare before it can set preapproval. |
233
+ | `work accept`, `work answer` and `work signoff` with `--interactive` | a prompt, which Codex and OpenCode turn into a denial | `--interactive` asks for a person at a terminal to type the digest of what it shows. |
234
+ | `work recover --apply` | a prompt, which Codex and OpenCode turn into a denial | It deletes a lock once a process probe calls its holder dead, and that probe sees only this machine's processes: a holder in a container or on another host that shares the checkout looks dead to it. |
235
+ | `sync --adopt`, `sync --interactive`, `reset --interactive`, `sibling add` and every other command | a prompt, which Codex and OpenCode turn into a denial | They rewrite `cockpit.toml` or a team's own settings, ask for a person, or delete data. |
236
+
237
+ A file such a command names, like `--criteria`, is checked as a read:
238
+ the command may quote it in a refusal. A declared instance, a file below `.secrets` or a `.env` or
239
+ `.env.*` file that is not documentation is denied, and a symlink or a path outside the configured
240
+ roots prompts.
241
+
242
+ "Allowed" means the guard does not object. Claude Code also needs its own allow rule, which the
243
+ generated settings carry for the commands the shipped skills use
244
+ ([Claude Code command rules](harness-surfaces.md#claude-code-command-rules)); in Codex's sandbox
245
+ most of these commands must run outside it
246
+ ([Run cockpit outside the Codex sandbox](harness-surfaces.md#run-cockpit-outside-the-codex-sandbox)).
247
+
248
+ Run these exactly as shown. A prefix such as `env -u NAME` or `nohup` makes any of them a wrapped
249
+ invocation, which prompts, and none needs one: `down`, `reset` and `runtime measure` choose their
250
+ Docker daemon themselves, as [Choose the Docker daemon](environment.md#choose-the-docker-daemon)
251
+ describes.
252
+
253
+ These count from the cockpit root with `--config` naming the configured `cockpit.toml`; `check`,
254
+ `doctor` and help also count from any directory. Each spelling counts only where the guard proves
255
+ it starts its own installed package:
256
+
257
+ - a path such as `./node_modules/.bin/cockpit`, or one given to `node`, must resolve to it;
258
+ - bare `cockpit` must be what the command search path finds first;
259
+ - the npx spellings in the table must run from the cockpit root with no root `.npmrc` and no `bin`
260
+ or `directories.bin` in the root `package.json`, because npm would otherwise run that program or
261
+ apply that configuration first. Writing an `.npmrc` anywhere inside the configured roots is
262
+ denied, so one cannot be planted in the same command after that check. Any other npx option, or
263
+ npx without `--no` (which may download a package), is not the installed cockpit.
264
+
265
+ Where npx cannot be proven, every npx spelling prompts, and Codex and OpenCode refuse it, while the
266
+ same command spelled as a path, such as `./node_modules/.bin/cockpit doctor --config cockpit.toml`,
267
+ still counts from the cockpit root.
268
+ `doctor` reports this as `COCKPIT_LAUNCHER_UNPROVEN`, using the guard's own check, and names which
269
+ spelling it can prove. The guard does not check which `npx` the command search path finds: it
270
+ assumes that program behaves as npm's own, as the version-manager and package-firewall shims that
271
+ hand over to npm do.
272
+
273
+ ### Reading secrets and instances
274
+
275
+ Every hard denial still applies first. Reading a declared instance, a `.env` or `.env.*` file that
276
+ is not documentation, or anything under a `.secrets` directory is denied under every spelling that resolves to it, including a case-folded spelling of
277
+ the checkout itself, and so is a recursive search rooted at or below one. Shell reads also compare
278
+ filesystem identity: a hard link to a declared instance, or to any file in the cockpit's
279
+ `env/.secrets` directory, is denied like the file itself. The guard enumerates that directory on
280
+ every call, up to 512 entries; above that bound every content read falls back to a prompt rather
281
+ than going unchecked. A hard link to a file in any other `.secrets` directory is recognised only by
282
+ its spelling.
283
+
284
+ These reads fall back to a prompt instead of being allowed:
285
+
286
+ - a recursive search, whenever a declared instance or an `env/.secrets` file has a second hard link
287
+ anywhere;
288
+ - a search whose tree contains an existing instance, a `.secrets` directory at any depth, or a
289
+ `.env*` file that is neither a declared template nor one of the documentation names, since `grep -r` reads every file below it. The guard
290
+ walks each searched tree to find them, without following links, and a tree too large for its
291
+ bounded walk is not searched either. The reason names the path, so the agent can search a
292
+ narrower one;
293
+ - an `rg` search that would read one. ripgrep skips what Git ignores, so the guard asks Git, with
294
+ the guard's own Git executable, which files the enclosing repository does not ignore, and a
295
+ gitignored `.env` or `node_modules` does not block it. Only `.gitignore` files are applied, and
296
+ hidden files count, because a type such as `rg -t sh` reads a `.env`. Where Git's list cannot stand
297
+ for ripgrep's (outside a repository, with an `.ignore` or `.rgignore` file in or above the tree,
298
+ through a nested repository or submodule, below a `.git` or `.jj` entry, above which ripgrep stops
299
+ applying ignore files, when the search names an ignored path, when a `.gitignore` Git reads holds
300
+ a line the two glob engines may read differently, such as braces, a POSIX class like `[[:alpha:]]`,
301
+ a backslash escape, trailing whitespace, a `**` that is not a whole path component, or bytes that
302
+ are not UTF-8, or when Git does not answer), the
303
+ search is walked like `grep -r`. Either way the guard sees only what exists before the call runs, so a
304
+ recursive search is allowed only when every other command in the call is read-only too, and
305
+ nothing in it can write an environment file first;
306
+ - `git diff`, `git show`, and `git log` with patch output, whenever the repository's index holds a
307
+ `.env*` file that is neither a declared template nor a documentation name, a file below a
308
+ `.secrets` directory or a declared instance, unless the command names no revision and is limited with `-- <path>` to paths that hold
309
+ none (`git log` may name revisions, but not `--full-diff`). `--check` counts as printing content,
310
+ and `git log -L<range>:<path>` is not read-only. A revision may name a blob, which prints whatever pathspec
311
+ follows. Only the index is asked: a file committed once and since removed from it is still in
312
+ history, and `git log -p` prints it. Run `git rm --cached` and rotate what it held;
313
+ - a path that is a symlink or leaves one through `..`, lies outside the configured roots, or has
314
+ another `.env*` name, such as `.envrc`. A declared environment `template` and the documentation
315
+ names are read like any other file.
316
+
317
+ The guard hook sees shell commands and edits only. Claude Code's own Read, Grep and Glob tools never
318
+ reach it, so `sync` also writes Claude `Read` deny rules into `.claude/settings.json`: one for every
319
+ `.env` and every `.env.*` file, one for every `.secrets` directory and one for every declared instance
320
+ of every sibling, whether or not the
321
+ sibling is mounted or granted to Claude. A sibling instance's rule is anchored on the path below the
322
+ sibling's parent, so the committed file is identical on every clone; it can match more than the
323
+ instance (any file with the same sibling-relative suffix), never less. An instance in the cockpit
324
+ root itself is anchored at the project root. These rules match path spellings only: Claude's native
325
+ tools cannot see filesystem identity, so a hard link or a symbolic link to an instance or secrets
326
+ file, under a name outside the rules, stays readable to them. The guard's identity checks cover
327
+ shell commands only. Claude applies a deny rule before any allow, so the `.env.*` rule cannot exempt
328
+ the documentation names: Claude's own tools refuse `.env.example`, `.env.schema` and declared
329
+ templates too, which `cat` in a shell still reads.
330
+
331
+ ## Who decides
332
+
333
+ `[autonomy]` and `[work.gates]` in `cockpit.toml` say who takes each decision cockpit gates: `agent`,
334
+ `person` or `ci`. Every field defaults to `agent` except `reset` and `mcp_approve`, which default to `person`.
335
+ `[work] grading` says how a work order earns done; the work-order fields are described in
336
+ [Who passes each gate](work-and-browser.md#who-passes-each-gate).
337
+
338
+ | Field | Decides | Default |
339
+ | --- | --- | --- |
340
+ | `sync` | whether the guard lets an agent run a writing `sync`; under `ci` a writing sync runs only where `CI` is set | `agent` |
341
+ | `stale_delete` | whether `sync` removes a file it generated before and no longer generates without a person typing the stale-removal digest | `agent` |
342
+ | `reset` | whether `reset --apply` deletes stack data without a person; otherwise a person approves the preview with `--interactive` | `person` |
343
+ | `mcp_approve` | `person`: sync enables only the MCP servers whose digest a person recorded in `[mcp.approved]`, and `MCP_NOT_APPROVED` names the rest; `agent`: sync enables every declared server as declared now, which lets an agent start processes outside the guard, because a sibling's MCP source is a file the agent can write and each harness starts an enabled server outside every guard boundary | `person` |
344
+
345
+ <!-- cockpit:ref path=packages/cockpit/src/guards/policy-pin.ts --> The guard pins the policy: an agent's edit, write or patch that would change `[work]`,
346
+ `[work.gates]` or `[autonomy]`, or `[mcp]` while `mcp_approve` is `person`, is a hard denial. It
347
+ applies the edit to the current text and compares the tables, so an edit elsewhere in the file stays
348
+ permitted; an edit it cannot apply exactly, and a shell command that names the file and is not a
349
+ proven read, a Git record or the `--config` operand of a cockpit command, are denied because the guard
350
+ cannot show the tables unchanged. A cockpit session's command after `--` is judged as a command of its
351
+ own, and a path or `node <script>` spelling of cockpit is admitted only where the guard proves it
352
+ starts the installed cockpit. The pin holds only for the
353
+ tool calls the guard inspects.
354
+
355
+ Every writing `sync` records the policy it ran under in `.cockpit/policy.json`. A later sync that finds
356
+ a field weaker than that record, such as a gate moved from `person` to `agent` or grading from
357
+ `independent` to `self`, writes nothing and reports `POLICY_WEAKENING_UNCONFIRMED` with the change and
358
+ its digest; a person runs `sync --interactive`, reads it and types the digest. `check` and `doctor` report
359
+ the same weakening before any sync runs. Until then every work
360
+ command refuses to run under the weaker policy, and so does `reset --apply` when `[autonomy] reset` is
361
+ the weakened field. A stronger policy needs nobody.
362
+
363
+ What no setting relaxes: reads of secrets and declared instances, pushes to protected branches,
364
+ writes to guard controls, and the policy pin. What only a person can do: trust Codex's hooks, trust a
365
+ workspace in Claude Code, and sign in to a secrets provider. `doctor` and `check` report missing
366
+ Codex hook trust as `CODEX_HOOK_UNTRUSTED`; cockpit cannot observe the other two, so a person
367
+ confirms them.
368
+
369
+ A local `person` gate is best-effort: cockpit cannot tell a person from a program driving a terminal.
370
+ `ci` relies on the `CI` variable, which an agent can set too, so locally it is best-effort as well.
371
+ The only enforced human gate is a required CI job behind a protected environment whose reviewers must
372
+ approve it, such as the [`work verify` job](work-and-browser.md#who-passes-each-gate).
373
+
374
+ ## Native adapter behavior
375
+
376
+ The [transport and adapter owner](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/src/guards/harness-adapter.ts) translates a
377
+ decision without adding grants or weakening hard boundaries:
378
+
379
+ | Harness | Translation and adapter exit |
380
+ | --- | --- |
381
+ | Claude Code | Allow, ask, and deny exit 0; ask and deny are carried in native decision JSON. |
382
+ | Codex CLI | Ask becomes deny, because Codex hooks have no prompt tier, and a decision a human cannot be shown must not let the call run. Allow and deny exit 0; deny is carried in native decision JSON. |
383
+ | OpenCode | Ask becomes deny, for the same reason: its plugin hook can only throw or continue. Allow exits 0; every non-allow decision exits 2. |
384
+
385
+ Unavailable or malformed decisions exit 2 on every target, so adapter exit 0 alone does not mean
386
+ permission was granted.
387
+
388
+ Guard transport uses a fixed handler argument vector, normalized absolute handler and
389
+ working-directory paths, bounded standard input, and bounded output and error. The
390
+ [transport owner](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/src/guards/harness-adapter.ts) sets a timeout so a stalled
391
+ handler cannot hold a guarded call indefinitely. Copied plans, failed transport, signals, oversized
392
+ output, nonzero handler status and invalid JSON become `unavailable` with exit 2. Lexical path
393
+ normalization in this adapter does not itself verify filesystem identity.
394
+
395
+ If an adapter is unavailable, no target-specific registration or read-only fragment is emitted; the
396
+ shared guard file may still be generated. What each harness is confirmed to enforce, and why
397
+ generated restrictions stay `instructed` until a run of the real tool says otherwise, is in
398
+ [Capability states](harness-surfaces.md#capability-states) and
399
+ [Guard adapters](harness-surfaces.md#guard-adapters).
400
+
401
+ ## Exit codes and generated references
402
+
403
+ Exit codes are listed in the [CLI reference](cli-reference.md). How cockpit records command
404
+ completion and keeps its generated reference pages current is maintainer detail, in the contributor
405
+ page "CLI completion and generated references", reached from [CONTRIBUTING.md](https://github.com/b0dea/cockpit/blob/main/CONTRIBUTING.md).
406
+
407
+ ## Evidence
408
+
409
+ Static configuration, source inspection, synthetic fixtures, model self-report and silence do not
410
+ prove native enforcement. The
411
+ [native evidence validator](https://github.com/b0dea/cockpit/blob/main/packages/cockpit/libexec/validate-harness-evidence.mjs) binds exact
412
+ current executable and wiring identities, generated-manifest and candidate digests, version,
413
+ bounded transcripts and validation results, and each record carries candidate and deliberately
414
+ broken-control evidence.
415
+
416
+ Missing evidence keeps a cell `instructed` or `unavailable`, with `human_needed` judgments still
417
+ pending. It never relaxes a hard denial or grants a permission. Switching defaults, deleting
418
+ fallbacks and publishing stay human decisions; a green source check or a generated reference does
419
+ not make them.