@b00dea/cockpit 0.1.0 → 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.
- package/CHANGELOG.md +99 -0
- package/README.md +3 -0
- package/cockpit.schema.json +73 -3
- package/dist/autonomy.d.ts +3 -2
- package/dist/autonomy.js +30 -13
- package/dist/browser/commands.d.ts +57 -2
- package/dist/browser/commands.js +114 -10
- package/dist/browser/runtime.d.ts +1 -0
- package/dist/browser/runtime.js +4 -1
- package/dist/browser/surfaces.d.ts +7 -7
- package/dist/browser/surfaces.js +5 -0
- package/dist/canonical-json.d.ts +2 -0
- package/dist/canonical-json.js +5 -0
- package/dist/cli-main.d.ts +40 -3
- package/dist/cli-main.js +241 -62
- package/dist/command-table.d.ts +19 -11
- package/dist/command-table.js +190 -38
- package/dist/config/load.d.ts +16 -4
- package/dist/config/load.js +25 -3
- package/dist/config/unconfirmed-toml.d.ts +9 -0
- package/dist/config/unconfirmed-toml.js +29 -0
- package/dist/diagnostics.js +10 -1
- package/dist/docs/check.d.ts +16 -0
- package/dist/docs/check.js +197 -0
- package/dist/docs/decision-record.d.ts +34 -0
- package/dist/docs/decision-record.js +135 -0
- package/dist/docs/decisions.d.ts +16 -0
- package/dist/docs/decisions.js +103 -0
- package/dist/docs/markdown.d.ts +36 -0
- package/dist/docs/markdown.js +88 -0
- package/dist/docs/references.d.ts +32 -0
- package/dist/docs/references.js +148 -0
- package/dist/environment/application/confirm.d.ts +35 -0
- package/dist/environment/application/confirm.js +122 -0
- package/dist/environment/application/destructive.js +6 -2
- package/dist/environment/application/doctor.d.ts +12 -7
- package/dist/environment/application/doctor.js +20 -8
- package/dist/environment/application/guard.d.ts +12 -6
- package/dist/environment/application/guard.js +87 -32
- package/dist/environment/application/health.d.ts +14 -5
- package/dist/environment/application/health.js +8 -2
- package/dist/environment/application/lifecycle-context.d.ts +10 -3
- package/dist/environment/application/lifecycle-state.js +4 -3
- package/dist/environment/application/lifecycle.d.ts +2 -1
- package/dist/environment/application/lifecycle.js +11 -3
- package/dist/environment/application/services.d.ts +60 -0
- package/dist/environment/application/services.js +89 -0
- package/dist/environment/application/siblings.d.ts +43 -0
- package/dist/environment/application/siblings.js +269 -0
- package/dist/environment/claims.d.ts +10 -10
- package/dist/environment/claims.js +3 -11
- package/dist/environment/compose-topology.d.ts +15 -7
- package/dist/environment/compose-topology.js +100 -23
- package/dist/environment/contract.d.ts +42 -9
- package/dist/environment/contract.js +33 -0
- package/dist/environment/executable.d.ts +12 -0
- package/dist/environment/executable.js +46 -23
- package/dist/environment/generated-application/check.js +2 -0
- package/dist/environment/generated-application/prepare.js +2 -0
- package/dist/environment/generated-application/shared.d.ts +10 -2
- package/dist/environment/generated-application/shared.js +6 -1
- package/dist/environment/generated-application/surface-outputs.js +23 -12
- package/dist/environment/generated-application/surfaces.js +16 -11
- package/dist/environment/generated-application/sync.js +19 -4
- package/dist/environment/git-observation.d.ts +25 -6
- package/dist/environment/git-observation.js +37 -28
- package/dist/environment/health-composition.d.ts +3 -2
- package/dist/environment/health-composition.js +19 -2
- package/dist/environment/init-application.d.ts +39 -14
- package/dist/environment/init-application.js +39 -10
- package/dist/environment/lifecycle-composition.d.ts +4 -2
- package/dist/environment/lifecycle-composition.js +84 -17
- package/dist/environment/lifecycle-stage.d.ts +8 -3
- package/dist/environment/lifecycle-stage.js +11 -1
- package/dist/environment/logs.d.ts +1 -1
- package/dist/environment/map-limit.d.ts +2 -0
- package/dist/environment/map-limit.js +13 -0
- package/dist/environment/mcp-observation.d.ts +9 -0
- package/dist/environment/mcp-observation.js +46 -0
- package/dist/environment/observations.d.ts +1 -1
- package/dist/environment/observations.js +2 -0
- package/dist/environment/operator-application.d.ts +35 -6
- package/dist/environment/operator-application.js +42 -0
- package/dist/environment/presence.d.ts +4 -0
- package/dist/environment/presence.js +26 -0
- package/dist/environment/read-composition.d.ts +8 -3
- package/dist/environment/read-composition.js +53 -8
- package/dist/environment/readiness-composition.d.ts +20 -1
- package/dist/environment/readiness-composition.js +23 -2
- package/dist/environment/reclaim.d.ts +56 -19
- package/dist/environment/reclaim.js +147 -42
- package/dist/environment/runtime.d.ts +64 -18
- package/dist/environment/runtime.js +73 -3
- package/dist/environment/served-checkout-grants.d.ts +53 -0
- package/dist/environment/served-checkout-grants.js +182 -0
- package/dist/environment/sibling-checkouts.d.ts +119 -0
- package/dist/environment/sibling-checkouts.js +254 -0
- package/dist/environment/sibling-observation.d.ts +27 -0
- package/dist/environment/sibling-observation.js +45 -0
- package/dist/environment/sibling-pull.d.ts +23 -0
- package/dist/environment/sibling-pull.js +95 -0
- package/dist/environment/stack-inputs.d.ts +18 -0
- package/dist/environment/stack-inputs.js +210 -0
- package/dist/environment/stack-inventory-prune.d.ts +31 -0
- package/dist/environment/stack-inventory-prune.js +129 -0
- package/dist/environment/stack-inventory-report.d.ts +44 -0
- package/dist/environment/stack-inventory-report.js +78 -0
- package/dist/environment/stack-inventory.d.ts +94 -0
- package/dist/environment/stack-inventory.js +418 -0
- package/dist/environment/state.d.ts +48 -9
- package/dist/environment/state.js +142 -2
- package/dist/environment/tool-registration.js +3 -7
- package/dist/environment-exec/execute.d.ts +6 -3
- package/dist/environment-exec/execute.js +4 -0
- package/dist/fix-catalogue.d.ts +1 -1
- package/dist/generated-environment/adopt.js +4 -8
- package/dist/guards/answer-confirmation.d.ts +41 -0
- package/dist/guards/answer-confirmation.js +109 -0
- package/dist/guards/evaluator.d.ts +20 -3
- package/dist/guards/evaluator.js +39 -7
- package/dist/guards/local-identity.d.ts +6 -2
- package/dist/guards/local-identity.js +10 -4
- package/dist/guards/policy-change.d.ts +43 -0
- package/dist/guards/policy-change.js +159 -0
- package/dist/guards/policy-pin.d.ts +1 -1
- package/dist/guards/policy-pin.js +14 -12
- package/dist/init/command.d.ts +4 -3
- package/dist/init/command.js +36 -16
- package/dist/init/derive.d.ts +8 -6
- package/dist/init/derive.js +140 -36
- package/dist/init/draft.d.ts +13 -11
- package/dist/init/draft.js +54 -31
- package/dist/init/render.d.ts +18 -6
- package/dist/init/render.js +31 -9
- package/dist/repository-path.d.ts +9 -0
- package/dist/repository-path.js +16 -0
- package/dist/schema.d.ts +42 -75
- package/dist/schema.js +62 -11
- package/dist/surfaces/harness-registry.d.ts +80 -0
- package/dist/surfaces/harness-registry.js +29 -0
- package/dist/surfaces/mcp.d.ts +67 -17
- package/dist/surfaces/mcp.js +194 -31
- package/dist/surfaces/projection.d.ts +7 -7
- package/dist/surfaces/projection.js +41 -6
- package/dist/surfaces/render.d.ts +5 -44
- package/dist/surfaces/render.js +5 -2
- package/dist/team-metadata.js +2 -1
- package/dist/testing/test-protection.d.ts +34 -0
- package/dist/testing/test-protection.js +137 -0
- package/dist/testing/weakening.d.ts +15 -0
- package/dist/testing/weakening.js +30 -0
- package/dist/work-orders/application-closure.d.ts +7 -0
- package/dist/work-orders/application-closure.js +76 -0
- package/dist/work-orders/application-context.d.ts +162 -0
- package/dist/work-orders/application-context.js +137 -0
- package/dist/work-orders/application-decisions.d.ts +27 -0
- package/dist/work-orders/application-decisions.js +121 -0
- package/dist/work-orders/application-grading.d.ts +11 -0
- package/dist/work-orders/application-grading.js +212 -0
- package/dist/work-orders/application.d.ts +4 -97
- package/dist/work-orders/application.js +94 -254
- package/dist/work-orders/composition.d.ts +35 -58
- package/dist/work-orders/composition.js +216 -24
- package/dist/work-orders/contract.d.ts +22 -6
- package/dist/work-orders/contract.js +34 -16
- package/dist/work-orders/decisions.d.ts +23 -0
- package/dist/work-orders/decisions.js +55 -0
- package/dist/work-orders/store.d.ts +54 -5
- package/dist/work-orders/store.js +118 -24
- package/docs/README.md +6 -3
- package/docs/capability-matrix.md +17 -9
- package/docs/cli-reference.md +209 -1
- package/docs/command-list.md +12 -1
- package/docs/concepts.md +6 -4
- package/docs/configuration-essentials.md +7 -2
- package/docs/configuration-reference.md +18 -3
- package/docs/docs-check.md +76 -0
- package/docs/environment.md +194 -6
- package/docs/faq.md +5 -3
- package/docs/getting-started.md +109 -25
- package/docs/harness-surfaces.md +69 -2
- package/docs/safety-and-autonomy.md +56 -12
- package/docs/troubleshooting.md +29 -8
- package/docs/tutorial.md +3 -2
- package/docs/work-and-browser.md +180 -14
- package/libexec/browser-operation.cjs +86 -2
- package/package.json +2 -2
- package/surfaces/skills/cockpit-browser.skill.md +7 -2
- package/surfaces/skills/cockpit-explain.skill.md +1 -1
- package/surfaces/skills/cockpit-fix.skill.md +1 -1
- package/surfaces/skills/cockpit-setup.skill.md +3 -3
- package/surfaces/skills/cockpit-work.skill.md +1 -1
- package/surfaces/skills/procedures/explain.md +9 -4
- package/surfaces/skills/procedures/fix.md +25 -11
- package/surfaces/skills/procedures/setup.md +113 -40
- package/surfaces/skills/procedures/work.md +45 -16
package/docs/command-list.md
CHANGED
|
@@ -8,8 +8,11 @@ This generated index is for users choosing the command that owns their next oper
|
|
|
8
8
|
|
|
9
9
|
- `cockpit init`: Preview, then accept, a first cockpit setup for one or more agent tools.
|
|
10
10
|
- `cockpit setup`: Clone or locate the declared sibling repositories and link them.
|
|
11
|
+
- `cockpit use`: Serve a sibling from another of its checkouts, such as a worktree.
|
|
12
|
+
- `cockpit pull`: Fast-forward the cockpit and its siblings to their upstreams.
|
|
11
13
|
- `cockpit sibling`: Add or remove a repository in cockpit.toml (sibling add, sibling remove).
|
|
12
14
|
- `cockpit tool`: Add or remove an agent tool in cockpit.toml (tool add, tool remove).
|
|
15
|
+
- `cockpit confirm`: Confirm an init answer no person stated by running the observation that verifies it.
|
|
13
16
|
- `cockpit registry-resolve`: Turn a validated shell registry into data shell scripts can source.
|
|
14
17
|
- `cockpit upgrade`: Move the exact cockpit pin to a newer version and re-run sync.
|
|
15
18
|
|
|
@@ -26,9 +29,14 @@ This generated index is for users choosing the command that owns their next oper
|
|
|
26
29
|
- `cockpit preflight`: Check that the environment is healthy and ready for work.
|
|
27
30
|
- `cockpit session`: Keep the environment available for one command, then release it.
|
|
28
31
|
- `cockpit logs`: Show recent logs for one declared service.
|
|
32
|
+
- `cockpit ps`: Show the state and health of each service in this checkout's stack.
|
|
33
|
+
- `cockpit restart`: Restart one service of this checkout's stack and wait until it is healthy.
|
|
34
|
+
- `cockpit rebuild`: Rebuild one service's image, replace its container and wait until it is healthy.
|
|
35
|
+
- `cockpit exec`: Run a command inside one service's container of this checkout's stack.
|
|
29
36
|
- `cockpit sleep`: Release this checkout and stop the stack if no other holder remains.
|
|
30
37
|
- `cockpit down`: Stop and remove the stack (on the active local Docker context).
|
|
31
38
|
- `cockpit reset`: Preview a reset, then approve it interactively or apply it as [autonomy] reset allows (on the active local Docker context).
|
|
39
|
+
- `cockpit stacks`: List every stack on this machine, or preview and remove those whose checkout is gone (stacks prune).
|
|
32
40
|
|
|
33
41
|
## Diagnose
|
|
34
42
|
|
|
@@ -40,8 +48,10 @@ This generated index is for users choosing the command that owns their next oper
|
|
|
40
48
|
- `cockpit work status`: Report each work order, its state and how it closed.
|
|
41
49
|
- `cockpit work accept`: Accept a work order, or a change to an accepted one, as [work.gates] allows.
|
|
42
50
|
- `cockpit work check`: Run every criterion's check and the order's gates.
|
|
43
|
-
- `cockpit work note`: Record a note on an order,
|
|
51
|
+
- `cockpit work note`: Record a note on an order, an open question with --ask, or a decision with --decision.
|
|
52
|
+
- `cockpit work decide`: Resolve a recorded decision: write or cite its decision record, or say it is not lasting.
|
|
44
53
|
- `cockpit work answer`: Answer an open question on an order, as [work.gates] allows.
|
|
54
|
+
- `cockpit work acknowledge`: Acknowledge that an order weakened tests, as [work.gates] allows.
|
|
45
55
|
- `cockpit work grade`: Grade an accepted order the way [work] grading says.
|
|
46
56
|
- `cockpit work signoff`: Close a graded order as done, or any open one as partial or abandoned.
|
|
47
57
|
- `cockpit work recover`: Inspect or remove a crashed command's work-order lock.
|
|
@@ -49,3 +59,4 @@ This generated index is for users choosing the command that owns their next oper
|
|
|
49
59
|
- `cockpit grade`: Independently grade uncommitted work against a criteria file, with no work order.
|
|
50
60
|
- `cockpit browser drive`: Drive the declared application browser surfaces.
|
|
51
61
|
- `cockpit browser screenshot`: Capture the declared application surfaces.
|
|
62
|
+
- `cockpit docs check`: Report removed paths and make targets living docs still cite, and broken decision records.
|
package/docs/concepts.md
CHANGED
|
@@ -68,10 +68,12 @@ holds its schema and limits.
|
|
|
68
68
|
### Evaluator
|
|
69
69
|
|
|
70
70
|
The grader for a finished work order under the default `independent` grading. It grades each
|
|
71
|
-
acceptance criterion
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
acceptance criterion, and the standing criteria cockpit adds (changes outside scope, flagged test
|
|
72
|
+
changes, the agent's amendments), against the checks cockpit ran and the change since the order was
|
|
73
|
+
accepted, in a fresh read-only run that never sees the session that did the work, in another listed
|
|
74
|
+
agent tool when one is available, otherwise the same tool in a new run. It never edits code. A cockpit
|
|
75
|
+
can instead let the checks alone decide, or let the agent report its own verdict; the record says
|
|
76
|
+
which.
|
|
75
77
|
|
|
76
78
|
### Enforced, instructed, generated and unavailable
|
|
77
79
|
|
|
@@ -22,7 +22,8 @@ siblings_root = ".."
|
|
|
22
22
|
## `[[sibling]]`
|
|
23
23
|
|
|
24
24
|
One table per product repository. `mount` says how the stack uses the checkout: `always`
|
|
25
|
-
bind-mounts it, `profile:<name>` mounts it only
|
|
25
|
+
bind-mounts it, `profile:<name>` mounts it only while that Compose profile is active
|
|
26
|
+
([Compose profiles](environment.md#compose-profiles)), `none` leaves it read
|
|
26
27
|
but never mounted, and `host` runs it outside the stack for the reason given in `host_reason`.
|
|
27
28
|
`acquire` says how it reaches disk: `auto` clones `remote` during `setup`, `manual` expects a
|
|
28
29
|
person to clone it, and `none` never clones it, so it must already be there. The two are
|
|
@@ -90,12 +91,15 @@ as written ([Compose-first stacks](environment.md#compose-first-stacks)). A smal
|
|
|
90
91
|
Compose file gets a starting one from `cockpit init --scaffold-compose`
|
|
91
92
|
([Scaffold a Compose file](environment.md#scaffold-a-compose-file)). `resettable_volumes` names the
|
|
92
93
|
Compose volumes `reset` may delete, and `seed` the command `up` runs to fill them
|
|
93
|
-
([Demo data, test users and roles](environment.md#demo-data-test-users-and-roles)).
|
|
94
|
+
([Demo data, test users and roles](environment.md#demo-data-test-users-and-roles)). `profiles`
|
|
95
|
+
names the Compose profiles every `up` activates; `up --profile <name>` adds one for a run
|
|
96
|
+
([Compose profiles](environment.md#compose-profiles)). Full entry:
|
|
94
97
|
[`[environment]`](configuration-reference.md#environment).
|
|
95
98
|
|
|
96
99
|
```toml
|
|
97
100
|
[environment]
|
|
98
101
|
compose_files = ["compose.yml"]
|
|
102
|
+
profiles = ["workers"]
|
|
99
103
|
resettable_volumes = ["postgres-data"]
|
|
100
104
|
seed = { argv = ["npm", "run", "db:seed"], timeout_seconds = 300 }
|
|
101
105
|
```
|
|
@@ -170,3 +174,4 @@ reference also lists the [defaults](configuration-reference.md#defaults) and the
|
|
|
170
174
|
| MCP approvals | [`[mcp]`](configuration-reference.md#mcp) | [MCP servers and restrictions](harness-surfaces.md#mcp-servers-and-restrictions) |
|
|
171
175
|
| Surface overlays | [`[[surfaces.overlays]]`](configuration-reference.md#surfacesoverlays) | [Ownership and extension](harness-surfaces.md#ownership-and-extension) |
|
|
172
176
|
| Custom harnesses | [`[[surfaces.harnesses]]`](configuration-reference.md#surfacesharnesses) | [Custom harnesses](harness-surfaces.md#custom-harnesses) |
|
|
177
|
+
| Living documents and decision records | [`[docs]`](configuration-reference.md#docs) | [Check living documents and decision records](docs-check.md) |
|
|
@@ -54,6 +54,7 @@ The values cockpit uses for a key the configuration leaves out.
|
|
|
54
54
|
"resettable_volumes": [],
|
|
55
55
|
"generated_host_paths": [],
|
|
56
56
|
"compose_files": [],
|
|
57
|
+
"profiles": [],
|
|
57
58
|
"entrypoint_derivatives": [],
|
|
58
59
|
"install_policies": []
|
|
59
60
|
},
|
|
@@ -91,6 +92,7 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
91
92
|
| `testing` | Test stages and gates. | table: [`[testing]`](#testing) | | |
|
|
92
93
|
| `environment` | How the stack is reached, signed in to, built and kept. | table: [`[environment]`](#environment) | `{}` | |
|
|
93
94
|
| `surfaces` | Instructions, skills and settings generated for agent tools. | table: [`[surfaces]`](#surfaces) | `{}` | |
|
|
95
|
+
| `docs` | Living documents and decision records: docs check keeps them true, and work orders record their decisions there. | table: [`[docs]`](#docs) | | |
|
|
94
96
|
|
|
95
97
|
### `[cockpit]`
|
|
96
98
|
|
|
@@ -118,6 +120,7 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
118
120
|
| `instruction_pointer` | Let setup add a pointer to the cockpit guide in this sibling, when the command line also approves it. | boolean | `false` | |
|
|
119
121
|
| `purpose` | What the sibling is for; printed when its checkout is missing. | string | | required; at least 1 character |
|
|
120
122
|
| `environment_files` | Template and instance environment file pairs the sibling needs. | array of table: [`[[sibling.environment_files]]`](#siblingenvironment_files) | | |
|
|
123
|
+
| `rebuild_inputs` | Files or directories in the sibling, beyond its lockfiles, whose change leaves a running stack stale, such as a migrations directory. | array of string | | at most 64 items; each item: pattern [P1](#patterns) |
|
|
121
124
|
| `derives` | Facts about the sibling that cockpit derives rows or MCP servers from. | table: [`[sibling.derives]`](#siblingderives) | | |
|
|
122
125
|
|
|
123
126
|
- Must match `{"oneOf":[{"properties":{"acquire":{"enum":["none"]}},"not":{"required":["remote"]}},{"properties":{"acquire":{"enum":["auto","manual"]}},"required":["remote"]}]}`.
|
|
@@ -209,9 +212,10 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
209
212
|
| Key | Meaning | Type | Default | Constraints |
|
|
210
213
|
| --- | --- | --- | --- | --- |
|
|
211
214
|
| `accept` | Who accepts a draft work order: agent, person or ci. Default agent. | string | | one of `"agent"`, `"person"`, `"ci"` |
|
|
212
|
-
| `amend` | Who accepts a changed contract. Default agent. Removing
|
|
215
|
+
| `amend` | Who accepts a changed contract. Default agent. Removing an accepted criterion or gate always needs a person or ci; an agent's rewrite of a criterion, scope, non-goal or objective is judged at the next grade, and needs a person under checks grading. | string | | one of `"agent"`, `"person"`, `"ci"` |
|
|
213
216
|
| `answer` | Who answers an open question on an order. Default agent. | string | | one of `"agent"`, `"person"`, `"ci"` |
|
|
214
217
|
| `signoff` | Who closes a graded order. Default agent. | string | | one of `"agent"`, `"person"`, `"ci"` |
|
|
218
|
+
| `acknowledge` | Who acknowledges that an order weakened tests, which checks grading otherwise fails; under independent and self grading the acknowledgement is context for the verdict. Default agent. | string | | one of `"agent"`, `"person"`, `"ci"` |
|
|
215
219
|
|
|
216
220
|
### `[autonomy]`
|
|
217
221
|
|
|
@@ -238,7 +242,7 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
238
242
|
| `resolver` | Fixed host name to address mappings the browser uses. | array of table: [`[[browser.resolver]]`](#browserresolver) | `[]` | at most 64 items |
|
|
239
243
|
| `authentication` | How browser sessions sign in to the application. | table: [`[browser.authentication]`](#browserauthentication) | | required |
|
|
240
244
|
| `data` | Statement about the data the browser touches; cockpit cannot observe it. | table: [`[browser.data]`](#browserdata) | | required |
|
|
241
|
-
| `request_preapproval` | Run browser tools without prompts; allowed only on isolated, non-production, non-restored data.
|
|
245
|
+
| `request_preapproval` | Run browser tools without prompts; allowed only on isolated, non-production, non-restored data. Defaults to true when data qualifies and false otherwise. | boolean | | |
|
|
242
246
|
| `artifacts` | Generated host paths for browser output. | table: [`[browser.artifacts]`](#browserartifacts) | | required |
|
|
243
247
|
|
|
244
248
|
- Must match at least one of `[{"properties":{"request_preapproval":{"enum":[false]}}},{"properties":{"data":{"required":["mode","isolated","reaches_production"],"properties":{"mode":{"enum":["empty","seeded"]},"isolated":{"enum":[true]},"reaches_production":{"enum":[false]}}}}}]`.
|
|
@@ -324,6 +328,7 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
324
328
|
|
|
325
329
|
| Key | Meaning | Type | Default | Constraints |
|
|
326
330
|
| --- | --- | --- | --- | --- |
|
|
331
|
+
| `test_files` | Paths and globs, relative to each checkout, that hold tests. Grading fails an order that deletes, skips or loosens what they match. Defaults to common layouts. | array of string | | 1–64 items; each item: pattern `^(?!\/)(?!.*(?:^\|\/)\.\.(?:\/\|$))[A-Za-z0-9._@+\-/*?]+$`, 1–512 characters |
|
|
327
332
|
| `stages` | Commands that make up the test gates. | array of table: [`[[testing.stages]]`](#testingstages) | | required; 1–128 items |
|
|
328
333
|
| `gates` | Named gates that run stages before handing back changes. | array of table: [`[[testing.gates]]`](#testinggates) | | required; 1–128 items |
|
|
329
334
|
| `native_hooks` | How the repository's own git hooks are handled. | table: [`[testing.native_hooks]`](#testingnative_hooks) | `{"install":"inspect"}` | |
|
|
@@ -383,6 +388,7 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
383
388
|
| `resettable_volumes` | Compose volumes that reset may delete and recreate, named by their Compose key. | array of string | `[]` | unique items; each item: pattern `^[a-z0-9][a-z0-9_.-]*$` |
|
|
384
389
|
| `generated_host_paths` | Host paths cockpit generates and owns, relative to the cockpit. | array of string | `[]` | unique items; each item: pattern [P1](#patterns) |
|
|
385
390
|
| `compose_files` | Compose files, relative to the cockpit, that make up the stack; cockpit runs them as written. | array of string | `[]` | unique items; each item: pattern [P1](#patterns), pattern `^[^:]+$` |
|
|
391
|
+
| `profiles` | Compose profiles every up and session activates; up --profile adds more for one run. | array of string | `[]` | at most 64 items; each item: pattern `^[a-z0-9][a-z0-9_.-]*$`, at most 64 characters |
|
|
386
392
|
| `entrypoint_derivatives` | Addresses derived from leased ports, such as application origins and callback URLs. | array of table: [`[[environment.entrypoint_derivatives]]`](#environmententrypoint_derivatives) | `[]` | |
|
|
387
393
|
| `install_policies` | The build and test commands the guard admits for each toolchain and lockfile. | array of table: [`[[environment.install_policies]]`](#environmentinstall_policies) | `[]` | |
|
|
388
394
|
| `seed` | Command up runs once the stack is healthy, whenever a resettable volume was created since the last successful seed. | table: [`[environment.seed]`](#environmentseed) | | |
|
|
@@ -523,6 +529,14 @@ Each section is one TOML table: `[name]` holds one, `[[name]]` repeats. A table
|
|
|
523
529
|
| `adopted_on` | Date the file was adopted. | string | | required; format `date`; pattern [P2](#patterns) |
|
|
524
530
|
| `provenance` | Where the adoption came from; its kind must be declared. | table: [`provenance` shape](#provenance-shape) | | required |
|
|
525
531
|
|
|
532
|
+
### `[docs]`
|
|
533
|
+
|
|
534
|
+
| Key | Meaning | Type | Default | Constraints |
|
|
535
|
+
| --- | --- | --- | --- | --- |
|
|
536
|
+
| `living` | Globs of the Markdown documents that must stay true; docs check reports the paths and make targets they cite that the repository has since removed. | array of string | `[]` | at most 64 items; each item: pattern `^(?!(?:[a-z0-9][a-z0-9-]{0,63}:)?(?:.*\/)?\.\.(?:\/\|$))(?:[a-z0-9][a-z0-9-]{0,63}:)?(?![/])[A-Za-z0-9._@+\-/*?]+$`, at most 1024 characters |
|
|
537
|
+
| `decisions` | Directory of decision records, such as docs/adr. Work orders record their lasting decisions there, and docs check reports duplicate numbers, missing statuses and broken supersedes links. | string | | pattern [P7](#patterns); at most 1024 characters |
|
|
538
|
+
| `decisions_index` | Index file that links every decision record; a record cockpit writes is appended to it, and docs check reports records it omits and links to records that do not exist. | string | | pattern [P7](#patterns); at most 1024 characters |
|
|
539
|
+
|
|
526
540
|
## Shapes
|
|
527
541
|
|
|
528
542
|
These tables recur in several places; each place links here instead of repeating the keys.
|
|
@@ -558,6 +572,7 @@ Long patterns that several keys share, cited by name in the tables.
|
|
|
558
572
|
| P4 | `^[^\x00-\x1f\x7f-\x9f\uD800-\uDFFF]{1,128}(?![\s\S])` |
|
|
559
573
|
| P5 | `^(?:0\|[1-9]\d*)\.(?:0\|[1-9]\d*)\.(?:0\|[1-9]\d*)(?:-(?:0\|[1-9]\d*\|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0\|[1-9]\d*\|\d*[A-Za-z-][0-9A-Za-z-]*))*)?$` |
|
|
560
574
|
| P6 | `^(?!.*(?:^\|\/)(?:\.git\|internal\|node_modules)(?:\/\|$)).+$` |
|
|
575
|
+
| P7 | `^(?!(?:[a-z0-9][a-z0-9-]{0,63}:)?(?:.*\/)?\.\.?(?:\/\|$))(?:[a-z0-9][a-z0-9-]{0,63}:)?(?![/])[A-Za-z0-9._@+\-/]*[A-Za-z0-9._@+-]$` |
|
|
561
576
|
|
|
562
577
|
## Checks beyond the schema
|
|
563
578
|
|
|
@@ -616,6 +631,6 @@ Agent tools load every skill's frontmatter into each session and its entry point
|
|
|
616
631
|
| `packages/cockpit/surfaces/skills/cockpit-fix.skill.md` | lines | 12 | `packages/cockpit/surfaces/skills/procedures/fix.md` |
|
|
617
632
|
| `packages/cockpit/surfaces/skills/cockpit-work.skill.md` | lines | 9 | `packages/cockpit/surfaces/skills/procedures/work.md` |
|
|
618
633
|
|
|
619
|
-
Each procedure is read on demand and has no size limit: `packages/cockpit/surfaces/skills/procedures/setup.md` (SHA-256 `
|
|
634
|
+
Each procedure is read on demand and has no size limit: `packages/cockpit/surfaces/skills/procedures/setup.md` (SHA-256 `f8aa06a781db377ce38e34517f64a523f631e9c6122a13073e38cba46f1d7a0e`), `packages/cockpit/surfaces/skills/procedures/explain.md` (SHA-256 `3055cd5929e13266151a1f5657e6ed6a0d9f2a43545770bda5a0dbe6b9a2c0f9`), `packages/cockpit/surfaces/skills/procedures/fix.md` (SHA-256 `ccb7c2e0c568d0a218c1c4bd8cdb31e5fad67e65df5018b73fe71207b0b555aa`) and `packages/cockpit/surfaces/skills/procedures/work.md` (SHA-256 `037ac35ad0c49202a19a6ee7a65104a9ed052917ac4fb3e15d4f49127103ba20`).
|
|
620
635
|
|
|
621
636
|
<!-- cockpit:ref schema=cockpit.guide_cap --> `cockpit.guide_cap` limits always-loaded guidance to 200 lines by default. The measured cost depends on each configuration's sibling guides, so it is not listed here.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Check living documents and decision records
|
|
2
|
+
|
|
3
|
+
`cockpit docs check` reports documents that have drifted from the repositories they describe: a
|
|
4
|
+
living document that still cites a path or `make` target the repository has removed, and a
|
|
5
|
+
decision-record set whose numbers, index, statuses or supersedes links no longer agree. It reads
|
|
6
|
+
files and runs read-only Git; it changes nothing.
|
|
7
|
+
|
|
8
|
+
## Declare what to check
|
|
9
|
+
|
|
10
|
+
<!-- cockpit:ref schema=docs.living --> List the documents that must stay true under `[docs]` in
|
|
11
|
+
`cockpit.toml`. Each entry is a glob in the cockpit's own repository, or `<sibling slug>:<glob>` in
|
|
12
|
+
a sibling, spelt as a work order's scope is. `decisions` and `decisions_index` are optional and
|
|
13
|
+
name a directory of decision records and the file that links them. Full entry:
|
|
14
|
+
[`[docs]`](configuration-reference.md#docs).
|
|
15
|
+
|
|
16
|
+
```toml
|
|
17
|
+
[docs]
|
|
18
|
+
living = ["README.md", "AGENTS.md", "docs/**/*.md", "api:README.md"]
|
|
19
|
+
decisions = "docs/adr"
|
|
20
|
+
decisions_index = "docs/adr/README.md"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Leave append-only logs and backlogs out of `living`: they are full of proposals and history, and
|
|
24
|
+
are true as records of their time. Without `[docs]` the command refuses with `DOCS_NOT_DECLARED`
|
|
25
|
+
rather than passing on nothing, and an entry that matches no file is reported as
|
|
26
|
+
`DOCS_DECLARATION_UNMATCHED`.
|
|
27
|
+
|
|
28
|
+
## Run it
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npx --no cockpit docs check --config cockpit.toml
|
|
32
|
+
npx --no cockpit docs check --config cockpit.toml --json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
It exits 2 when it reports anything, so a CI job runs it the way it runs `work verify`. The guard
|
|
36
|
+
admits it for agents without asking, because it writes nothing. `doctor` names it when `[docs]` is
|
|
37
|
+
declared but does not run it, and `check` does not run it either: both report on the environment
|
|
38
|
+
and its generated files, while this reads every repository's history and judges prose, which is a
|
|
39
|
+
different verdict and a slower one.
|
|
40
|
+
|
|
41
|
+
## Stale references
|
|
42
|
+
|
|
43
|
+
A path counts when it is an inline code span or a relative link target; spans resolve from the
|
|
44
|
+
repository root, links from the document. A `make` target counts when an inline code span or a
|
|
45
|
+
shell fence runs it. Either is reported only when it existed in the repository's history and does
|
|
46
|
+
not exist now:
|
|
47
|
+
|
|
48
|
+
- `DOCS_REFERENCE_REMOVED`: the path was deleted, or renamed, in which case the message names
|
|
49
|
+
where it went.
|
|
50
|
+
- `DOCS_TARGET_REMOVED`: a Makefile once defined the target and none does now.
|
|
51
|
+
|
|
52
|
+
Keying on history keeps proposals quiet: "add `make park`" names a target that never existed, so
|
|
53
|
+
it is not reported, and no allowlist is needed. A link that never resolved is a link checker's
|
|
54
|
+
job, not this one. npm and pnpm scripts are not checked.
|
|
55
|
+
|
|
56
|
+
## Decision records
|
|
57
|
+
|
|
58
|
+
The records are the Markdown files directly inside `decisions`, except the index, a `README.md`
|
|
59
|
+
and any file named as a template.
|
|
60
|
+
|
|
61
|
+
| Code | Reported when |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `DECISION_NUMBER_REUSED` | two records share a numeric prefix; dated names such as `2026-09-cache.md` are not numbered |
|
|
64
|
+
| `DECISION_UNINDEXED` | `decisions_index` does not link a record |
|
|
65
|
+
| `DECISION_INDEX_ENTRY_MISSING` | `decisions_index` links a record file that does not exist |
|
|
66
|
+
| `DECISION_STATUS_MISSING` | the status is absent or does not start with proposed, accepted, superseded, deprecated or rejected |
|
|
67
|
+
| `DECISION_LINK_UNRESOLVED` | a "Supersedes" or "Superseded by" names no record |
|
|
68
|
+
| `DECISION_SUPERSEDED_STALE` | an accepted record supersedes another in full, and that one still says accepted |
|
|
69
|
+
|
|
70
|
+
The status is read from `status:` in YAML front matter, a `Status:` line (bold or not), or the
|
|
71
|
+
first line under a `## Status` heading. A supersedes reference is a link, a file name, `ADR-12`,
|
|
72
|
+
`#12`, or a number right after the keyword. "Supersedes 0012" replaces the whole record;
|
|
73
|
+
"supersedes the retry clause of 0012" replaces part of it, so 0012 only has to exist.
|
|
74
|
+
|
|
75
|
+
What this cannot see is a decision that was made and never written down; nothing here makes an
|
|
76
|
+
agent record one.
|
package/docs/environment.md
CHANGED
|
@@ -34,7 +34,7 @@ input passed validation.
|
|
|
34
34
|
| `environment.compose_files` | compose first | the surfaces, plus `check` reads the Compose topology | run the declared Compose files |
|
|
35
35
|
|
|
36
36
|
The runtime commands are `up`, `sleep`, `session`, `down`,
|
|
37
|
-
`reset`, `preflight`, `logs` and `runtime measure`. Every mode writes the harness
|
|
37
|
+
`reset`, `preflight`, `logs`, `ps`, `restart`, `rebuild`, `exec` and `runtime measure`. Every mode writes the harness
|
|
38
38
|
[surfaces](concepts.md#surface) (instructions, skills, guards, permissions, evaluator and work
|
|
39
39
|
orders) and checks them for [drift](concepts.md#drift). A cockpit that declares only
|
|
40
40
|
`[environment.machine]` still gets the machine-capacity checks in `preflight`, so it is not refused
|
|
@@ -66,12 +66,21 @@ with `COMPOSE_TOPOLOGY_UNAVAILABLE` if Docker cannot produce it. It also checks:
|
|
|
66
66
|
`COMPOSE_PORT_ALL_INTERFACES`, because Docker then binds every interface and the service is
|
|
67
67
|
reachable from the network; write `"127.0.0.1:${API_HOST_PORT}:3000"`, or name `0.0.0.0` when you
|
|
68
68
|
mean the wider exposure;
|
|
69
|
+
- a service that sets `container_name` fails with `COMPOSE_CONTAINER_NAME_FIXED`, because Docker allows
|
|
70
|
+
one container of a name and the second checkout's stack would fail to start; remove it and address
|
|
71
|
+
the service by its Compose service name, or with `docker compose exec <service>`;
|
|
72
|
+
- a service with `build` and a fixed `image` fails with `COMPOSE_IMAGE_TAG_SHARED`, because every
|
|
73
|
+
checkout builds to the same tag and one checkout's build replaces the image another's stack runs;
|
|
74
|
+
remove `image`, so Compose names the build after the stack's own project;
|
|
75
|
+
- a profile in `environment.profiles` or a `profile:<name>` mount that no service declares fails
|
|
76
|
+
with `COMPOSE_PROFILE_UNDEFINED`, because Compose accepts an unknown profile and starts nothing
|
|
77
|
+
for it;
|
|
69
78
|
- a service with no Compose healthcheck warns with `COMPOSE_HEALTHCHECK_MISSING`, because running
|
|
70
79
|
is then treated as ready;
|
|
71
80
|
- an image referenced by tag rather than digest warns with `COMPOSE_IMAGE_UNPINNED`.
|
|
72
81
|
|
|
73
82
|
`doctor` reports a refusal from this check as itself, with its fix, not as the surface evidence it makes
|
|
74
|
-
unavailable. `init` shows the port and healthcheck findings beside the drafted `cockpit.toml`, as
|
|
83
|
+
unavailable. `init` shows the port, container name, shared image tag and healthcheck findings beside the drafted `cockpit.toml`, as
|
|
75
84
|
warnings carrying the same fix; it never edits a Compose file, so apply the edit before or right after
|
|
76
85
|
accepting.
|
|
77
86
|
|
|
@@ -128,6 +137,25 @@ each image by digest when you can. The file is yours from then
|
|
|
128
137
|
on: cockpit runs it as written and never rewrites it, and the scaffold refuses with
|
|
129
138
|
`INIT_SCAFFOLD_COMPOSE_EXISTS` when the cockpit root already holds any Compose file.
|
|
130
139
|
|
|
140
|
+
### Compose profiles
|
|
141
|
+
|
|
142
|
+
A service with `profiles: [workers]` in the Compose file runs only while that profile is active.
|
|
143
|
+
`environment.profiles` lists the profiles every `up` and `session` activates, and
|
|
144
|
+
`up --profile <name>` or `session --profile <name>`, repeated for several, adds more for that run.
|
|
145
|
+
A sibling declared `mount = "profile:<name>"` is mounted, and checked as mounted, exactly while its
|
|
146
|
+
profile is active; the generated agent files follow `environment.profiles`. A profile no service
|
|
147
|
+
declares is refused with `COMPOSE_PROFILE_UNDEFINED`, by `check` for the declared ones and by `up`
|
|
148
|
+
for the requested ones.
|
|
149
|
+
|
|
150
|
+
The stack records the profiles it started with, and every later command on it, `down`, `sleep`,
|
|
151
|
+
`logs`, `preflight`, `ps` and the service verbs included, activates the same set, so `down` removes
|
|
152
|
+
the profile services too. A plain `up` or `session` joins the running stack with its recorded set.
|
|
153
|
+
Adding a profile changes what the stack runs, so `up` refuses it on a running stack with
|
|
154
|
+
`LIFECYCLE_PROGRESS_INVALID`, as it refuses any change to what the stack was started from: run
|
|
155
|
+
`down`, then `up --profile <name>`. `check` judges each service's bind mounts under the default
|
|
156
|
+
set and under the default set plus each other profile, so a bind that only one profile set would
|
|
157
|
+
refuse still fails `check`.
|
|
158
|
+
|
|
131
159
|
## Local URLs and port families
|
|
132
160
|
|
|
133
161
|
Write each published port with an explicit loopback binding in your Compose file, as in
|
|
@@ -222,6 +250,63 @@ stale key names. Restore the named checkout or bring its instance keys in line w
|
|
|
222
250
|
then rerun `cockpit doctor --config cockpit.toml`. When no sibling declares an environment file,
|
|
223
251
|
the instance-presence and key-freshness checks pass: there is nothing to seed or compare.
|
|
224
252
|
|
|
253
|
+
## Serve a sibling from a worktree
|
|
254
|
+
|
|
255
|
+
The stack mounts each sibling's declared checkout. When you work on a branch in another checkout of
|
|
256
|
+
that repository, usually a linked worktree, point the sibling at it for this cockpit checkout:
|
|
257
|
+
|
|
258
|
+
```sh
|
|
259
|
+
npx --no cockpit use api /path/to/api/.worktrees/feature --config cockpit.toml
|
|
260
|
+
npx --no cockpit use api --clear --config cockpit.toml
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
`use` accepts the root of a checkout that shares the declared checkout's object store, or whose
|
|
264
|
+
`origin` names the same repository as the declared checkout or its `remote`; anything else is
|
|
265
|
+
refused with `SIBLING_CHECKOUT_FOREIGN`. Name the checkout's own directory: a path that reaches it
|
|
266
|
+
through a symbolic link is refused. The choice is recorded in `.cockpit/local/sibling-checkouts`,
|
|
267
|
+
never in `cockpit.toml`, so it applies to this checkout of the cockpit alone. `up`, `logs`, the guard's
|
|
268
|
+
allowed roots and protected instance files, `doctor` and `preflight`, work orders (checks, grades,
|
|
269
|
+
test gates and test-weakening detection) and `docs check` all use the recorded checkout, and each
|
|
270
|
+
refuses with `SIBLING_CHECKOUT_UNAVAILABLE` once that checkout is gone. `doctor` and `preflight`
|
|
271
|
+
name each one (`SIBLING_CHECKOUT_OVERRIDDEN`) and warn with
|
|
272
|
+
`SIBLING_ENVIRONMENT_FILE_MISSING` for every declared environment file the worktree lacks: a fresh
|
|
273
|
+
worktree has none of the ignored ones, and cockpit never copies them from another checkout.
|
|
274
|
+
|
|
275
|
+
A running stack keeps the checkout it mounted: run `down` and `up` after `use`. An agent may run
|
|
276
|
+
`use` for a checkout inside a directory it may already write; any other path is a person's call. The
|
|
277
|
+
directory grants `sync` writes for each agent tool are committed and name the declared checkout, so a
|
|
278
|
+
worktree kept inside it stays reachable without a prompt. For a checkout outside it, `use` grants
|
|
279
|
+
the tools that read a machine-local setting, and `use --clear` takes that grant back:
|
|
280
|
+
|
|
281
|
+
- **Claude Code**: `use` adds the checkout to `permissions.additionalDirectories` in
|
|
282
|
+
`.claude/settings.local.json`, keeping everything else in the file, and removes only the entry it
|
|
283
|
+
added. It refuses a file it cannot parse rather than rewrite it, because Claude Code ignores such
|
|
284
|
+
a file entirely.
|
|
285
|
+
- **OpenCode**: `use` writes the checkout to the machine-local grant file `sync` writes for the
|
|
286
|
+
sibling, and `sync` keeps it there.
|
|
287
|
+
- **Codex** has no machine-local setting for extra writable roots, so its sandbox still reaches only
|
|
288
|
+
the declared checkout: start Codex with `--add-dir <checkout>`.
|
|
289
|
+
- **Cursor** and **Grok Build** have no measured machine-local grant, so `use` writes nothing for
|
|
290
|
+
them and they may ask before editing the checkout.
|
|
291
|
+
|
|
292
|
+
`use` lists in its output which tools got the grant, and `--json` reports them as `agentGrants`.
|
|
293
|
+
Restart an agent session that is already running so it reads the new grant.
|
|
294
|
+
[Harness surfaces](harness-surfaces.md#sibling-projection-and-standing-cost) records what was measured.
|
|
295
|
+
|
|
296
|
+
## Bring checkouts up to date
|
|
297
|
+
|
|
298
|
+
`cockpit pull --config cockpit.toml` fetches and fast-forwards the cockpit and every sibling
|
|
299
|
+
checkout, including one `use` recorded, to the upstream of the branch each has checked out. It
|
|
300
|
+
never merges, rebases, stashes or switches branch, and it runs no Git hooks. A checkout with
|
|
301
|
+
modified tracked files, a branch that has diverged from its upstream, an upstream that is gone or a
|
|
302
|
+
failed fetch is left exactly as it was and reported with `PULL_SKIPPED` and the command that
|
|
303
|
+
resolves it; a detached HEAD or a branch that tracks nothing is listed and skipped without a
|
|
304
|
+
warning. Like `setup`, its Git reads only each repository's own configuration, so a credential
|
|
305
|
+
helper set only in your global Git configuration is not used, and a repository whose attributes name
|
|
306
|
+
a filter defined only there, such as Git LFS, is skipped rather than checked out as placeholder
|
|
307
|
+
files; run `git pull --ff-only` in it yourself. Because it can only fast-forward, an
|
|
308
|
+
agent may run it without asking.
|
|
309
|
+
|
|
225
310
|
## Lifecycle and ownership
|
|
226
311
|
|
|
227
312
|
`setup` gets the declared sibling checkouts onto disk and wires them up. `mount` controls how the
|
|
@@ -375,6 +460,65 @@ identity, control socket or stop confirmation did not match; cockpit then keeps
|
|
|
375
460
|
refuses any overlapping cleanup. Do not remove its state or runtime resources by hand: that
|
|
376
461
|
destroys the records cockpit needs to repair it safely.
|
|
377
462
|
|
|
463
|
+
### List and prune stacks across the machine
|
|
464
|
+
|
|
465
|
+
Each checkout gets its own stack, port lease and state, so deleting a worktree leaves its containers,
|
|
466
|
+
network, volumes and lease behind with no checkout left to run `down` from. `stacks` lists every
|
|
467
|
+
stack this machine knows about, whichever cockpit and checkout started it, and changes nothing:
|
|
468
|
+
|
|
469
|
+
```sh
|
|
470
|
+
npx --no cockpit stacks --config cockpit.toml --json
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
It reads cockpit's state root and the containers, networks and volumes on the local Docker daemon
|
|
474
|
+
that carry cockpit's ownership labels, and attributes a resource to a stack only when all of them
|
|
475
|
+
are present and well formed; nothing is attributed by its name. Each row gives the cockpit, the stack,
|
|
476
|
+
its Compose project, its checkout, the state record and whether this version can read it, running
|
|
477
|
+
and stopped containers, networks, volumes, the port lease it still holds, its last recorded
|
|
478
|
+
activity, and a verdict with the reason.
|
|
479
|
+
|
|
480
|
+
A stack's checkout is proven, never guessed. Compose labels each container with the directory it
|
|
481
|
+
ran from, and the ancestor whose checkout identity derives the stack's own identity is its
|
|
482
|
+
checkout; or the cockpit's main checkout is known and none of the checkouts Git records for it
|
|
483
|
+
derives the stack. `checkout.source` says which. The checkout is `present`, `missing`, `replaced`
|
|
484
|
+
(the path exists but is no longer a checkout of that cockpit) or `unknown`. A worktree whose path
|
|
485
|
+
does not exist while Git still registers it, or marks it locked, is `unknown`, not `missing`: a
|
|
486
|
+
drive or share that is not mounted, or a checkout moved without `git worktree repair`, looks exactly
|
|
487
|
+
like that. Once such a checkout is really gone, `git worktree prune` in its main checkout (after
|
|
488
|
+
`git worktree unlock` for a locked one) lets `stacks prune` remove its stack.
|
|
489
|
+
|
|
490
|
+
A stack is `orphaned` only when its checkout is proven `missing`. Every other stack is kept: one
|
|
491
|
+
whose checkout exists or cannot be found, one that a `down` or `reset` is still draining, the
|
|
492
|
+
current checkout's own, and one whose state this cockpit version cannot read, because a newer
|
|
493
|
+
version may still use it for a checkout that exists. A state folder this version cannot read is
|
|
494
|
+
listed with the stacks; one in the colon spelling an earlier build used is orphaned once none of its
|
|
495
|
+
stacks is kept, and one named as current versions name their state is kept for a version that reads
|
|
496
|
+
it.
|
|
497
|
+
|
|
498
|
+
`stacks prune` shows exactly what it would remove and a digest of it, and removes nothing:
|
|
499
|
+
|
|
500
|
+
```sh
|
|
501
|
+
npx --no cockpit stacks prune --config cockpit.toml
|
|
502
|
+
npx --no cockpit stacks prune --config cockpit.toml --apply
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
`--apply` observes the machine again and removes only while the plan still has the previewed digest:
|
|
506
|
+
each orphan's containers, then its networks and labelled volumes, then the state records that hold
|
|
507
|
+
its port lease, then the orphaned state folders. State is removed only while every file still holds
|
|
508
|
+
the bytes the preview read, under the lock `up` takes to lease ports. A step that fails stops the
|
|
509
|
+
prune with `STACKS_PRUNE_INCOMPLETE`; what it had not removed stays listed, and running `--apply`
|
|
510
|
+
again resumes. The result is reported only once a fresh inventory no longer lists what was removed.
|
|
511
|
+
|
|
512
|
+
Removing an orphan is housekeeping, so `--apply` runs for an agent. A prune that deletes volumes
|
|
513
|
+
deletes data, and follows the reset gate: it runs only where `[autonomy] reset` lets the caller
|
|
514
|
+
reset, and otherwise a person runs `stacks prune --interactive` in a terminal and types the
|
|
515
|
+
preview's digest. That gate is the running cockpit's own policy and says nothing for another
|
|
516
|
+
cockpit's, so `--apply` removes only this cockpit's orphans and the state folders an earlier build
|
|
517
|
+
left. The preview still lists every orphan, marks each with `thisCockpit`, and warns with
|
|
518
|
+
`STACKS_PRUNE_UNCONFIRMED` that another cockpit's are removed only by a person's
|
|
519
|
+
`stacks prune --interactive`, which covers the whole machine. `doctor` warns with `STACKS_ORPHANED` when a stack of this cockpit has lost its
|
|
520
|
+
checkout or a state record cannot be read, without asking Docker; `stacks` gives the full picture.
|
|
521
|
+
|
|
378
522
|
### Change a running stack
|
|
379
523
|
|
|
380
524
|
A stack's identity, carried in its ownership labels and saved progress, is a digest of the Compose
|
|
@@ -390,9 +534,12 @@ receive, gives the stack a new identity, and `up` refuses with `LIFECYCLE_PROGRE
|
|
|
390
534
|
running stack in place. To apply such a change, for example a `[ports.bases]` edit:
|
|
391
535
|
|
|
392
536
|
1. Edit `cockpit.toml`. This can happen while the stack runs.
|
|
393
|
-
2.
|
|
394
|
-
|
|
395
|
-
|
|
537
|
+
2. Run `cockpit sync --config cockpit.toml`. Until then, the agent guard holds every tool call
|
|
538
|
+
except that sync, because the configuration no longer matches what it was generated for, and
|
|
539
|
+
`sleep` and `down` refuse because they read the Compose files `sync` publishes. An agent may run
|
|
540
|
+
it where `[autonomy] sync = "agent"` and the edit does not
|
|
541
|
+
[widen what agents may do](safety-and-autonomy.md#edits-the-guard-has-not-applied), as a
|
|
542
|
+
`[ports.bases]` edit does not; otherwise a person runs it in a terminal.
|
|
396
543
|
3. Run `cockpit down --config cockpit.toml`. It finds the stack and its port lease by the stack,
|
|
397
544
|
not by the edited declaration, and removes the containers still running the old declaration.
|
|
398
545
|
While another holder, such as a running `cockpit session`, still holds the stack, it refuses
|
|
@@ -403,15 +550,32 @@ Restoring `cockpit.toml` to the exact bytes `sync` last saw, for example with
|
|
|
403
550
|
`git restore cockpit.toml`, clears the guard's hold without a `sync`: the guard compares the file's
|
|
404
551
|
content, not which file holds it.
|
|
405
552
|
|
|
553
|
+
### When a sibling changes under a running stack
|
|
554
|
+
|
|
555
|
+
A bind mount follows a sibling's files at once, but installed dependencies usually live in an image
|
|
556
|
+
or volume built earlier and the database keeps the schema it was migrated to. When `up` starts a
|
|
557
|
+
stack it records a digest of each mounted sibling's lockfiles and of its `rebuild_inputs`, such as
|
|
558
|
+
a migrations directory. Lockfiles come from the `environment.install_policies` rows for the
|
|
559
|
+
sibling's toolchain, or, without one, from the common lockfile names present in the checkout; each
|
|
560
|
+
finding names which source it came from. `doctor` and `preflight` warn with `STACK_INPUTS_CHANGED`
|
|
561
|
+
when any of them, or the checkout serving the sibling, changed since, and `pull` warns after
|
|
562
|
+
moving one. Run `down` and then `up` so every service starts on the current files; rebuild an image
|
|
563
|
+
that installs the dependencies before `up`. A resumed `up` keeps the record, because resuming
|
|
564
|
+
restarts nothing; `down`, or a `sleep` that stops the stack, drops it.
|
|
565
|
+
|
|
566
|
+
It is a warning, not a refusal: whether a changed lockfile matters is the product's call, and
|
|
567
|
+
`test-run` does not block on it.
|
|
568
|
+
|
|
406
569
|
## Choose the Docker daemon
|
|
407
570
|
|
|
408
571
|
Every command uses the daemon Docker itself would select: a `DOCKER_HOST` when set, otherwise the
|
|
409
|
-
context `DOCKER_CONTEXT` names, otherwise the active context `docker context show` reports.
|
|
572
|
+
context `DOCKER_CONTEXT` names, otherwise the active context `docker context show` reports. Four
|
|
410
573
|
commands fix that daemon once, before their first step, and address only it:
|
|
411
574
|
|
|
412
575
|
| Command | Why it fixes the daemon |
|
|
413
576
|
|---|---|
|
|
414
577
|
| `down`, `reset` | they delete; reading the context per step could list one daemon and delete from another if `docker context use` ran mid-command |
|
|
578
|
+
| `stacks` | `stacks prune` deletes, for the same reason |
|
|
415
579
|
| `runtime measure` | the measurement must describe the daemon `up` will use, not one selected while the probe ran |
|
|
416
580
|
|
|
417
581
|
None of them needs a prefix, so they run as printed:
|
|
@@ -753,6 +917,30 @@ that, `logs` keeps the newest whole records that fit, sets `truncated` to `true`
|
|
|
753
917
|
and warns with `LOGS_TRUNCATED`; lower `--tail` to stay under it. Output is returned after
|
|
754
918
|
collection, including structured records in JSON mode, rather than streamed.
|
|
755
919
|
|
|
920
|
+
### Work on one service
|
|
921
|
+
|
|
922
|
+
`ps`, `restart`, `rebuild` and `exec` act on one service of this checkout's own running stack, with
|
|
923
|
+
its Compose project, files and profiles, so neither a person nor an agent names the derived project.
|
|
924
|
+
The stack must have been started by `up` from this checkout; after `down` they refuse and name `up`.
|
|
925
|
+
|
|
926
|
+
- `ps` lists every service of the stack with its container state, health and status; a service
|
|
927
|
+
with no container is `absent`.
|
|
928
|
+
- `restart --service <name>` restarts the container in place, without its dependents, then waits
|
|
929
|
+
for it as `up` does and reports its last log lines when it does not become healthy.
|
|
930
|
+
- `rebuild --service <name>` builds the service's image, replaces its container and waits the same
|
|
931
|
+
way; use it when a change is baked into the image. It also works on a stack whose start stopped at
|
|
932
|
+
that service, and it records the new container so `preflight` and `logs` follow it.
|
|
933
|
+
- `exec --service <name> -- <command> [args...]` runs the command inside the service's container
|
|
934
|
+
and exits with the command's own status, as `session` does. It gets a terminal only when cockpit
|
|
935
|
+
runs in one.
|
|
936
|
+
|
|
937
|
+
The guard admits these verbs as it admits `up`. The command after `exec --` runs in the container,
|
|
938
|
+
whose files the guard cannot see, so it is never proven read-only: the name-based denials still apply
|
|
939
|
+
(`exec --service web -- cat .env` is refused like `cat .env`), and it runs without asking only when a
|
|
940
|
+
`[guards] allow` rule or a declared build or test command admits it
|
|
941
|
+
([Cockpit and project commands](safety-and-autonomy.md#cockpit-and-project-commands)). `reset` stays
|
|
942
|
+
gated by `[autonomy]`.
|
|
943
|
+
|
|
756
944
|
## Where the decisions live
|
|
757
945
|
|
|
758
946
|
Contributors looking for the source module behind each step should start at
|
package/docs/faq.md
CHANGED
|
@@ -67,9 +67,11 @@ its declared remote. It never rewrites Git remotes or edits undeclared files.
|
|
|
67
67
|
|
|
68
68
|
## Can two agents use the same machine at once?
|
|
69
69
|
|
|
70
|
-
Yes. Each checkout leases its own port family
|
|
71
|
-
|
|
72
|
-
another's environment.
|
|
70
|
+
Yes. Each checkout, a linked worktree included, leases its own port family and runs its own stack,
|
|
71
|
+
and each running `up` or `session` is a holder of it. `sleep` stops the stack only when no holder
|
|
72
|
+
remains, so one agent cannot stop another's environment. `cockpit use` points a sibling at a worktree
|
|
73
|
+
for one cockpit checkout, and `cockpit stacks prune` removes the stack a deleted worktree left behind.
|
|
74
|
+
See [Environment](environment.md#lifecycle-and-ownership).
|
|
73
75
|
|
|
74
76
|
## What happens to my secrets?
|
|
75
77
|
|