@cleocode/contracts 2026.9.8 → 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.
Files changed (151) hide show
  1. package/dist/__tests__/acceptance-gate.test.js +242 -1
  2. package/dist/__tests__/acceptance-gate.test.js.map +1 -1
  3. package/dist/__tests__/evidence-atom-schema.test.js +17 -14
  4. package/dist/__tests__/evidence-atom-schema.test.js.map +1 -1
  5. package/dist/__tests__/memory-wire-shapes.test.js.map +1 -1
  6. package/dist/__tests__/operations-registry.test.js +18 -0
  7. package/dist/__tests__/operations-registry.test.js.map +1 -1
  8. package/dist/acceptance-gate-schema.d.ts +60 -2
  9. package/dist/acceptance-gate-schema.d.ts.map +1 -1
  10. package/dist/acceptance-gate-schema.js +273 -1
  11. package/dist/acceptance-gate-schema.js.map +1 -1
  12. package/dist/acceptance-gate.d.ts +122 -11
  13. package/dist/acceptance-gate.d.ts.map +1 -1
  14. package/dist/acceptance-gate.js +3 -3
  15. package/dist/audit.d.ts +71 -2
  16. package/dist/audit.d.ts.map +1 -1
  17. package/dist/backup-manifest.d.ts +80 -0
  18. package/dist/backup-manifest.d.ts.map +1 -1
  19. package/dist/caamp-markers.d.ts +20 -0
  20. package/dist/caamp-markers.d.ts.map +1 -1
  21. package/dist/capabilities.d.ts +282 -0
  22. package/dist/capabilities.d.ts.map +1 -1
  23. package/dist/changesets.d.ts +4 -4
  24. package/dist/code-symbol.d.ts +33 -0
  25. package/dist/code-symbol.d.ts.map +1 -1
  26. package/dist/daemon/health.d.ts +3 -3
  27. package/dist/data-accessor.d.ts +15 -0
  28. package/dist/data-accessor.d.ts.map +1 -1
  29. package/dist/data-accessor.js.map +1 -1
  30. package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js +19 -1
  31. package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js.map +1 -1
  32. package/dist/dispatch/operations-registry.d.ts.map +1 -1
  33. package/dist/dispatch/operations-registry.js +684 -3
  34. package/dist/dispatch/operations-registry.js.map +1 -1
  35. package/dist/docs-taxonomy.d.ts +25 -0
  36. package/dist/docs-taxonomy.d.ts.map +1 -1
  37. package/dist/docs-taxonomy.js.map +1 -1
  38. package/dist/evidence-atom-schema.d.ts +7 -6
  39. package/dist/evidence-atom-schema.d.ts.map +1 -1
  40. package/dist/evidence-atom-schema.js +10 -9
  41. package/dist/evidence-atom-schema.js.map +1 -1
  42. package/dist/graph.d.ts +283 -2
  43. package/dist/graph.d.ts.map +1 -1
  44. package/dist/index.d.ts +6 -5
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/invariants/adr-070-orchestration.d.ts.map +1 -1
  48. package/dist/invariants/adr-070-orchestration.js +1 -1
  49. package/dist/invariants/adr-070-orchestration.js.map +1 -1
  50. package/dist/invariants/adr-073-saga.js +2 -2
  51. package/dist/invariants/adr-073-saga.js.map +1 -1
  52. package/dist/jobs.d.ts +329 -3
  53. package/dist/jobs.d.ts.map +1 -1
  54. package/dist/knowledge-health.d.ts +695 -0
  55. package/dist/knowledge-health.d.ts.map +1 -0
  56. package/dist/knowledge-health.js +8 -0
  57. package/dist/knowledge-health.js.map +1 -0
  58. package/dist/llm/catalog-schema.d.ts +4 -4
  59. package/dist/memory/observe.d.ts +4 -2
  60. package/dist/memory/observe.d.ts.map +1 -1
  61. package/dist/memory/search.d.ts +4 -0
  62. package/dist/memory/search.d.ts.map +1 -1
  63. package/dist/nexus-living-brain-ops.d.ts +28 -3
  64. package/dist/nexus-living-brain-ops.d.ts.map +1 -1
  65. package/dist/nexus-tasks-bridge-ops.d.ts +11 -0
  66. package/dist/nexus-tasks-bridge-ops.d.ts.map +1 -1
  67. package/dist/operations/admin.d.ts +10 -4
  68. package/dist/operations/admin.d.ts.map +1 -1
  69. package/dist/operations/docs.d.ts +138 -0
  70. package/dist/operations/docs.d.ts.map +1 -1
  71. package/dist/operations/docs.js +47 -0
  72. package/dist/operations/docs.js.map +1 -1
  73. package/dist/operations/focus.d.ts +7 -0
  74. package/dist/operations/focus.d.ts.map +1 -1
  75. package/dist/operations/nexus.d.ts +7 -2
  76. package/dist/operations/nexus.d.ts.map +1 -1
  77. package/dist/operations/output-contracts-data.d.ts.map +1 -1
  78. package/dist/operations/output-contracts-data.js +31 -3
  79. package/dist/operations/output-contracts-data.js.map +1 -1
  80. package/dist/operations/research.d.ts +33 -0
  81. package/dist/operations/research.d.ts.map +1 -1
  82. package/dist/operations/tasks.d.ts +107 -4
  83. package/dist/operations/tasks.d.ts.map +1 -1
  84. package/dist/operations/tasks.js +5 -0
  85. package/dist/operations/tasks.js.map +1 -1
  86. package/dist/package-artifact.d.ts +112 -0
  87. package/dist/package-artifact.d.ts.map +1 -0
  88. package/dist/package-artifact.js +8 -0
  89. package/dist/package-artifact.js.map +1 -0
  90. package/dist/release/evidence-atoms.d.ts +10 -0
  91. package/dist/release/evidence-atoms.d.ts.map +1 -1
  92. package/dist/release/evidence-atoms.js +6 -0
  93. package/dist/release/evidence-atoms.js.map +1 -1
  94. package/dist/release/plan.d.ts +6 -6
  95. package/dist/resource-governor.d.ts +114 -0
  96. package/dist/resource-governor.d.ts.map +1 -1
  97. package/dist/resource-governor.js.map +1 -1
  98. package/dist/supervisor-ipc/messages.d.ts +6 -6
  99. package/dist/task-record.d.ts +25 -4
  100. package/dist/task-record.d.ts.map +1 -1
  101. package/dist/task.d.ts +55 -36
  102. package/dist/task.d.ts.map +1 -1
  103. package/dist/task.js.map +1 -1
  104. package/dist/tasks/archive.d.ts +3 -3
  105. package/dist/templates/manifest.d.ts +1 -1
  106. package/dist/workgraph.d.ts +5 -3
  107. package/dist/workgraph.d.ts.map +1 -1
  108. package/dist/workgraph.js +19 -0
  109. package/dist/workgraph.js.map +1 -1
  110. package/package.json +2 -2
  111. package/schemas/gate-result.schema.json +350 -1
  112. package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
  113. package/src/__tests__/acceptance-gate.test.ts +282 -1
  114. package/src/__tests__/evidence-atom-schema.test.ts +17 -14
  115. package/src/__tests__/memory-wire-shapes.test.ts +2 -0
  116. package/src/__tests__/operations-registry.test.ts +26 -0
  117. package/src/acceptance-gate-schema.ts +320 -14
  118. package/src/acceptance-gate.ts +133 -11
  119. package/src/audit.ts +72 -2
  120. package/src/backup-manifest.ts +88 -0
  121. package/src/caamp-markers.ts +22 -0
  122. package/src/capabilities.ts +311 -0
  123. package/src/code-symbol.ts +37 -0
  124. package/src/data-accessor.ts +16 -0
  125. package/src/dispatch/__tests__/tasks-gateway-crud-ops.test.ts +31 -1
  126. package/src/dispatch/operations-registry.ts +689 -3
  127. package/src/docs-taxonomy.ts +26 -0
  128. package/src/evidence-atom-schema.ts +10 -9
  129. package/src/graph.ts +326 -2
  130. package/src/index.ts +43 -1
  131. package/src/invariants/adr-070-orchestration.ts +2 -1
  132. package/src/invariants/adr-073-saga.ts +2 -2
  133. package/src/jobs.ts +382 -3
  134. package/src/knowledge-health.ts +748 -0
  135. package/src/memory/observe.ts +4 -2
  136. package/src/memory/search.ts +4 -0
  137. package/src/nexus-living-brain-ops.ts +34 -3
  138. package/src/nexus-tasks-bridge-ops.ts +12 -0
  139. package/src/operations/admin.ts +11 -4
  140. package/src/operations/docs.ts +153 -0
  141. package/src/operations/focus.ts +11 -0
  142. package/src/operations/nexus.ts +7 -1
  143. package/src/operations/output-contracts-data.ts +33 -3
  144. package/src/operations/research.ts +36 -0
  145. package/src/operations/tasks.ts +116 -4
  146. package/src/package-artifact.ts +127 -0
  147. package/src/release/evidence-atoms.ts +6 -0
  148. package/src/resource-governor.ts +132 -0
  149. package/src/task-record.ts +27 -4
  150. package/src/task.ts +58 -36
  151. package/src/workgraph.ts +19 -0
@@ -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
- export type TasksFindResult = MinimalTask[];
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
- * Appends a signed attestation to `.cleo/audit/severity-attestation.jsonl`.
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 to `.cleo/audit/depends-waiver.jsonl`.
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(
@@ -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
+ }
@@ -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
- acceptance?: string[];
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;