@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
|
@@ -60,6 +60,22 @@ export declare const WorkRecord: z.ZodObject<{
|
|
|
60
60
|
from: z.ZodString;
|
|
61
61
|
to: z.ZodString;
|
|
62
62
|
weakened: z.ZodArray<z.ZodString>;
|
|
63
|
+
review: z.ZodArray<z.ZodObject<{
|
|
64
|
+
field: z.ZodString;
|
|
65
|
+
before: z.ZodString;
|
|
66
|
+
after: z.ZodString;
|
|
67
|
+
}, z.core.$strict>>;
|
|
68
|
+
}, z.core.$strict>>;
|
|
69
|
+
acknowledgements: z.ZodArray<z.ZodObject<{
|
|
70
|
+
at: z.ZodString;
|
|
71
|
+
by: z.ZodEnum<{
|
|
72
|
+
agent: "agent";
|
|
73
|
+
ci: "ci";
|
|
74
|
+
person: "person";
|
|
75
|
+
}>;
|
|
76
|
+
digest: z.ZodString;
|
|
77
|
+
findings: z.ZodArray<z.ZodString>;
|
|
78
|
+
note: z.ZodString;
|
|
63
79
|
}, z.core.$strict>>;
|
|
64
80
|
attempts: z.ZodNumber;
|
|
65
81
|
checks: z.ZodOptional<z.ZodObject<{
|
|
@@ -105,6 +121,10 @@ export declare const WorkRecord: z.ZodObject<{
|
|
|
105
121
|
}, z.core.$strict>>;
|
|
106
122
|
note: z.ZodOptional<z.ZodString>;
|
|
107
123
|
}, z.core.$strict>>;
|
|
124
|
+
amendmentsFailedReview: z.ZodOptional<z.ZodObject<{
|
|
125
|
+
at: z.ZodString;
|
|
126
|
+
note: z.ZodString;
|
|
127
|
+
}, z.core.$strict>>;
|
|
108
128
|
notes: z.ZodArray<z.ZodObject<{
|
|
109
129
|
at: z.ZodString;
|
|
110
130
|
by: z.ZodEnum<{
|
|
@@ -114,11 +134,15 @@ export declare const WorkRecord: z.ZodObject<{
|
|
|
114
134
|
}>;
|
|
115
135
|
kind: z.ZodEnum<{
|
|
116
136
|
answer: "answer";
|
|
137
|
+
decision: "decision";
|
|
117
138
|
note: "note";
|
|
118
139
|
question: "question";
|
|
140
|
+
resolution: "resolution";
|
|
119
141
|
}>;
|
|
120
142
|
text: z.ZodString;
|
|
121
143
|
answers: z.ZodOptional<z.ZodNumber>;
|
|
144
|
+
resolves: z.ZodOptional<z.ZodNumber>;
|
|
145
|
+
record: z.ZodOptional<z.ZodString>;
|
|
122
146
|
}, z.core.$strict>>;
|
|
123
147
|
closure: z.ZodOptional<z.ZodObject<{
|
|
124
148
|
at: z.ZodString;
|
|
@@ -136,6 +160,11 @@ export declare const WorkRecord: z.ZodObject<{
|
|
|
136
160
|
}>;
|
|
137
161
|
note: z.ZodOptional<z.ZodString>;
|
|
138
162
|
}, z.core.$strict>>;
|
|
163
|
+
recoveries: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
164
|
+
at: z.ZodString;
|
|
165
|
+
holder: z.ZodString;
|
|
166
|
+
checked: z.ZodArray<z.ZodString>;
|
|
167
|
+
}, z.core.$strict>>>;
|
|
139
168
|
}, z.core.$strict>;
|
|
140
169
|
export type WorkRecord = z.infer<typeof WorkRecord>;
|
|
141
170
|
/** Keeps the end of a command's output, where a runner prints its summary, within the record's bound. */
|
|
@@ -148,11 +177,31 @@ export interface WorkStore {
|
|
|
148
177
|
record?: WorkRecord;
|
|
149
178
|
value: T;
|
|
150
179
|
}>) => Promise<T>;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
lock: 'none' | 'live' | 'unknown' | 'dead' | 'removed';
|
|
154
|
-
holder?: string;
|
|
155
|
-
}>>;
|
|
180
|
+
/** Names a lock's holder and, with `apply`, removes the lock once the holder is shown gone, recording what was checked. */
|
|
181
|
+
readonly recover: (id: string, apply: boolean, containers: () => Promise<ContainerEvidence>) => Promise<LockRecovery>;
|
|
156
182
|
}
|
|
183
|
+
/** The containers cockpit labels on this machine's Docker daemon, which a process probe cannot look inside. */
|
|
184
|
+
export type ContainerEvidence = Readonly<{
|
|
185
|
+
state: 'listed';
|
|
186
|
+
context: string;
|
|
187
|
+
containers: readonly Readonly<{
|
|
188
|
+
id: string;
|
|
189
|
+
name: string;
|
|
190
|
+
running: boolean;
|
|
191
|
+
}>[];
|
|
192
|
+
}> | Readonly<{
|
|
193
|
+
state: 'no-docker';
|
|
194
|
+
reason: string;
|
|
195
|
+
}> | Readonly<{
|
|
196
|
+
state: 'unavailable';
|
|
197
|
+
reason: string;
|
|
198
|
+
}>;
|
|
199
|
+
type LockRecovery = Readonly<{
|
|
200
|
+
id: string;
|
|
201
|
+
lock: 'none' | 'live' | 'unknown' | 'dead' | 'removed';
|
|
202
|
+
holder?: string;
|
|
203
|
+
checked?: readonly string[];
|
|
204
|
+
recorded?: boolean;
|
|
205
|
+
}>;
|
|
157
206
|
export declare function createWorkStore(root: string): WorkStore;
|
|
158
207
|
export {};
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
// an agent wrote there would read as cockpit's own. A write holds the order's lock file, which a
|
|
6
6
|
// crashed writer leaves behind until `work recover --apply` removes it.
|
|
7
7
|
import { randomUUID } from 'node:crypto';
|
|
8
|
-
import {
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { link, lstat, mkdir, open, readFile, readdir, rename, rm, writeFile } from 'node:fs/promises';
|
|
10
|
+
import { hostname } from 'node:os';
|
|
9
11
|
import { join } from 'node:path';
|
|
10
12
|
import { z } from 'zod';
|
|
11
13
|
import { isProcessGone, observeProcessStart, processHost } from '../environment/claims.js';
|
|
@@ -46,24 +48,62 @@ export const WorkRecord = z.object({
|
|
|
46
48
|
sources: z.record(z.string(), z.string().length(64)),
|
|
47
49
|
base: z.record(z.string(), z.string().regex(/^[a-f0-9]{40,64}$/)),
|
|
48
50
|
}).strict(),
|
|
49
|
-
|
|
51
|
+
// `weakened` names what the amendment removed; `review` each change a model, or a person where none grades, judges
|
|
52
|
+
// against the bar, with its text before and after. An agent's amendment is judged at the next grade.
|
|
53
|
+
amendments: z.array(z.object({ at, by, from: z.string().length(64), to: z.string().length(64), weakened: z.array(z.string()).max(64),
|
|
54
|
+
review: z.array(z.object({ field: z.string().max(64), before: z.string().max(131_072), after: z.string().max(131_072) }).strict()).max(128) }).strict()).max(256),
|
|
55
|
+
// A person's (or, where [work.gates] allows, an agent's or CI's) acknowledgement that the change weakened tests:
|
|
56
|
+
// it covers exactly the findings its digest names, so a later weakening needs its own.
|
|
57
|
+
acknowledgements: z.array(z.object({ at, by, digest: z.string().length(64), findings: z.array(z.string().max(1_100)).max(256), note }).strict()).max(256),
|
|
50
58
|
attempts: z.number().int().min(0),
|
|
51
59
|
checks: z.object({ at, digest: z.string().length(64), results: z.array(CheckResult).max(64) }).strict().optional(),
|
|
52
60
|
grade: Grade.optional(),
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
// A grade found the agent's amendments lowered the bar. It outlives the grade a later check or grade
|
|
62
|
+
// replaces, and only an amendment a person or CI accepts clears it, so the next amendment stays theirs.
|
|
63
|
+
amendmentsFailedReview: z.object({ at, note: z.string().max(4_096) }).strict().optional(),
|
|
64
|
+
// A decision is resolved by a later `resolution` note naming it in `resolves`: with `record`, the decision
|
|
65
|
+
// record it is written in; without, `text` says why it made no lasting decision. The latest resolution counts.
|
|
66
|
+
notes: z.array(z.object({ at, by: z.enum(['agent', 'person', 'ci']), kind: z.enum(['note', 'question', 'answer', 'decision', 'resolution']), text: note,
|
|
67
|
+
answers: z.number().int().min(1).optional(), resolves: z.number().int().min(1).optional(), record: z.string().max(1_100).optional() }).strict()).max(1_024),
|
|
55
68
|
closure: z.object({ at, by, how: z.enum(['graded', 'checks-passed', 'self-reported', 'partial', 'abandoned']), note: note.optional() }).strict().optional(),
|
|
69
|
+
// Each lock `work recover --apply` removed: the holder it named and what was checked to call it gone.
|
|
70
|
+
recoveries: z.array(z.object({ at, holder: z.string().max(1_024), checked: z.array(z.string().max(1_024)).max(16) }).strict()).max(256).optional(),
|
|
56
71
|
}).strict();
|
|
57
72
|
/** Keeps the end of a command's output, where a runner prints its summary, within the record's bound. */
|
|
58
73
|
export function outputTail(value) {
|
|
59
74
|
const bytes = Buffer.from(value);
|
|
60
75
|
return bytes.byteLength <= OUTPUT_TAIL_BYTES ? value : `[...]${bytes.subarray(bytes.byteLength - OUTPUT_TAIL_BYTES).toString('utf8')}`;
|
|
61
76
|
}
|
|
62
|
-
// A lock names its
|
|
77
|
+
// A lock names its writer: pid and start, so a reused pid never keeps a dead writer's lock alive, and
|
|
78
|
+
// the host and whether it ran in a container, because a pid means nothing outside the process table
|
|
79
|
+
// it came from. Docker names a container's host after the container, unless it shares the machine's network.
|
|
80
|
+
const LockHolder = z.object({ pid: z.number().int().min(1), start: z.string().max(256).optional(), host: z.string().min(1).max(255), container: z.boolean() }).strict();
|
|
81
|
+
const inContainer = () => existsSync('/.dockerenv') || existsSync('/run/.containerenv');
|
|
63
82
|
const holder = async () => {
|
|
64
83
|
const observed = await observeProcessStart(process.pid, processHost(executeProbe));
|
|
65
|
-
return observed.state === 'present' ?
|
|
84
|
+
return { pid: process.pid, ...observed.state === 'present' ? { start: observed.start } : {}, host: hostname(), container: inContainer() };
|
|
66
85
|
};
|
|
86
|
+
// Whether the holder is shown running or gone, looking first where a pid probe cannot; anything unproven is unknown.
|
|
87
|
+
async function judgeHolder(found, containers) {
|
|
88
|
+
const here = hostname();
|
|
89
|
+
const listed = containers.state === 'listed' ? containers.containers : [];
|
|
90
|
+
const checked = [`the lock was written by process ${found.pid} on host ${found.host}${found.container ? ' inside a container' : ''}`, `this machine is host ${here}`,
|
|
91
|
+
(containers.state === 'listed' ? `Docker context ${containers.context} lists ${listed.length} cockpit-labelled container(s)${listed.length
|
|
92
|
+
? `: ${listed.map(row => `${row.name} (${row.running ? 'running' : 'stopped'})`).join(', ')}` : ''}`
|
|
93
|
+
: containers.state === 'no-docker' ? `no Docker client is installed (${containers.reason}), so no container on this machine runs cockpit`
|
|
94
|
+
: `Docker could not be read: ${containers.reason}`).slice(0, 1_024)];
|
|
95
|
+
if (containers.state === 'unavailable')
|
|
96
|
+
return { lock: 'unknown', checked };
|
|
97
|
+
if (found.host !== here || found.container) {
|
|
98
|
+
const writer = /^[a-f0-9]{12}$/.test(found.host) ? listed.find(row => row.id.startsWith(found.host)) : undefined;
|
|
99
|
+
if (!writer)
|
|
100
|
+
return { lock: 'unknown', checked: [...checked, 'the writer ran on another host or in a container this machine does not list, whose processes this machine cannot see'] };
|
|
101
|
+
return { lock: writer.running ? 'live' : 'dead', checked: [...checked, `container ${writer.name}, which wrote it, is ${writer.running ? 'running' : 'stopped, so none of its processes runs'}`] };
|
|
102
|
+
}
|
|
103
|
+
const observed = await observeProcessStart(found.pid, processHost(executeProbe));
|
|
104
|
+
const lock = isProcessGone(found.start, observed) ? 'dead' : observed.state === 'unknown' ? 'unknown' : 'live';
|
|
105
|
+
return { lock, checked: [...checked, `process ${found.pid} on this machine is ${lock === 'dead' ? 'gone' : observed.state === 'unknown' ? `not observable (${observed.reason})` : 'running'}`] };
|
|
106
|
+
}
|
|
67
107
|
export function createWorkStore(root) {
|
|
68
108
|
const directory = join(root, WORK_RECORD_DIRECTORY);
|
|
69
109
|
const pathOf = (id, suffix) => {
|
|
@@ -103,21 +143,21 @@ export function createWorkStore(root) {
|
|
|
103
143
|
const lock = async (id) => {
|
|
104
144
|
await mkdir(directory, { recursive: true });
|
|
105
145
|
const path = pathOf(id, '.lock');
|
|
106
|
-
|
|
146
|
+
// The holder is written before the lock appears, by linking a finished file into place, so a
|
|
147
|
+
// crash never leaves a lock that names nobody and so could never be shown gone.
|
|
148
|
+
const staged = `${path}.${randomUUID()}.tmp`;
|
|
149
|
+
await writeFile(staged, `${JSON.stringify(await holder())}\n`, { flag: 'wx', mode: 0o644 });
|
|
107
150
|
try {
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
await handle.writeFile(`${recorded}\n`);
|
|
111
|
-
}
|
|
112
|
-
finally {
|
|
113
|
-
await handle.close();
|
|
114
|
-
}
|
|
151
|
+
await link(staged, path);
|
|
115
152
|
}
|
|
116
153
|
catch (error) {
|
|
117
154
|
if (!hasErrorCode(error, 'EEXIST'))
|
|
118
155
|
throw error;
|
|
119
156
|
throw new RefusalError(`work order ${id} is locked by another cockpit command (${WORK_RECORD_DIRECTORY}/${id}.lock); wait for it, or if it crashed run npx --no cockpit work recover --config <your cockpit.toml> --work-order ${id} --apply`);
|
|
120
157
|
}
|
|
158
|
+
finally {
|
|
159
|
+
await rm(staged, { force: true });
|
|
160
|
+
}
|
|
121
161
|
return async () => { await rm(path, { force: true }); };
|
|
122
162
|
};
|
|
123
163
|
const write = async (record) => {
|
|
@@ -170,7 +210,7 @@ export function createWorkStore(root) {
|
|
|
170
210
|
await release();
|
|
171
211
|
}
|
|
172
212
|
},
|
|
173
|
-
recover: async (id, apply) => {
|
|
213
|
+
recover: async (id, apply, containers) => {
|
|
174
214
|
const path = pathOf(id, '.lock');
|
|
175
215
|
let text;
|
|
176
216
|
try {
|
|
@@ -181,16 +221,70 @@ export function createWorkStore(root) {
|
|
|
181
221
|
return { id, lock: 'none' };
|
|
182
222
|
throw error;
|
|
183
223
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
224
|
+
let parsed;
|
|
225
|
+
try {
|
|
226
|
+
parsed = JSON.parse(text);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
if (!(error instanceof SyntaxError))
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
const found = LockHolder.safeParse(parsed);
|
|
233
|
+
const shown = text.trim().slice(0, 1_024);
|
|
234
|
+
if (!found.success)
|
|
235
|
+
return { id, lock: 'unknown', holder: shown, checked: ['the lock does not name its holder the way cockpit writes one'] };
|
|
187
236
|
// A lock whose writer is still running, or cannot be shown gone, is never removed: the write it guards may be in progress.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
237
|
+
const judged = await judgeHolder(found.data, await containers());
|
|
238
|
+
if (judged.lock !== 'dead' || !apply)
|
|
239
|
+
return { id, lock: judged.lock, holder: shown, checked: judged.checked };
|
|
240
|
+
// The lock is taken over rather than deleted, so no other writer slips in before the recovery is recorded.
|
|
241
|
+
// Two recoveries that both judged it dead must not both replace it and then each delete the other's: each
|
|
242
|
+
// links its holder at the takeover name, which only one can create, and only that one replaces the lock.
|
|
243
|
+
const ours = `${path}.${randomUUID()}.tmp`;
|
|
244
|
+
const takeover = `${path}.takeover`;
|
|
245
|
+
await writeFile(ours, `${JSON.stringify(await holder())}\n`, { flag: 'wx', mode: 0o644 });
|
|
246
|
+
try {
|
|
247
|
+
try {
|
|
248
|
+
await link(ours, takeover);
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
if (!hasErrorCode(error, 'EEXIST'))
|
|
252
|
+
throw error;
|
|
253
|
+
throw new RefusalError(`another work recover is taking over the lock on ${id}; rerun work recover once it finishes, `
|
|
254
|
+
+ `or if none is running, a person removes ${WORK_RECORD_DIRECTORY}/${id}.lock.takeover, which a crashed recovery left`);
|
|
255
|
+
}
|
|
256
|
+
let replaced = false;
|
|
257
|
+
try {
|
|
258
|
+
let current;
|
|
259
|
+
try {
|
|
260
|
+
current = await readFile(path, 'utf8');
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
if (!hasErrorCode(error, 'ENOENT'))
|
|
264
|
+
throw error;
|
|
265
|
+
}
|
|
266
|
+
if (current !== text)
|
|
267
|
+
throw new RefusalError(`the lock on ${id} changed while it was being recovered; rerun work recover`);
|
|
268
|
+
await rename(takeover, path);
|
|
269
|
+
replaced = true;
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
if (!replaced)
|
|
273
|
+
await rm(takeover, { force: true });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
await rm(ours, { force: true });
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
const record = await read(id);
|
|
281
|
+
if (record)
|
|
282
|
+
await write({ ...record, recoveries: [...record.recoveries ?? [], { at: new Date().toISOString(), holder: shown, checked: [...judged.checked] }] });
|
|
283
|
+
return { id, lock: 'removed', holder: shown, checked: judged.checked, recorded: record !== undefined };
|
|
284
|
+
}
|
|
285
|
+
finally {
|
|
286
|
+
await rm(path, { force: true });
|
|
287
|
+
}
|
|
194
288
|
},
|
|
195
289
|
};
|
|
196
290
|
return store;
|
package/docs/README.md
CHANGED
|
@@ -22,13 +22,16 @@ contributor pages live separately under docs/contributing/.
|
|
|
22
22
|
## Guides
|
|
23
23
|
|
|
24
24
|
- [Joining a team's cockpit](joining-a-team.md): install and verify a cockpit from a fresh clone.
|
|
25
|
-
- [Environment lifecycle](environment.md): setup, bring-up, health, logs, reset and seeding
|
|
25
|
+
- [Environment lifecycle](environment.md): setup, bring-up, health, logs, reset and seeding;
|
|
26
|
+
worktrees, Compose profiles, one-service commands and pruning stacks across the machine.
|
|
26
27
|
- [Compose patterns](compose-patterns.md): vendor stubs, TLS and data restore in plain Compose.
|
|
27
28
|
- [Harness surfaces](harness-surfaces.md): what `sync` writes for each agent tool, and overlays.
|
|
28
29
|
- [Extending cockpit](extending.md): supported extension points, what an upgrade replaces and the build-beside pattern.
|
|
29
30
|
- [Safety and autonomy](safety-and-autonomy.md): what guards allow, ask about and deny.
|
|
30
|
-
- [Work and browser workflows](work-and-browser.md): work orders, grading,
|
|
31
|
-
test tiers.
|
|
31
|
+
- [Work and browser workflows](work-and-browser.md): work orders, grading, test protection,
|
|
32
|
+
decisions, browser checks and test tiers.
|
|
33
|
+
- [Living documents and decision records](docs-check.md): find documents that cite removed paths
|
|
34
|
+
or make targets, and decision records whose numbers, index or statuses disagree.
|
|
32
35
|
|
|
33
36
|
## Reference
|
|
34
37
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- Generated by `npm run references`; edit its sources, not this file. -->
|
|
4
4
|
|
|
5
|
-
<!-- Source manifest:
|
|
5
|
+
<!-- Source manifest: 7db847121f6f4cf7fc6608625e755acc97326e8320ea425b807d7de8a283f70c -->
|
|
6
6
|
|
|
7
7
|
This generated page is for users checking what cockpit actually enforces in each agent tool. Each cell holds one of four states:
|
|
8
8
|
|
|
@@ -15,15 +15,15 @@ Only a dated run of the real tool changes a state; writing a file or passing coc
|
|
|
15
15
|
|
|
16
16
|
Written says whether `sync` writes the tool's files for a cockpit.toml that lists no tools: the tools whose guard firing is measured are the default `[surfaces] tools`, and any other tool is written only once listed (`npx --no cockpit tool add <tool> --config <your cockpit.toml>`).
|
|
17
17
|
|
|
18
|
-
Guard firing is the generated hook refusing a protected operation. Instruction loading is the tool reading the guidance cockpit writes for it, including the guides of sibling repositories. Skills are the tool loading the skills cockpit renders: `cockpit-setup`, `cockpit-explain`, `cockpit-fix` and `cockpit-work`. The session-start check is the tool running `cockpit check` as a session starts and showing its drift report to the agent.
|
|
18
|
+
Guard firing is the generated hook refusing a protected operation. Instruction loading is the tool reading the guidance cockpit writes for it, including the guides of sibling repositories. Skills are the tool loading the skills cockpit renders: `cockpit-setup`, `cockpit-explain`, `cockpit-fix` and `cockpit-work`. The session-start check is the tool running `cockpit check` as a session starts and showing its drift report to the agent. Remote MCP servers are the tool connecting to an approved streamable HTTP server with the credential cockpit spells for it: an environment reference or a headers helper. Worktree grants are the tool letting the agent write a checkout `cockpit use` serves from outside the declared one, through a machine-local file cockpit writes.
|
|
19
19
|
|
|
20
|
-
| Tool | Written | Guard firing | Instruction loading | Skills | Session-start check |
|
|
21
|
-
| --- | --- | --- | --- | --- | --- |
|
|
22
|
-
| Claude Code (`claudecode`) | by default | enforced | instructed | instructed | instructed |
|
|
23
|
-
| Codex (`codexcli`) | by default | enforced (needs a person) | instructed | instructed | instructed (needs a person) |
|
|
24
|
-
| OpenCode (`opencode`) | by default | enforced | instructed | instructed | unavailable |
|
|
25
|
-
| Cursor (`cursor`) | when listed | unavailable | generated | generated | unavailable |
|
|
26
|
-
| Grok Build (`grokcli`) | when listed | unavailable | generated | generated | unavailable |
|
|
20
|
+
| Tool | Written | Guard firing | Instruction loading | Skills | Session-start check | Remote MCP servers | Worktree grants |
|
|
21
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
22
|
+
| Claude Code (`claudecode`) | by default | enforced | instructed | instructed | instructed | instructed (needs a person) | enforced (needs a person) |
|
|
23
|
+
| Codex (`codexcli`) | by default | enforced (needs a person) | instructed | instructed | instructed (needs a person) | instructed | unavailable |
|
|
24
|
+
| OpenCode (`opencode`) | by default | enforced | instructed | instructed | unavailable | instructed | enforced |
|
|
25
|
+
| Cursor (`cursor`) | when listed | unavailable | generated | generated | unavailable | unavailable | unavailable |
|
|
26
|
+
| Grok Build (`grokcli`) | when listed | unavailable | generated | generated | unavailable | unavailable | unavailable |
|
|
27
27
|
|
|
28
28
|
## Measurements
|
|
29
29
|
|
|
@@ -37,6 +37,12 @@ Each line gives the date and tool version of the run and what it showed.
|
|
|
37
37
|
- OpenCode, instruction loading (2026-11-03, version 1.19.5): a sibling guide copied into the root AGENTS.md loaded, as did a guide named through a link in the opencode.jsonc instructions list, while the undeclared sibling's guide and the decoy did not.
|
|
38
38
|
- Claude Code, session-start check (2026-11-03, version 2.1.317): a SessionStart hook in .claude/settings.json ran under claude -p and the agent quoted its stdout back, while a hook under a misspelled event name never ran and Claude Code named it as ignored.
|
|
39
39
|
- Codex, session-start check (2026-11-03, version 0.166.0): only after a person trusts the hook, as for the guard: a trusted SessionStart hook in .codex/hooks.json ran under codex exec and the agent quoted its stdout back, while a hook under a misspelled event name never ran.
|
|
40
|
+
- Claude Code, remote MCP servers (2026-11-04, version 2.1.318): from a project .mcp.json, Claude Code sent the Authorization header a ${NAME} reference named while a $NAME control went out literally; it ran a headersHelper given with --mcp-config, but refused to run one from the project file until a person trusts the workspace, and a misspelled headerHelper sent nothing.
|
|
41
|
+
- Codex, remote MCP servers (2026-11-04, version 0.166.0): from a project .codex/config.toml in a directory Codex had not been told to trust, codex exec sent the bearer_token_env_var and env_http_headers values and the http_headers_helper output, named a misspelled http_header_helper as ignored, and sent a ${NAME} written in http_headers literally.
|
|
42
|
+
- OpenCode, remote MCP servers (2026-11-04, version 1.19.5): opencode mcp list sent headers expanded from {env:NAME} in a project opencode.jsonc while a ${NAME} control went out literally; its remote server schema has no headers helper, so a server that declares one is not written for it.
|
|
43
|
+
- Claude Code, worktree grants (2026-11-04, version 2.1.318): a directory in .claude/settings.local.json permissions.additionalDirectories was written and the control refused, and a malformed twin granted nothing; measured in an untrusted workspace, so whether it combines with the committed list once a person trusts the workspace is unmeasured.
|
|
44
|
+
- Codex, worktree grants (2026-11-04, version 0.166.0): Codex reads no machine-local project file; --add-dir at start made the worktree writable and without it the write was refused, so cockpit use prints that flag and writes nothing.
|
|
45
|
+
- OpenCode, worktree grants (2026-11-04, version 1.19.5): the machine-local grant file holding the worktree path allowed the write and the control was denied, and a pattern naming a missing grant file stopped OpenCode at start, naming the file.
|
|
40
46
|
|
|
41
47
|
## Without a measurement
|
|
42
48
|
|
|
@@ -47,4 +53,6 @@ Each line gives the date and tool version of the run and what it showed.
|
|
|
47
53
|
- Skills in Cursor (`.cursor/skills`) and Grok Build (`.grok/skills`): cockpit writes the files, but no run of the tool beside a broken control has shown that it loads them.
|
|
48
54
|
- Session-start check in OpenCode: OpenCode 1.19.5 delivers session.created to a plugin, but no run has shown a plugin putting text in the agent's context, so cockpit generates no session-start check.
|
|
49
55
|
- Session-start check in Cursor and Grok Build: cockpit generates no hook for this tool.
|
|
56
|
+
- Remote MCP servers in Cursor and Grok Build: cockpit writes no remote MCP server for this tool: its remote transport and header spelling have not been checked.
|
|
57
|
+
- Worktree grants in Cursor and Grok Build: the tool was not installed where this was measured, so cockpit use writes nothing for it.
|
|
50
58
|
- Browser native transports (the playwright MCP tools and the pinned Playwright CLI) in Claude Code, Codex and OpenCode: cockpit declares them and the browser skill says each still needs a person's paired call beside a broken control; no cockpit command runs or records that call, so the browser commands drive the browser through cockpit's own project client instead.
|
package/docs/cli-reference.md
CHANGED
|
@@ -53,6 +53,41 @@ Reads `cockpit.toml` from `--config`.
|
|
|
53
53
|
| 2 | failure |
|
|
54
54
|
| 130 | cancelled |
|
|
55
55
|
|
|
56
|
+
## cockpit use
|
|
57
|
+
|
|
58
|
+
Serve a sibling from another of its checkouts, such as a worktree.
|
|
59
|
+
|
|
60
|
+
Reads `cockpit.toml` from `--config`.
|
|
61
|
+
|
|
62
|
+
| Flag | Type | Default |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `--config` | string | unset |
|
|
65
|
+
| `--clear` | boolean | `false` |
|
|
66
|
+
| `--json` | boolean | `false` |
|
|
67
|
+
|
|
68
|
+
| Exit | Meaning |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| 0 | success |
|
|
71
|
+
| 2 | failure |
|
|
72
|
+
| 130 | cancelled |
|
|
73
|
+
|
|
74
|
+
## cockpit pull
|
|
75
|
+
|
|
76
|
+
Fast-forward the cockpit and its siblings to their upstreams.
|
|
77
|
+
|
|
78
|
+
Reads `cockpit.toml` from `--config`.
|
|
79
|
+
|
|
80
|
+
| Flag | Type | Default |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| `--config` | string | unset |
|
|
83
|
+
| `--json` | boolean | `false` |
|
|
84
|
+
|
|
85
|
+
| Exit | Meaning |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| 0 | success |
|
|
88
|
+
| 2 | failure |
|
|
89
|
+
| 130 | cancelled |
|
|
90
|
+
|
|
56
91
|
## cockpit sibling
|
|
57
92
|
|
|
58
93
|
Add or remove a repository in cockpit.toml (sibling add, sibling remove).
|
|
@@ -96,6 +131,23 @@ Reads `cockpit.toml` from `--config`.
|
|
|
96
131
|
| 2 | failure |
|
|
97
132
|
| 130 | cancelled |
|
|
98
133
|
|
|
134
|
+
## cockpit confirm
|
|
135
|
+
|
|
136
|
+
Confirm an init answer no person stated by running the observation that verifies it.
|
|
137
|
+
|
|
138
|
+
Reads `cockpit.toml` from `--config`.
|
|
139
|
+
|
|
140
|
+
| Flag | Type | Default |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| `--config` | string | unset |
|
|
143
|
+
| `--json` | boolean | `false` |
|
|
144
|
+
|
|
145
|
+
| Exit | Meaning |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| 0 | success |
|
|
148
|
+
| 2 | failure |
|
|
149
|
+
| 130 | cancelled |
|
|
150
|
+
|
|
99
151
|
## cockpit registry-resolve
|
|
100
152
|
|
|
101
153
|
Turn a validated shell registry into data shell scripts can source.
|
|
@@ -217,6 +269,7 @@ Reads `cockpit.toml` from `--config`.
|
|
|
217
269
|
| --- | --- | --- |
|
|
218
270
|
| `--config` | string | unset |
|
|
219
271
|
| `--json` | boolean | `false` |
|
|
272
|
+
| `--profile` | string | unset |
|
|
220
273
|
|
|
221
274
|
| Exit | Meaning |
|
|
222
275
|
| --- | --- |
|
|
@@ -250,6 +303,7 @@ Reads `cockpit.toml` from `--config`.
|
|
|
250
303
|
| Flag | Type | Default |
|
|
251
304
|
| --- | --- | --- |
|
|
252
305
|
| `--config` | string | unset |
|
|
306
|
+
| `--profile` | string | unset |
|
|
253
307
|
|
|
254
308
|
| Exit | Meaning |
|
|
255
309
|
| --- | --- |
|
|
@@ -278,6 +332,76 @@ Reads `cockpit.toml` from `--config`.
|
|
|
278
332
|
| 2 | failure |
|
|
279
333
|
| 130 | cancelled |
|
|
280
334
|
|
|
335
|
+
## cockpit ps
|
|
336
|
+
|
|
337
|
+
Show the state and health of each service in this checkout's stack.
|
|
338
|
+
|
|
339
|
+
Reads `cockpit.toml` from `--config`.
|
|
340
|
+
|
|
341
|
+
| Flag | Type | Default |
|
|
342
|
+
| --- | --- | --- |
|
|
343
|
+
| `--config` | string | unset |
|
|
344
|
+
| `--json` | boolean | `false` |
|
|
345
|
+
|
|
346
|
+
| Exit | Meaning |
|
|
347
|
+
| --- | --- |
|
|
348
|
+
| 0 | success |
|
|
349
|
+
| 2 | failure |
|
|
350
|
+
| 130 | cancelled |
|
|
351
|
+
|
|
352
|
+
## cockpit restart
|
|
353
|
+
|
|
354
|
+
Restart one service of this checkout's stack and wait until it is healthy.
|
|
355
|
+
|
|
356
|
+
Reads `cockpit.toml` from `--config`.
|
|
357
|
+
|
|
358
|
+
| Flag | Type | Default |
|
|
359
|
+
| --- | --- | --- |
|
|
360
|
+
| `--config` | string | unset |
|
|
361
|
+
| `--json` | boolean | `false` |
|
|
362
|
+
| `--service` | string | unset |
|
|
363
|
+
|
|
364
|
+
| Exit | Meaning |
|
|
365
|
+
| --- | --- |
|
|
366
|
+
| 0 | success |
|
|
367
|
+
| 2 | failure |
|
|
368
|
+
| 130 | cancelled |
|
|
369
|
+
|
|
370
|
+
## cockpit rebuild
|
|
371
|
+
|
|
372
|
+
Rebuild one service's image, replace its container and wait until it is healthy.
|
|
373
|
+
|
|
374
|
+
Reads `cockpit.toml` from `--config`.
|
|
375
|
+
|
|
376
|
+
| Flag | Type | Default |
|
|
377
|
+
| --- | --- | --- |
|
|
378
|
+
| `--config` | string | unset |
|
|
379
|
+
| `--json` | boolean | `false` |
|
|
380
|
+
| `--service` | string | unset |
|
|
381
|
+
|
|
382
|
+
| Exit | Meaning |
|
|
383
|
+
| --- | --- |
|
|
384
|
+
| 0 | success |
|
|
385
|
+
| 2 | failure |
|
|
386
|
+
| 130 | cancelled |
|
|
387
|
+
|
|
388
|
+
## cockpit exec
|
|
389
|
+
|
|
390
|
+
Run a command inside one service's container of this checkout's stack.
|
|
391
|
+
|
|
392
|
+
Reads `cockpit.toml` from `--config`.
|
|
393
|
+
|
|
394
|
+
| Flag | Type | Default |
|
|
395
|
+
| --- | --- | --- |
|
|
396
|
+
| `--config` | string | unset |
|
|
397
|
+
| `--service` | string | unset |
|
|
398
|
+
|
|
399
|
+
| Exit | Meaning |
|
|
400
|
+
| --- | --- |
|
|
401
|
+
| 0 | success |
|
|
402
|
+
| 2 | failure |
|
|
403
|
+
| 130 | cancelled |
|
|
404
|
+
|
|
281
405
|
## cockpit sleep
|
|
282
406
|
|
|
283
407
|
Release this checkout and stop the stack if no other holder remains.
|
|
@@ -331,6 +455,25 @@ Reads `cockpit.toml` from `--config`.
|
|
|
331
455
|
| 2 | failure |
|
|
332
456
|
| 130 | cancelled |
|
|
333
457
|
|
|
458
|
+
## cockpit stacks
|
|
459
|
+
|
|
460
|
+
List every stack on this machine, or preview and remove those whose checkout is gone (stacks prune).
|
|
461
|
+
|
|
462
|
+
Reads `cockpit.toml` from `--config`.
|
|
463
|
+
|
|
464
|
+
| Flag | Type | Default |
|
|
465
|
+
| --- | --- | --- |
|
|
466
|
+
| `--config` | string | unset |
|
|
467
|
+
| `--apply` | boolean | `false` |
|
|
468
|
+
| `--interactive` | boolean | `false` |
|
|
469
|
+
| `--json` | boolean | `false` |
|
|
470
|
+
|
|
471
|
+
| Exit | Meaning |
|
|
472
|
+
| --- | --- |
|
|
473
|
+
| 0 | success |
|
|
474
|
+
| 2 | failure |
|
|
475
|
+
| 130 | cancelled |
|
|
476
|
+
|
|
334
477
|
## cockpit doctor
|
|
335
478
|
|
|
336
479
|
Report environment problems without changing anything.
|
|
@@ -425,7 +568,7 @@ Reads `cockpit.toml` from `--config`.
|
|
|
425
568
|
|
|
426
569
|
## cockpit work note
|
|
427
570
|
|
|
428
|
-
Record a note on an order,
|
|
571
|
+
Record a note on an order, an open question with --ask, or a decision with --decision.
|
|
429
572
|
|
|
430
573
|
Reads `cockpit.toml` from `--config`.
|
|
431
574
|
|
|
@@ -436,6 +579,31 @@ Reads `cockpit.toml` from `--config`.
|
|
|
436
579
|
| `--work-order` | string | unset |
|
|
437
580
|
| `--text` | string | unset |
|
|
438
581
|
| `--ask` | boolean | `false` |
|
|
582
|
+
| `--decision` | boolean | `false` |
|
|
583
|
+
|
|
584
|
+
| Exit | Meaning |
|
|
585
|
+
| --- | --- |
|
|
586
|
+
| 0 | success |
|
|
587
|
+
| 2 | failure |
|
|
588
|
+
| 130 | cancelled |
|
|
589
|
+
|
|
590
|
+
## cockpit work decide
|
|
591
|
+
|
|
592
|
+
Resolve a recorded decision: write or cite its decision record, or say it is not lasting.
|
|
593
|
+
|
|
594
|
+
Reads `cockpit.toml` from `--config`.
|
|
595
|
+
|
|
596
|
+
| Flag | Type | Default |
|
|
597
|
+
| --- | --- | --- |
|
|
598
|
+
| `--config` | string | unset |
|
|
599
|
+
| `--json` | boolean | `false` |
|
|
600
|
+
| `--work-order` | string | unset |
|
|
601
|
+
| `--decision` | string | unset |
|
|
602
|
+
| `--record` | boolean | `false` |
|
|
603
|
+
| `--record-file` | string | unset |
|
|
604
|
+
| `--supersedes` | string | unset |
|
|
605
|
+
| `--none` | boolean | `false` |
|
|
606
|
+
| `--reason` | string | unset |
|
|
439
607
|
|
|
440
608
|
| Exit | Meaning |
|
|
441
609
|
| --- | --- |
|
|
@@ -464,6 +632,26 @@ Reads `cockpit.toml` from `--config`.
|
|
|
464
632
|
| 2 | failure |
|
|
465
633
|
| 130 | cancelled |
|
|
466
634
|
|
|
635
|
+
## cockpit work acknowledge
|
|
636
|
+
|
|
637
|
+
Acknowledge that an order weakened tests, as [work.gates] allows.
|
|
638
|
+
|
|
639
|
+
Reads `cockpit.toml` from `--config`.
|
|
640
|
+
|
|
641
|
+
| Flag | Type | Default |
|
|
642
|
+
| --- | --- | --- |
|
|
643
|
+
| `--config` | string | unset |
|
|
644
|
+
| `--json` | boolean | `false` |
|
|
645
|
+
| `--work-order` | string | unset |
|
|
646
|
+
| `--note` | string | unset |
|
|
647
|
+
| `--interactive` | boolean | `false` |
|
|
648
|
+
|
|
649
|
+
| Exit | Meaning |
|
|
650
|
+
| --- | --- |
|
|
651
|
+
| 0 | success |
|
|
652
|
+
| 2 | failure |
|
|
653
|
+
| 130 | cancelled |
|
|
654
|
+
|
|
467
655
|
## cockpit work grade
|
|
468
656
|
|
|
469
657
|
Grade an accepted order the way [work] grading says.
|
|
@@ -573,6 +761,8 @@ Reads `cockpit.toml` from `--config`.
|
|
|
573
761
|
| `--config` | string | unset |
|
|
574
762
|
| `--json` | boolean | `false` |
|
|
575
763
|
| `--role` | string | unset |
|
|
764
|
+
| `--route` | string | unset |
|
|
765
|
+
| `--fail-on-findings` | boolean | `false` |
|
|
576
766
|
|
|
577
767
|
| Exit | Meaning |
|
|
578
768
|
| --- | --- |
|
|
@@ -591,6 +781,24 @@ Reads `cockpit.toml` from `--config`.
|
|
|
591
781
|
| `--config` | string | unset |
|
|
592
782
|
| `--json` | boolean | `false` |
|
|
593
783
|
| `--role` | string | unset |
|
|
784
|
+
| `--route` | string | unset |
|
|
785
|
+
|
|
786
|
+
| Exit | Meaning |
|
|
787
|
+
| --- | --- |
|
|
788
|
+
| 0 | success |
|
|
789
|
+
| 2 | failure |
|
|
790
|
+
| 130 | cancelled |
|
|
791
|
+
|
|
792
|
+
## cockpit docs check
|
|
793
|
+
|
|
794
|
+
Report removed paths and make targets living docs still cite, and broken decision records.
|
|
795
|
+
|
|
796
|
+
Reads `cockpit.toml` from `--config`.
|
|
797
|
+
|
|
798
|
+
| Flag | Type | Default |
|
|
799
|
+
| --- | --- | --- |
|
|
800
|
+
| `--config` | string | unset |
|
|
801
|
+
| `--json` | boolean | `false` |
|
|
594
802
|
|
|
595
803
|
| Exit | Meaning |
|
|
596
804
|
| --- | --- |
|