@cleocode/contracts 2026.10.17 → 2026.10.18
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/dist/__tests__/goal-contract.test.d.ts +9 -0
- package/dist/__tests__/goal-contract.test.d.ts.map +1 -0
- package/dist/__tests__/goal-contract.test.js +107 -0
- package/dist/__tests__/goal-contract.test.js.map +1 -0
- package/dist/acceptance-gate-schema.d.ts +19 -0
- package/dist/acceptance-gate-schema.d.ts.map +1 -1
- package/dist/acceptance-gate-schema.js +28 -0
- package/dist/acceptance-gate-schema.js.map +1 -1
- package/dist/cloud/api.d.ts +6 -0
- package/dist/cloud/api.d.ts.map +1 -1
- package/dist/cloud/api.js +16 -0
- package/dist/cloud/api.js.map +1 -1
- package/dist/done-plan.d.ts +4 -2
- package/dist/done-plan.d.ts.map +1 -1
- package/dist/goal-contract.d.ts +404 -0
- package/dist/goal-contract.d.ts.map +1 -0
- package/dist/goal-contract.js +37 -0
- package/dist/goal-contract.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/invariants/sync-write-invariants.js +1 -1
- package/dist/invariants/sync-write-invariants.js.map +1 -1
- package/dist/lean.d.ts +28 -0
- package/dist/lean.d.ts.map +1 -1
- package/dist/nexus-cloud.d.ts +6 -0
- package/dist/nexus-cloud.d.ts.map +1 -1
- package/dist/nexus-cloud.js +6 -0
- package/dist/nexus-cloud.js.map +1 -1
- package/dist/row-identity.d.ts +16 -0
- package/dist/row-identity.d.ts.map +1 -1
- package/dist/task.d.ts +19 -0
- package/dist/task.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/goal-contract.test.ts +112 -0
- package/src/acceptance-gate-schema.ts +31 -0
- package/src/cloud/api.ts +16 -0
- package/src/done-plan.ts +4 -2
- package/src/goal-contract.ts +438 -0
- package/src/index.ts +39 -0
- package/src/invariants/sync-write-invariants.ts +1 -1
- package/src/lean.ts +30 -0
- package/src/nexus-cloud.ts +7 -0
- package/src/row-identity.ts +16 -0
- package/src/task.ts +16 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* goal/v1 — the contract a goal runtime executes against, and what CLEO reads
|
|
3
|
+
* back from a run.
|
|
4
|
+
*
|
|
5
|
+
* CLEO owns the goal protocol; OpenCode-Goal (OCG) is the goal runtime (owner
|
|
6
|
+
* decision 2026-10-16, epic T13791). The two stay separate packages and talk
|
|
7
|
+
* only through the `cleo` CLI and LAFS envelopes:
|
|
8
|
+
*
|
|
9
|
+
* 1. `cleo goal draft` writes a {@link GoalContract} (`goal.yaml`) from a
|
|
10
|
+
* task's acceptance criteria.
|
|
11
|
+
* 2. The runtime locks the contract by the sha256 of its bytes, runs it, and
|
|
12
|
+
* writes a {@link GoalOutcome}.
|
|
13
|
+
* 3. `cleo goal close` reads the outcome and records evidence for each passing
|
|
14
|
+
* criterion on the gate it demonstrates, via {@link GoalCriterion.proves}.
|
|
15
|
+
*
|
|
16
|
+
* The shapes mirror OCG's `src/contract/types.ts` field for field, in OCG's
|
|
17
|
+
* snake_case YAML spelling, so one file means the same thing on both sides.
|
|
18
|
+
* The only addition is the optional per-criterion `proves` list.
|
|
19
|
+
*
|
|
20
|
+
* Relation to `GoalRecord` (`goal.ts`): a GoalRecord is CLEO's own
|
|
21
|
+
* per-agent, turn-budgeted loop state, whose criteria are free text. A goal/v1
|
|
22
|
+
* contract is the portable, hash-locked agreement a runtime executes; its
|
|
23
|
+
* criteria carry checks. They share no fields.
|
|
24
|
+
*
|
|
25
|
+
* Types only (gate 10): parsing and validation live in core.
|
|
26
|
+
*
|
|
27
|
+
* @packageDocumentation
|
|
28
|
+
* @module @cleocode/contracts/goal-contract
|
|
29
|
+
*
|
|
30
|
+
* @epic T13791
|
|
31
|
+
* @task T13792
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/** The schema tag every goal/v1 contract carries. */
|
|
35
|
+
export const GOAL_CONTRACT_SCHEMA = 'goal/v1' as const;
|
|
36
|
+
|
|
37
|
+
/** Expected result of a {@link GoalCommandCheck}. Absent fields are not checked; no field at all means `exit: 0`. */
|
|
38
|
+
export interface GoalCheckExpect {
|
|
39
|
+
/** Required exit code. */
|
|
40
|
+
exit?: number;
|
|
41
|
+
/** Text stdout must contain. */
|
|
42
|
+
stdout_contains?: string;
|
|
43
|
+
/** Regular expression stdout must match. */
|
|
44
|
+
stdout_regex?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The host runs a shell command and checks its result. */
|
|
48
|
+
export interface GoalCommandCheck {
|
|
49
|
+
/** Discriminant. */
|
|
50
|
+
kind: 'command';
|
|
51
|
+
/** Shell command, run from the goal workspace. */
|
|
52
|
+
run: string;
|
|
53
|
+
/** Expected result. */
|
|
54
|
+
expect?: GoalCheckExpect;
|
|
55
|
+
/** Timeout in seconds (runtime default 300). */
|
|
56
|
+
timeout?: number;
|
|
57
|
+
/** Repeat count, 1 to 10; every run must pass. */
|
|
58
|
+
runs?: number;
|
|
59
|
+
/** The command reaches a live service. */
|
|
60
|
+
live?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The host checks that a path exists (or, with `exists: false`, that it does not). */
|
|
64
|
+
export interface GoalFileCheck {
|
|
65
|
+
/** Discriminant. */
|
|
66
|
+
kind: 'file';
|
|
67
|
+
/** Workspace-relative path. */
|
|
68
|
+
path: string;
|
|
69
|
+
/** Expected existence (default true). */
|
|
70
|
+
exists?: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The host checks that a file contains text or matches a regex. */
|
|
74
|
+
export interface GoalContainsCheck {
|
|
75
|
+
/** Discriminant. */
|
|
76
|
+
kind: 'contains';
|
|
77
|
+
/** Workspace-relative path. */
|
|
78
|
+
path: string;
|
|
79
|
+
/** Literal text to find. */
|
|
80
|
+
text?: string;
|
|
81
|
+
/** Regular expression to match. */
|
|
82
|
+
regex?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The host checks that a pattern occurs nowhere (optionally within `paths`). */
|
|
86
|
+
export interface GoalAbsentCheck {
|
|
87
|
+
/** Discriminant. */
|
|
88
|
+
kind: 'absent';
|
|
89
|
+
/** Pattern that must not occur. */
|
|
90
|
+
pattern: string;
|
|
91
|
+
/** Paths to search; absent means the workspace. */
|
|
92
|
+
paths?: string[];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** The host checks that the given paths are unchanged since the run's base commit (a protected oracle). */
|
|
96
|
+
export interface GoalDiffCheck {
|
|
97
|
+
/** Discriminant. */
|
|
98
|
+
kind: 'diff';
|
|
99
|
+
/** Paths (or globs) that must not change. */
|
|
100
|
+
paths: string[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** An independent verifier agent answers the question, citing quotes the host re-reads. */
|
|
104
|
+
export interface GoalVerifierCheck {
|
|
105
|
+
/** Discriminant. */
|
|
106
|
+
kind: 'verifier';
|
|
107
|
+
/** Question the verifier must answer. */
|
|
108
|
+
ask: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** The owner signs the criterion off. */
|
|
112
|
+
export interface GoalHumanCheck {
|
|
113
|
+
/** Discriminant. */
|
|
114
|
+
kind: 'human';
|
|
115
|
+
/** Question the owner answers. */
|
|
116
|
+
ask: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** How a criterion is proven. */
|
|
120
|
+
export type GoalCheck =
|
|
121
|
+
| GoalCommandCheck
|
|
122
|
+
| GoalFileCheck
|
|
123
|
+
| GoalContainsCheck
|
|
124
|
+
| GoalAbsentCheck
|
|
125
|
+
| GoalDiffCheck
|
|
126
|
+
| GoalVerifierCheck
|
|
127
|
+
| GoalHumanCheck;
|
|
128
|
+
|
|
129
|
+
/** Discriminant of {@link GoalCheck}. */
|
|
130
|
+
export type GoalCheckKind = GoalCheck['kind'];
|
|
131
|
+
|
|
132
|
+
/** Check kinds the host itself runs; invariants may use only these. */
|
|
133
|
+
export const GOAL_HOST_CHECK_KINDS = ['command', 'file', 'contains', 'absent', 'diff'] as const;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A CLEO acceptance-criterion reference: exactly the three target forms of a
|
|
137
|
+
* `satisfies:` evidence atom (`evidence-atom-schema.ts`, ADR-079-r2 §2.1).
|
|
138
|
+
*
|
|
139
|
+
* - positional `T1234#AC2` — drifts when the task's ACs are renumbered;
|
|
140
|
+
* - canonical `T1234#<lowercase uuid>` — the criterion's stable id, preferred
|
|
141
|
+
* in a hash-locked contract;
|
|
142
|
+
* - pinned `T1234#AC2@20260524223045` — an alias pinned to a 14-digit
|
|
143
|
+
* `YYYYMMDDhhmmss` version.
|
|
144
|
+
*
|
|
145
|
+
* The template types only shape the value (`${bigint}` still admits `-2`, and
|
|
146
|
+
* the uuid part is any dashed string). Core validates every reference with the
|
|
147
|
+
* real regexes: `SATISFIES_TASK_ID_REGEX` (`^T[0-9]{1,7}$`), `AC_ALIAS_REGEX`
|
|
148
|
+
* (`^AC[0-9]{1,4}$`), `AC_UUID_REGEX` and `SATISFIES_VERSION_PIN_REGEX`
|
|
149
|
+
* (`^[0-9]{14}$`).
|
|
150
|
+
*/
|
|
151
|
+
export type GoalAcRef =
|
|
152
|
+
| `T${bigint}#AC${bigint}`
|
|
153
|
+
| `T${bigint}#${string}-${string}-${string}-${string}-${string}`
|
|
154
|
+
| `T${bigint}#AC${bigint}@${bigint}`;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* One criterion (`C<n>`) or invariant (`I<n>`) of a goal.
|
|
158
|
+
*
|
|
159
|
+
* Invariants are always essential and always host-checked.
|
|
160
|
+
*/
|
|
161
|
+
export interface GoalCriterion {
|
|
162
|
+
/** `C1`, `C2`, … for criteria; `I1`, `I2`, … for invariants. */
|
|
163
|
+
id: string;
|
|
164
|
+
/** End state that is true when the criterion holds. */
|
|
165
|
+
statement: string;
|
|
166
|
+
/** The goal is not done until every essential criterion passes. */
|
|
167
|
+
essential: boolean;
|
|
168
|
+
/** How the criterion is proven. */
|
|
169
|
+
check: GoalCheck;
|
|
170
|
+
/**
|
|
171
|
+
* CLEO acceptance criteria this criterion's evidence demonstrates. When the
|
|
172
|
+
* criterion passes, `cleo goal close` links its evidence to each one with
|
|
173
|
+
* `satisfies:`. Absent means the criterion proves no CLEO AC.
|
|
174
|
+
*/
|
|
175
|
+
proves?: GoalAcRef[];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** A decision the agent made without the owner, open to veto. */
|
|
179
|
+
export interface GoalAssumption {
|
|
180
|
+
/** `A1`, `A2`, … */
|
|
181
|
+
id: string;
|
|
182
|
+
/** What was assumed. */
|
|
183
|
+
text: string;
|
|
184
|
+
/** Why. */
|
|
185
|
+
rationale?: string;
|
|
186
|
+
/** Whether it can be undone cheaply. */
|
|
187
|
+
reversible?: boolean;
|
|
188
|
+
/** Owner disposition. */
|
|
189
|
+
status: 'assumed' | 'confirmed' | 'vetoed';
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** One plan step. */
|
|
193
|
+
export interface GoalStep {
|
|
194
|
+
/** `S1`, `S2`, … */
|
|
195
|
+
id: string;
|
|
196
|
+
/** What the step does. */
|
|
197
|
+
title: string;
|
|
198
|
+
/** Criterion ids the step proves. */
|
|
199
|
+
proves: string[];
|
|
200
|
+
/** Step ids that must finish first. */
|
|
201
|
+
depends_on: string[];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Optional goal priority; absent sorts last. */
|
|
205
|
+
export type GoalPriority = 'low' | 'medium' | 'high';
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Run budget. In YAML, `wall` is a duration (`"90m"`) and `tokens` a count
|
|
209
|
+
* (`400k`); the parsed form holds milliseconds and integers.
|
|
210
|
+
*/
|
|
211
|
+
export interface GoalBudget {
|
|
212
|
+
/** Agent turns. */
|
|
213
|
+
turns?: number;
|
|
214
|
+
/** Active wall-clock time, milliseconds (YAML `wall`). */
|
|
215
|
+
wallMs?: number;
|
|
216
|
+
/** Input + output + reasoning tokens. */
|
|
217
|
+
tokens?: number;
|
|
218
|
+
/** Spend ceiling in US dollars. */
|
|
219
|
+
cost_usd?: number;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Contract changes the owner lets the agent apply to its own contract. */
|
|
223
|
+
export type GoalAmendClass = 'timeout' | 'budget' | 'plan' | 'recover';
|
|
224
|
+
|
|
225
|
+
/** Owner-set autonomy policy. */
|
|
226
|
+
export interface GoalAutonomy {
|
|
227
|
+
/** Whether the agent may ask the owner questions mid-run (`defer` queues them). */
|
|
228
|
+
questions: 'defer' | 'allow';
|
|
229
|
+
/** What an owner message does to a running goal. */
|
|
230
|
+
on_user_message: 'steer' | 'pause';
|
|
231
|
+
/** What an interrupt does. */
|
|
232
|
+
on_interrupt: 'pause' | 'resume-on-message';
|
|
233
|
+
/** Amendment classes the agent may apply itself (default none). */
|
|
234
|
+
amend: GoalAmendClass[];
|
|
235
|
+
/** What the stall detector does. */
|
|
236
|
+
on_stall: 'pause' | 'continue';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** How completion is decided. */
|
|
240
|
+
export type GoalVerificationMode = 'host' | 'host+verifier' | 'strict';
|
|
241
|
+
|
|
242
|
+
/** The CLEO evidence gates a goal can declare evidence for. */
|
|
243
|
+
export type GoalCleoGate = 'implemented' | 'testsPassed' | 'qaPassed';
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* A CLEO task the goal serves (OCG `CleoTaskLink`).
|
|
247
|
+
*
|
|
248
|
+
* The bare id links the task for reporting. `acs` is OCG's older per-gate
|
|
249
|
+
* claim of which AC aliases a gate's evidence proves; per-criterion
|
|
250
|
+
* {@link GoalCriterion.proves} is the precise form and what `cleo goal draft`
|
|
251
|
+
* writes. An AC neither form claims stays open.
|
|
252
|
+
*/
|
|
253
|
+
export interface GoalTaskLink {
|
|
254
|
+
/** Task id (`T123`). */
|
|
255
|
+
id: string;
|
|
256
|
+
/** Per-gate AC aliases (`AC1`, …) the gate's evidence proves. */
|
|
257
|
+
acs?: Partial<Record<GoalCleoGate, string[]>>;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** A goal/v1 contract: written by the owner (or `cleo goal draft`), locked by hash when a run starts. */
|
|
261
|
+
export interface GoalContract {
|
|
262
|
+
/** Always {@link GOAL_CONTRACT_SCHEMA}. */
|
|
263
|
+
schema: typeof GOAL_CONTRACT_SCHEMA;
|
|
264
|
+
/** Kebab-case slug; equals the goal's directory name. */
|
|
265
|
+
id: string;
|
|
266
|
+
/** Short title (under 80 characters). */
|
|
267
|
+
title: string;
|
|
268
|
+
/** Optional priority. */
|
|
269
|
+
priority?: GoalPriority;
|
|
270
|
+
/** `"<slug>@<lock-prefix>"` of the goal this one replaces. */
|
|
271
|
+
supersedes?: string;
|
|
272
|
+
/** The owner's own words, kept verbatim as the authoritative source. */
|
|
273
|
+
intent: { verbatim: string };
|
|
274
|
+
/** The one end state that is true when the goal is done. */
|
|
275
|
+
outcome: string;
|
|
276
|
+
/** Why the goal matters. */
|
|
277
|
+
why?: string;
|
|
278
|
+
/** What is in and out of scope. */
|
|
279
|
+
scope: { in: string[]; out: string[] };
|
|
280
|
+
/** At least one non-goal. */
|
|
281
|
+
non_goals: string[];
|
|
282
|
+
/** Constraints the run must respect. */
|
|
283
|
+
constraints: string[];
|
|
284
|
+
/** At least one criterion, at least one essential. */
|
|
285
|
+
criteria: GoalCriterion[];
|
|
286
|
+
/** Host-checked conditions that must hold throughout. */
|
|
287
|
+
invariants: GoalCriterion[];
|
|
288
|
+
/** Root-relative execution workspace (default: project root). */
|
|
289
|
+
workspace?: string;
|
|
290
|
+
/** The CLEO tasks this goal serves. Absent means no CLEO behaviour. */
|
|
291
|
+
cleo?: { tasks: GoalTaskLink[] };
|
|
292
|
+
/** Paths the agent must not modify. */
|
|
293
|
+
protect: string[];
|
|
294
|
+
/** Decisions made without the owner. */
|
|
295
|
+
assumptions: GoalAssumption[];
|
|
296
|
+
/** Ordered plan. */
|
|
297
|
+
plan: GoalStep[];
|
|
298
|
+
/** Run budget. */
|
|
299
|
+
budget: GoalBudget;
|
|
300
|
+
/** Stop conditions. */
|
|
301
|
+
stop: { when?: string; escalate_when: string[] };
|
|
302
|
+
/** Autonomy policy. */
|
|
303
|
+
autonomy: GoalAutonomy;
|
|
304
|
+
/** Verification policy. */
|
|
305
|
+
verification: {
|
|
306
|
+
/** How completion is decided (default `host+verifier`). */
|
|
307
|
+
mode: GoalVerificationMode;
|
|
308
|
+
/** Verifier rejections before the run escalates, 1 to 10 (default 3). */
|
|
309
|
+
max_rejections: number;
|
|
310
|
+
/** Folders the verifier may read. */
|
|
311
|
+
read: string[];
|
|
312
|
+
/** Verifier model, `providerID/modelID[#variant]`. */
|
|
313
|
+
model?: string;
|
|
314
|
+
/** Verifier effort. */
|
|
315
|
+
effort?: string;
|
|
316
|
+
};
|
|
317
|
+
/** Execution settings. */
|
|
318
|
+
execution: { agent?: string };
|
|
319
|
+
/** Free-form metadata: any YAML value, opaque to CLEO. */
|
|
320
|
+
meta: Record<string, unknown>;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Who produced a criterion's verdict. */
|
|
324
|
+
export type GoalVerdictSource = 'host' | 'verifier' | 'verifier-fallback' | 'human';
|
|
325
|
+
|
|
326
|
+
/** A quote the verifier cited, which the host re-read from the file. */
|
|
327
|
+
export interface GoalVerifierQuote {
|
|
328
|
+
/** Workspace-relative path. */
|
|
329
|
+
path: string;
|
|
330
|
+
/** Exact text quoted. */
|
|
331
|
+
quote: string;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/** Evidence of a passing or failing `command` check. */
|
|
335
|
+
export interface GoalCommandEvidence {
|
|
336
|
+
/** Discriminant. */
|
|
337
|
+
kind: 'command';
|
|
338
|
+
/** The command as run. */
|
|
339
|
+
command: string;
|
|
340
|
+
/** Exit code of the last run. */
|
|
341
|
+
exitCode: number;
|
|
342
|
+
/**
|
|
343
|
+
* Path of a vitest-shaped JSON report the command wrote, when it ran tests.
|
|
344
|
+
* `cleo goal close` records it as a `test-run:` atom.
|
|
345
|
+
*/
|
|
346
|
+
reportPath?: string;
|
|
347
|
+
/**
|
|
348
|
+
* sha256 (hex) of the report bytes the run produced. `cleo goal close`
|
|
349
|
+
* refuses a `test-run:` whose file does not hash to it, or that has none.
|
|
350
|
+
*/
|
|
351
|
+
reportSha256?: string;
|
|
352
|
+
/** Test files the report covers. */
|
|
353
|
+
testFiles?: string[];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Evidence of a `file`, `contains`, `absent` or `diff` check.
|
|
358
|
+
*
|
|
359
|
+
* A passing `diff` proves the paths did NOT change (a protected oracle held),
|
|
360
|
+
* so it must never become `implemented` / `files:` evidence.
|
|
361
|
+
*/
|
|
362
|
+
export interface GoalPathEvidence {
|
|
363
|
+
/** Discriminant: the check kind that ran. */
|
|
364
|
+
kind: 'file' | 'contains' | 'absent' | 'diff';
|
|
365
|
+
/** Repo-relative paths the check examined. */
|
|
366
|
+
paths: string[];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/** Evidence of a verifier check. */
|
|
370
|
+
export interface GoalVerifierEvidence {
|
|
371
|
+
/** Discriminant. */
|
|
372
|
+
kind: 'verifier';
|
|
373
|
+
/** The verifier's verdict. */
|
|
374
|
+
verdict: 'proven' | 'not_proven' | 'contradicted';
|
|
375
|
+
/** Quotes the verifier cited. */
|
|
376
|
+
quotes: GoalVerifierQuote[];
|
|
377
|
+
/** The verifier's reason. */
|
|
378
|
+
reason?: string;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Evidence of a human sign-off, as the runtime reports it. It is not CLEO
|
|
383
|
+
* evidence on its own: it counts only when CLEO's own owner or HITL record
|
|
384
|
+
* backs it.
|
|
385
|
+
*/
|
|
386
|
+
export interface GoalHumanEvidence {
|
|
387
|
+
/** Discriminant. */
|
|
388
|
+
kind: 'human';
|
|
389
|
+
/** Who signed off. */
|
|
390
|
+
by?: string;
|
|
391
|
+
/** The owner's note. */
|
|
392
|
+
note?: string;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/** What a criterion's check produced. */
|
|
396
|
+
export type GoalCheckEvidence =
|
|
397
|
+
| GoalCommandEvidence
|
|
398
|
+
| GoalPathEvidence
|
|
399
|
+
| GoalVerifierEvidence
|
|
400
|
+
| GoalHumanEvidence;
|
|
401
|
+
|
|
402
|
+
/** The verdict on one criterion or invariant. */
|
|
403
|
+
export interface GoalCriterionOutcome {
|
|
404
|
+
/** Criterion or invariant id (`C1`, `I1`). */
|
|
405
|
+
id: string;
|
|
406
|
+
/** Whether it passed. */
|
|
407
|
+
pass: boolean;
|
|
408
|
+
/** Who decided. */
|
|
409
|
+
by: GoalVerdictSource;
|
|
410
|
+
/** Human-readable detail. */
|
|
411
|
+
detail?: string;
|
|
412
|
+
/** What the check produced. */
|
|
413
|
+
evidence: GoalCheckEvidence;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* What a goal run produced, written by the runtime and read by
|
|
418
|
+
* `cleo goal close`.
|
|
419
|
+
*
|
|
420
|
+
* `lock` ties the outcome to the exact contract bytes; `headCommit` is the
|
|
421
|
+
* tree the checks ran on.
|
|
422
|
+
*/
|
|
423
|
+
export interface GoalOutcome {
|
|
424
|
+
/** Always `goal-outcome/v1`. */
|
|
425
|
+
schema: 'goal-outcome/v1';
|
|
426
|
+
/** Goal slug ({@link GoalContract.id}). */
|
|
427
|
+
goal: string;
|
|
428
|
+
/** Runtime run id. */
|
|
429
|
+
runId?: string;
|
|
430
|
+
/** sha256 (hex) of the `goal.yaml` bytes the run locked. */
|
|
431
|
+
lock: string;
|
|
432
|
+
/** Commit the run started from (the diff base), or null when none. */
|
|
433
|
+
baseCommit: string | null;
|
|
434
|
+
/** Commit the checks ran on. */
|
|
435
|
+
headCommit: string;
|
|
436
|
+
/** Per-criterion and per-invariant verdicts. */
|
|
437
|
+
results: GoalCriterionOutcome[];
|
|
438
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ export {
|
|
|
44
44
|
lintGateSchema,
|
|
45
45
|
manualGateSchema,
|
|
46
46
|
testCountReportSchema,
|
|
47
|
+
testCountSummarySchema,
|
|
47
48
|
testGateSchema,
|
|
48
49
|
} from './acceptance-gate-schema.js';
|
|
49
50
|
// === Provider Adapter Contracts ===
|
|
@@ -748,6 +749,41 @@ export {
|
|
|
748
749
|
isTerminalGoalStatus,
|
|
749
750
|
isValidGoalTargetTaskId,
|
|
750
751
|
} from './goal.js';
|
|
752
|
+
// === goal/v1 protocol: contract, task link, outcome (T13792 · Epic T13791) ===
|
|
753
|
+
export type {
|
|
754
|
+
GoalAbsentCheck,
|
|
755
|
+
GoalAcRef,
|
|
756
|
+
GoalAmendClass,
|
|
757
|
+
GoalAssumption,
|
|
758
|
+
GoalAutonomy,
|
|
759
|
+
GoalBudget,
|
|
760
|
+
GoalCheck,
|
|
761
|
+
GoalCheckEvidence,
|
|
762
|
+
GoalCheckExpect,
|
|
763
|
+
GoalCheckKind,
|
|
764
|
+
GoalCleoGate,
|
|
765
|
+
GoalCommandCheck,
|
|
766
|
+
GoalCommandEvidence,
|
|
767
|
+
GoalContainsCheck,
|
|
768
|
+
GoalContract,
|
|
769
|
+
GoalCriterion,
|
|
770
|
+
GoalCriterionOutcome,
|
|
771
|
+
GoalDiffCheck,
|
|
772
|
+
GoalFileCheck,
|
|
773
|
+
GoalHumanCheck,
|
|
774
|
+
GoalHumanEvidence,
|
|
775
|
+
GoalOutcome,
|
|
776
|
+
GoalPathEvidence,
|
|
777
|
+
GoalPriority,
|
|
778
|
+
GoalStep,
|
|
779
|
+
GoalTaskLink,
|
|
780
|
+
GoalVerdictSource,
|
|
781
|
+
GoalVerificationMode,
|
|
782
|
+
GoalVerifierCheck,
|
|
783
|
+
GoalVerifierEvidence,
|
|
784
|
+
GoalVerifierQuote,
|
|
785
|
+
} from './goal-contract.js';
|
|
786
|
+
export { GOAL_CONTRACT_SCHEMA, GOAL_HOST_CHECK_KINDS } from './goal-contract.js';
|
|
751
787
|
// === Graph Intelligence Types (T512, T529, T1862, T9145) ===
|
|
752
788
|
export type {
|
|
753
789
|
AmbiguousProvenance,
|
|
@@ -902,6 +938,8 @@ export type {
|
|
|
902
938
|
LeanConfig,
|
|
903
939
|
LeanDebtItem,
|
|
904
940
|
LeanDebtReport,
|
|
941
|
+
LeanGainMetric,
|
|
942
|
+
LeanGainReport,
|
|
905
943
|
LeanLevel,
|
|
906
944
|
LeanLevelSource,
|
|
907
945
|
} from './lean.js';
|
|
@@ -3133,6 +3171,7 @@ export {
|
|
|
3133
3171
|
NEXUS_DEVICE_LIST_STATES,
|
|
3134
3172
|
NEXUS_DEVICE_STATE_UNKNOWN,
|
|
3135
3173
|
NEXUS_DEVICE_STATES,
|
|
3174
|
+
NEXUS_FEATURE_MANIFEST_SNAPSHOT_AUTHORITATIVE,
|
|
3136
3175
|
NEXUS_FEATURE_PROJECT_INITIAL_KEY,
|
|
3137
3176
|
NEXUS_FORBIDDEN_ERRORS,
|
|
3138
3177
|
NEXUS_FORBIDDEN_REASONS,
|
|
@@ -245,7 +245,7 @@ export const SYNC_WRITE_INVARIANTS: readonly SyncWriteInvariant[] = Object.freez
|
|
|
245
245
|
['tasks_session_handoff_entries'],
|
|
246
246
|
['trg_tasks_session_handoff_no_update'],
|
|
247
247
|
['H2'],
|
|
248
|
-
'handoff entries are never updated',
|
|
248
|
+
'handoff entries are never updated, and one session has one (the natural uid over the session merges a peer’s; T13777)',
|
|
249
249
|
),
|
|
250
250
|
trigger(
|
|
251
251
|
'task.claim.lease-iso',
|
package/src/lean.ts
CHANGED
|
@@ -69,3 +69,33 @@ export interface LeanDebtReport {
|
|
|
69
69
|
/** Keys that already had a `lean-debt` task, so none was filed. */
|
|
70
70
|
readonly alreadyFiled: readonly string[];
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
/** One measured metric on the `cleo lean gain` scoreboard (T13669). */
|
|
74
|
+
export interface LeanGainMetric {
|
|
75
|
+
/** What was measured, e.g. `Source lines of code`. */
|
|
76
|
+
readonly name: string;
|
|
77
|
+
/** ct-lean as a share of the no-skill baseline (0.35 = 35%). */
|
|
78
|
+
readonly ctLeanShare: number;
|
|
79
|
+
/** Ponytail 5.1.0 as a share of the same baseline, for comparison. */
|
|
80
|
+
readonly ponytailShare: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** The measured scoreboard `cleo lean gain` prints: benchmark numbers, never per-repo ones. */
|
|
84
|
+
export interface LeanGainReport {
|
|
85
|
+
/** Scoreboard heading naming the run the numbers come from. */
|
|
86
|
+
readonly heading: string;
|
|
87
|
+
/** Canonical research doc the numbers come from (`cleo docs fetch <slug>`). */
|
|
88
|
+
readonly source: string;
|
|
89
|
+
/** How the numbers were measured, in one line. */
|
|
90
|
+
readonly method: string;
|
|
91
|
+
/** Size, cost and time metrics. */
|
|
92
|
+
readonly metrics: readonly LeanGainMetric[];
|
|
93
|
+
/** Hidden checks passed per arm, e.g. `{ baseline: '23/24', ponytail: '24/24', ctLean: '24/24' }`. */
|
|
94
|
+
readonly hiddenChecks: {
|
|
95
|
+
readonly baseline: string;
|
|
96
|
+
readonly ponytail: string;
|
|
97
|
+
readonly ctLean: string;
|
|
98
|
+
};
|
|
99
|
+
/** The honesty boundary, always present. */
|
|
100
|
+
readonly note: string;
|
|
101
|
+
}
|
package/src/nexus-cloud.ts
CHANGED
|
@@ -274,6 +274,13 @@ export const nexusCloudStatusCheckSchema = z.object({
|
|
|
274
274
|
*/
|
|
275
275
|
export const NEXUS_FEATURE_PROJECT_INITIAL_KEY = 'project.initial-key';
|
|
276
276
|
|
|
277
|
+
/**
|
|
278
|
+
* The E3 `features` entry of a server whose checkpoint/v3 rule skips the tables a manifest lists as
|
|
279
|
+
* `snapshotAuthoritative` (cleo-nexus #45, cleocode T13777). A journal checkpoint sends the list only to
|
|
280
|
+
* such a server.
|
|
281
|
+
*/
|
|
282
|
+
export const NEXUS_FEATURE_MANIFEST_SNAPSHOT_AUTHORITATIVE = 'manifest.snapshot-authoritative';
|
|
283
|
+
|
|
277
284
|
/** `NexusStatus` (E3 `GET /v1/status`). */
|
|
278
285
|
export const nexusCloudStatusSchema = z.object({
|
|
279
286
|
serverTime: isoTime.optional(),
|
package/src/row-identity.ts
CHANGED
|
@@ -114,6 +114,22 @@ export interface RowIdentitySpec {
|
|
|
114
114
|
readonly birthFacts?: readonly string[];
|
|
115
115
|
/** `natural` relation tables: the symmetric relation types. */
|
|
116
116
|
readonly symmetric?: SymmetricEdge;
|
|
117
|
+
/**
|
|
118
|
+
* `natural`: nullable key columns. A row whose value in one of them is NULL
|
|
119
|
+
* gets no uid and stays on its device: it is never captured, never filled
|
|
120
|
+
* and never pending (T12914). SQLite admits several NULLs in a composite
|
|
121
|
+
* primary key, so such rows would otherwise fold into one uid and diverge.
|
|
122
|
+
*/
|
|
123
|
+
readonly localWhenNull?: readonly string[];
|
|
124
|
+
/**
|
|
125
|
+
* `natural`: the order columns that pick, among rows sharing one natural
|
|
126
|
+
* key, the FIRST (T13777). Only that row gets the uid; a later row with the
|
|
127
|
+
* same key gets none and stays on its device: it is never captured, never
|
|
128
|
+
* filled and never pending. For a key the schema does not make unique (a
|
|
129
|
+
* write-once table whose legacy DDL lacks the UNIQUE), so a duplicate never
|
|
130
|
+
* wedges the fill.
|
|
131
|
+
*/
|
|
132
|
+
readonly localUnlessFirst?: readonly string[];
|
|
117
133
|
/**
|
|
118
134
|
* `minted`: every uid is random, never derived from content, including for
|
|
119
135
|
* existing rows. Required for `portable-secret` tables.
|
package/src/task.ts
CHANGED
|
@@ -303,6 +303,13 @@ export type EvidenceAtom =
|
|
|
303
303
|
* longer matches, unless `ci:<pr>` or a full tool run carries the gate.
|
|
304
304
|
*/
|
|
305
305
|
treeHash?: string;
|
|
306
|
+
/**
|
|
307
|
+
* HEAD as of the run, when it differs from `headSha` because commits
|
|
308
|
+
* landed on origin's default branch after the run (T13784). Those
|
|
309
|
+
* commits stand only while they touch none of the change's files, the
|
|
310
|
+
* test files the report ran, or the shared test configs.
|
|
311
|
+
*/
|
|
312
|
+
runHeadSha?: string;
|
|
306
313
|
/** Test files the report covered, relative to the bound checkout (capped, T12965). */
|
|
307
314
|
testFiles?: string[];
|
|
308
315
|
/** Total test files the report covered; exceeds `testFiles.length` when capped. */
|
|
@@ -400,6 +407,8 @@ export type EvidenceAtom =
|
|
|
400
407
|
affectedPackages?: string[];
|
|
401
408
|
/** The test projects the affected run actually selected (incl. non-package projects). */
|
|
402
409
|
affectedProjects?: string[];
|
|
410
|
+
/** Test files outside every package the affected run named (T13754). */
|
|
411
|
+
affectedTestFiles?: string[];
|
|
403
412
|
/** Affected DEPENDENT packages with no test project (a changed one refuses the scope). */
|
|
404
413
|
untestedPackages?: string[];
|
|
405
414
|
/**
|
|
@@ -602,6 +611,13 @@ export type EvidenceAtom =
|
|
|
602
611
|
baseSha: string;
|
|
603
612
|
baseRunId: number;
|
|
604
613
|
}>;
|
|
614
|
+
/**
|
|
615
|
+
* The merge commit's own run FAILED, but only on the flaky-quarantine
|
|
616
|
+
* budget: every failing job's tests all passed (T13809). `descendantSha`
|
|
617
|
+
* is the later green main run standing in. Each job records its failing
|
|
618
|
+
* merge-commit run.
|
|
619
|
+
*/
|
|
620
|
+
nonTestFailures?: Array<{ name: string; mergeRunId: number }>;
|
|
605
621
|
/**
|
|
606
622
|
* The PR edited a pinned workflow, so only default-branch `push` runs
|
|
607
623
|
* attested it; its own `pull_request` runs (which ran the edited
|