@cleocode/contracts 2026.9.7 → 2026.9.9
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__/acceptance-gate.test.js +242 -1
- package/dist/__tests__/acceptance-gate.test.js.map +1 -1
- package/dist/__tests__/evidence-atom-schema.test.js +17 -14
- package/dist/__tests__/evidence-atom-schema.test.js.map +1 -1
- package/dist/__tests__/memory-wire-shapes.test.js.map +1 -1
- package/dist/__tests__/operations-registry.test.js +18 -0
- package/dist/__tests__/operations-registry.test.js.map +1 -1
- package/dist/acceptance-gate-schema.d.ts +60 -2
- package/dist/acceptance-gate-schema.d.ts.map +1 -1
- package/dist/acceptance-gate-schema.js +273 -1
- package/dist/acceptance-gate-schema.js.map +1 -1
- package/dist/acceptance-gate.d.ts +122 -11
- package/dist/acceptance-gate.d.ts.map +1 -1
- package/dist/acceptance-gate.js +3 -3
- package/dist/audit.d.ts +71 -2
- package/dist/audit.d.ts.map +1 -1
- package/dist/backup-manifest.d.ts +80 -0
- package/dist/backup-manifest.d.ts.map +1 -1
- package/dist/caamp-markers.d.ts +20 -0
- package/dist/caamp-markers.d.ts.map +1 -1
- package/dist/capabilities.d.ts +282 -0
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/changesets.d.ts +4 -4
- package/dist/code-symbol.d.ts +33 -0
- package/dist/code-symbol.d.ts.map +1 -1
- package/dist/daemon/health.d.ts +3 -3
- package/dist/data-accessor.d.ts +15 -0
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js +19 -1
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +684 -3
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/docs-taxonomy.d.ts +25 -0
- package/dist/docs-taxonomy.d.ts.map +1 -1
- package/dist/docs-taxonomy.js.map +1 -1
- package/dist/evidence-atom-schema.d.ts +7 -6
- package/dist/evidence-atom-schema.d.ts.map +1 -1
- package/dist/evidence-atom-schema.js +10 -9
- package/dist/evidence-atom-schema.js.map +1 -1
- package/dist/graph.d.ts +283 -2
- package/dist/graph.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/invariants/adr-070-orchestration.d.ts.map +1 -1
- package/dist/invariants/adr-070-orchestration.js +1 -1
- package/dist/invariants/adr-070-orchestration.js.map +1 -1
- package/dist/invariants/adr-073-saga.js +2 -2
- package/dist/invariants/adr-073-saga.js.map +1 -1
- package/dist/jobs.d.ts +329 -3
- package/dist/jobs.d.ts.map +1 -1
- package/dist/knowledge-health.d.ts +695 -0
- package/dist/knowledge-health.d.ts.map +1 -0
- package/dist/knowledge-health.js +8 -0
- package/dist/knowledge-health.js.map +1 -0
- package/dist/llm/catalog-schema.d.ts +4 -4
- package/dist/memory/observe.d.ts +4 -2
- package/dist/memory/observe.d.ts.map +1 -1
- package/dist/memory/search.d.ts +4 -0
- package/dist/memory/search.d.ts.map +1 -1
- package/dist/nexus-living-brain-ops.d.ts +28 -3
- package/dist/nexus-living-brain-ops.d.ts.map +1 -1
- package/dist/nexus-tasks-bridge-ops.d.ts +11 -0
- package/dist/nexus-tasks-bridge-ops.d.ts.map +1 -1
- package/dist/operations/admin.d.ts +10 -4
- package/dist/operations/admin.d.ts.map +1 -1
- package/dist/operations/docs.d.ts +138 -0
- package/dist/operations/docs.d.ts.map +1 -1
- package/dist/operations/docs.js +47 -0
- package/dist/operations/docs.js.map +1 -1
- package/dist/operations/focus.d.ts +7 -0
- package/dist/operations/focus.d.ts.map +1 -1
- package/dist/operations/nexus.d.ts +7 -2
- package/dist/operations/nexus.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.js +31 -3
- package/dist/operations/output-contracts-data.js.map +1 -1
- package/dist/operations/research.d.ts +33 -0
- package/dist/operations/research.d.ts.map +1 -1
- package/dist/operations/tasks.d.ts +107 -4
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js +5 -0
- package/dist/operations/tasks.js.map +1 -1
- package/dist/package-artifact.d.ts +112 -0
- package/dist/package-artifact.d.ts.map +1 -0
- package/dist/package-artifact.js +8 -0
- package/dist/package-artifact.js.map +1 -0
- package/dist/release/evidence-atoms.d.ts +10 -0
- package/dist/release/evidence-atoms.d.ts.map +1 -1
- package/dist/release/evidence-atoms.js +6 -0
- package/dist/release/evidence-atoms.js.map +1 -1
- package/dist/release/plan.d.ts +6 -6
- package/dist/resource-governor.d.ts +114 -0
- package/dist/resource-governor.d.ts.map +1 -1
- package/dist/resource-governor.js.map +1 -1
- package/dist/supervisor-ipc/messages.d.ts +6 -6
- package/dist/task-record.d.ts +25 -4
- package/dist/task-record.d.ts.map +1 -1
- package/dist/task.d.ts +55 -36
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js.map +1 -1
- package/dist/tasks/archive.d.ts +3 -3
- package/dist/templates/manifest.d.ts +1 -1
- package/dist/workgraph.d.ts +5 -3
- package/dist/workgraph.d.ts.map +1 -1
- package/dist/workgraph.js +19 -0
- package/dist/workgraph.js.map +1 -1
- package/package.json +2 -2
- package/schemas/gate-result.schema.json +350 -1
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/__tests__/acceptance-gate.test.ts +282 -1
- package/src/__tests__/evidence-atom-schema.test.ts +17 -14
- package/src/__tests__/memory-wire-shapes.test.ts +2 -0
- package/src/__tests__/operations-registry.test.ts +26 -0
- package/src/acceptance-gate-schema.ts +320 -14
- package/src/acceptance-gate.ts +133 -11
- package/src/audit.ts +72 -2
- package/src/backup-manifest.ts +88 -0
- package/src/caamp-markers.ts +22 -0
- package/src/capabilities.ts +311 -0
- package/src/code-symbol.ts +37 -0
- package/src/data-accessor.ts +16 -0
- package/src/dispatch/__tests__/tasks-gateway-crud-ops.test.ts +31 -1
- package/src/dispatch/operations-registry.ts +689 -3
- package/src/docs-taxonomy.ts +26 -0
- package/src/evidence-atom-schema.ts +10 -9
- package/src/graph.ts +326 -2
- package/src/index.ts +43 -1
- package/src/invariants/adr-070-orchestration.ts +2 -1
- package/src/invariants/adr-073-saga.ts +2 -2
- package/src/jobs.ts +382 -3
- package/src/knowledge-health.ts +748 -0
- package/src/memory/observe.ts +4 -2
- package/src/memory/search.ts +4 -0
- package/src/nexus-living-brain-ops.ts +34 -3
- package/src/nexus-tasks-bridge-ops.ts +12 -0
- package/src/operations/admin.ts +11 -4
- package/src/operations/docs.ts +153 -0
- package/src/operations/focus.ts +11 -0
- package/src/operations/nexus.ts +7 -1
- package/src/operations/output-contracts-data.ts +33 -3
- package/src/operations/research.ts +36 -0
- package/src/operations/tasks.ts +116 -4
- package/src/package-artifact.ts +127 -0
- package/src/release/evidence-atoms.ts +6 -0
- package/src/resource-governor.ts +132 -0
- package/src/task-record.ts +27 -4
- package/src/task.ts +58 -36
- package/src/workgraph.ts +19 -0
package/src/operations/tasks.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* @task T1703 — Fill Result=unknown stubs with canonical typed shapes
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import type { TaskPopulation } from '../data-accessor.js';
|
|
21
22
|
import type { ImpactReport } from '../facade.js';
|
|
22
23
|
import type { TaskAnalysisResult, TaskRef } from '../results.js';
|
|
23
24
|
/**
|
|
@@ -25,7 +26,7 @@ import type { TaskAnalysisResult, TaskRef } from '../results.js';
|
|
|
25
26
|
*/
|
|
26
27
|
import type { TaskStatus } from '../status-registry.js';
|
|
27
28
|
import type { TaskKind, TaskPriority, TaskSeverity, TaskType } from '../task.js';
|
|
28
|
-
import type { TaskRecord } from '../task-record.js';
|
|
29
|
+
import type { MinimalTaskRecord, TaskMatch, TaskRecord } from '../task-record.js';
|
|
29
30
|
import type { ExternalTask, ExternalTaskLink, ReconcileResult } from '../task-sync.js';
|
|
30
31
|
import type {
|
|
31
32
|
CompletionEvaluateParams,
|
|
@@ -115,11 +116,14 @@ export interface TasksListParams {
|
|
|
115
116
|
limit?: number;
|
|
116
117
|
offset?: number;
|
|
117
118
|
compact?: boolean;
|
|
119
|
+
/** Include archive rows under the same filters. */
|
|
120
|
+
includeArchive?: boolean;
|
|
118
121
|
}
|
|
119
122
|
export interface TasksListResult {
|
|
120
123
|
tasks: TaskOp[];
|
|
121
124
|
total: number;
|
|
122
125
|
filtered: number;
|
|
126
|
+
population: TaskPopulation;
|
|
123
127
|
}
|
|
124
128
|
|
|
125
129
|
// tasks.find
|
|
@@ -142,6 +146,10 @@ export interface TasksFindParams {
|
|
|
142
146
|
id?: string;
|
|
143
147
|
/** When true, require exact string match instead of fuzzy. @task T963 */
|
|
144
148
|
exact?: boolean;
|
|
149
|
+
/** Explicitly allow character-subsequence matching. Default is lexical. */
|
|
150
|
+
fuzzy?: boolean;
|
|
151
|
+
/** Restrict matching to this field; unsupported values reject. */
|
|
152
|
+
field?: string;
|
|
145
153
|
/** Filter by status. @task T963 */
|
|
146
154
|
status?: TaskStatus;
|
|
147
155
|
/** When true, include archived tasks in the search. @task T963 */
|
|
@@ -201,7 +209,14 @@ export interface TasksFindParams {
|
|
|
201
209
|
*/
|
|
202
210
|
parent?: string;
|
|
203
211
|
}
|
|
204
|
-
|
|
212
|
+
/** Canonical task-search wrapper, including retrieval basis and population scope. */
|
|
213
|
+
export interface TasksFindResult {
|
|
214
|
+
results: (MinimalTaskRecord | TaskRecord)[];
|
|
215
|
+
total: number;
|
|
216
|
+
population: TaskPopulation;
|
|
217
|
+
query: string;
|
|
218
|
+
searchType: TaskMatch['kind'];
|
|
219
|
+
}
|
|
205
220
|
|
|
206
221
|
/**
|
|
207
222
|
* Mutate Operations
|
|
@@ -1343,6 +1358,8 @@ export interface TasksAddBatchParams {
|
|
|
1343
1358
|
scope?: string;
|
|
1344
1359
|
severity?: string;
|
|
1345
1360
|
forceDuplicate?: boolean;
|
|
1361
|
+
/** Resolve design-point 3 in-line by decomposing a text-AC parent. @task T12298 */
|
|
1362
|
+
autoDecompose?: boolean;
|
|
1346
1363
|
}>;
|
|
1347
1364
|
/** Optional default parent ID applied when a task spec omits `parent`. */
|
|
1348
1365
|
defaultParent?: string;
|
|
@@ -1440,6 +1457,8 @@ export interface TasksAddParams {
|
|
|
1440
1457
|
*/
|
|
1441
1458
|
parentSource?: 'explicit' | 'session-inference';
|
|
1442
1459
|
depends?: string[];
|
|
1460
|
+
/** Justification preserved in the creation audit for a critical-priority task. */
|
|
1461
|
+
dependsWaiver?: string;
|
|
1443
1462
|
priority?: string;
|
|
1444
1463
|
labels?: string[];
|
|
1445
1464
|
type?: TaskType; // SSoT-EXEMPT:kind≠type — 'type' is hierarchy(saga|epic|task|subtask), 'kind' is intent(work|bug|...) — separate axes T944 // ssot-exempt-ok: pre-existing exempt, narrowed string→TaskType (T10328)
|
|
@@ -1464,6 +1483,8 @@ export interface TasksAddParams {
|
|
|
1464
1483
|
* @task T1633
|
|
1465
1484
|
*/
|
|
1466
1485
|
forceDuplicate?: boolean;
|
|
1486
|
+
/** Resolve design-point 3 in-line by decomposing a text-AC parent. @task T12298 */
|
|
1487
|
+
autoDecompose?: boolean;
|
|
1467
1488
|
}
|
|
1468
1489
|
/**
|
|
1469
1490
|
* Result of `tasks.add` — the newly created task.
|
|
@@ -1500,6 +1521,8 @@ export interface TasksUpdateQueryParams {
|
|
|
1500
1521
|
description?: string;
|
|
1501
1522
|
status?: string;
|
|
1502
1523
|
priority?: string;
|
|
1524
|
+
/** Project-defined task phase, persisted independently of pipelineStage. */
|
|
1525
|
+
phase?: string;
|
|
1503
1526
|
notes?: string;
|
|
1504
1527
|
labels?: string[];
|
|
1505
1528
|
addLabels?: string[];
|
|
@@ -1524,7 +1547,7 @@ export interface TasksUpdateQueryParams {
|
|
|
1524
1547
|
scope?: string;
|
|
1525
1548
|
/**
|
|
1526
1549
|
* Severity level — valid for any kind (T9073). Orthogonal to priority.
|
|
1527
|
-
*
|
|
1550
|
+
* Persists a signed project-identity assertion in the task transaction audit.
|
|
1528
1551
|
*/
|
|
1529
1552
|
severity?: string;
|
|
1530
1553
|
/**
|
|
@@ -1536,6 +1559,8 @@ export interface TasksUpdateQueryParams {
|
|
|
1536
1559
|
dependsWaiver?: string;
|
|
1537
1560
|
/** Set the blockedBy free-text reason. @task T9241 (gh#1106) */
|
|
1538
1561
|
blockedBy?: string;
|
|
1562
|
+
/** Disable automatic parent completion when true; false restores automatic completion. */
|
|
1563
|
+
noAutoComplete?: boolean;
|
|
1539
1564
|
/** Clear the blockedBy free-text reason (set to undefined). @task T9241 */
|
|
1540
1565
|
clearBlockedBy?: boolean;
|
|
1541
1566
|
/** Set related tasks (replaces existing). @task T9327 */
|
|
@@ -1619,7 +1644,7 @@ export interface TasksCompleteQueryParams {
|
|
|
1619
1644
|
/**
|
|
1620
1645
|
* Reason for waiving the `E_CLEO_DEPENDENCY` gate when this task's own work
|
|
1621
1646
|
* is done but its `depends` edges point at not-yet-terminal tasks (a stale or
|
|
1622
|
-
* over-specified dependency). Recorded
|
|
1647
|
+
* over-specified dependency). Recorded with the task mutation in its transaction audit.
|
|
1623
1648
|
*
|
|
1624
1649
|
* @task T11954 (DHQ-071)
|
|
1625
1650
|
*/
|
|
@@ -1639,10 +1664,88 @@ export interface TasksCompleteQueryResult {
|
|
|
1639
1664
|
unblockedTasks?: Array<Pick<TaskRef, 'id' | 'title'>>;
|
|
1640
1665
|
}
|
|
1641
1666
|
|
|
1667
|
+
// tasks.reconcile-scope (dispatch-level params) — containment-aware overlap sweep
|
|
1668
|
+
/**
|
|
1669
|
+
* Params for `tasks.reconcile-scope` — sweep a container for tasks whose scope
|
|
1670
|
+
* overlaps and propose merge / absorb / split / link for each pair.
|
|
1671
|
+
*
|
|
1672
|
+
* @task T12299
|
|
1673
|
+
*/
|
|
1674
|
+
export interface TasksReconcileScopeParams {
|
|
1675
|
+
/** Saga, epic or any container to sweep; its whole subtree is considered. */
|
|
1676
|
+
rootId: string;
|
|
1677
|
+
/** Write the proposed `relates` edges. Read-only when false or omitted. */
|
|
1678
|
+
apply?: boolean;
|
|
1679
|
+
/** Report pairs at or above this similarity score (0-1). */
|
|
1680
|
+
threshold?: number;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
/** One overlapping pair and the action proposed for it. @task T12299 */
|
|
1684
|
+
export interface TasksScopeOverlap {
|
|
1685
|
+
keepId: string;
|
|
1686
|
+
keepTitle: string;
|
|
1687
|
+
otherId: string;
|
|
1688
|
+
otherTitle: string;
|
|
1689
|
+
action: 'merge' | 'absorb' | 'split' | 'link';
|
|
1690
|
+
score: number;
|
|
1691
|
+
relation: 'duplicates' | 'absorbs' | 'related';
|
|
1692
|
+
rationale: string;
|
|
1693
|
+
sameParent: boolean;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
/** Result of `tasks.reconcile-scope`. @task T12299 */
|
|
1697
|
+
export interface TasksReconcileScopeResult {
|
|
1698
|
+
rootId: string;
|
|
1699
|
+
scanned: number;
|
|
1700
|
+
pairs: number;
|
|
1701
|
+
overlaps: TasksScopeOverlap[];
|
|
1702
|
+
applied: number;
|
|
1703
|
+
truncated?: { limit: number; liveNodes: number };
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
// tasks.decompose (dispatch-level params) — PM-Core V2 design-point 3
|
|
1707
|
+
/**
|
|
1708
|
+
* Params for `tasks.decompose` — move a task's free-text acceptance criteria
|
|
1709
|
+
* onto a new first child so the task becomes a pure container.
|
|
1710
|
+
*
|
|
1711
|
+
* @task T12281
|
|
1712
|
+
*/
|
|
1713
|
+
export interface TasksDecomposeParams {
|
|
1714
|
+
/** Task whose text acceptance criteria move to a new child. */
|
|
1715
|
+
taskId: string;
|
|
1716
|
+
/** Title for the child that inherits the criteria. Defaults to the parent's. */
|
|
1717
|
+
childTitle?: string;
|
|
1718
|
+
/** Description for the child. Defaults to the parent's. */
|
|
1719
|
+
childDescription?: string;
|
|
1720
|
+
/** Preview the move without writing. */
|
|
1721
|
+
dryRun?: boolean;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/**
|
|
1725
|
+
* Result of `tasks.decompose` — the container/child pair and the criteria moved.
|
|
1726
|
+
*
|
|
1727
|
+
* @task T12281
|
|
1728
|
+
*/
|
|
1729
|
+
export interface TasksDecomposeResult {
|
|
1730
|
+
/** The task that is now a pure container. */
|
|
1731
|
+
parentId: string;
|
|
1732
|
+
/** The created child, or `null` on a dry run. */
|
|
1733
|
+
childId: string | null;
|
|
1734
|
+
/** The criteria texts moved from parent to child, in ordinal order. */
|
|
1735
|
+
movedAcceptance: string[];
|
|
1736
|
+
/** True when nothing was written. */
|
|
1737
|
+
dryRun: boolean;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1642
1740
|
// tasks.delete (dispatch-level params)
|
|
1741
|
+
/** Canonical task deletion controls shared by dispatch and core wrappers. */
|
|
1643
1742
|
export interface TasksDeleteQueryParams {
|
|
1743
|
+
/** Task to move into the archive. */
|
|
1644
1744
|
taskId: string;
|
|
1745
|
+
/** Allow dependents and orphan children unless cascade is explicitly enabled. */
|
|
1645
1746
|
force?: boolean;
|
|
1747
|
+
/** Archive the entire descendant subtree rather than orphaning children. */
|
|
1748
|
+
cascade?: boolean;
|
|
1646
1749
|
}
|
|
1647
1750
|
/**
|
|
1648
1751
|
* Result of `tasks.delete` — deletion confirmation with cascade details.
|
|
@@ -2154,6 +2257,8 @@ export type TasksOps = {
|
|
|
2154
2257
|
readonly update: readonly [TasksUpdateQueryParams, TasksUpdateQueryResult];
|
|
2155
2258
|
readonly complete: readonly [TasksCompleteQueryParams, TasksCompleteQueryResult];
|
|
2156
2259
|
readonly cancel: readonly [TasksCancelParams, TasksCancelResult];
|
|
2260
|
+
readonly decompose: readonly [TasksDecomposeParams, TasksDecomposeResult];
|
|
2261
|
+
readonly 'reconcile-scope': readonly [TasksReconcileScopeParams, TasksReconcileScopeResult];
|
|
2157
2262
|
readonly delete: readonly [TasksDeleteQueryParams, TasksDeleteQueryResult];
|
|
2158
2263
|
readonly archive: readonly [TasksArchiveQueryParams, TasksArchiveQueryResult];
|
|
2159
2264
|
readonly restore: readonly [TasksRestoreParams, TasksRestoreResult];
|
|
@@ -2252,6 +2357,8 @@ export interface TasksAddBatchEntry {
|
|
|
2252
2357
|
severity?: string;
|
|
2253
2358
|
/** Bypass BRAIN duplicate-task rejection (audited). */
|
|
2254
2359
|
forceDuplicate?: boolean;
|
|
2360
|
+
/** Resolve design-point 3 in-line by decomposing a text-AC parent. @task T12298 */
|
|
2361
|
+
autoDecompose?: boolean;
|
|
2255
2362
|
}
|
|
2256
2363
|
|
|
2257
2364
|
/**
|
|
@@ -2273,6 +2380,7 @@ export const TASKS_ADD_INPUT_SCHEMA: JsonSchema = {
|
|
|
2273
2380
|
description: { type: 'string' },
|
|
2274
2381
|
parent: { type: 'string' },
|
|
2275
2382
|
depends: { type: 'array', items: { type: 'string' } },
|
|
2383
|
+
dependsWaiver: { type: 'string', minLength: 1 },
|
|
2276
2384
|
priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
|
|
2277
2385
|
labels: { type: 'array', items: { type: 'string' } },
|
|
2278
2386
|
type: { type: 'string', enum: ['saga', 'epic', 'task', 'subtask'] },
|
|
@@ -2290,6 +2398,7 @@ export const TASKS_ADD_INPUT_SCHEMA: JsonSchema = {
|
|
|
2290
2398
|
scope: { type: 'string', enum: ['project', 'feature', 'unit'] },
|
|
2291
2399
|
severity: { type: 'string', enum: ['P0', 'P1', 'P2', 'P3'] },
|
|
2292
2400
|
forceDuplicate: { type: 'boolean' },
|
|
2401
|
+
autoDecompose: { type: 'boolean' },
|
|
2293
2402
|
},
|
|
2294
2403
|
};
|
|
2295
2404
|
|
|
@@ -2369,6 +2478,7 @@ export const TASKS_ADD_BATCH_INPUT_SCHEMA: JsonSchema = {
|
|
|
2369
2478
|
scope: { type: 'string', enum: ['project', 'feature', 'unit'] },
|
|
2370
2479
|
severity: { type: 'string', enum: ['P0', 'P1', 'P2', 'P3'] },
|
|
2371
2480
|
forceDuplicate: { type: 'boolean' },
|
|
2481
|
+
autoDecompose: { type: 'boolean' },
|
|
2372
2482
|
},
|
|
2373
2483
|
},
|
|
2374
2484
|
},
|
|
@@ -2438,6 +2548,7 @@ export const TASKS_UPDATE_INPUT_SCHEMA: JsonSchema = {
|
|
|
2438
2548
|
enum: ['pending', 'active', 'blocked', 'done', 'cancelled'],
|
|
2439
2549
|
},
|
|
2440
2550
|
priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
|
|
2551
|
+
phase: { type: 'string' },
|
|
2441
2552
|
notes: { type: 'string' },
|
|
2442
2553
|
labels: { type: 'array', items: { type: 'string' } },
|
|
2443
2554
|
addLabels: { type: 'array', items: { type: 'string' } },
|
|
@@ -2463,6 +2574,7 @@ export const TASKS_UPDATE_INPUT_SCHEMA: JsonSchema = {
|
|
|
2463
2574
|
dependsWaiver: { type: 'string' },
|
|
2464
2575
|
blockedBy: { type: 'string' },
|
|
2465
2576
|
clearBlockedBy: { type: 'boolean' },
|
|
2577
|
+
noAutoComplete: { type: 'boolean' },
|
|
2466
2578
|
relates: {
|
|
2467
2579
|
type: 'array',
|
|
2468
2580
|
items: {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contracts for semantic validation of a package inventory.
|
|
3
|
+
*
|
|
4
|
+
* Code placed in `packages/contracts/` per Package-Boundary Check — verified
|
|
5
|
+
* against AGENTS.md. Inventory validation does not certify runtime behavior.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** A file reported by the packer; hashes describe supplied evidence, not inferred bytes. */
|
|
9
|
+
export interface PackageArtifactFile {
|
|
10
|
+
/** Canonical POSIX path relative to the package root. */
|
|
11
|
+
path: string;
|
|
12
|
+
/** Uncompressed file length in bytes. */
|
|
13
|
+
size: number;
|
|
14
|
+
/** SHA-256 computed by the inventory producer, when bytes were inspected. */
|
|
15
|
+
sha256?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Identity and file evidence supplied by a pack operation or an explicit test fixture. */
|
|
19
|
+
export interface PackageArtifactInventory {
|
|
20
|
+
/** Package name from the packed manifest. */
|
|
21
|
+
packageName: string;
|
|
22
|
+
/** Package version from the packed manifest. */
|
|
23
|
+
version: string;
|
|
24
|
+
/** Distinguishes a real packed artifact from a preview or synthetic fixture. */
|
|
25
|
+
source: 'npm-pack' | 'npm-pack-dry-run' | 'fixture';
|
|
26
|
+
/** Compressed artifact length reported by the packer. */
|
|
27
|
+
packedBytes: number;
|
|
28
|
+
/** SHA-256 of the retained tarball, absent for previews. */
|
|
29
|
+
tarballSha256?: string;
|
|
30
|
+
/** Actual selected file inventory, including files npm includes implicitly. */
|
|
31
|
+
files: readonly PackageArtifactFile[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Classification of a manifest entry; classification does not reproduce npm's selection rules. */
|
|
35
|
+
export interface PackageFilesEntry {
|
|
36
|
+
/** Original manifest string, preserved for diagnostics. */
|
|
37
|
+
entry: string;
|
|
38
|
+
/** Exclusions are patterns, never filesystem paths that must exist. */
|
|
39
|
+
kind: 'literal' | 'glob' | 'exclusion' | 'invalid';
|
|
40
|
+
/** Relative path or pattern without a leading exclusion marker. */
|
|
41
|
+
pattern: string;
|
|
42
|
+
/** Why an entry cannot be assessed, or null for a supported classification. */
|
|
43
|
+
reason: string | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** One independently stated content requirement against a packer's inventory. */
|
|
47
|
+
export interface PackageArtifactRequirement {
|
|
48
|
+
/** Stable semantic role, such as studio-server-entry. */
|
|
49
|
+
id: string;
|
|
50
|
+
/** Exact path or POSIX glob evaluated against already selected files. */
|
|
51
|
+
path: string;
|
|
52
|
+
/** Exact files and deliberately variable build filenames remain distinct. */
|
|
53
|
+
match: 'exact' | 'glob';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Upper installation-cost budgets; there is deliberately no mass-based presence floor. */
|
|
57
|
+
export interface PackageArtifactBudgets {
|
|
58
|
+
/** Maximum compressed bytes. */
|
|
59
|
+
packedBytes: number;
|
|
60
|
+
/** Maximum sum of uncompressed file bytes. */
|
|
61
|
+
unpackedBytes: number;
|
|
62
|
+
/** Maximum number of selected files. */
|
|
63
|
+
fileCount: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Explicit content and comparison policy, independent of historical package size. */
|
|
67
|
+
export interface PackageArtifactPolicy {
|
|
68
|
+
/** Required nonempty resources; an empty policy is rejected. */
|
|
69
|
+
requirements: readonly PackageArtifactRequirement[];
|
|
70
|
+
/** Existing upper budgets to enforce without increasing their values. */
|
|
71
|
+
budgets: PackageArtifactBudgets;
|
|
72
|
+
/** Manifest entries to classify only; the packer's inventory remains authoritative. */
|
|
73
|
+
filesEntries?: readonly string[];
|
|
74
|
+
/** Paths/globs that must be absent from the selected inventory. */
|
|
75
|
+
forbiddenPatterns?: readonly string[];
|
|
76
|
+
/** Independently captured expected files; supplied hashes must match actual hashes. */
|
|
77
|
+
expectedFiles?: readonly PackageArtifactFile[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A concrete invalid inventory, policy, required resource, comparison, or budget finding. */
|
|
81
|
+
export interface PackageArtifactIssue {
|
|
82
|
+
/** Machine-readable finding class. */
|
|
83
|
+
code:
|
|
84
|
+
| 'invalid-inventory'
|
|
85
|
+
| 'invalid-policy'
|
|
86
|
+
| 'missing'
|
|
87
|
+
| 'empty'
|
|
88
|
+
| 'mismatch'
|
|
89
|
+
| 'forbidden'
|
|
90
|
+
| 'budget';
|
|
91
|
+
/** File path, semantic role, or policy field identifying the affected evidence. */
|
|
92
|
+
subject: string;
|
|
93
|
+
/** Independently understandable failure explanation. */
|
|
94
|
+
message: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** One semantic resource assessment, preserving its actual matched file identities. */
|
|
98
|
+
export interface PackageArtifactRequirementResult {
|
|
99
|
+
/** Original requirement identity. */
|
|
100
|
+
id: string;
|
|
101
|
+
/** Actual paths selected from the supplied inventory. */
|
|
102
|
+
matchedPaths: readonly string[];
|
|
103
|
+
/** Whether at least one matching nonempty file exists and no match is empty. */
|
|
104
|
+
satisfied: boolean;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Result of validating supplied package evidence, with explicit limits on the claim. */
|
|
108
|
+
export interface PackageArtifactValidation {
|
|
109
|
+
/** True only when the supplied inventory and policy have no findings. */
|
|
110
|
+
valid: boolean;
|
|
111
|
+
/** Original inventory identity and file/hash evidence, copied into the receipt. */
|
|
112
|
+
inventory: PackageArtifactInventory;
|
|
113
|
+
/** Computed byte total, or null if malformed/overflowing evidence prevents accounting. */
|
|
114
|
+
unpackedBytes: number | null;
|
|
115
|
+
/** Every detected failure; a failed diagnostic never becomes empty success. */
|
|
116
|
+
issues: readonly PackageArtifactIssue[];
|
|
117
|
+
/** Classified manifest entries without pretending to reproduce npm packlist. */
|
|
118
|
+
filesEntries: readonly PackageFilesEntry[];
|
|
119
|
+
/** Required resource assessments. */
|
|
120
|
+
requirements: readonly PackageArtifactRequirementResult[];
|
|
121
|
+
/** Hash comparisons establish equality with supplied expected evidence only. */
|
|
122
|
+
hashComparison: 'not-requested' | 'matched' | 'failed';
|
|
123
|
+
/** No runtime loading, install, dependency resolution, or dynamic-reference discovery occurs here. */
|
|
124
|
+
runtime: 'not-assessed';
|
|
125
|
+
/** Follow-up verification needed before claiming a usable installed artifact. */
|
|
126
|
+
limitations: readonly string[];
|
|
127
|
+
}
|
|
@@ -104,6 +104,12 @@ export const ghPrViewSchema = z
|
|
|
104
104
|
state: z.enum(['OPEN', 'CLOSED', 'MERGED']),
|
|
105
105
|
mergedAt: z.string().nullable(),
|
|
106
106
|
headRefOid: z.string().optional(),
|
|
107
|
+
mergeCommit: z.object({ oid: z.string() }).nullable().optional(),
|
|
108
|
+
title: z.string().optional(),
|
|
109
|
+
body: z.string().optional(),
|
|
110
|
+
headRefName: z.string().optional(),
|
|
111
|
+
files: z.array(z.object({ path: z.string() })).optional(),
|
|
112
|
+
changedFiles: z.number().int().nonnegative().optional(),
|
|
107
113
|
mergeable: z.string().optional(),
|
|
108
114
|
statusCheckRollup: z
|
|
109
115
|
.array(
|
package/src/resource-governor.ts
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* @adr resource-governor-never-oom-architecture §3.4
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import type { OperationExecutionContext } from './jobs.js';
|
|
20
|
+
|
|
19
21
|
/**
|
|
20
22
|
* Governor arbitration mode. Mirrors the writer-lease mode shape
|
|
21
23
|
* (`writer-lease.ts` {@link LeaseMode}).
|
|
@@ -121,3 +123,133 @@ export const DEFAULT_RESOURCE_RETRY_AFTER_MS = 2_000;
|
|
|
121
123
|
export function isResourceGrant(r: AdmissionResult): r is ResourceGrant {
|
|
122
124
|
return r.deferred === false;
|
|
123
125
|
}
|
|
126
|
+
|
|
127
|
+
/** Explicit local user-manager connection for resource-controlled process launch. */
|
|
128
|
+
export interface SystemdControlContext {
|
|
129
|
+
/** Absolute existing runtime directory used only by the manager probe and launcher. */
|
|
130
|
+
runtimeDirectory: string;
|
|
131
|
+
/**
|
|
132
|
+
* Optional local Unix bus address.
|
|
133
|
+
* @defaultValue The bus socket in runtimeDirectory.
|
|
134
|
+
*/
|
|
135
|
+
busAddress?: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Original execution deadline and optional cancellation observed at process-launch boundaries. */
|
|
139
|
+
export type ProcessLaunchExecution = Pick<OperationExecutionContext, 'deadlineAt'> &
|
|
140
|
+
Partial<Pick<OperationExecutionContext, 'signal'>>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Captured inputs for a bounded process invocation; environment is copied before launch.
|
|
144
|
+
* @remarks The original absolute deadline covers launcher discovery and target execution;
|
|
145
|
+
* bounded cleanup may finish later. No caller environment is implicitly merged.
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const options: ProcessCaptureOptions = { cwd: '/project', env: {}, execution: { deadlineAt: Date.now() + 2000 } };
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export interface ProcessCaptureOptions {
|
|
152
|
+
/** Explicit working directory for the requested executable. */
|
|
153
|
+
readonly cwd: string;
|
|
154
|
+
/** Explicit child environment; caller credentials are not added implicitly. */
|
|
155
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
156
|
+
/** Original shared deadline and cancellation, never reset between gates. */
|
|
157
|
+
readonly execution: ProcessLaunchExecution;
|
|
158
|
+
/** Aggregate stdout/stderr byte limit; exceeding it stops execution without a verdict. */
|
|
159
|
+
readonly maxOutputBytes?: number;
|
|
160
|
+
/** Requested hard native-memory ceiling in MiB; target admission requires observed cgroup enforcement. */
|
|
161
|
+
readonly memoryMaxMb?: number;
|
|
162
|
+
/** Requested kernel task ceiling (processes and threads); target admission requires observed cgroup enforcement. */
|
|
163
|
+
readonly tasksMax?: number;
|
|
164
|
+
/** Existing manager connection used only for launcher/control operations. */
|
|
165
|
+
readonly systemdControl?: SystemdControlContext;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Why capture stopped without a complete target verdict.
|
|
170
|
+
* @remarks Cancellation, deadline and malformed transport are not target test failures.
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* const stopped: ProcessCaptureStop = 'deadline';
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export type ProcessCaptureStop =
|
|
177
|
+
| 'deadline'
|
|
178
|
+
| 'cancelled'
|
|
179
|
+
| 'teardown'
|
|
180
|
+
| 'output-limit'
|
|
181
|
+
| 'resource-limit'
|
|
182
|
+
| 'transport-error';
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Kernel limits observed inside the owned cgroup before target admission.
|
|
186
|
+
* @remarks Values describe the capture scope, including its transport and descendants.
|
|
187
|
+
* They are observations at admission, not protection against later privileged reconfiguration.
|
|
188
|
+
* Null means the corresponding cgroup file contains an unlimited value.
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const bounded = result.resourceLimits?.memoryMaxBytes === 4096 * 1024 * 1024;
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export interface ProcessCaptureResourceObservation {
|
|
195
|
+
/** Exact unified cgroup path containing the capture transport. */
|
|
196
|
+
readonly cgroup: string;
|
|
197
|
+
/** Observed memory.max bytes, or null when no finite ceiling was observed. */
|
|
198
|
+
readonly memoryMaxBytes: number | null;
|
|
199
|
+
/** Observed pids.max, counting kernel tasks including threads, or null. */
|
|
200
|
+
readonly tasksMax: number | null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Observed target result, kept separate from wrapper and cleanup outcomes.
|
|
205
|
+
* @remarks A numeric exit alone is insufficient: started, stop/error and output completeness
|
|
206
|
+
* must also be checked. Cleanup scope does not cover descendants deliberately escaping it.
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* const completed = result.started && result.stopped === null && result.error === null;
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export interface ProcessCaptureResult {
|
|
213
|
+
/** True only after the transport observed the requested executable's spawn event. */
|
|
214
|
+
readonly started: boolean;
|
|
215
|
+
/** Requested executable PID when observed; distinct from the scope launcher. */
|
|
216
|
+
readonly targetPid: number | null;
|
|
217
|
+
/** Actual target close code, never synthesized from a wrapper or launch error. */
|
|
218
|
+
readonly exitCode: number | null;
|
|
219
|
+
/** Actual target terminating signal, if reported before transport termination. */
|
|
220
|
+
readonly signal: string | null;
|
|
221
|
+
/** Missing executable, permission or transport failure diagnostic. */
|
|
222
|
+
readonly error: string | null;
|
|
223
|
+
/** Original stop condition; stopped executions cannot establish a passing verdict. */
|
|
224
|
+
readonly stopped: ProcessCaptureStop | null;
|
|
225
|
+
/** Bounded UTF-8 standard output. */
|
|
226
|
+
readonly stdout: string;
|
|
227
|
+
/** Bounded UTF-8 standard error. */
|
|
228
|
+
readonly stderr: string;
|
|
229
|
+
/** Whether output exceeded the capture limit. */
|
|
230
|
+
readonly outputTruncated: boolean;
|
|
231
|
+
/** Total wall time including cleanup, which may exceed the execution deadline. */
|
|
232
|
+
readonly durationMs: number;
|
|
233
|
+
/** Actual selected launcher mode; does not establish observed memory containment. */
|
|
234
|
+
readonly mode: 'systemd' | 'pgid';
|
|
235
|
+
/** Exact scope name, where the launcher selected systemd. */
|
|
236
|
+
readonly unitName?: string;
|
|
237
|
+
/** Only a finite kernel ceiling observed inside the exact owned scope establishes this claim. */
|
|
238
|
+
readonly nativeMemory: 'unverified' | 'observed-cgroup';
|
|
239
|
+
/** Present only after validated pre-target observation of requested hard limits. */
|
|
240
|
+
readonly resourceLimits?: ProcessCaptureResourceObservation;
|
|
241
|
+
/** POSIX group cleanup covers members, not descendants that deliberately escape it. */
|
|
242
|
+
readonly cleanupScope: 'process-group' | 'direct-child';
|
|
243
|
+
/** Returned only after the owned transport emitted close; not a claim about escaped descendants. */
|
|
244
|
+
readonly transportClosed: true;
|
|
245
|
+
/** Whether the transport observed the requested target close before stopping. */
|
|
246
|
+
readonly targetCloseObserved: boolean;
|
|
247
|
+
/** Exact observed cleanup evidence, distinct from mere absence of an error. */
|
|
248
|
+
readonly cleanupObservation:
|
|
249
|
+
| 'scope-terminal'
|
|
250
|
+
| 'process-group-absent'
|
|
251
|
+
| 'process-group-signalled'
|
|
252
|
+
| 'unverified';
|
|
253
|
+
/** Cleanup failures remain visible; no successful cleanup claim is inferred from exit. */
|
|
254
|
+
readonly cleanupErrors: readonly string[];
|
|
255
|
+
}
|
package/src/task-record.ts
CHANGED
|
@@ -8,7 +8,25 @@
|
|
|
8
8
|
* @epic T4654
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { TaskVerification } from './task.js';
|
|
11
|
+
import type { AcceptanceItem, TaskVerification } from './task.js';
|
|
12
|
+
|
|
13
|
+
/** Omitted source fields and their UTF-8 serialized sizes on partial records. */
|
|
14
|
+
export interface RecordProjectionDisclosure {
|
|
15
|
+
/** Absence means this projection did not omit any source fields. */
|
|
16
|
+
_withheld?: Record<string, number>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Per-result retrieval basis; never implies semantic or runtime-call completeness. */
|
|
20
|
+
export interface TaskMatch {
|
|
21
|
+
/** Actual reason this row matched, including explicitly requested fuzzy fallback. */
|
|
22
|
+
kind: 'lexical' | 'fuzzy' | 'exact' | 'id' | 'filter';
|
|
23
|
+
/** Source fields that support this match. */
|
|
24
|
+
fields: Array<'title' | 'description' | 'notes' | 'id'>;
|
|
25
|
+
/** Query terms present literally in those fields (empty for fuzzy-only matches). */
|
|
26
|
+
terms: string[];
|
|
27
|
+
/** Human-readable ranking basis without exposing hidden source content. */
|
|
28
|
+
reason: string;
|
|
29
|
+
}
|
|
12
30
|
|
|
13
31
|
/** A single task relation entry (string-widened version). */
|
|
14
32
|
export interface TaskRecordRelation {
|
|
@@ -40,7 +58,9 @@ export interface TaskRecordRelationCounts {
|
|
|
40
58
|
}
|
|
41
59
|
|
|
42
60
|
/** String-widened Task for JSON serialization in dispatch/LAFS layer. */
|
|
43
|
-
export interface TaskRecord {
|
|
61
|
+
export interface TaskRecord extends RecordProjectionDisclosure {
|
|
62
|
+
/** Search provenance when this full record is returned by task search. */
|
|
63
|
+
match?: TaskMatch;
|
|
44
64
|
id: string;
|
|
45
65
|
title: string;
|
|
46
66
|
description: string;
|
|
@@ -58,7 +78,8 @@ export interface TaskRecord {
|
|
|
58
78
|
depends?: string[];
|
|
59
79
|
relates?: TaskRecordRelation[];
|
|
60
80
|
files?: string[];
|
|
61
|
-
|
|
81
|
+
/** Canonical text criteria and typed gates, preserved in full record projections. */
|
|
82
|
+
acceptance?: AcceptanceItem[];
|
|
62
83
|
notes?: string[];
|
|
63
84
|
labels?: string[];
|
|
64
85
|
size?: string | null;
|
|
@@ -107,7 +128,9 @@ export interface TaskRecord {
|
|
|
107
128
|
* task readiness without N+1 show calls.
|
|
108
129
|
* @task T091
|
|
109
130
|
*/
|
|
110
|
-
export interface MinimalTaskRecord {
|
|
131
|
+
export interface MinimalTaskRecord extends RecordProjectionDisclosure {
|
|
132
|
+
/** Search provenance when this record is a search result. */
|
|
133
|
+
match?: TaskMatch;
|
|
111
134
|
id: string;
|
|
112
135
|
title: string;
|
|
113
136
|
status: string;
|