@cleocode/contracts 2026.9.23 → 2026.9.25
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/branch-lock.d.ts +51 -0
- package/dist/branch-lock.d.ts.map +1 -1
- package/dist/branch-lock.js +25 -3
- package/dist/branch-lock.js.map +1 -1
- package/dist/cloud/api.d.ts +1 -1
- package/dist/data-accessor.d.ts +270 -16
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/decide.d.ts +110 -1
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +23 -0
- package/dist/decide.js.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +137 -6
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/doctor.d.ts +9 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/exit-codes.d.ts +7 -0
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +7 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge-health.d.ts +21 -0
- package/dist/knowledge-health.d.ts.map +1 -1
- package/dist/nexus-account.d.ts +160 -0
- package/dist/nexus-account.d.ts.map +1 -0
- package/dist/nexus-account.js +68 -0
- package/dist/nexus-account.js.map +1 -0
- package/dist/operations/focus.d.ts +7 -3
- package/dist/operations/focus.d.ts.map +1 -1
- package/dist/operations/nexus-scope-map.d.ts +8 -0
- package/dist/operations/nexus-scope-map.d.ts.map +1 -1
- package/dist/operations/nexus-scope-map.js +8 -0
- package/dist/operations/nexus-scope-map.js.map +1 -1
- package/dist/operations/nexus.d.ts +265 -0
- package/dist/operations/nexus.d.ts.map +1 -1
- package/dist/operations/nexus.js +9 -1
- package/dist/operations/nexus.js.map +1 -1
- package/dist/operations/orchestrate.d.ts +6 -1
- package/dist/operations/orchestrate.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.js +115 -1
- package/dist/operations/output-contracts-data.js.map +1 -1
- package/dist/operations/tasks.d.ts +73 -9
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/dist/project-lifecycle.d.ts +6 -2
- package/dist/project-lifecycle.d.ts.map +1 -1
- package/dist/row-identity.d.ts +128 -0
- package/dist/row-identity.d.ts.map +1 -0
- package/dist/row-identity.js +20 -0
- package/dist/row-identity.js.map +1 -0
- package/dist/session.d.ts +19 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +9 -2
- package/dist/session.js.map +1 -1
- package/dist/task.d.ts +56 -2
- package/dist/task.d.ts.map +1 -1
- package/dist/tools/score-task-priority.d.ts +1 -1
- package/dist/tools/score-task-priority.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/branch-lock.ts +80 -3
- package/src/data-accessor.ts +283 -17
- package/src/decide.ts +127 -1
- package/src/dispatch/operations-registry.ts +144 -6
- package/src/doctor.ts +9 -0
- package/src/exit-codes.ts +7 -0
- package/src/index.ts +56 -0
- package/src/knowledge-health.ts +22 -0
- package/src/nexus-account.ts +181 -0
- package/src/operations/focus.ts +7 -3
- package/src/operations/nexus-scope-map.ts +9 -0
- package/src/operations/nexus.ts +281 -0
- package/src/operations/orchestrate.ts +6 -2
- package/src/operations/output-contracts-data.ts +125 -1
- package/src/operations/tasks.ts +78 -12
- package/src/project-lifecycle.ts +6 -2
- package/src/row-identity.ts +132 -0
- package/src/session.ts +20 -2
- package/src/task.ts +58 -2
- package/src/tools/score-task-priority.ts +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row identity contracts — the uid every syncing row carries as its merge key
|
|
3
|
+
* (T12341).
|
|
4
|
+
*
|
|
5
|
+
* A table whose Gate A class syncs (`portable-*`) gets a `uid` column. The
|
|
6
|
+
* local primary key stays the local key and local foreign keys keep pointing
|
|
7
|
+
* at it; the uid is what a merge compares. The registry that declares, per
|
|
8
|
+
* table, how its uid is made lives in core (`store/row-identity.ts`); this
|
|
9
|
+
* module holds only the shapes.
|
|
10
|
+
*
|
|
11
|
+
* Spec: `cleo docs fetch t12341-uid-scheme`.
|
|
12
|
+
*
|
|
13
|
+
* Types only (arch gate 10): no runtime values are exported from here.
|
|
14
|
+
*
|
|
15
|
+
* @task T12341
|
|
16
|
+
* @epic T12323
|
|
17
|
+
* @module row-identity
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* How a table's uid is made.
|
|
22
|
+
*
|
|
23
|
+
* - `minted` — the local key was allocated on one device (`T####`, an
|
|
24
|
+
* autoincrement integer, a random id), so equal keys on two devices may be
|
|
25
|
+
* different rows. A new row gets a random UUIDv7; a row without a uid (an
|
|
26
|
+
* existing row, or one an older build wrote) gets a deterministic v7-layout
|
|
27
|
+
* uid over (table, key, birth, owner uids, content).
|
|
28
|
+
* - `natural` — the key is content or a relationship (an edge, a label), so
|
|
29
|
+
* equal keys mean the same row everywhere. The uid is a UUIDv8 over the key
|
|
30
|
+
* with every reference replaced by the referenced row's uid.
|
|
31
|
+
*
|
|
32
|
+
* @task T12341
|
|
33
|
+
*/
|
|
34
|
+
export type RowIdentityKind = 'minted' | 'natural';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A column that holds another row's local key.
|
|
38
|
+
*
|
|
39
|
+
* @task T12341
|
|
40
|
+
*/
|
|
41
|
+
export interface RowIdentityRef {
|
|
42
|
+
/** Physical column in this table. */
|
|
43
|
+
readonly column: string;
|
|
44
|
+
/** Physical table the column points into (its single-column local key). */
|
|
45
|
+
readonly table: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A stored copy of a fact about a referenced row, taken when the row is
|
|
50
|
+
* written: its uid (`ac_uid`, kept because an AC id is derived from the AC
|
|
51
|
+
* text and changes on edit), or the hash of its text (`ac_text_hash`, the
|
|
52
|
+
* text the evidence was recorded against).
|
|
53
|
+
*
|
|
54
|
+
* @task T12341
|
|
55
|
+
*/
|
|
56
|
+
export interface StoredRefUid {
|
|
57
|
+
/** Physical column holding the copied fact (e.g. `ac_uid`). */
|
|
58
|
+
readonly column: string;
|
|
59
|
+
/** Column holding the referenced local key (e.g. `ac_id`). */
|
|
60
|
+
readonly from: string;
|
|
61
|
+
/** Referenced table. */
|
|
62
|
+
readonly table: string;
|
|
63
|
+
/** What is copied: the referenced row's uid (default) or the hash of its `text`. */
|
|
64
|
+
readonly source?: 'uid' | 'text_hash';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A relation table whose rows are symmetric for some values of a type column:
|
|
69
|
+
* the endpoint uids are hashed in sorted order, so `A related B` and
|
|
70
|
+
* `B related A` are one edge.
|
|
71
|
+
*
|
|
72
|
+
* @task T12341
|
|
73
|
+
*/
|
|
74
|
+
export interface SymmetricEdge {
|
|
75
|
+
/** Column holding the relation type. */
|
|
76
|
+
readonly column: string;
|
|
77
|
+
/** Type values that are symmetric; every other value keeps direction. */
|
|
78
|
+
readonly values: readonly string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* How one syncing table carries its uid.
|
|
83
|
+
*
|
|
84
|
+
* @task T12341
|
|
85
|
+
*/
|
|
86
|
+
export interface RowIdentitySpec {
|
|
87
|
+
/** Physical table name. */
|
|
88
|
+
readonly table: string;
|
|
89
|
+
/** How the uid is made. */
|
|
90
|
+
readonly kind: RowIdentityKind;
|
|
91
|
+
/** Local key columns, in hash order. */
|
|
92
|
+
readonly key: readonly string[];
|
|
93
|
+
/** `minted`: the column recording when the row was created. */
|
|
94
|
+
readonly birth?: string;
|
|
95
|
+
/** `minted`: references whose target uid is part of the row's identity. */
|
|
96
|
+
readonly owners?: readonly RowIdentityRef[];
|
|
97
|
+
/**
|
|
98
|
+
* `minted`, append-only tables only: columns hashed into the uid. Their
|
|
99
|
+
* rows never change, and their keys collide across devices by construction.
|
|
100
|
+
*/
|
|
101
|
+
readonly content?: readonly string[];
|
|
102
|
+
/** `natural`: key columns that reference rows; their target uid is hashed. */
|
|
103
|
+
readonly keyRefs?: readonly RowIdentityRef[];
|
|
104
|
+
/**
|
|
105
|
+
* `minted`: facts of the row's creation hashed into its birth fingerprint
|
|
106
|
+
* (`birth_fp`), besides the canonical birth. Each entry is a column name,
|
|
107
|
+
* `@ownerFp:<column>` (the birth fingerprint of the owner that column
|
|
108
|
+
* references, so the children of two colliding owners fingerprint apart),
|
|
109
|
+
* or `@refFp:<column>` (the fingerprint of the row a stored reference uid
|
|
110
|
+
* column names, e.g. the AC behind `ac_uid`).
|
|
111
|
+
* Read from the row as it is when its identity is first assigned; frozen
|
|
112
|
+
* per recipe version.
|
|
113
|
+
*/
|
|
114
|
+
readonly birthFacts?: readonly string[];
|
|
115
|
+
/** `natural` relation tables: the symmetric relation types. */
|
|
116
|
+
readonly symmetric?: SymmetricEdge;
|
|
117
|
+
/**
|
|
118
|
+
* `minted`: every uid is random, never derived from content, including for
|
|
119
|
+
* existing rows. Required for `portable-secret` tables.
|
|
120
|
+
*/
|
|
121
|
+
readonly randomOnly?: boolean;
|
|
122
|
+
/** Other references, translated to uids on the wire (not hashed). */
|
|
123
|
+
readonly refs?: readonly RowIdentityRef[];
|
|
124
|
+
/** JSON-array columns of referenced keys, translated element by element. */
|
|
125
|
+
readonly jsonArrayRefs?: readonly RowIdentityRef[];
|
|
126
|
+
/** Stored copies of referenced uids. */
|
|
127
|
+
readonly storedRefUids?: readonly StoredRefUid[];
|
|
128
|
+
/** The key is a user-facing display id that a collision re-mints. */
|
|
129
|
+
readonly displayId?: boolean;
|
|
130
|
+
/** Task that declared the table. */
|
|
131
|
+
readonly task: string;
|
|
132
|
+
}
|
package/src/session.ts
CHANGED
|
@@ -132,6 +132,17 @@ export interface Session {
|
|
|
132
132
|
* @defaultValue undefined
|
|
133
133
|
*/
|
|
134
134
|
parentSessionId?: string | null;
|
|
135
|
+
/**
|
|
136
|
+
* ID of the orchestrator session that SPAWNED this one, recorded by the
|
|
137
|
+
* spawn itself (T12502). Unlike {@link Session.parentSessionId}, which a
|
|
138
|
+
* process declares for itself at `session start`, only the spawn writes
|
|
139
|
+
* this edge, so the task-claim chokepoint trusts it to let a spawn family
|
|
140
|
+
* pass a live lease between its members. Read-only on the session record:
|
|
141
|
+
* the whole-row session upsert never writes it.
|
|
142
|
+
*
|
|
143
|
+
* @defaultValue undefined
|
|
144
|
+
*/
|
|
145
|
+
spawnedBySessionId?: string | null;
|
|
135
146
|
/** Provider-specific agent identifier string. @defaultValue undefined */
|
|
136
147
|
agentIdentifier?: string | null;
|
|
137
148
|
/** ISO 8601 timestamp of when the handoff was consumed. @defaultValue undefined */
|
|
@@ -233,9 +244,16 @@ export class SessionView {
|
|
|
233
244
|
return this._sessions.length;
|
|
234
245
|
}
|
|
235
246
|
|
|
236
|
-
/**
|
|
247
|
+
/**
|
|
248
|
+
* First `active` session in THIS collection — a scan over the rows the
|
|
249
|
+
* caller loaded, NOT the caller's own session (T12500). With several agents
|
|
250
|
+
* active it names an arbitrary one of them.
|
|
251
|
+
*
|
|
252
|
+
* @deprecated For "my session" use `resolveBoundSession` (mutations) or
|
|
253
|
+
* `resolveSessionForRead` (reads, labels an unbound guess).
|
|
254
|
+
*/
|
|
237
255
|
findActive(): Session | undefined {
|
|
238
|
-
return this._sessions.find((s) => s.status === 'active');
|
|
256
|
+
return this._sessions.find((s) => s.status === 'active'); // get-active-session-allowed: collection scan over caller-supplied rows, not identity (T12500)
|
|
239
257
|
}
|
|
240
258
|
|
|
241
259
|
/** Find a session by ID. */
|
package/src/task.ts
CHANGED
|
@@ -435,8 +435,28 @@ export type EvidenceAtom =
|
|
|
435
435
|
/** Event of the judged run (`push`, `pull_request`, …), when known. */
|
|
436
436
|
event?: string;
|
|
437
437
|
}>;
|
|
438
|
-
/** Tree of the merge commit — the content every
|
|
438
|
+
/** Tree of the merge commit — the content every check judged on it (or on a tree-equal PR head) tested. */
|
|
439
439
|
testedTree?: string;
|
|
440
|
+
/**
|
|
441
|
+
* Later default-branch commit whose green `push` runs stood in for a
|
|
442
|
+
* required check the merge commit's own run only had cancelled or
|
|
443
|
+
* skipped (T12742). Its CI tested the DESCENDANT's tree, not the merge
|
|
444
|
+
* tree: it descends from the merge commit, and no commit in
|
|
445
|
+
* `descendantRange` — merge or not — touched the PR's changed files or a
|
|
446
|
+
* pinned CI workflow. Checks judged there record it as their `sha`.
|
|
447
|
+
*/
|
|
448
|
+
descendantSha?: string;
|
|
449
|
+
/**
|
|
450
|
+
* `<mergeCommitSha>..<descendantSha>`: the first-parent range proven to
|
|
451
|
+
* leave the PR's files and the pinned workflows untouched (T12742).
|
|
452
|
+
*/
|
|
453
|
+
descendantRange?: string;
|
|
454
|
+
/**
|
|
455
|
+
* Final PR head whose latest `pull_request` runs were green for every
|
|
456
|
+
* check the descendant stood in for (T12742); a descendant never
|
|
457
|
+
* vouches for a PR that was not itself green.
|
|
458
|
+
*/
|
|
459
|
+
descendantPrHeadSha?: string;
|
|
440
460
|
/** Task the PR was verified to be linked to (T12634). */
|
|
441
461
|
taskId?: string;
|
|
442
462
|
/** Component PR the task is linked through; its CI ran as this integration PR's (T12671). */
|
|
@@ -723,9 +743,22 @@ export interface Task {
|
|
|
723
743
|
*/
|
|
724
744
|
pipelineStage?: string | null;
|
|
725
745
|
|
|
726
|
-
/**
|
|
746
|
+
/**
|
|
747
|
+
* First-class human / owner assignee (`cleo assignee`, Studio boards).
|
|
748
|
+
* Separate from the agent work lease in {@link Task.claim}: `cleo start`,
|
|
749
|
+
* `cleo claim` and spawn never write it (T12502). @defaultValue undefined
|
|
750
|
+
*/
|
|
727
751
|
assignee?: string | null;
|
|
728
752
|
|
|
753
|
+
/**
|
|
754
|
+
* The agent work lease held on this task, when one is recorded (T12502).
|
|
755
|
+
* Absent when the task is unclaimed. Distinct from the human
|
|
756
|
+
* {@link Task.assignee}. Read-only on the task object: full-row writes
|
|
757
|
+
* never carry it, only the claim chokepoint changes it.
|
|
758
|
+
* @defaultValue undefined
|
|
759
|
+
*/
|
|
760
|
+
claim?: TaskClaim;
|
|
761
|
+
|
|
729
762
|
/**
|
|
730
763
|
* Abort reason when a worker was stopped due to runaway detection (T1658).
|
|
731
764
|
*
|
|
@@ -1020,3 +1053,26 @@ export interface TaskWorkState {
|
|
|
1020
1053
|
/** ID of the primary session managing this work state. @defaultValue undefined */
|
|
1021
1054
|
primarySession?: string | null;
|
|
1022
1055
|
}
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* A leased agent claim on a task (T12502 · epic T12497).
|
|
1059
|
+
*
|
|
1060
|
+
* Taken by `cleo start`, `cleo claim` and spawn with a compare-and-set in the
|
|
1061
|
+
* same write transaction; renewed by the holder session's activity or
|
|
1062
|
+
* `cleo claim <id> --renew`; released by `cleo stop`, completion,
|
|
1063
|
+
* cancellation, archive and the holder session ending. A claim whose
|
|
1064
|
+
* `leaseExpiresAt` has passed stays recorded until another session takes it
|
|
1065
|
+
* over explicitly (`--take-over`, audited).
|
|
1066
|
+
*
|
|
1067
|
+
* @task T12502
|
|
1068
|
+
*/
|
|
1069
|
+
export interface TaskClaim {
|
|
1070
|
+
/** Session holding the lease. */
|
|
1071
|
+
sessionId: string;
|
|
1072
|
+
/** Agent identity of the holder (`CLEO_AGENT_ID` / spawn handle), or `null`. */
|
|
1073
|
+
agentId: string | null;
|
|
1074
|
+
/** ISO-8601 UTC instant the lease was taken. */
|
|
1075
|
+
claimedAt: string;
|
|
1076
|
+
/** ISO-8601 UTC instant the lease lapses unless renewed. */
|
|
1077
|
+
leaseExpiresAt: string;
|
|
1078
|
+
}
|
|
@@ -26,7 +26,7 @@ export interface ScoreTaskInput {
|
|
|
26
26
|
labels?: string[];
|
|
27
27
|
/** Severity axis (orthogonal to priority); unset for most tasks. */
|
|
28
28
|
severity?: TaskSeverity | null;
|
|
29
|
-
/** Kind axis;
|
|
29
|
+
/** Kind axis; not part of the order — an unset severity is unknown, never imputed from `kind` (D11161). */
|
|
30
30
|
kind?: TaskKind | null;
|
|
31
31
|
}
|
|
32
32
|
|