@cleocode/cleo 2026.6.6 → 2026.6.8

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/cli/index.js CHANGED
@@ -362,6 +362,21 @@ var init_dist = __esm({
362
362
  }
363
363
  });
364
364
 
365
+ // packages/cleo/src/cli/describe-context.ts
366
+ function setDescribeMode(requested) {
367
+ describeRequested = requested;
368
+ }
369
+ function isDescribeMode() {
370
+ return describeRequested;
371
+ }
372
+ var describeRequested;
373
+ var init_describe_context = __esm({
374
+ "packages/cleo/src/cli/describe-context.ts"() {
375
+ "use strict";
376
+ describeRequested = false;
377
+ }
378
+ });
379
+
365
380
  // packages/cleo/src/cli/field-context.ts
366
381
  import {
367
382
  resolveFieldExtraction
@@ -9665,7 +9680,7 @@ var init_operations_registry = __esm({
9665
9680
  gateway: "mutate",
9666
9681
  domain: "docs",
9667
9682
  operation: "add",
9668
- description: "docs.add (mutate) \u2014 attach a local file or URL to a CLEO owner entity (task, session, observation)",
9683
+ description: "docs.add (mutate) \u2014 attach a local file, URL, or inline content to a CLEO owner entity (task, session, observation)",
9669
9684
  tier: 1,
9670
9685
  idempotent: false,
9671
9686
  sessionRequired: false,
@@ -9689,6 +9704,12 @@ var init_operations_registry = __esm({
9689
9704
  required: false,
9690
9705
  description: "Remote URL to attach"
9691
9706
  },
9707
+ {
9708
+ name: "content",
9709
+ type: "string",
9710
+ required: false,
9711
+ description: "Inline document body (T10965); mutually exclusive with file/url"
9712
+ },
9692
9713
  {
9693
9714
  name: "desc",
9694
9715
  type: "string",
@@ -11395,7 +11416,8 @@ var init_provenance = __esm({
11395
11416
  "superseded-by",
11396
11417
  "related-task",
11397
11418
  "linked-decision",
11398
- "derived-from"
11419
+ "derived-from",
11420
+ "shares-topic"
11399
11421
  ];
11400
11422
  DOC_LIFECYCLE_STATUSES = [
11401
11423
  "active",
@@ -11470,6 +11492,41 @@ var init_provenance = __esm({
11470
11492
  }
11471
11493
  });
11472
11494
 
11495
+ // packages/contracts/src/docs/read.ts
11496
+ import { z as z8 } from "zod";
11497
+ var docFrontmatterSchema, docBodySchema, docReadResponseSchema;
11498
+ var init_read = __esm({
11499
+ "packages/contracts/src/docs/read.ts"() {
11500
+ "use strict";
11501
+ docFrontmatterSchema = z8.object({
11502
+ slug: z8.string(),
11503
+ kind: z8.string().nullable(),
11504
+ title: z8.string().nullable(),
11505
+ summary: z8.string().nullable(),
11506
+ lifecycleStatus: z8.string(),
11507
+ docVersion: z8.number().int(),
11508
+ ownerVersion: z8.string().nullable(),
11509
+ supersedes: z8.string().nullable(),
11510
+ supersededBy: z8.string().nullable(),
11511
+ topics: z8.array(z8.string()).readonly(),
11512
+ relatedTasks: z8.array(z8.string()).readonly(),
11513
+ sha256: z8.string(),
11514
+ createdAt: z8.string()
11515
+ });
11516
+ docBodySchema = z8.object({
11517
+ encoding: z8.enum(["utf-8", "base64"]),
11518
+ text: z8.string().optional(),
11519
+ base64: z8.string().optional(),
11520
+ sizeBytes: z8.number().int().nonnegative(),
11521
+ mimeType: z8.string().nullable()
11522
+ });
11523
+ docReadResponseSchema = z8.object({
11524
+ frontmatter: docFrontmatterSchema,
11525
+ body: docBodySchema
11526
+ });
11527
+ }
11528
+ });
11529
+
11473
11530
  // packages/contracts/src/engine-result.ts
11474
11531
  var init_engine_result = __esm({
11475
11532
  "packages/contracts/src/engine-result.ts"() {
@@ -11625,72 +11682,72 @@ var init_errors = __esm({
11625
11682
  });
11626
11683
 
11627
11684
  // packages/contracts/src/evidence-atom-schema.ts
11628
- import { z as z8 } from "zod";
11685
+ import { z as z9 } from "zod";
11629
11686
  var commitAtomSchema, filesAtomSchema, testRunAtomSchema, toolAtomSchema, urlAtomSchema, noteAtomSchema, decisionAtomSchema, prAtomSchema, locDropAtomSchema, callsiteCoverageAtomSchema, AC_UUID_REGEX, AC_ALIAS_REGEX, SATISFIES_TASK_ID_REGEX, SATISFIES_VERSION_PIN_REGEX, satisfiesAtomSchema, EvidenceAtomSchema, GATE_EVIDENCE_REQUIREMENTS, ATOM_EXAMPLES;
11630
11687
  var init_evidence_atom_schema = __esm({
11631
11688
  "packages/contracts/src/evidence-atom-schema.ts"() {
11632
11689
  "use strict";
11633
- commitAtomSchema = z8.object({
11634
- kind: z8.literal("commit"),
11635
- sha: z8.string().regex(/^[0-9a-f]{7,40}$/i, "commit sha must be 7-40 hex characters")
11690
+ commitAtomSchema = z9.object({
11691
+ kind: z9.literal("commit"),
11692
+ sha: z9.string().regex(/^[0-9a-f]{7,40}$/i, "commit sha must be 7-40 hex characters")
11636
11693
  });
11637
- filesAtomSchema = z8.object({
11638
- kind: z8.literal("files"),
11639
- paths: z8.array(z8.string().min(1)).min(1, "files atom requires at least one path")
11694
+ filesAtomSchema = z9.object({
11695
+ kind: z9.literal("files"),
11696
+ paths: z9.array(z9.string().min(1)).min(1, "files atom requires at least one path")
11640
11697
  });
11641
- testRunAtomSchema = z8.object({
11642
- kind: z8.literal("test-run"),
11643
- path: z8.string().min(1, "test-run atom requires a non-empty path")
11698
+ testRunAtomSchema = z9.object({
11699
+ kind: z9.literal("test-run"),
11700
+ path: z9.string().min(1, "test-run atom requires a non-empty path")
11644
11701
  });
11645
- toolAtomSchema = z8.object({
11646
- kind: z8.literal("tool"),
11647
- tool: z8.string().min(1, "tool atom requires a non-empty tool name")
11702
+ toolAtomSchema = z9.object({
11703
+ kind: z9.literal("tool"),
11704
+ tool: z9.string().min(1, "tool atom requires a non-empty tool name")
11648
11705
  });
11649
- urlAtomSchema = z8.object({
11650
- kind: z8.literal("url"),
11651
- url: z8.string().min(1).regex(/^https?:\/\//, "url atom must start with http:// or https://")
11706
+ urlAtomSchema = z9.object({
11707
+ kind: z9.literal("url"),
11708
+ url: z9.string().min(1).regex(/^https?:\/\//, "url atom must start with http:// or https://")
11652
11709
  });
11653
- noteAtomSchema = z8.object({
11654
- kind: z8.literal("note"),
11655
- note: z8.string().min(1, "note atom must be non-empty").max(512, "note atom is too long (max 512 chars)")
11710
+ noteAtomSchema = z9.object({
11711
+ kind: z9.literal("note"),
11712
+ note: z9.string().min(1, "note atom must be non-empty").max(512, "note atom is too long (max 512 chars)")
11656
11713
  });
11657
- decisionAtomSchema = z8.object({
11658
- kind: z8.literal("decision"),
11659
- decisionId: z8.string().min(1, "decision atom requires a non-empty decision ID")
11714
+ decisionAtomSchema = z9.object({
11715
+ kind: z9.literal("decision"),
11716
+ decisionId: z9.string().min(1, "decision atom requires a non-empty decision ID")
11660
11717
  });
11661
- prAtomSchema = z8.object({
11662
- kind: z8.literal("pr"),
11663
- prNumber: z8.number().int().positive("pr atom requires a positive integer PR number")
11718
+ prAtomSchema = z9.object({
11719
+ kind: z9.literal("pr"),
11720
+ prNumber: z9.number().int().positive("pr atom requires a positive integer PR number")
11664
11721
  });
11665
- locDropAtomSchema = z8.object({
11666
- kind: z8.literal("loc-drop"),
11667
- fromLines: z8.number().int().nonnegative("loc-drop fromLines must be \u2265 0"),
11668
- toLines: z8.number().int().nonnegative("loc-drop toLines must be \u2265 0")
11722
+ locDropAtomSchema = z9.object({
11723
+ kind: z9.literal("loc-drop"),
11724
+ fromLines: z9.number().int().nonnegative("loc-drop fromLines must be \u2265 0"),
11725
+ toLines: z9.number().int().nonnegative("loc-drop toLines must be \u2265 0")
11669
11726
  });
11670
- callsiteCoverageAtomSchema = z8.object({
11671
- kind: z8.literal("callsite-coverage"),
11672
- symbolName: z8.string().min(1, "callsite-coverage atom requires a non-empty symbolName"),
11673
- relativeSourcePath: z8.string().min(1, "callsite-coverage atom requires a non-empty relativeSourcePath")
11727
+ callsiteCoverageAtomSchema = z9.object({
11728
+ kind: z9.literal("callsite-coverage"),
11729
+ symbolName: z9.string().min(1, "callsite-coverage atom requires a non-empty symbolName"),
11730
+ relativeSourcePath: z9.string().min(1, "callsite-coverage atom requires a non-empty relativeSourcePath")
11674
11731
  });
11675
11732
  AC_UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
11676
11733
  AC_ALIAS_REGEX = /^AC[0-9]{1,4}$/;
11677
11734
  SATISFIES_TASK_ID_REGEX = /^T[0-9]{1,7}$/;
11678
11735
  SATISFIES_VERSION_PIN_REGEX = /^[0-9]{14}$/;
11679
- satisfiesAtomSchema = z8.object({
11680
- kind: z8.literal("satisfies"),
11736
+ satisfiesAtomSchema = z9.object({
11737
+ kind: z9.literal("satisfies"),
11681
11738
  /** Target task ID — `T<1-7 digits>` per ADR-079-r2 §2.1. */
11682
- targetTaskId: z8.string().regex(SATISFIES_TASK_ID_REGEX, "satisfies atom targetTaskId must match /^T[0-9]{1,7}$/"),
11739
+ targetTaskId: z9.string().regex(SATISFIES_TASK_ID_REGEX, "satisfies atom targetTaskId must match /^T[0-9]{1,7}$/"),
11683
11740
  /** Lowercase UUIDv4/v5 — populated for the canonical form; undefined for alias form. */
11684
- targetAcId: z8.string().regex(AC_UUID_REGEX, "satisfies atom targetAcId must be a lowercase UUIDv4/v5").optional(),
11741
+ targetAcId: z9.string().regex(AC_UUID_REGEX, "satisfies atom targetAcId must be a lowercase UUIDv4/v5").optional(),
11685
11742
  /** Positional alias `AC<1-4 digits>` — populated for alias form; undefined for UUID form. */
11686
- targetAcAlias: z8.string().regex(AC_ALIAS_REGEX, "satisfies atom targetAcAlias must match /^AC[0-9]{1,4}$/").optional(),
11743
+ targetAcAlias: z9.string().regex(AC_ALIAS_REGEX, "satisfies atom targetAcAlias must match /^AC[0-9]{1,4}$/").optional(),
11687
11744
  /** Optional `@<14-digit YYYYMMDDhhmmss>` pin captured at mint time. */
11688
- versionPin: z8.string().regex(
11745
+ versionPin: z9.string().regex(
11689
11746
  SATISFIES_VERSION_PIN_REGEX,
11690
11747
  "satisfies atom versionPin must be 14 digits (YYYYMMDDhhmmss)"
11691
11748
  ).optional()
11692
11749
  });
11693
- EvidenceAtomSchema = z8.discriminatedUnion("kind", [
11750
+ EvidenceAtomSchema = z9.discriminatedUnion("kind", [
11694
11751
  commitAtomSchema,
11695
11752
  filesAtomSchema,
11696
11753
  testRunAtomSchema,
@@ -11737,58 +11794,58 @@ var init_evidence_atom_schema = __esm({
11737
11794
  });
11738
11795
 
11739
11796
  // packages/contracts/src/evidence-record-schema.ts
11740
- import { z as z9 } from "zod";
11797
+ import { z as z10 } from "zod";
11741
11798
  var evidenceBaseSchema, implDiffRecordSchema, validateSpecCheckRecordSchema, testOutputRecordSchema, lintReportRecordSchema, commandOutputRecordSchema, evidenceRecordSchema;
11742
11799
  var init_evidence_record_schema = __esm({
11743
11800
  "packages/contracts/src/evidence-record-schema.ts"() {
11744
11801
  "use strict";
11745
- evidenceBaseSchema = z9.object({
11802
+ evidenceBaseSchema = z10.object({
11746
11803
  /** Identity string of the agent that produced this record. */
11747
- agentIdentity: z9.string().min(1),
11804
+ agentIdentity: z10.string().min(1),
11748
11805
  /** SHA-256 hex digest (64 chars) of the attached artifact. */
11749
- attachmentSha256: z9.string().length(64),
11806
+ attachmentSha256: z10.string().length(64),
11750
11807
  /** ISO 8601 timestamp at which the action ran. */
11751
- ranAt: z9.string().datetime(),
11808
+ ranAt: z10.string().datetime(),
11752
11809
  /** Wall-clock duration of the action in milliseconds. */
11753
- durationMs: z9.number().nonnegative()
11810
+ durationMs: z10.number().nonnegative()
11754
11811
  });
11755
11812
  implDiffRecordSchema = evidenceBaseSchema.extend({
11756
- kind: z9.literal("impl-diff"),
11757
- phase: z9.literal("implement"),
11758
- filesChanged: z9.array(z9.string().min(1)).min(1),
11759
- linesAdded: z9.number().int().nonnegative(),
11760
- linesRemoved: z9.number().int().nonnegative()
11813
+ kind: z10.literal("impl-diff"),
11814
+ phase: z10.literal("implement"),
11815
+ filesChanged: z10.array(z10.string().min(1)).min(1),
11816
+ linesAdded: z10.number().int().nonnegative(),
11817
+ linesRemoved: z10.number().int().nonnegative()
11761
11818
  });
11762
11819
  validateSpecCheckRecordSchema = evidenceBaseSchema.extend({
11763
- kind: z9.literal("validate-spec-check"),
11764
- phase: z9.literal("validate"),
11765
- reqIdsChecked: z9.array(z9.string().min(1)).min(1),
11766
- passed: z9.boolean(),
11767
- details: z9.string().min(1)
11820
+ kind: z10.literal("validate-spec-check"),
11821
+ phase: z10.literal("validate"),
11822
+ reqIdsChecked: z10.array(z10.string().min(1)).min(1),
11823
+ passed: z10.boolean(),
11824
+ details: z10.string().min(1)
11768
11825
  });
11769
11826
  testOutputRecordSchema = evidenceBaseSchema.extend({
11770
- kind: z9.literal("test-output"),
11771
- phase: z9.literal("test"),
11772
- command: z9.string().min(1),
11773
- exitCode: z9.number().int(),
11774
- testsPassed: z9.number().int().nonnegative(),
11775
- testsFailed: z9.number().int().nonnegative()
11827
+ kind: z10.literal("test-output"),
11828
+ phase: z10.literal("test"),
11829
+ command: z10.string().min(1),
11830
+ exitCode: z10.number().int(),
11831
+ testsPassed: z10.number().int().nonnegative(),
11832
+ testsFailed: z10.number().int().nonnegative()
11776
11833
  });
11777
11834
  lintReportRecordSchema = evidenceBaseSchema.extend({
11778
- kind: z9.literal("lint-report"),
11779
- phase: z9.enum(["implement", "test"]),
11780
- tool: z9.string().min(1),
11781
- passed: z9.boolean(),
11782
- warnings: z9.number().int().nonnegative(),
11783
- errors: z9.number().int().nonnegative()
11835
+ kind: z10.literal("lint-report"),
11836
+ phase: z10.enum(["implement", "test"]),
11837
+ tool: z10.string().min(1),
11838
+ passed: z10.boolean(),
11839
+ warnings: z10.number().int().nonnegative(),
11840
+ errors: z10.number().int().nonnegative()
11784
11841
  });
11785
11842
  commandOutputRecordSchema = evidenceBaseSchema.extend({
11786
- kind: z9.literal("command-output"),
11787
- phase: z9.enum(["implement", "validate", "test"]),
11788
- cmd: z9.string().min(1),
11789
- exitCode: z9.number().int()
11843
+ kind: z10.literal("command-output"),
11844
+ phase: z10.enum(["implement", "validate", "test"]),
11845
+ cmd: z10.string().min(1),
11846
+ exitCode: z10.number().int()
11790
11847
  });
11791
- evidenceRecordSchema = z9.discriminatedUnion("kind", [
11848
+ evidenceRecordSchema = z10.discriminatedUnion("kind", [
11792
11849
  implDiffRecordSchema,
11793
11850
  validateSpecCheckRecordSchema,
11794
11851
  testOutputRecordSchema,
@@ -12348,7 +12405,7 @@ var init_status_registry = __esm({
12348
12405
  });
12349
12406
 
12350
12407
  // packages/contracts/src/workgraph.ts
12351
- import { z as z10 } from "zod";
12408
+ import { z as z11 } from "zod";
12352
12409
  var E_WORKGRAPH_PARENT_TYPE_MATRIX, taskTypeSchema, taskPrioritySchema, taskStatusSchema, verificationGateSchema, workGraphRelationKindSchema, workGraphTraversalDirectionSchema, workGraphEdgeDirectionSchema, paginationParamsSchema, workGraphNodeSchema, workGraphEdgeSchema, workGraphHierarchyEdgeSchema, workGraphPageInfoSchema, workGraphRollupCountsSchema, workGraphSubtreePercentagesSchema, workGraphProjectionMismatchSchema, workGraphReadyFrontierTaskSchema, workGraphRelationEdgeSchema, workGraphDependencyEdgeSchema, workGraphOmissionReasonSchema, workGraphContextBudgetSchema, workGraphOmissionSchema, workGraphDirectEdgeSchema, workGraphContextPackParamsSchema, workGraphSliceParamsSchema, workGraphSliceSchema, workGraphReadinessParamsSchema, workGraphReadinessResultSchema, workGraphContextPackSchema, workGraphScaffoldValidateParamsSchema, workGraphScaffoldValidationIssueSchema, workGraphScaffoldValidateResultSchema, workGraphScaffoldApplyParamsSchema, workGraphScaffoldApplyResultSchema, workGraphPlanningDocParamsSchema, workGraphPlanningDocSchema, tasksTraverseParamsSchema, tasksTraverseResultSchema, tasksTreeParamsSchema, tasksTreeResultSchema, tasksRollupParamsSchema, tasksRollupResultSchema, tasksFrontierParamsSchema, tasksFrontierResultSchema, tasksWorkGraphAuditParamsSchema, tasksWorkGraphAuditResultSchema;
12353
12410
  var init_workgraph = __esm({
12354
12411
  "packages/contracts/src/workgraph.ts"() {
@@ -12356,10 +12413,10 @@ var init_workgraph = __esm({
12356
12413
  init_enums();
12357
12414
  init_status_registry();
12358
12415
  E_WORKGRAPH_PARENT_TYPE_MATRIX = "E_WORKGRAPH_PARENT_TYPE_MATRIX";
12359
- taskTypeSchema = z10.enum(["saga", "epic", "task", "subtask"]);
12360
- taskPrioritySchema = z10.enum(["critical", "high", "medium", "low"]);
12361
- taskStatusSchema = z10.enum(TASK_STATUSES);
12362
- verificationGateSchema = z10.enum([
12416
+ taskTypeSchema = z11.enum(["saga", "epic", "task", "subtask"]);
12417
+ taskPrioritySchema = z11.enum(["critical", "high", "medium", "low"]);
12418
+ taskStatusSchema = z11.enum(TASK_STATUSES);
12419
+ verificationGateSchema = z11.enum([
12363
12420
  "implemented",
12364
12421
  "testsPassed",
12365
12422
  "qaPassed",
@@ -12368,7 +12425,7 @@ var init_workgraph = __esm({
12368
12425
  "documented",
12369
12426
  "nexusImpact"
12370
12427
  ]);
12371
- workGraphRelationKindSchema = z10.enum([
12428
+ workGraphRelationKindSchema = z11.enum([
12372
12429
  "contains",
12373
12430
  "depends_on",
12374
12431
  "blocks",
@@ -12376,317 +12433,317 @@ var init_workgraph = __esm({
12376
12433
  "groups",
12377
12434
  "satisfies"
12378
12435
  ]);
12379
- workGraphTraversalDirectionSchema = z10.enum([
12436
+ workGraphTraversalDirectionSchema = z11.enum([
12380
12437
  "ancestors",
12381
12438
  "descendants",
12382
12439
  "upstream",
12383
12440
  "downstream"
12384
12441
  ]);
12385
- workGraphEdgeDirectionSchema = z10.enum(["out", "in", "both"]);
12386
- paginationParamsSchema = z10.object({
12387
- cursor: z10.string().min(1).optional(),
12388
- limit: z10.number().int().positive().max(500).optional()
12442
+ workGraphEdgeDirectionSchema = z11.enum(["out", "in", "both"]);
12443
+ paginationParamsSchema = z11.object({
12444
+ cursor: z11.string().min(1).optional(),
12445
+ limit: z11.number().int().positive().max(500).optional()
12389
12446
  });
12390
- workGraphNodeSchema = z10.object({
12391
- id: z10.string().min(1),
12447
+ workGraphNodeSchema = z11.object({
12448
+ id: z11.string().min(1),
12392
12449
  type: taskTypeSchema,
12393
- title: z10.string(),
12450
+ title: z11.string(),
12394
12451
  status: taskStatusSchema,
12395
12452
  priority: taskPrioritySchema,
12396
- parentId: z10.string().min(1).optional()
12453
+ parentId: z11.string().min(1).optional()
12397
12454
  });
12398
- workGraphEdgeSchema = z10.object({
12399
- fromId: z10.string().min(1),
12400
- toId: z10.string().min(1),
12455
+ workGraphEdgeSchema = z11.object({
12456
+ fromId: z11.string().min(1),
12457
+ toId: z11.string().min(1),
12401
12458
  kind: workGraphRelationKindSchema
12402
12459
  });
12403
- workGraphHierarchyEdgeSchema = z10.object({
12404
- fromId: z10.string().min(1),
12405
- toId: z10.string().min(1),
12406
- kind: z10.literal("contains")
12460
+ workGraphHierarchyEdgeSchema = z11.object({
12461
+ fromId: z11.string().min(1),
12462
+ toId: z11.string().min(1),
12463
+ kind: z11.literal("contains")
12407
12464
  }).strict();
12408
- workGraphPageInfoSchema = z10.object({
12409
- nextCursor: z10.string().min(1).optional(),
12410
- hasMore: z10.boolean()
12411
- });
12412
- workGraphRollupCountsSchema = z10.object({
12413
- total: z10.number().int().nonnegative(),
12414
- byStatus: z10.partialRecord(taskStatusSchema, z10.number().int().nonnegative()),
12415
- byType: z10.partialRecord(taskTypeSchema, z10.number().int().nonnegative())
12416
- });
12417
- workGraphSubtreePercentagesSchema = z10.object({
12418
- done: z10.number().nonnegative(),
12419
- active: z10.number().nonnegative(),
12420
- blocked: z10.number().nonnegative(),
12421
- pending: z10.number().nonnegative(),
12422
- cancelled: z10.number().nonnegative()
12423
- });
12424
- workGraphProjectionMismatchSchema = z10.object({
12425
- field: z10.string().min(1),
12426
- expected: z10.number().int().nonnegative(),
12427
- actual: z10.number().int().nonnegative()
12465
+ workGraphPageInfoSchema = z11.object({
12466
+ nextCursor: z11.string().min(1).optional(),
12467
+ hasMore: z11.boolean()
12468
+ });
12469
+ workGraphRollupCountsSchema = z11.object({
12470
+ total: z11.number().int().nonnegative(),
12471
+ byStatus: z11.partialRecord(taskStatusSchema, z11.number().int().nonnegative()),
12472
+ byType: z11.partialRecord(taskTypeSchema, z11.number().int().nonnegative())
12473
+ });
12474
+ workGraphSubtreePercentagesSchema = z11.object({
12475
+ done: z11.number().nonnegative(),
12476
+ active: z11.number().nonnegative(),
12477
+ blocked: z11.number().nonnegative(),
12478
+ pending: z11.number().nonnegative(),
12479
+ cancelled: z11.number().nonnegative()
12480
+ });
12481
+ workGraphProjectionMismatchSchema = z11.object({
12482
+ field: z11.string().min(1),
12483
+ expected: z11.number().int().nonnegative(),
12484
+ actual: z11.number().int().nonnegative()
12428
12485
  });
12429
12486
  workGraphReadyFrontierTaskSchema = workGraphNodeSchema.extend({
12430
- role: z10.string().min(1).optional(),
12431
- dependencyBlockers: z10.array(z10.object({ taskId: z10.string().min(1), status: taskStatusSchema })),
12432
- gateBlockers: z10.array(z10.object({ gate: verificationGateSchema }))
12487
+ role: z11.string().min(1).optional(),
12488
+ dependencyBlockers: z11.array(z11.object({ taskId: z11.string().min(1), status: taskStatusSchema })),
12489
+ gateBlockers: z11.array(z11.object({ gate: verificationGateSchema }))
12433
12490
  });
12434
12491
  workGraphRelationEdgeSchema = workGraphEdgeSchema.extend({
12435
- source: z10.literal("relation"),
12436
- relationType: z10.enum(TASK_RELATION_TYPES),
12437
- reason: z10.string().min(1).optional()
12492
+ source: z11.literal("relation"),
12493
+ relationType: z11.enum(TASK_RELATION_TYPES),
12494
+ reason: z11.string().min(1).optional()
12438
12495
  });
12439
12496
  workGraphDependencyEdgeSchema = workGraphEdgeSchema.extend({
12440
- source: z10.literal("dependency"),
12441
- kind: z10.literal("depends_on")
12497
+ source: z11.literal("dependency"),
12498
+ kind: z11.literal("depends_on")
12442
12499
  });
12443
- workGraphOmissionReasonSchema = z10.enum([
12500
+ workGraphOmissionReasonSchema = z11.enum([
12444
12501
  "budget_exceeded",
12445
12502
  "not_requested",
12446
12503
  "not_available",
12447
12504
  "redacted",
12448
12505
  "truncated"
12449
12506
  ]);
12450
- workGraphContextBudgetSchema = z10.object({
12451
- tokenBudget: z10.number().int().nonnegative(),
12452
- estimatedTokens: z10.number().int().nonnegative(),
12453
- remainingTokens: z10.number().int().nonnegative(),
12454
- truncated: z10.boolean()
12455
- });
12456
- workGraphOmissionSchema = z10.object({
12457
- path: z10.string().min(1),
12507
+ workGraphContextBudgetSchema = z11.object({
12508
+ tokenBudget: z11.number().int().nonnegative(),
12509
+ estimatedTokens: z11.number().int().nonnegative(),
12510
+ remainingTokens: z11.number().int().nonnegative(),
12511
+ truncated: z11.boolean()
12512
+ });
12513
+ workGraphOmissionSchema = z11.object({
12514
+ path: z11.string().min(1),
12458
12515
  reason: workGraphOmissionReasonSchema,
12459
- message: z10.string().min(1),
12460
- estimatedTokens: z10.number().int().nonnegative().optional()
12516
+ message: z11.string().min(1),
12517
+ estimatedTokens: z11.number().int().nonnegative().optional()
12461
12518
  });
12462
- workGraphDirectEdgeSchema = z10.discriminatedUnion("source", [
12519
+ workGraphDirectEdgeSchema = z11.discriminatedUnion("source", [
12463
12520
  workGraphRelationEdgeSchema,
12464
12521
  workGraphDependencyEdgeSchema
12465
12522
  ]);
12466
12523
  workGraphContextPackParamsSchema = paginationParamsSchema.extend({
12467
- rootId: z10.string().min(1),
12468
- tokenBudget: z10.number().int().positive().optional(),
12469
- includeRelations: z10.boolean().optional(),
12470
- includeReadiness: z10.boolean().optional(),
12471
- includeRollup: z10.boolean().optional()
12524
+ rootId: z11.string().min(1),
12525
+ tokenBudget: z11.number().int().positive().optional(),
12526
+ includeRelations: z11.boolean().optional(),
12527
+ includeReadiness: z11.boolean().optional(),
12528
+ includeRollup: z11.boolean().optional()
12472
12529
  });
12473
12530
  workGraphSliceParamsSchema = paginationParamsSchema.extend({
12474
- rootId: z10.string().min(1),
12531
+ rootId: z11.string().min(1),
12475
12532
  direction: workGraphTraversalDirectionSchema.optional(),
12476
- maxDepth: z10.number().int().nonnegative().optional(),
12477
- includeRelations: z10.boolean().optional()
12533
+ maxDepth: z11.number().int().nonnegative().optional(),
12534
+ includeRelations: z11.boolean().optional()
12478
12535
  });
12479
- workGraphSliceSchema = z10.object({
12480
- rootId: z10.string().min(1),
12536
+ workGraphSliceSchema = z11.object({
12537
+ rootId: z11.string().min(1),
12481
12538
  direction: workGraphTraversalDirectionSchema,
12482
- nodes: z10.array(workGraphNodeSchema),
12483
- edges: z10.array(workGraphEdgeSchema),
12539
+ nodes: z11.array(workGraphNodeSchema),
12540
+ edges: z11.array(workGraphEdgeSchema),
12484
12541
  pageInfo: workGraphPageInfoSchema,
12485
- omissions: z10.array(workGraphOmissionSchema).optional()
12486
- });
12487
- workGraphReadinessParamsSchema = z10.object({
12488
- rootId: z10.string().min(1),
12489
- role: z10.string().min(1).optional(),
12490
- includeGateBlockers: z10.boolean().optional()
12491
- });
12492
- workGraphReadinessResultSchema = z10.object({
12493
- rootId: z10.string().min(1),
12494
- role: z10.string().min(1).optional(),
12495
- ready: z10.boolean(),
12496
- warnings: z10.array(z10.string()),
12497
- groups: z10.object({
12498
- ready: z10.array(workGraphReadyFrontierTaskSchema),
12499
- blocked: z10.array(workGraphReadyFrontierTaskSchema),
12500
- blockedBy: z10.array(
12501
- z10.discriminatedUnion("kind", [
12502
- z10.object({
12503
- kind: z10.literal("dependency"),
12504
- blockerId: z10.string().min(1),
12505
- blocks: z10.array(z10.string().min(1))
12542
+ omissions: z11.array(workGraphOmissionSchema).optional()
12543
+ });
12544
+ workGraphReadinessParamsSchema = z11.object({
12545
+ rootId: z11.string().min(1),
12546
+ role: z11.string().min(1).optional(),
12547
+ includeGateBlockers: z11.boolean().optional()
12548
+ });
12549
+ workGraphReadinessResultSchema = z11.object({
12550
+ rootId: z11.string().min(1),
12551
+ role: z11.string().min(1).optional(),
12552
+ ready: z11.boolean(),
12553
+ warnings: z11.array(z11.string()),
12554
+ groups: z11.object({
12555
+ ready: z11.array(workGraphReadyFrontierTaskSchema),
12556
+ blocked: z11.array(workGraphReadyFrontierTaskSchema),
12557
+ blockedBy: z11.array(
12558
+ z11.discriminatedUnion("kind", [
12559
+ z11.object({
12560
+ kind: z11.literal("dependency"),
12561
+ blockerId: z11.string().min(1),
12562
+ blocks: z11.array(z11.string().min(1))
12506
12563
  }),
12507
- z10.object({
12508
- kind: z10.literal("gate"),
12564
+ z11.object({
12565
+ kind: z11.literal("gate"),
12509
12566
  gate: verificationGateSchema,
12510
- blocks: z10.array(z10.string().min(1))
12567
+ blocks: z11.array(z11.string().min(1))
12511
12568
  })
12512
12569
  ])
12513
12570
  )
12514
12571
  })
12515
12572
  });
12516
- workGraphContextPackSchema = z10.object({
12517
- rootId: z10.string().min(1),
12518
- generatedAt: z10.string().min(1),
12573
+ workGraphContextPackSchema = z11.object({
12574
+ rootId: z11.string().min(1),
12575
+ generatedAt: z11.string().min(1),
12519
12576
  budget: workGraphContextBudgetSchema,
12520
12577
  slice: workGraphSliceSchema,
12521
- relationEdges: z10.object({
12522
- rootId: z10.string().min(1),
12578
+ relationEdges: z11.object({
12579
+ rootId: z11.string().min(1),
12523
12580
  direction: workGraphEdgeDirectionSchema,
12524
- edges: z10.array(workGraphDirectEdgeSchema)
12581
+ edges: z11.array(workGraphDirectEdgeSchema)
12525
12582
  }).optional(),
12526
12583
  readiness: workGraphReadinessResultSchema.optional(),
12527
- rollup: z10.lazy(() => tasksRollupResultSchema).optional(),
12528
- omissions: z10.array(workGraphOmissionSchema)
12529
- });
12530
- workGraphScaffoldValidateParamsSchema = z10.object({
12531
- rootId: z10.string().min(1),
12532
- nodes: z10.array(
12533
- z10.object({
12534
- id: z10.string().min(1),
12584
+ rollup: z11.lazy(() => tasksRollupResultSchema).optional(),
12585
+ omissions: z11.array(workGraphOmissionSchema)
12586
+ });
12587
+ workGraphScaffoldValidateParamsSchema = z11.object({
12588
+ rootId: z11.string().min(1),
12589
+ nodes: z11.array(
12590
+ z11.object({
12591
+ id: z11.string().min(1),
12535
12592
  type: taskTypeSchema,
12536
- parentId: z10.string().min(1).nullable().optional()
12593
+ parentId: z11.string().min(1).nullable().optional()
12537
12594
  })
12538
12595
  ),
12539
- edges: z10.array(workGraphDirectEdgeSchema).optional(),
12540
- dryRun: z10.boolean().optional()
12541
- });
12542
- workGraphScaffoldValidationIssueSchema = z10.object({
12543
- code: z10.string().min(1),
12544
- message: z10.string().min(1),
12545
- taskId: z10.string().min(1).optional(),
12546
- severity: z10.enum(["error", "warning"])
12547
- });
12548
- workGraphScaffoldValidateResultSchema = z10.object({
12549
- rootId: z10.string().min(1),
12550
- valid: z10.boolean(),
12551
- dryRun: z10.boolean(),
12552
- issues: z10.array(workGraphScaffoldValidationIssueSchema),
12553
- hierarchy: z10.object({
12554
- valid: z10.boolean(),
12555
- violations: z10.array(
12556
- z10.object({
12557
- code: z10.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
12558
- taskId: z10.string().min(1),
12596
+ edges: z11.array(workGraphDirectEdgeSchema).optional(),
12597
+ dryRun: z11.boolean().optional()
12598
+ });
12599
+ workGraphScaffoldValidationIssueSchema = z11.object({
12600
+ code: z11.string().min(1),
12601
+ message: z11.string().min(1),
12602
+ taskId: z11.string().min(1).optional(),
12603
+ severity: z11.enum(["error", "warning"])
12604
+ });
12605
+ workGraphScaffoldValidateResultSchema = z11.object({
12606
+ rootId: z11.string().min(1),
12607
+ valid: z11.boolean(),
12608
+ dryRun: z11.boolean(),
12609
+ issues: z11.array(workGraphScaffoldValidationIssueSchema),
12610
+ hierarchy: z11.object({
12611
+ valid: z11.boolean(),
12612
+ violations: z11.array(
12613
+ z11.object({
12614
+ code: z11.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
12615
+ taskId: z11.string().min(1),
12559
12616
  taskType: taskTypeSchema,
12560
- parentId: z10.string().min(1).nullable(),
12617
+ parentId: z11.string().min(1).nullable(),
12561
12618
  parentType: taskTypeSchema.optional(),
12562
- message: z10.string().min(1)
12619
+ message: z11.string().min(1)
12563
12620
  })
12564
12621
  )
12565
12622
  })
12566
12623
  });
12567
12624
  workGraphScaffoldApplyParamsSchema = workGraphScaffoldValidateParamsSchema.extend({
12568
- apply: z10.boolean().optional()
12625
+ apply: z11.boolean().optional()
12569
12626
  });
12570
12627
  workGraphScaffoldApplyResultSchema = workGraphScaffoldValidateResultSchema.extend({
12571
- applied: z10.boolean(),
12572
- nodesChanged: z10.number().int().nonnegative(),
12573
- edgesChanged: z10.number().int().nonnegative()
12574
- });
12575
- workGraphPlanningDocParamsSchema = z10.object({
12576
- rootId: z10.string().min(1),
12577
- audience: z10.enum(["agent", "maintainer"]),
12578
- tokenBudget: z10.number().int().positive().optional(),
12579
- includeRelations: z10.boolean().optional(),
12580
- includeReadiness: z10.boolean().optional(),
12581
- includeRollup: z10.boolean().optional()
12582
- });
12583
- workGraphPlanningDocSchema = z10.object({
12584
- rootId: z10.string().min(1),
12585
- generatedAt: z10.string().min(1),
12586
- audience: z10.enum(["agent", "maintainer"]),
12587
- title: z10.string().min(1),
12588
- content: z10.string(),
12589
- sections: z10.array(z10.string().min(1)),
12590
- estimatedTokens: z10.number().int().nonnegative(),
12591
- budget: z10.object({
12592
- tokenBudget: z10.number().int().positive(),
12593
- truncated: z10.boolean()
12628
+ applied: z11.boolean(),
12629
+ nodesChanged: z11.number().int().nonnegative(),
12630
+ edgesChanged: z11.number().int().nonnegative()
12631
+ });
12632
+ workGraphPlanningDocParamsSchema = z11.object({
12633
+ rootId: z11.string().min(1),
12634
+ audience: z11.enum(["agent", "maintainer"]),
12635
+ tokenBudget: z11.number().int().positive().optional(),
12636
+ includeRelations: z11.boolean().optional(),
12637
+ includeReadiness: z11.boolean().optional(),
12638
+ includeRollup: z11.boolean().optional()
12639
+ });
12640
+ workGraphPlanningDocSchema = z11.object({
12641
+ rootId: z11.string().min(1),
12642
+ generatedAt: z11.string().min(1),
12643
+ audience: z11.enum(["agent", "maintainer"]),
12644
+ title: z11.string().min(1),
12645
+ content: z11.string(),
12646
+ sections: z11.array(z11.string().min(1)),
12647
+ estimatedTokens: z11.number().int().nonnegative(),
12648
+ budget: z11.object({
12649
+ tokenBudget: z11.number().int().positive(),
12650
+ truncated: z11.boolean()
12594
12651
  }).optional()
12595
12652
  });
12596
12653
  tasksTraverseParamsSchema = paginationParamsSchema.extend({
12597
- rootId: z10.string().min(1),
12654
+ rootId: z11.string().min(1),
12598
12655
  direction: workGraphTraversalDirectionSchema,
12599
- maxDepth: z10.number().int().nonnegative().optional(),
12600
- includeRelations: z10.boolean().optional()
12656
+ maxDepth: z11.number().int().nonnegative().optional(),
12657
+ includeRelations: z11.boolean().optional()
12601
12658
  });
12602
- tasksTraverseResultSchema = z10.object({
12603
- rootId: z10.string().min(1),
12659
+ tasksTraverseResultSchema = z11.object({
12660
+ rootId: z11.string().min(1),
12604
12661
  direction: workGraphTraversalDirectionSchema,
12605
- nodes: z10.array(workGraphNodeSchema),
12606
- edges: z10.array(workGraphEdgeSchema),
12662
+ nodes: z11.array(workGraphNodeSchema),
12663
+ edges: z11.array(workGraphEdgeSchema),
12607
12664
  pageInfo: workGraphPageInfoSchema
12608
12665
  });
12609
12666
  tasksTreeParamsSchema = paginationParamsSchema.extend({
12610
- rootId: z10.string().min(1),
12611
- maxDepth: z10.number().int().nonnegative().optional()
12667
+ rootId: z11.string().min(1),
12668
+ maxDepth: z11.number().int().nonnegative().optional()
12612
12669
  });
12613
- tasksTreeResultSchema = z10.object({
12614
- rootId: z10.string().min(1),
12615
- nodes: z10.array(workGraphNodeSchema.extend({ depth: z10.number().int().positive() })),
12616
- edges: z10.array(workGraphHierarchyEdgeSchema),
12670
+ tasksTreeResultSchema = z11.object({
12671
+ rootId: z11.string().min(1),
12672
+ nodes: z11.array(workGraphNodeSchema.extend({ depth: z11.number().int().positive() })),
12673
+ edges: z11.array(workGraphHierarchyEdgeSchema),
12617
12674
  pageInfo: workGraphPageInfoSchema
12618
12675
  });
12619
- tasksRollupParamsSchema = z10.object({
12620
- rootId: z10.string().min(1),
12676
+ tasksRollupParamsSchema = z11.object({
12677
+ rootId: z11.string().min(1),
12621
12678
  expectedDirectRollup: workGraphRollupCountsSchema.optional()
12622
12679
  });
12623
- tasksRollupResultSchema = z10.object({
12624
- rootId: z10.string().min(1),
12680
+ tasksRollupResultSchema = z11.object({
12681
+ rootId: z11.string().min(1),
12625
12682
  direct: workGraphRollupCountsSchema,
12626
12683
  subtree: workGraphRollupCountsSchema,
12627
- percentDenominator: z10.object({
12628
- basis: z10.literal("subtree-total"),
12629
- total: z10.number().int().nonnegative(),
12630
- description: z10.string().min(1)
12684
+ percentDenominator: z11.object({
12685
+ basis: z11.literal("subtree-total"),
12686
+ total: z11.number().int().nonnegative(),
12687
+ description: z11.string().min(1)
12631
12688
  }),
12632
12689
  percentages: workGraphSubtreePercentagesSchema,
12633
- staleProjection: z10.boolean(),
12634
- projectionMismatches: z10.array(workGraphProjectionMismatchSchema)
12635
- });
12636
- tasksFrontierParamsSchema = z10.object({
12637
- rootId: z10.string().min(1),
12638
- role: z10.string().min(1).optional()
12639
- });
12640
- tasksFrontierResultSchema = z10.object({
12641
- rootId: z10.string().min(1),
12642
- role: z10.string().min(1).optional(),
12643
- groups: z10.object({
12644
- ready: z10.array(workGraphReadyFrontierTaskSchema),
12645
- blocked: z10.array(workGraphReadyFrontierTaskSchema),
12646
- blockedBy: z10.array(
12647
- z10.discriminatedUnion("kind", [
12648
- z10.object({
12649
- kind: z10.literal("dependency"),
12650
- blockerId: z10.string().min(1),
12651
- blocks: z10.array(z10.string().min(1))
12690
+ staleProjection: z11.boolean(),
12691
+ projectionMismatches: z11.array(workGraphProjectionMismatchSchema)
12692
+ });
12693
+ tasksFrontierParamsSchema = z11.object({
12694
+ rootId: z11.string().min(1),
12695
+ role: z11.string().min(1).optional()
12696
+ });
12697
+ tasksFrontierResultSchema = z11.object({
12698
+ rootId: z11.string().min(1),
12699
+ role: z11.string().min(1).optional(),
12700
+ groups: z11.object({
12701
+ ready: z11.array(workGraphReadyFrontierTaskSchema),
12702
+ blocked: z11.array(workGraphReadyFrontierTaskSchema),
12703
+ blockedBy: z11.array(
12704
+ z11.discriminatedUnion("kind", [
12705
+ z11.object({
12706
+ kind: z11.literal("dependency"),
12707
+ blockerId: z11.string().min(1),
12708
+ blocks: z11.array(z11.string().min(1))
12652
12709
  }),
12653
- z10.object({
12654
- kind: z10.literal("gate"),
12710
+ z11.object({
12711
+ kind: z11.literal("gate"),
12655
12712
  gate: verificationGateSchema,
12656
- blocks: z10.array(z10.string().min(1))
12713
+ blocks: z11.array(z11.string().min(1))
12657
12714
  })
12658
12715
  ])
12659
12716
  )
12660
12717
  })
12661
12718
  });
12662
12719
  tasksWorkGraphAuditParamsSchema = paginationParamsSchema.extend({
12663
- rootId: z10.string().min(1),
12664
- maxDepth: z10.number().int().nonnegative().optional(),
12665
- includeRelations: z10.boolean().optional()
12666
- });
12667
- tasksWorkGraphAuditResultSchema = z10.object({
12668
- rootId: z10.string().min(1),
12669
- hierarchy: z10.object({
12670
- valid: z10.boolean(),
12671
- violations: z10.array(
12672
- z10.object({
12673
- code: z10.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
12674
- taskId: z10.string().min(1),
12720
+ rootId: z11.string().min(1),
12721
+ maxDepth: z11.number().int().nonnegative().optional(),
12722
+ includeRelations: z11.boolean().optional()
12723
+ });
12724
+ tasksWorkGraphAuditResultSchema = z11.object({
12725
+ rootId: z11.string().min(1),
12726
+ hierarchy: z11.object({
12727
+ valid: z11.boolean(),
12728
+ violations: z11.array(
12729
+ z11.object({
12730
+ code: z11.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
12731
+ taskId: z11.string().min(1),
12675
12732
  taskType: taskTypeSchema,
12676
- parentId: z10.string().min(1).nullable(),
12733
+ parentId: z11.string().min(1).nullable(),
12677
12734
  parentType: taskTypeSchema.optional(),
12678
- message: z10.string().min(1)
12735
+ message: z11.string().min(1)
12679
12736
  })
12680
12737
  )
12681
12738
  }),
12682
12739
  traversal: tasksTraverseResultSchema,
12683
12740
  frontier: tasksFrontierResultSchema,
12684
12741
  rollup: tasksRollupResultSchema,
12685
- relationEdges: z10.object({
12686
- rootId: z10.string().min(1),
12742
+ relationEdges: z11.object({
12743
+ rootId: z11.string().min(1),
12687
12744
  direction: workGraphEdgeDirectionSchema,
12688
- edges: z10.array(
12689
- z10.discriminatedUnion("source", [
12745
+ edges: z11.array(
12746
+ z11.discriminatedUnion("source", [
12690
12747
  workGraphRelationEdgeSchema,
12691
12748
  workGraphDependencyEdgeSchema
12692
12749
  ])
@@ -12979,6 +13036,87 @@ var init_nexus_scope_map = __esm({
12979
13036
  }
12980
13037
  });
12981
13038
 
13039
+ // packages/contracts/src/operations/output-contracts-data.ts
13040
+ var TASK_MUTATION_DATA_SCHEMA, tasksAddOutputContract, tasksAddBatchOutputContract, tasksUpdateOutputContract, tasksCompleteOutputContract;
13041
+ var init_output_contracts_data = __esm({
13042
+ "packages/contracts/src/operations/output-contracts-data.ts"() {
13043
+ "use strict";
13044
+ TASK_MUTATION_DATA_SCHEMA = {
13045
+ type: "object",
13046
+ required: ["count", "created", "updated", "deleted"],
13047
+ additionalProperties: true,
13048
+ properties: {
13049
+ count: { type: "number", description: "Number of records the mutation affected." },
13050
+ created: {
13051
+ type: "array",
13052
+ description: 'Task IDs created by the mutation (bare strings, e.g. "T11692"). Empty for update/delete-only mutations.',
13053
+ items: { type: "string" }
13054
+ },
13055
+ updated: {
13056
+ type: "array",
13057
+ description: "Task IDs updated by the mutation (bare strings). Empty for create/delete-only mutations.",
13058
+ items: { type: "string" }
13059
+ },
13060
+ deleted: {
13061
+ type: "array",
13062
+ description: "Task IDs deleted by the mutation (bare strings). Empty for create/update-only mutations.",
13063
+ items: { type: "string" }
13064
+ },
13065
+ ids: {
13066
+ type: "array",
13067
+ description: "Deprecated alias for the non-empty bucket. Prefer created/updated/deleted.",
13068
+ items: { type: "string" }
13069
+ },
13070
+ dryRun: { type: "boolean", description: "True when this was a preview-only mutation." },
13071
+ status: { type: "string", description: "Post-mutation task status (add/update/complete)." }
13072
+ }
13073
+ };
13074
+ tasksAddOutputContract = {
13075
+ operation: "tasks.add",
13076
+ shapeNote: 'The created task ID (bare string) is at /data/created/0 \u2014 NOT /data/created/0/id. Example: /data/created/0 \u2192 "T11692".',
13077
+ dataSchema: { ...TASK_MUTATION_DATA_SCHEMA },
13078
+ fieldPointers: ["/data/created/0", "/data/count"]
13079
+ };
13080
+ tasksAddBatchOutputContract = {
13081
+ operation: "tasks.add-batch",
13082
+ shapeNote: "Atomic batch insert. Each created task ID (bare string) is in /data/created (array). Dry-run projections are at root: /data/wouldCreate and /data/insertedCount (=0). NOT under /data/dryRunSummary.",
13083
+ dataSchema: {
13084
+ type: "object",
13085
+ required: ["count", "created", "updated", "deleted"],
13086
+ additionalProperties: true,
13087
+ properties: {
13088
+ ...TASK_MUTATION_DATA_SCHEMA.properties,
13089
+ wouldCreate: {
13090
+ type: "number",
13091
+ description: "Dry-run: predicted write count. Present only when dryRun=true."
13092
+ },
13093
+ insertedCount: {
13094
+ type: "number",
13095
+ description: "Dry-run: always 0 (no DB write). Present only when dryRun=true."
13096
+ },
13097
+ wouldAffect: {
13098
+ type: "number",
13099
+ description: "Dry-run: generic affected count. Present only when dryRun=true."
13100
+ }
13101
+ }
13102
+ },
13103
+ fieldPointers: ["/data/created/0", "/data/count", "/data/wouldCreate", "/data/insertedCount"]
13104
+ };
13105
+ tasksUpdateOutputContract = {
13106
+ operation: "tasks.update",
13107
+ shapeNote: "The updated task ID (bare string) is at /data/updated/0 \u2014 NOT /data/updated/0/id. Use /data/status for the post-mutation status.",
13108
+ dataSchema: { ...TASK_MUTATION_DATA_SCHEMA },
13109
+ fieldPointers: ["/data/updated/0", "/data/status", "/data/count"]
13110
+ };
13111
+ tasksCompleteOutputContract = {
13112
+ operation: "tasks.complete",
13113
+ shapeNote: "Completion is a status mutation \u2014 the task ID (bare string) is at /data/updated/0 (status=done). Use /data/status for the post-mutation status.",
13114
+ dataSchema: { ...TASK_MUTATION_DATA_SCHEMA },
13115
+ fieldPointers: ["/data/updated/0", "/data/status", "/data/count"]
13116
+ };
13117
+ }
13118
+ });
13119
+
12982
13120
  // packages/contracts/src/peer.ts
12983
13121
  var init_peer = __esm({
12984
13122
  "packages/contracts/src/peer.ts"() {
@@ -12987,31 +13125,31 @@ var init_peer = __esm({
12987
13125
  });
12988
13126
 
12989
13127
  // packages/contracts/src/release/evidence-atoms.ts
12990
- import { z as z11 } from "zod";
13128
+ import { z as z12 } from "zod";
12991
13129
  var parsedPrEvidenceAtomSchema, prEvidenceStateModifierSchema, ghPrViewSchema, PR_REQUIRED_WORKFLOWS;
12992
13130
  var init_evidence_atoms = __esm({
12993
13131
  "packages/contracts/src/release/evidence-atoms.ts"() {
12994
13132
  "use strict";
12995
- parsedPrEvidenceAtomSchema = z11.object({
12996
- kind: z11.literal("pr"),
12997
- prNumber: z11.number().int().positive()
12998
- });
12999
- prEvidenceStateModifierSchema = z11.object({
13000
- kind: z11.literal("state"),
13001
- value: z11.literal("MERGED")
13002
- });
13003
- ghPrViewSchema = z11.object({
13004
- state: z11.enum(["OPEN", "CLOSED", "MERGED"]),
13005
- mergedAt: z11.string().nullable(),
13006
- headRefOid: z11.string().optional(),
13007
- mergeable: z11.string().optional(),
13008
- statusCheckRollup: z11.array(
13009
- z11.object({
13010
- __typename: z11.string().optional(),
13011
- name: z11.string().optional(),
13012
- workflowName: z11.string().optional(),
13013
- conclusion: z11.string().nullable().optional(),
13014
- status: z11.string().optional()
13133
+ parsedPrEvidenceAtomSchema = z12.object({
13134
+ kind: z12.literal("pr"),
13135
+ prNumber: z12.number().int().positive()
13136
+ });
13137
+ prEvidenceStateModifierSchema = z12.object({
13138
+ kind: z12.literal("state"),
13139
+ value: z12.literal("MERGED")
13140
+ });
13141
+ ghPrViewSchema = z12.object({
13142
+ state: z12.enum(["OPEN", "CLOSED", "MERGED"]),
13143
+ mergedAt: z12.string().nullable(),
13144
+ headRefOid: z12.string().optional(),
13145
+ mergeable: z12.string().optional(),
13146
+ statusCheckRollup: z12.array(
13147
+ z12.object({
13148
+ __typename: z12.string().optional(),
13149
+ name: z12.string().optional(),
13150
+ workflowName: z12.string().optional(),
13151
+ conclusion: z12.string().nullable().optional(),
13152
+ status: z12.string().optional()
13015
13153
  }).passthrough()
13016
13154
  ).optional().default([])
13017
13155
  }).passthrough();
@@ -13024,7 +13162,7 @@ var init_evidence_atoms = __esm({
13024
13162
  });
13025
13163
 
13026
13164
  // packages/contracts/src/release/plan.ts
13027
- import { z as z12 } from "zod";
13165
+ import { z as z13 } from "zod";
13028
13166
  var RELEASE_CHANNEL, RELEASE_SCHEME, RELEASE_KIND, RELEASE_STATUS, GATE_STATUS, GATE_NAME, PLATFORM_TUPLE, PUBLISHER, TASK_KIND, IMPACT, RESOLVED_SOURCE, ReleaseChannelSchema, ReleaseSchemeSchema, ReleaseKindSchema, ReleaseStatusSchema, GateStatusSchema, GateNameSchema, PlatformTupleSchema, PublisherSchema, TaskKindSchema, ImpactSchema, ResolvedSourceSchema, Iso8601, NonEmptyString, ReleasePlanTaskSchema, ReleaseGateSchema, ReleasePlatformMatrixEntrySchema, ReleasePreflightSummarySchema, ReleasePlanChangelogSchema, ReleasePlanMetaSchema, ReleasePlanSchema;
13029
13167
  var init_plan = __esm({
13030
13168
  "packages/contracts/src/release/plan.ts"() {
@@ -13067,20 +13205,20 @@ var init_plan = __esm({
13067
13205
  ];
13068
13206
  IMPACT = ["major", "minor", "patch"];
13069
13207
  RESOLVED_SOURCE = ["project-context", "language-default", "legacy-alias"];
13070
- ReleaseChannelSchema = z12.enum(RELEASE_CHANNEL);
13071
- ReleaseSchemeSchema = z12.enum(RELEASE_SCHEME);
13072
- ReleaseKindSchema = z12.enum(RELEASE_KIND);
13073
- ReleaseStatusSchema = z12.enum(RELEASE_STATUS);
13074
- GateStatusSchema = z12.enum(GATE_STATUS);
13075
- GateNameSchema = z12.enum(GATE_NAME);
13076
- PlatformTupleSchema = z12.enum(PLATFORM_TUPLE);
13077
- PublisherSchema = z12.enum(PUBLISHER);
13078
- TaskKindSchema = z12.enum(TASK_KIND);
13079
- ImpactSchema = z12.enum(IMPACT);
13080
- ResolvedSourceSchema = z12.enum(RESOLVED_SOURCE);
13081
- Iso8601 = z12.iso.datetime({ offset: true });
13082
- NonEmptyString = z12.string().min(1);
13083
- ReleasePlanTaskSchema = z12.object({
13208
+ ReleaseChannelSchema = z13.enum(RELEASE_CHANNEL);
13209
+ ReleaseSchemeSchema = z13.enum(RELEASE_SCHEME);
13210
+ ReleaseKindSchema = z13.enum(RELEASE_KIND);
13211
+ ReleaseStatusSchema = z13.enum(RELEASE_STATUS);
13212
+ GateStatusSchema = z13.enum(GATE_STATUS);
13213
+ GateNameSchema = z13.enum(GATE_NAME);
13214
+ PlatformTupleSchema = z13.enum(PLATFORM_TUPLE);
13215
+ PublisherSchema = z13.enum(PUBLISHER);
13216
+ TaskKindSchema = z13.enum(TASK_KIND);
13217
+ ImpactSchema = z13.enum(IMPACT);
13218
+ ResolvedSourceSchema = z13.enum(RESOLVED_SOURCE);
13219
+ Iso8601 = z13.iso.datetime({ offset: true });
13220
+ NonEmptyString = z13.string().min(1);
13221
+ ReleasePlanTaskSchema = z13.object({
13084
13222
  /** Task ID (e.g. "T10001"). Format intentionally loose so historical IDs validate. */
13085
13223
  id: NonEmptyString,
13086
13224
  /** Conventional-commit-aligned task classification. */
@@ -13088,20 +13226,20 @@ var init_plan = __esm({
13088
13226
  /** SemVer impact classification. */
13089
13227
  impact: ImpactSchema,
13090
13228
  /** Human-readable changelog line for this task. */
13091
- userFacingSummary: z12.string(),
13229
+ userFacingSummary: z13.string(),
13092
13230
  /**
13093
13231
  * ADR-051 evidence atoms attesting the task's gate results. Format is
13094
13232
  * `kind:value` (e.g. `commit:abc123`, `test-run:vitest.json`). The contract
13095
13233
  * accepts empty arrays so legacy plans validate; `cleo release plan`
13096
13234
  * enforces non-empty via R-301.
13097
13235
  */
13098
- evidenceAtoms: z12.array(NonEmptyString),
13236
+ evidenceAtoms: z13.array(NonEmptyString),
13099
13237
  /** IVTR phase at plan time — informational only per R-316. */
13100
- ivtrPhaseAtPlan: z12.string().optional(),
13238
+ ivtrPhaseAtPlan: z13.string().optional(),
13101
13239
  /** Epic this task rolls up to, locked at plan time per R-303. */
13102
13240
  epicAncestor: NonEmptyString
13103
13241
  });
13104
- ReleaseGateSchema = z12.object({
13242
+ ReleaseGateSchema = z13.object({
13105
13243
  /** Canonical gate name. */
13106
13244
  name: GateNameSchema,
13107
13245
  /** ADR-051 atom string identifying the resolved tool (e.g. `tool:test`). */
@@ -13111,11 +13249,11 @@ var init_plan = __esm({
13111
13249
  /** ISO-8601 timestamp the gate was last verified. */
13112
13250
  lastVerifiedAt: Iso8601,
13113
13251
  /** Resolved shell command (e.g. `pnpm run test`). Optional for unresolved gates. */
13114
- resolvedCommand: z12.string().optional(),
13252
+ resolvedCommand: z13.string().optional(),
13115
13253
  /** Provenance of the resolved command. Optional for unresolved gates. */
13116
13254
  resolvedSource: ResolvedSourceSchema.optional()
13117
13255
  });
13118
- ReleasePlatformMatrixEntrySchema = z12.object({
13256
+ ReleasePlatformMatrixEntrySchema = z13.object({
13119
13257
  /** Target platform tuple. */
13120
13258
  platform: PlatformTupleSchema,
13121
13259
  /** Distribution backend. */
@@ -13123,47 +13261,47 @@ var init_plan = __esm({
13123
13261
  /** Package identifier on the target backend (e.g. `@cleocode/cleo`). */
13124
13262
  package: NonEmptyString,
13125
13263
  /** Whether to run the GHA smoke job for this matrix entry. */
13126
- smoke: z12.boolean().default(true).optional()
13264
+ smoke: z13.boolean().default(true).optional()
13127
13265
  });
13128
- ReleasePreflightSummarySchema = z12.object({
13266
+ ReleasePreflightSummarySchema = z13.object({
13129
13267
  /** True if esbuild externals are out of sync with package.json. */
13130
- esbuildExternalsDrift: z12.boolean(),
13268
+ esbuildExternalsDrift: z13.boolean(),
13131
13269
  /** True if `pnpm-lock.yaml` diverges from the workspace manifest. */
13132
- lockfileDrift: z12.boolean(),
13270
+ lockfileDrift: z13.boolean(),
13133
13271
  /** True if all epic children are in terminal lifecycle states. */
13134
- epicCompletenessClean: z12.boolean(),
13272
+ epicCompletenessClean: z13.boolean(),
13135
13273
  /** True if no task appears in multiple in-flight release plans. */
13136
- doubleListingClean: z12.boolean(),
13274
+ doubleListingClean: z13.boolean(),
13137
13275
  /** Non-fatal preflight warnings (e.g. unresolved tools per R-024). */
13138
- preflightWarnings: z12.array(z12.string()).default([]).optional()
13276
+ preflightWarnings: z13.array(z13.string()).default([]).optional()
13139
13277
  });
13140
- ReleasePlanChangelogSchema = z12.object({
13278
+ ReleasePlanChangelogSchema = z13.object({
13141
13279
  /** `kind=feat` tasks. */
13142
- features: z12.array(NonEmptyString).default([]),
13280
+ features: z13.array(NonEmptyString).default([]),
13143
13281
  /** `kind=fix` or `kind=hotfix` tasks. */
13144
- fixes: z12.array(NonEmptyString).default([]),
13282
+ fixes: z13.array(NonEmptyString).default([]),
13145
13283
  /** `kind=chore`, `docs`, `refactor`, `test`, `perf` tasks. */
13146
- chores: z12.array(NonEmptyString).default([]),
13284
+ chores: z13.array(NonEmptyString).default([]),
13147
13285
  /** `kind=breaking` or `kind=revert` tasks. */
13148
- breaking: z12.array(NonEmptyString).default([])
13286
+ breaking: z13.array(NonEmptyString).default([])
13149
13287
  });
13150
- ReleasePlanMetaSchema = z12.object({
13288
+ ReleasePlanMetaSchema = z13.object({
13151
13289
  /** True if this is the project's first ever release. */
13152
- firstEverRelease: z12.boolean().optional(),
13290
+ firstEverRelease: z13.boolean().optional(),
13153
13291
  /** Canonical tool names that could not be resolved at plan time. */
13154
- unresolvedTools: z12.array(z12.string()).optional(),
13292
+ unresolvedTools: z13.array(z13.string()).optional(),
13155
13293
  /** Project archetype detected at plan time. */
13156
- archetype: z12.string().optional()
13157
- }).catchall(z12.unknown());
13158
- ReleasePlanSchema = z12.object({
13294
+ archetype: z13.string().optional()
13295
+ }).catchall(z13.unknown());
13296
+ ReleasePlanSchema = z13.object({
13159
13297
  /** Schema URL for this plan version. */
13160
- $schema: z12.string().optional(),
13298
+ $schema: z13.string().optional(),
13161
13299
  /** Requested version string (e.g. "v2026.6.0"). Includes the leading `v`. */
13162
13300
  version: NonEmptyString,
13163
13301
  /** Resolved version string after suffix application (e.g. "v2026.6.0.2"). */
13164
13302
  resolvedVersion: NonEmptyString,
13165
13303
  /** True if a `calver-suffix` was applied to disambiguate a same-day hotfix. */
13166
- suffixApplied: z12.boolean(),
13304
+ suffixApplied: z13.boolean(),
13167
13305
  /** Versioning scheme governing `version` / `resolvedVersion`. */
13168
13306
  scheme: ReleaseSchemeSchema,
13169
13307
  /** npm dist-tag channel for this release. */
@@ -13180,27 +13318,27 @@ var init_plan = __esm({
13180
13318
  * Version of the previous release on the same channel. MUST be `null` only
13181
13319
  * for first-ever releases (R-300, enforced at the verb layer).
13182
13320
  */
13183
- previousVersion: z12.string().nullable(),
13321
+ previousVersion: z13.string().nullable(),
13184
13322
  /** Git tag of the previous release (typically `previousVersion` prefixed). */
13185
- previousTag: z12.string().nullable(),
13323
+ previousTag: z13.string().nullable(),
13186
13324
  /** ISO-8601 timestamp the previous release was published. */
13187
13325
  previousShippedAt: Iso8601.nullable(),
13188
13326
  /** Tasks rolled into this release. */
13189
- tasks: z12.array(ReleasePlanTaskSchema),
13327
+ tasks: z13.array(ReleasePlanTaskSchema),
13190
13328
  /** Bucketed changelog. */
13191
13329
  changelog: ReleasePlanChangelogSchema,
13192
13330
  /** Per-gate verification status. */
13193
- gates: z12.array(ReleaseGateSchema),
13331
+ gates: z13.array(ReleaseGateSchema),
13194
13332
  /** Platform / publisher matrix. */
13195
- platformMatrix: z12.array(ReleasePlatformMatrixEntrySchema),
13333
+ platformMatrix: z13.array(ReleasePlatformMatrixEntrySchema),
13196
13334
  /** Preflight summary from `cleo release plan`. */
13197
13335
  preflightSummary: ReleasePreflightSummarySchema,
13198
13336
  /** URL of the GHA workflow run (populated by `release-prepare.yml`). */
13199
- workflowRunUrl: z12.string().nullable(),
13337
+ workflowRunUrl: z13.string().nullable(),
13200
13338
  /** URL of the bump PR (populated by `cleo release open`). */
13201
- prUrl: z12.string().nullable(),
13339
+ prUrl: z13.string().nullable(),
13202
13340
  /** Merge commit SHA on `main` (populated by `release-publish.yml`). */
13203
- mergeCommitSha: z12.string().nullable(),
13341
+ mergeCommitSha: z13.string().nullable(),
13204
13342
  /** Current FSM state per R-302. */
13205
13343
  status: ReleaseStatusSchema,
13206
13344
  /** Informational / forward-compat metadata. */
@@ -13256,52 +13394,52 @@ var init_session2 = __esm({
13256
13394
  });
13257
13395
 
13258
13396
  // packages/contracts/src/session-journal.ts
13259
- import { z as z13 } from "zod";
13397
+ import { z as z14 } from "zod";
13260
13398
  var SESSION_JOURNAL_SCHEMA_VERSION, sessionJournalDoctorSummarySchema, sessionJournalDebriefSummarySchema, sessionJournalEntrySchema;
13261
13399
  var init_session_journal = __esm({
13262
13400
  "packages/contracts/src/session-journal.ts"() {
13263
13401
  "use strict";
13264
13402
  SESSION_JOURNAL_SCHEMA_VERSION = "1.0";
13265
- sessionJournalDoctorSummarySchema = z13.object({
13403
+ sessionJournalDoctorSummarySchema = z14.object({
13266
13404
  /** `true` when zero noise patterns were detected. */
13267
- isClean: z13.boolean(),
13405
+ isClean: z14.boolean(),
13268
13406
  /** Total number of noise findings across all patterns. */
13269
- findingsCount: z13.number().int().nonnegative(),
13407
+ findingsCount: z14.number().int().nonnegative(),
13270
13408
  /** Pattern names that were detected (empty when isClean). */
13271
- patterns: z13.array(z13.string()),
13409
+ patterns: z14.array(z14.string()),
13272
13410
  /** Total brain entries scanned. `0` = empty or unavailable. */
13273
- totalScanned: z13.number().int().nonnegative()
13411
+ totalScanned: z14.number().int().nonnegative()
13274
13412
  });
13275
- sessionJournalDebriefSummarySchema = z13.object({
13413
+ sessionJournalDebriefSummarySchema = z14.object({
13276
13414
  /** First 200 characters of the session end note (if provided). */
13277
- noteExcerpt: z13.string().max(200).optional(),
13415
+ noteExcerpt: z14.string().max(200).optional(),
13278
13416
  /** Number of tasks completed during the session. */
13279
- tasksCompletedCount: z13.number().int().nonnegative(),
13417
+ tasksCompletedCount: z14.number().int().nonnegative(),
13280
13418
  /** Up to 5 task IDs (not titles) that were the focus of the session. */
13281
- tasksFocused: z13.array(z13.string()).max(5).optional()
13419
+ tasksFocused: z14.array(z14.string()).max(5).optional()
13282
13420
  });
13283
- sessionJournalEntrySchema = z13.object({
13421
+ sessionJournalEntrySchema = z14.object({
13284
13422
  // Identity
13285
13423
  /** Schema version for forward-compatibility. Always `'1.0'` in this release. */
13286
- schemaVersion: z13.literal(SESSION_JOURNAL_SCHEMA_VERSION),
13424
+ schemaVersion: z14.literal(SESSION_JOURNAL_SCHEMA_VERSION),
13287
13425
  /** ISO 8601 timestamp when the entry was written. */
13288
- timestamp: z13.string(),
13426
+ timestamp: z14.string(),
13289
13427
  /** CLEO session ID (e.g. `ses_20260424055456_ede571`). */
13290
- sessionId: z13.string(),
13428
+ sessionId: z14.string(),
13291
13429
  /** Event type that triggered this journal entry. */
13292
- eventType: z13.enum(["session_start", "session_end", "observation", "decision", "error"]),
13430
+ eventType: z14.enum(["session_start", "session_end", "observation", "decision", "error"]),
13293
13431
  // Session metadata (set on session_start / session_end)
13294
13432
  /** Agent identifier (e.g. `cleo-prime`, `claude-code`). */
13295
- agentIdentifier: z13.string().optional(),
13433
+ agentIdentifier: z14.string().optional(),
13296
13434
  /** Provider adapter ID active for this session. */
13297
- providerId: z13.string().optional(),
13435
+ providerId: z14.string().optional(),
13298
13436
  /** Session scope string (e.g. `'global'` or `'epic:T1263'`). */
13299
- scope: z13.string().optional(),
13437
+ scope: z14.string().optional(),
13300
13438
  // Session-end fields
13301
13439
  /** Duration of the session in seconds (session_end only). */
13302
- duration: z13.number().int().nonnegative().optional(),
13440
+ duration: z14.number().int().nonnegative().optional(),
13303
13441
  /** Task IDs (not titles) completed during the session. */
13304
- tasksCompleted: z13.array(z13.string()).optional(),
13442
+ tasksCompleted: z14.array(z14.string()).optional(),
13305
13443
  // Doctor summary (T1262 absorbed)
13306
13444
  /** Compact result of `scanBrainNoise` run at session-end. */
13307
13445
  doctorSummary: sessionJournalDoctorSummarySchema.optional(),
@@ -13310,7 +13448,7 @@ var init_session_journal = __esm({
13310
13448
  debriefSummary: sessionJournalDebriefSummarySchema.optional(),
13311
13449
  // Optional hash chain
13312
13450
  /** SHA-256 hex of the previous entry's raw JSON string (for integrity chain). */
13313
- prevEntryHash: z13.string().optional()
13451
+ prevEntryHash: z14.string().optional()
13314
13452
  });
13315
13453
  }
13316
13454
  });
@@ -13323,52 +13461,52 @@ var init_task = __esm({
13323
13461
  });
13324
13462
 
13325
13463
  // packages/contracts/src/task-evidence.ts
13326
- import { z as z14 } from "zod";
13464
+ import { z as z15 } from "zod";
13327
13465
  var fileEvidenceSchema, logEvidenceSchema, screenshotEvidenceSchema, testOutputEvidenceSchema, commandOutputEvidenceSchema, taskEvidenceSchema;
13328
13466
  var init_task_evidence = __esm({
13329
13467
  "packages/contracts/src/task-evidence.ts"() {
13330
13468
  "use strict";
13331
- fileEvidenceSchema = z14.object({
13332
- kind: z14.literal("file"),
13333
- sha256: z14.string().length(64),
13334
- timestamp: z14.string().datetime(),
13335
- path: z14.string().min(1),
13336
- mime: z14.string().optional(),
13337
- description: z14.string().optional()
13338
- });
13339
- logEvidenceSchema = z14.object({
13340
- kind: z14.literal("log"),
13341
- sha256: z14.string().length(64),
13342
- timestamp: z14.string().datetime(),
13343
- source: z14.string().min(1),
13344
- description: z14.string().optional()
13345
- });
13346
- screenshotEvidenceSchema = z14.object({
13347
- kind: z14.literal("screenshot"),
13348
- sha256: z14.string().length(64),
13349
- timestamp: z14.string().datetime(),
13350
- mime: z14.enum(["image/png", "image/jpeg", "image/webp"]).optional(),
13351
- description: z14.string().optional()
13352
- });
13353
- testOutputEvidenceSchema = z14.object({
13354
- kind: z14.literal("test-output"),
13355
- sha256: z14.string().length(64),
13356
- timestamp: z14.string().datetime(),
13357
- passed: z14.number().int().nonnegative(),
13358
- failed: z14.number().int().nonnegative(),
13359
- skipped: z14.number().int().nonnegative(),
13360
- exitCode: z14.number().int(),
13361
- description: z14.string().optional()
13362
- });
13363
- commandOutputEvidenceSchema = z14.object({
13364
- kind: z14.literal("command-output"),
13365
- sha256: z14.string().length(64),
13366
- timestamp: z14.string().datetime(),
13367
- cmd: z14.string().min(1),
13368
- exitCode: z14.number().int(),
13369
- description: z14.string().optional()
13370
- });
13371
- taskEvidenceSchema = z14.discriminatedUnion("kind", [
13469
+ fileEvidenceSchema = z15.object({
13470
+ kind: z15.literal("file"),
13471
+ sha256: z15.string().length(64),
13472
+ timestamp: z15.string().datetime(),
13473
+ path: z15.string().min(1),
13474
+ mime: z15.string().optional(),
13475
+ description: z15.string().optional()
13476
+ });
13477
+ logEvidenceSchema = z15.object({
13478
+ kind: z15.literal("log"),
13479
+ sha256: z15.string().length(64),
13480
+ timestamp: z15.string().datetime(),
13481
+ source: z15.string().min(1),
13482
+ description: z15.string().optional()
13483
+ });
13484
+ screenshotEvidenceSchema = z15.object({
13485
+ kind: z15.literal("screenshot"),
13486
+ sha256: z15.string().length(64),
13487
+ timestamp: z15.string().datetime(),
13488
+ mime: z15.enum(["image/png", "image/jpeg", "image/webp"]).optional(),
13489
+ description: z15.string().optional()
13490
+ });
13491
+ testOutputEvidenceSchema = z15.object({
13492
+ kind: z15.literal("test-output"),
13493
+ sha256: z15.string().length(64),
13494
+ timestamp: z15.string().datetime(),
13495
+ passed: z15.number().int().nonnegative(),
13496
+ failed: z15.number().int().nonnegative(),
13497
+ skipped: z15.number().int().nonnegative(),
13498
+ exitCode: z15.number().int(),
13499
+ description: z15.string().optional()
13500
+ });
13501
+ commandOutputEvidenceSchema = z15.object({
13502
+ kind: z15.literal("command-output"),
13503
+ sha256: z15.string().length(64),
13504
+ timestamp: z15.string().datetime(),
13505
+ cmd: z15.string().min(1),
13506
+ exitCode: z15.number().int(),
13507
+ description: z15.string().optional()
13508
+ });
13509
+ taskEvidenceSchema = z15.discriminatedUnion("kind", [
13372
13510
  fileEvidenceSchema,
13373
13511
  logEvidenceSchema,
13374
13512
  screenshotEvidenceSchema,
@@ -13379,12 +13517,12 @@ var init_task_evidence = __esm({
13379
13517
  });
13380
13518
 
13381
13519
  // packages/contracts/src/tasks/archive.ts
13382
- import { z as z15 } from "zod";
13520
+ import { z as z16 } from "zod";
13383
13521
  var ArchiveReason, ARCHIVE_REASON_VALUES;
13384
13522
  var init_archive = __esm({
13385
13523
  "packages/contracts/src/tasks/archive.ts"() {
13386
13524
  "use strict";
13387
- ArchiveReason = z15.enum([
13525
+ ArchiveReason = z16.enum([
13388
13526
  "verified",
13389
13527
  "reconciled",
13390
13528
  "superseded",
@@ -13397,47 +13535,47 @@ var init_archive = __esm({
13397
13535
  });
13398
13536
 
13399
13537
  // packages/contracts/src/tasks.ts
13400
- import { z as z16 } from "zod";
13538
+ import { z as z17 } from "zod";
13401
13539
  var taskMutationWarningSeveritySchema, taskMutationWarningSchema, taskMutationDryRunSummarySchema, taskMutationTaskRecordSchema, taskMutationEnvelopeSchema, completionTaskStatusSchema, completionCriterionKindSchema, completionCriterionStatusSchema, completionBlockerReasonSchema, completionStaleReasonSchema, completionProjectionRepairErrorCodeSchema, completionCriterionWaiverSchema, completionCriterionReplacementSchema, completionCriterionEvaluationSchema, unsatisfiedCompletionCriterionSchema, completionTotalsSchema, completionContextPackSchema, completionEvaluationSchema, completionExplanationSchema, completionListParamsSchema, completionListResultSchema, completionEvaluateParamsSchema, completionProjectionRepairErrorSchema, completionProjectionRepairParamsSchema, completionProjectionRepairResultSchema;
13402
13540
  var init_tasks2 = __esm({
13403
13541
  "packages/contracts/src/tasks.ts"() {
13404
13542
  "use strict";
13405
13543
  init_status_registry();
13406
- taskMutationWarningSeveritySchema = z16.enum(["info", "warning"]);
13407
- taskMutationWarningSchema = z16.object({
13408
- code: z16.string().min(1),
13409
- message: z16.string().min(1),
13544
+ taskMutationWarningSeveritySchema = z17.enum(["info", "warning"]);
13545
+ taskMutationWarningSchema = z17.object({
13546
+ code: z17.string().min(1),
13547
+ message: z17.string().min(1),
13410
13548
  severity: taskMutationWarningSeveritySchema.optional(),
13411
- taskId: z16.string().min(1).optional(),
13412
- field: z16.string().min(1).optional(),
13413
- index: z16.number().int().nonnegative().optional()
13414
- });
13415
- taskMutationDryRunSummarySchema = z16.object({
13416
- dryRun: z16.literal(true),
13417
- wouldCreate: z16.number().int().nonnegative(),
13418
- wouldUpdate: z16.number().int().nonnegative(),
13419
- wouldDelete: z16.number().int().nonnegative(),
13420
- wouldAffect: z16.number().int().nonnegative(),
13421
- validatedCount: z16.number().int().nonnegative(),
13422
- insertedCount: z16.literal(0),
13423
- updatedCount: z16.literal(0),
13424
- deletedCount: z16.literal(0),
13425
- warnings: z16.array(taskMutationWarningSchema)
13426
- });
13427
- taskMutationTaskRecordSchema = z16.object({ id: z16.string().min(1) }).passthrough();
13428
- taskMutationEnvelopeSchema = z16.object({
13429
- dryRun: z16.boolean().optional(),
13430
- created: z16.array(taskMutationTaskRecordSchema),
13431
- updated: z16.array(taskMutationTaskRecordSchema),
13432
- deleted: z16.array(taskMutationTaskRecordSchema),
13433
- affectedCount: z16.number().int().nonnegative(),
13434
- mutationWarnings: z16.array(taskMutationWarningSchema),
13549
+ taskId: z17.string().min(1).optional(),
13550
+ field: z17.string().min(1).optional(),
13551
+ index: z17.number().int().nonnegative().optional()
13552
+ });
13553
+ taskMutationDryRunSummarySchema = z17.object({
13554
+ dryRun: z17.literal(true),
13555
+ wouldCreate: z17.number().int().nonnegative(),
13556
+ wouldUpdate: z17.number().int().nonnegative(),
13557
+ wouldDelete: z17.number().int().nonnegative(),
13558
+ wouldAffect: z17.number().int().nonnegative(),
13559
+ validatedCount: z17.number().int().nonnegative(),
13560
+ insertedCount: z17.literal(0),
13561
+ updatedCount: z17.literal(0),
13562
+ deletedCount: z17.literal(0),
13563
+ warnings: z17.array(taskMutationWarningSchema)
13564
+ });
13565
+ taskMutationTaskRecordSchema = z17.object({ id: z17.string().min(1) }).passthrough();
13566
+ taskMutationEnvelopeSchema = z17.object({
13567
+ dryRun: z17.boolean().optional(),
13568
+ created: z17.array(taskMutationTaskRecordSchema),
13569
+ updated: z17.array(taskMutationTaskRecordSchema),
13570
+ deleted: z17.array(taskMutationTaskRecordSchema),
13571
+ affectedCount: z17.number().int().nonnegative(),
13572
+ mutationWarnings: z17.array(taskMutationWarningSchema),
13435
13573
  dryRunSummary: taskMutationDryRunSummarySchema.optional()
13436
13574
  });
13437
- completionTaskStatusSchema = z16.enum(TASK_STATUSES);
13438
- completionCriterionKindSchema = z16.enum(["text", "evidence_bound", "child_task"]);
13439
- completionCriterionStatusSchema = z16.enum(["satisfied", "unsatisfied", "waived", "replaced"]);
13440
- completionBlockerReasonSchema = z16.enum([
13575
+ completionTaskStatusSchema = z17.enum(TASK_STATUSES);
13576
+ completionCriterionKindSchema = z17.enum(["text", "evidence_bound", "child_task"]);
13577
+ completionCriterionStatusSchema = z17.enum(["satisfied", "unsatisfied", "waived", "replaced"]);
13578
+ completionBlockerReasonSchema = z17.enum([
13441
13579
  "missing_evidence_binding",
13442
13580
  "child_not_done",
13443
13581
  "child_cancelled_requires_waiver",
@@ -13445,68 +13583,68 @@ var init_tasks2 = __esm({
13445
13583
  "child_missing",
13446
13584
  "done_parent_stale"
13447
13585
  ]);
13448
- completionStaleReasonSchema = z16.enum(["done_parent_has_unsatisfied_criteria"]);
13449
- completionProjectionRepairErrorCodeSchema = z16.enum([
13586
+ completionStaleReasonSchema = z17.enum(["done_parent_has_unsatisfied_criteria"]);
13587
+ completionProjectionRepairErrorCodeSchema = z17.enum([
13450
13588
  "projection_not_stale",
13451
13589
  "criteria_missing",
13452
13590
  "binding_target_missing",
13453
13591
  "repair_conflict"
13454
13592
  ]);
13455
- completionCriterionWaiverSchema = z16.object({
13456
- criterionAcId: z16.string().min(1),
13457
- childTaskId: z16.string().min(1),
13458
- reason: z16.string().min(1),
13459
- actor: z16.string().min(1),
13460
- waivedAt: z16.string().min(1)
13461
- });
13462
- completionCriterionReplacementSchema = z16.object({
13463
- criterionAcId: z16.string().min(1),
13464
- originalChildTaskId: z16.string().min(1),
13465
- replacementChildTaskId: z16.string().min(1),
13466
- reason: z16.string().min(1),
13467
- actor: z16.string().min(1),
13468
- replacedAt: z16.string().min(1)
13469
- });
13470
- completionCriterionEvaluationSchema = z16.object({
13471
- acId: z16.string().min(1),
13472
- alias: z16.string().min(1),
13473
- text: z16.string(),
13593
+ completionCriterionWaiverSchema = z17.object({
13594
+ criterionAcId: z17.string().min(1),
13595
+ childTaskId: z17.string().min(1),
13596
+ reason: z17.string().min(1),
13597
+ actor: z17.string().min(1),
13598
+ waivedAt: z17.string().min(1)
13599
+ });
13600
+ completionCriterionReplacementSchema = z17.object({
13601
+ criterionAcId: z17.string().min(1),
13602
+ originalChildTaskId: z17.string().min(1),
13603
+ replacementChildTaskId: z17.string().min(1),
13604
+ reason: z17.string().min(1),
13605
+ actor: z17.string().min(1),
13606
+ replacedAt: z17.string().min(1)
13607
+ });
13608
+ completionCriterionEvaluationSchema = z17.object({
13609
+ acId: z17.string().min(1),
13610
+ alias: z17.string().min(1),
13611
+ text: z17.string(),
13474
13612
  kind: completionCriterionKindSchema,
13475
13613
  status: completionCriterionStatusSchema,
13476
13614
  reason: completionBlockerReasonSchema.optional(),
13477
- targetTaskId: z16.string().min(1).optional(),
13615
+ targetTaskId: z17.string().min(1).optional(),
13478
13616
  targetTaskStatus: completionTaskStatusSchema.optional(),
13479
13617
  waiver: completionCriterionWaiverSchema.optional(),
13480
13618
  replacement: completionCriterionReplacementSchema.optional(),
13481
13619
  replacementTaskStatus: completionTaskStatusSchema.optional(),
13482
- evidenceBindings: z16.number().int().nonnegative()
13620
+ evidenceBindings: z17.number().int().nonnegative()
13483
13621
  });
13484
13622
  unsatisfiedCompletionCriterionSchema = completionCriterionEvaluationSchema.extend({
13485
- status: z16.literal("unsatisfied"),
13623
+ status: z17.literal("unsatisfied"),
13486
13624
  reason: completionBlockerReasonSchema
13487
13625
  });
13488
- completionTotalsSchema = z16.object({
13489
- criteria: z16.number().int().nonnegative(),
13490
- satisfied: z16.number().int().nonnegative(),
13491
- unsatisfied: z16.number().int().nonnegative(),
13492
- waived: z16.number().int().nonnegative(),
13493
- replaced: z16.number().int().nonnegative()
13494
- });
13495
- completionContextPackSchema = z16.object({
13496
- taskId: z16.string().min(1),
13497
- generatedAt: z16.string().min(1),
13498
- source: z16.literal("audit_log"),
13499
- window: z16.object({
13500
- limit: z16.number().int().positive(),
13501
- since: z16.string().min(1).optional(),
13502
- relationDepth: z16.number().int().nonnegative(),
13503
- relatedTaskIds: z16.array(z16.string().min(1))
13626
+ completionTotalsSchema = z17.object({
13627
+ criteria: z17.number().int().nonnegative(),
13628
+ satisfied: z17.number().int().nonnegative(),
13629
+ unsatisfied: z17.number().int().nonnegative(),
13630
+ waived: z17.number().int().nonnegative(),
13631
+ replaced: z17.number().int().nonnegative()
13632
+ });
13633
+ completionContextPackSchema = z17.object({
13634
+ taskId: z17.string().min(1),
13635
+ generatedAt: z17.string().min(1),
13636
+ source: z17.literal("audit_log"),
13637
+ window: z17.object({
13638
+ limit: z17.number().int().positive(),
13639
+ since: z17.string().min(1).optional(),
13640
+ relationDepth: z17.number().int().nonnegative(),
13641
+ relatedTaskIds: z17.array(z17.string().min(1))
13504
13642
  }),
13505
- events: z16.array(
13506
- z16.object({
13507
- id: z16.string().min(1),
13508
- timestamp: z16.string().min(1),
13509
- action: z16.enum([
13643
+ events: z17.array(
13644
+ z17.object({
13645
+ id: z17.string().min(1),
13646
+ timestamp: z17.string().min(1),
13647
+ action: z17.enum([
13510
13648
  "task_completed",
13511
13649
  "task_reopened",
13512
13650
  "task_cancelled",
@@ -13514,77 +13652,77 @@ var init_tasks2 = __esm({
13514
13652
  "task_reparented",
13515
13653
  "ac_projection_rebuilt"
13516
13654
  ]),
13517
- taskId: z16.string().min(1),
13518
- relation: z16.enum(["self", "parent", "child", "sibling", "related"]),
13519
- actor: z16.string().min(1),
13520
- details: z16.record(z16.string(), z16.unknown()).optional(),
13521
- before: z16.record(z16.string(), z16.unknown()).optional(),
13522
- after: z16.record(z16.string(), z16.unknown()).optional()
13655
+ taskId: z17.string().min(1),
13656
+ relation: z17.enum(["self", "parent", "child", "sibling", "related"]),
13657
+ actor: z17.string().min(1),
13658
+ details: z17.record(z17.string(), z17.unknown()).optional(),
13659
+ before: z17.record(z17.string(), z17.unknown()).optional(),
13660
+ after: z17.record(z17.string(), z17.unknown()).optional()
13523
13661
  })
13524
13662
  ),
13525
- summary: z16.object({
13526
- totalEvents: z16.number().int().nonnegative(),
13527
- byAction: z16.record(z16.string(), z16.number().int().nonnegative()),
13528
- byRelation: z16.record(z16.string(), z16.number().int().nonnegative()),
13529
- latestEventAt: z16.string().nullable()
13663
+ summary: z17.object({
13664
+ totalEvents: z17.number().int().nonnegative(),
13665
+ byAction: z17.record(z17.string(), z17.number().int().nonnegative()),
13666
+ byRelation: z17.record(z17.string(), z17.number().int().nonnegative()),
13667
+ latestEventAt: z17.string().nullable()
13530
13668
  })
13531
13669
  });
13532
- completionEvaluationSchema = z16.object({
13533
- taskId: z16.string().min(1),
13670
+ completionEvaluationSchema = z17.object({
13671
+ taskId: z17.string().min(1),
13534
13672
  taskStatus: completionTaskStatusSchema,
13535
- ready: z16.boolean(),
13536
- stale: z16.boolean(),
13537
- staleReasons: z16.array(completionStaleReasonSchema),
13673
+ ready: z17.boolean(),
13674
+ stale: z17.boolean(),
13675
+ staleReasons: z17.array(completionStaleReasonSchema),
13538
13676
  contextPack: completionContextPackSchema.optional(),
13539
- satisfied: z16.array(completionCriterionEvaluationSchema),
13540
- unsatisfied: z16.array(unsatisfiedCompletionCriterionSchema),
13541
- waived: z16.array(completionCriterionEvaluationSchema),
13542
- replaced: z16.array(completionCriterionEvaluationSchema),
13677
+ satisfied: z17.array(completionCriterionEvaluationSchema),
13678
+ unsatisfied: z17.array(unsatisfiedCompletionCriterionSchema),
13679
+ waived: z17.array(completionCriterionEvaluationSchema),
13680
+ replaced: z17.array(completionCriterionEvaluationSchema),
13543
13681
  totals: completionTotalsSchema
13544
13682
  });
13545
- completionExplanationSchema = z16.object({
13546
- taskId: z16.string().min(1),
13547
- ready: z16.boolean(),
13548
- stale: z16.boolean(),
13549
- summary: z16.string(),
13683
+ completionExplanationSchema = z17.object({
13684
+ taskId: z17.string().min(1),
13685
+ ready: z17.boolean(),
13686
+ stale: z17.boolean(),
13687
+ summary: z17.string(),
13550
13688
  contextPack: completionContextPackSchema.optional(),
13551
- blockers: z16.array(completionCriterionEvaluationSchema)
13689
+ blockers: z17.array(completionCriterionEvaluationSchema)
13552
13690
  });
13553
- completionListParamsSchema = z16.object({
13554
- taskId: z16.string().min(1),
13691
+ completionListParamsSchema = z17.object({
13692
+ taskId: z17.string().min(1),
13555
13693
  status: completionCriterionStatusSchema.optional(),
13556
13694
  kind: completionCriterionKindSchema.optional()
13557
13695
  });
13558
- completionListResultSchema = z16.object({
13559
- taskId: z16.string().min(1),
13560
- criteria: z16.array(completionCriterionEvaluationSchema),
13696
+ completionListResultSchema = z17.object({
13697
+ taskId: z17.string().min(1),
13698
+ criteria: z17.array(completionCriterionEvaluationSchema),
13561
13699
  totals: completionTotalsSchema
13562
13700
  });
13563
- completionEvaluateParamsSchema = z16.object({
13564
- taskId: z16.string().min(1),
13565
- includeContext: z16.boolean().optional(),
13566
- limit: z16.number().int().positive().optional(),
13567
- since: z16.string().min(1).optional(),
13568
- relationDepth: z16.number().int().nonnegative().optional()
13701
+ completionEvaluateParamsSchema = z17.object({
13702
+ taskId: z17.string().min(1),
13703
+ includeContext: z17.boolean().optional(),
13704
+ limit: z17.number().int().positive().optional(),
13705
+ since: z17.string().min(1).optional(),
13706
+ relationDepth: z17.number().int().nonnegative().optional()
13569
13707
  });
13570
- completionProjectionRepairErrorSchema = z16.object({
13708
+ completionProjectionRepairErrorSchema = z17.object({
13571
13709
  code: completionProjectionRepairErrorCodeSchema,
13572
- message: z16.string().min(1),
13573
- taskId: z16.string().min(1),
13574
- acId: z16.string().min(1).optional(),
13575
- evidenceAtomId: z16.string().min(1).optional()
13710
+ message: z17.string().min(1),
13711
+ taskId: z17.string().min(1),
13712
+ acId: z17.string().min(1).optional(),
13713
+ evidenceAtomId: z17.string().min(1).optional()
13576
13714
  });
13577
- completionProjectionRepairParamsSchema = z16.object({
13578
- taskId: z16.string().min(1),
13579
- dryRun: z16.boolean().optional()
13715
+ completionProjectionRepairParamsSchema = z17.object({
13716
+ taskId: z17.string().min(1),
13717
+ dryRun: z17.boolean().optional()
13580
13718
  });
13581
- completionProjectionRepairResultSchema = z16.object({
13582
- taskId: z16.string().min(1),
13583
- repaired: z16.boolean(),
13584
- dryRun: z16.boolean(),
13585
- staleBefore: z16.boolean(),
13586
- staleAfter: z16.boolean(),
13587
- errors: z16.array(completionProjectionRepairErrorSchema)
13719
+ completionProjectionRepairResultSchema = z17.object({
13720
+ taskId: z17.string().min(1),
13721
+ repaired: z17.boolean(),
13722
+ dryRun: z17.boolean(),
13723
+ staleBefore: z17.boolean(),
13724
+ staleAfter: z17.boolean(),
13725
+ errors: z17.array(completionProjectionRepairErrorSchema)
13588
13726
  });
13589
13727
  }
13590
13728
  });
@@ -14095,7 +14233,7 @@ var init_taxonomy = __esm({
14095
14233
  });
14096
14234
 
14097
14235
  // packages/contracts/src/templates/manifest.ts
14098
- import { z as z17 } from "zod";
14236
+ import { z as z18 } from "zod";
14099
14237
  var TEMPLATE_KINDS, TEMPLATE_SUBSTITUTIONS, TEMPLATE_UPDATE_STRATEGIES, PLACEHOLDER_SOURCES, PlaceholderSpecSchema, TemplateManifestEntrySchema;
14100
14238
  var init_manifest2 = __esm({
14101
14239
  "packages/contracts/src/templates/manifest.ts"() {
@@ -14116,85 +14254,85 @@ var init_manifest2 = __esm({
14116
14254
  "tool-resolver",
14117
14255
  "literal"
14118
14256
  ];
14119
- PlaceholderSpecSchema = z17.object({
14257
+ PlaceholderSpecSchema = z18.object({
14120
14258
  /**
14121
14259
  * Placeholder identifier as it appears in the template body
14122
14260
  * (e.g. `NODE_VERSION` matches `{{NODE_VERSION}}`).
14123
14261
  */
14124
- name: z17.string().min(1, "placeholder name must be non-empty"),
14262
+ name: z18.string().min(1, "placeholder name must be non-empty"),
14125
14263
  /** Resolver source the installer consults for this placeholder. */
14126
- source: z17.enum(PLACEHOLDER_SOURCES),
14264
+ source: z18.enum(PLACEHOLDER_SOURCES),
14127
14265
  /**
14128
14266
  * Path expression evaluated against `source` (e.g. `engines.node` against
14129
14267
  * `project-context`, `defaults.branchModel` against `.cleo/config`).
14130
14268
  * For `literal` source, this MAY be the literal value's identifier.
14131
14269
  */
14132
- sourcePath: z17.string().min(1, "placeholder sourcePath must be non-empty"),
14270
+ sourcePath: z18.string().min(1, "placeholder sourcePath must be non-empty"),
14133
14271
  /**
14134
14272
  * Fallback value used when `source[sourcePath]` resolves to `undefined`.
14135
14273
  * `null` is permitted to explicitly mark "no default — failure required".
14136
14274
  */
14137
- defaultValue: z17.union([z17.string(), z17.number(), z17.boolean(), z17.null()]).optional()
14275
+ defaultValue: z18.union([z18.string(), z18.number(), z18.boolean(), z18.null()]).optional()
14138
14276
  });
14139
- TemplateManifestEntrySchema = z17.object({
14277
+ TemplateManifestEntrySchema = z18.object({
14140
14278
  /** Stable identifier for this template entry. */
14141
- id: z17.string().min(1, "id must be non-empty"),
14279
+ id: z18.string().min(1, "id must be non-empty"),
14142
14280
  /** Category of file this template represents. */
14143
- kind: z17.enum(TEMPLATE_KINDS),
14281
+ kind: z18.enum(TEMPLATE_KINDS),
14144
14282
  /** Repo-relative path of the template source file. */
14145
- sourcePath: z17.string().min(1, "sourcePath must be non-empty"),
14283
+ sourcePath: z18.string().min(1, "sourcePath must be non-empty"),
14146
14284
  /** Project-relative path where the rendered template installs. */
14147
- installPath: z17.string().min(1, "installPath must be non-empty"),
14285
+ installPath: z18.string().min(1, "installPath must be non-empty"),
14148
14286
  /** Substitution strategy the installer applies to `sourcePath`. */
14149
- substitution: z17.enum(TEMPLATE_SUBSTITUTIONS),
14287
+ substitution: z18.enum(TEMPLATE_SUBSTITUTIONS),
14150
14288
  /** Declared placeholders this template requires. May be empty. */
14151
- placeholders: z17.array(PlaceholderSpecSchema),
14289
+ placeholders: z18.array(PlaceholderSpecSchema),
14152
14290
  /** Reconciliation policy on upgrade. */
14153
- updateStrategy: z17.enum(TEMPLATE_UPDATE_STRATEGIES)
14291
+ updateStrategy: z18.enum(TEMPLATE_UPDATE_STRATEGIES)
14154
14292
  });
14155
14293
  }
14156
14294
  });
14157
14295
 
14158
14296
  // packages/contracts/src/validator/index.ts
14159
- import { z as z18 } from "zod";
14297
+ import { z as z19 } from "zod";
14160
14298
  var VALIDATOR_ID_REGEX, validatorFindingSchema, validatorAttestationSchema, validatorRejectionSchema, validatorVerdictSchema;
14161
14299
  var init_validator = __esm({
14162
14300
  "packages/contracts/src/validator/index.ts"() {
14163
14301
  "use strict";
14164
14302
  VALIDATOR_ID_REGEX = /^validator-[a-z0-9][a-z0-9-]*$/;
14165
- validatorFindingSchema = z18.object({
14166
- acId: z18.string().min(1, "acId must be non-empty"),
14167
- status: z18.enum(["pass", "fail", "inconclusive"]),
14168
- reasoning: z18.string().min(1, "reasoning must be non-empty"),
14169
- evidenceRefs: z18.array(z18.string()).optional(),
14170
- checkedAt: z18.string().min(1, "checkedAt must be a non-empty ISO-8601 string")
14171
- });
14172
- validatorAttestationSchema = z18.object({
14173
- verdict: z18.literal("attest"),
14174
- taskId: z18.string().min(1),
14175
- validatorId: z18.string().regex(VALIDATOR_ID_REGEX, "validatorId must match the pattern validator-<discriminator>"),
14176
- findings: z18.array(validatorFindingSchema).min(1, "attestation must contain at least one finding").refine(
14303
+ validatorFindingSchema = z19.object({
14304
+ acId: z19.string().min(1, "acId must be non-empty"),
14305
+ status: z19.enum(["pass", "fail", "inconclusive"]),
14306
+ reasoning: z19.string().min(1, "reasoning must be non-empty"),
14307
+ evidenceRefs: z19.array(z19.string()).optional(),
14308
+ checkedAt: z19.string().min(1, "checkedAt must be a non-empty ISO-8601 string")
14309
+ });
14310
+ validatorAttestationSchema = z19.object({
14311
+ verdict: z19.literal("attest"),
14312
+ taskId: z19.string().min(1),
14313
+ validatorId: z19.string().regex(VALIDATOR_ID_REGEX, "validatorId must match the pattern validator-<discriminator>"),
14314
+ findings: z19.array(validatorFindingSchema).min(1, "attestation must contain at least one finding").refine(
14177
14315
  (findings) => findings.every((f) => f.status === "pass"),
14178
14316
  'attestation requires every finding to have status="pass"'
14179
14317
  ),
14180
- summary: z18.string().optional(),
14181
- attestedAt: z18.string().min(1),
14182
- schemaVersion: z18.literal("1")
14183
- });
14184
- validatorRejectionSchema = z18.object({
14185
- verdict: z18.literal("reject"),
14186
- taskId: z18.string().min(1),
14187
- validatorId: z18.string().regex(VALIDATOR_ID_REGEX, "validatorId must match the pattern validator-<discriminator>"),
14188
- findings: z18.array(validatorFindingSchema).min(1, "rejection must contain at least one finding").refine(
14318
+ summary: z19.string().optional(),
14319
+ attestedAt: z19.string().min(1),
14320
+ schemaVersion: z19.literal("1")
14321
+ });
14322
+ validatorRejectionSchema = z19.object({
14323
+ verdict: z19.literal("reject"),
14324
+ taskId: z19.string().min(1),
14325
+ validatorId: z19.string().regex(VALIDATOR_ID_REGEX, "validatorId must match the pattern validator-<discriminator>"),
14326
+ findings: z19.array(validatorFindingSchema).min(1, "rejection must contain at least one finding").refine(
14189
14327
  (findings) => findings.some((f) => f.status !== "pass"),
14190
14328
  'rejection requires at least one finding with status "fail" or "inconclusive"'
14191
14329
  ),
14192
- summary: z18.string().min(1, "rejection summary must be non-empty"),
14193
- remediationHints: z18.array(z18.string()).optional(),
14194
- rejectedAt: z18.string().min(1),
14195
- schemaVersion: z18.literal("1")
14330
+ summary: z19.string().min(1, "rejection summary must be non-empty"),
14331
+ remediationHints: z19.array(z19.string()).optional(),
14332
+ rejectedAt: z19.string().min(1),
14333
+ schemaVersion: z19.literal("1")
14196
14334
  });
14197
- validatorVerdictSchema = z18.discriminatedUnion("verdict", [
14335
+ validatorVerdictSchema = z19.discriminatedUnion("verdict", [
14198
14336
  validatorAttestationSchema,
14199
14337
  validatorRejectionSchema
14200
14338
  ]);
@@ -14218,6 +14356,7 @@ var init_src2 = __esm({
14218
14356
  init_identity();
14219
14357
  init_operations_registry();
14220
14358
  init_provenance();
14359
+ init_read();
14221
14360
  init_docs_taxonomy();
14222
14361
  init_engine_result();
14223
14362
  init_enums();
@@ -14239,6 +14378,7 @@ var init_src2 = __esm({
14239
14378
  init_docs();
14240
14379
  init_operations();
14241
14380
  init_nexus_scope_map();
14381
+ init_output_contracts_data();
14242
14382
  init_params();
14243
14383
  init_tasks();
14244
14384
  init_peer();
@@ -19093,6 +19233,7 @@ Recovery command: cleo docs update {slug} --file <your-file>`;
19093
19233
  ownerId,
19094
19234
  file: filePath,
19095
19235
  url,
19236
+ content: inlineContent,
19096
19237
  desc: description,
19097
19238
  labels: rawLabels,
19098
19239
  attachedBy: rawAttachedBy,
@@ -19104,13 +19245,23 @@ Recovery command: cleo docs update {slug} --file <your-file>`;
19104
19245
  if (!ownerId) {
19105
19246
  return lafsError("E_INVALID_INPUT", "ownerId is required", "add");
19106
19247
  }
19107
- if (!filePath && !url) {
19248
+ const hasContent = typeof inlineContent === "string";
19249
+ const sourceCount = (filePath ? 1 : 0) + (url ? 1 : 0) + (hasContent ? 1 : 0);
19250
+ if (sourceCount === 0) {
19108
19251
  return lafsError(
19109
19252
  "E_INVALID_INPUT",
19110
- "Provide either a file path (positional or --file) or --url",
19253
+ "Provide a file path (positional or --file), --url, or --content <text>",
19111
19254
  "add"
19112
19255
  );
19113
19256
  }
19257
+ if (sourceCount > 1) {
19258
+ return lafsError(
19259
+ "E_INVALID_INPUT",
19260
+ "--file, --url, and --content are mutually exclusive \u2014 provide exactly one source",
19261
+ "add",
19262
+ 'Use `cleo docs add <owner> ./file.md` OR `--url <url>` OR `--content "<text>"` (not more than one).'
19263
+ );
19264
+ }
19114
19265
  let slug;
19115
19266
  if (rawSlug !== void 0) {
19116
19267
  let candidate = rawSlug;
@@ -19447,6 +19598,126 @@ Recovery command: cleo docs update {slug} --file <your-file>`;
19447
19598
  "add"
19448
19599
  );
19449
19600
  }
19601
+ if (hasContent) {
19602
+ const bytes = Buffer.from(inlineContent, "utf-8");
19603
+ if (type2 !== void 0) {
19604
+ let registry;
19605
+ try {
19606
+ registry = DocKindRegistry.load(getProjectRoot5());
19607
+ } catch {
19608
+ registry = void 0;
19609
+ }
19610
+ const check = validateDocBody(type2, inlineContent, registry);
19611
+ if (!check.ok) {
19612
+ const missingList = check.missing.join(", ");
19613
+ if (strictMode === true) {
19614
+ if (slug !== void 0) releaseReservedSlug(slug);
19615
+ return lafsError(
19616
+ "E_DOC_SCHEMA_MISMATCH",
19617
+ `body for kind '${type2}' is missing required section(s): ${missingList}`,
19618
+ "add",
19619
+ `Add the missing H2 section(s) \u2014 '## ${check.missing[0] ?? ""}' \u2014 then retry. Pass --strict=false (default) to surface as an advisory warning instead of an error.`,
19620
+ { kind: type2, missing: check.missing, strict: true }
19621
+ );
19622
+ }
19623
+ pushWarning({
19624
+ code: "W_DOC_SCHEMA_MISMATCH",
19625
+ message: `body for kind '${type2}' is missing required section(s): ${missingList}. Add '--strict' to fail on schema violations.`
19626
+ });
19627
+ }
19628
+ }
19629
+ const mime = "text/markdown";
19630
+ const attachment = {
19631
+ kind: "blob",
19632
+ mime,
19633
+ ...description ? { description } : {},
19634
+ ...labels ? { labels } : {}
19635
+ };
19636
+ let meta;
19637
+ try {
19638
+ meta = await store.put(
19639
+ bytes,
19640
+ attachment,
19641
+ ownerType,
19642
+ ownerId,
19643
+ attachedBy,
19644
+ void 0,
19645
+ extras
19646
+ );
19647
+ } catch (err) {
19648
+ if (slug !== void 0) releaseReservedSlug(slug);
19649
+ if (err instanceof SlugCollisionError) {
19650
+ return {
19651
+ success: false,
19652
+ error: {
19653
+ code: "E_SLUG_RESERVED",
19654
+ message: SLUG_COLLISION_GUIDANCE.replaceAll("{slug}", err.slug ?? ""),
19655
+ fix: `cleo docs update ${err.slug ?? "<slug>"} --content "..."`,
19656
+ details: {
19657
+ suggestions: err.suggestions,
19658
+ aliases: ["E_SLUG_TAKEN"]
19659
+ }
19660
+ }
19661
+ };
19662
+ }
19663
+ throw err;
19664
+ }
19665
+ if (adrNumber !== void 0 && slug !== void 0) consumeReservedSlug(slug);
19666
+ const blobName = slug ?? meta.sha256.slice(0, 12);
19667
+ let backend = "llmtxt";
19668
+ try {
19669
+ const blobMirror = createAttachmentBlobStore(getProjectRoot5());
19670
+ const mirrorResult = await blobMirror.put(ownerId, {
19671
+ name: blobName,
19672
+ data: new Uint8Array(bytes),
19673
+ contentType: mime
19674
+ });
19675
+ backend = mirrorResult.backend;
19676
+ } catch {
19677
+ backend = await currentAttachmentBackend();
19678
+ }
19679
+ import("@cleocode/core/internal").then(
19680
+ ({ ensureLlmtxtNode }) => ensureLlmtxtNode(getProjectRoot5(), meta.sha256, `${ownerType}:${ownerId}`, blobName)
19681
+ ).catch(() => {
19682
+ });
19683
+ const contentPayload = {
19684
+ kind: "doc-attachment",
19685
+ attachmentId: meta.id,
19686
+ ownerId,
19687
+ addedAt: (/* @__PURE__ */ new Date()).toISOString(),
19688
+ ...slug !== void 0 ? { slug } : {},
19689
+ ...type2 !== void 0 ? { type: type2 } : {}
19690
+ };
19691
+ emitDocAttachmentObservation(contentPayload, getProjectRoot5());
19692
+ try {
19693
+ writeAuditEntry(getProjectRoot5(), {
19694
+ op: "docs.add",
19695
+ slug,
19696
+ type: type2,
19697
+ attachmentId: meta.id,
19698
+ sha256: meta.sha256,
19699
+ ownerId,
19700
+ summary: `Added inline doc '${slug ?? meta.sha256.slice(0, 12)}'${type2 ? ` of type '${type2}'` : ""} for owner ${ownerId}`
19701
+ });
19702
+ } catch {
19703
+ }
19704
+ return lafsSuccess(
19705
+ {
19706
+ attachmentId: meta.id,
19707
+ sha256: meta.sha256,
19708
+ refCount: meta.refCount,
19709
+ kind: "blob",
19710
+ ownerId,
19711
+ ownerType,
19712
+ // Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
19713
+ attachmentBackend: backend,
19714
+ ...slug !== void 0 ? { slug } : {},
19715
+ ...type2 !== void 0 ? { type: type2 } : {},
19716
+ ...adrNumber !== void 0 ? { adrNumber } : {}
19717
+ },
19718
+ "add"
19719
+ );
19720
+ }
19450
19721
  if (url) {
19451
19722
  const attachment = {
19452
19723
  kind: "url",
@@ -28136,8 +28407,8 @@ async function loadPlaybookByName(name) {
28136
28407
  return null;
28137
28408
  }
28138
28409
  try {
28139
- const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
28140
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot58();
28410
+ const { getProjectRoot: getProjectRoot59 } = await import("@cleocode/core/internal");
28411
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot59();
28141
28412
  const resolved = resolvePlaybook(name, {
28142
28413
  projectRoot,
28143
28414
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -28181,8 +28452,8 @@ async function acquireDb() {
28181
28452
  async function buildDefaultDispatcher() {
28182
28453
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
28183
28454
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await import("@cleocode/runtime/gateway");
28184
- const { getProjectRoot: getProjectRoot58, createToolGuard, runSkillNodeOrSpawn } = await import("@cleocode/core/internal");
28185
- const projectRoot = getProjectRoot58();
28455
+ const { getProjectRoot: getProjectRoot59, createToolGuard, runSkillNodeOrSpawn } = await import("@cleocode/core/internal");
28456
+ const projectRoot = getProjectRoot59();
28186
28457
  const tools = createToolGuard({ allowedRoots: [projectRoot] });
28187
28458
  const spawn5 = async (input2) => {
28188
28459
  const result = await orchestrateSpawnExecute2(
@@ -28379,8 +28650,8 @@ var init_playbook2 = __esm({
28379
28650
  projectRoot = __playbookRuntimeOverrides.projectRoot;
28380
28651
  } else {
28381
28652
  try {
28382
- const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
28383
- projectRoot = getProjectRoot58();
28653
+ const { getProjectRoot: getProjectRoot59 } = await import("@cleocode/core/internal");
28654
+ projectRoot = getProjectRoot59();
28384
28655
  } catch {
28385
28656
  projectRoot = void 0;
28386
28657
  }
@@ -28444,14 +28715,14 @@ var init_playbook2 = __esm({
28444
28715
  const dispatcher = await buildDefaultDispatcher();
28445
28716
  let result;
28446
28717
  try {
28447
- const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core/internal");
28718
+ const { getProjectRoot: getProjectRoot59 } = await import("@cleocode/core/internal");
28448
28719
  const opts = {
28449
28720
  db,
28450
28721
  playbook: parsed.definition,
28451
28722
  playbookHash: parsed.sourceHash,
28452
28723
  initialContext,
28453
28724
  dispatcher,
28454
- projectRoot: getProjectRoot58()
28725
+ projectRoot: getProjectRoot59()
28455
28726
  };
28456
28727
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
28457
28728
  opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
@@ -32693,6 +32964,7 @@ var init_tasks3 = __esm({
32693
32964
  await taskCancel(projectRoot, params.taskId, {
32694
32965
  reason: params.reason,
32695
32966
  children: params.children,
32967
+ reparentTo: params.reparentTo,
32696
32968
  force: params.force,
32697
32969
  cascadeThreshold: params.cascadeThreshold,
32698
32970
  allowCascade: params.allowCascade
@@ -35160,11 +35432,11 @@ var init_security = __esm({
35160
35432
  });
35161
35433
 
35162
35434
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
35163
- function createSanitizer(getProjectRoot58) {
35435
+ function createSanitizer(getProjectRoot59) {
35164
35436
  return async (req, next) => {
35165
35437
  if (req.params) {
35166
35438
  try {
35167
- const root = getProjectRoot58 ? getProjectRoot58() : void 0;
35439
+ const root = getProjectRoot59 ? getProjectRoot59() : void 0;
35168
35440
  req.params = sanitizeParams(req.params, root, {
35169
35441
  domain: req.domain,
35170
35442
  operation: req.operation
@@ -35298,6 +35570,7 @@ __export(cli_exports, {
35298
35570
  dispatchRaw: () => dispatchRaw,
35299
35571
  getCliDispatcher: () => getCliDispatcher,
35300
35572
  handleRawError: () => handleRawError,
35573
+ maybeEmitDescribe: () => maybeEmitDescribe,
35301
35574
  resetCliDispatcher: () => resetCliDispatcher
35302
35575
  });
35303
35576
  import { randomUUID as randomUUID5 } from "node:crypto";
@@ -35306,7 +35579,12 @@ import { createRequire } from "node:module";
35306
35579
  import { dirname as dirname3, join as join8 } from "node:path";
35307
35580
  import { fileURLToPath as fileURLToPath2 } from "node:url";
35308
35581
  import { catalog, registerSkillLibraryFromPath } from "@cleocode/caamp";
35309
- import { autoRecordDispatchTokenUsage, getProjectRoot as getProjectRoot22, hooks } from "@cleocode/core/internal";
35582
+ import {
35583
+ autoRecordDispatchTokenUsage,
35584
+ describeOperation,
35585
+ getProjectRoot as getProjectRoot22,
35586
+ hooks
35587
+ } from "@cleocode/core/internal";
35310
35588
  function ensureCaampLibrary() {
35311
35589
  if (catalog.isCatalogAvailable()) return;
35312
35590
  try {
@@ -35387,7 +35665,31 @@ function createCliDispatcher() {
35387
35665
  function resetCliDispatcher() {
35388
35666
  _dispatcher = null;
35389
35667
  }
35668
+ function maybeEmitDescribe(gateway, domain, operation, outputOpts) {
35669
+ if (!isDescribeMode()) return false;
35670
+ const key = `${domain}.${operation}`;
35671
+ const descriptor = describeOperation(key);
35672
+ const command = outputOpts?.command ?? operation;
35673
+ if (descriptor === null) {
35674
+ cliOutput(
35675
+ { operation: key, gateway, inputContract: null, outputContract: null },
35676
+ {
35677
+ command,
35678
+ operation: `describe.${key}`,
35679
+ message: `No registered operation found for "${key}".`
35680
+ }
35681
+ );
35682
+ return true;
35683
+ }
35684
+ cliOutput(descriptor, {
35685
+ command,
35686
+ operation: `describe.${key}`,
35687
+ message: `Schema for ${key} (input + output). Use the outputContract.fieldPointers for --field.`
35688
+ });
35689
+ return true;
35690
+ }
35390
35691
  async function dispatchFromCli(gateway, domain, operation, params, outputOpts) {
35692
+ if (maybeEmitDescribe(gateway, domain, operation, outputOpts)) return;
35391
35693
  const dispatcher = getCliDispatcher();
35392
35694
  const projectRoot = getProjectRoot22();
35393
35695
  const dispatchStart = Date.now();
@@ -35550,6 +35852,7 @@ var init_cli = __esm({
35550
35852
  "packages/cleo/src/dispatch/adapters/cli.ts"() {
35551
35853
  "use strict";
35552
35854
  init_animation_bridge();
35855
+ init_describe_context();
35553
35856
  init_idempotency_context();
35554
35857
  init_renderers();
35555
35858
  init_dispatcher();
@@ -35845,6 +36148,7 @@ var init_add_batch = __esm({
35845
36148
  }
35846
36149
  },
35847
36150
  async run({ args }) {
36151
+ if (maybeEmitDescribe("mutate", "tasks", "add-batch", { command: "add-batch" })) return;
35848
36152
  const defaultParent = args.parent;
35849
36153
  const dryRunFlag = args["dry-run"];
35850
36154
  const paramsArg = args.params;
@@ -36156,6 +36460,7 @@ For 2+ tasks at once: cleo add-batch --file tasks.json (single transaction, atom
36156
36460
  }
36157
36461
  },
36158
36462
  async run({ args, cmd }) {
36463
+ if (maybeEmitDescribe("mutate", "tasks", "add", { command: "add" })) return;
36159
36464
  const paramsArg = args.params;
36160
36465
  const paramsFileArg = args["params-file"];
36161
36466
  if (paramsArg !== void 0 || paramsFileArg !== void 0) {
@@ -40962,9 +41267,9 @@ var init_backup = __esm({
40962
41267
  async run({ args }) {
40963
41268
  const scope = args.scope;
40964
41269
  const { packBundle } = await import("@cleocode/core/store/backup-pack.js");
40965
- const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
41270
+ const { getProjectRoot: getProjectRoot59 } = await import("@cleocode/core");
40966
41271
  const includesProject = scope === "project" || scope === "all";
40967
- const projectRoot = includesProject ? getProjectRoot58() : void 0;
41272
+ const projectRoot = includesProject ? getProjectRoot59() : void 0;
40968
41273
  let passphrase;
40969
41274
  if (args.encrypt === true) {
40970
41275
  passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
@@ -41040,12 +41345,12 @@ var init_backup = __esm({
41040
41345
  },
41041
41346
  async run({ args }) {
41042
41347
  const bundlePath = args.bundle;
41043
- const { getProjectRoot: getProjectRoot58, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
41348
+ const { getProjectRoot: getProjectRoot59, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
41044
41349
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
41045
41350
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
41046
41351
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
41047
41352
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
41048
- const projectRoot = getProjectRoot58();
41353
+ const projectRoot = getProjectRoot59();
41049
41354
  if (args.force !== true) {
41050
41355
  const existing = checkForExistingData(projectRoot, getCleoHome6());
41051
41356
  if (existing.length > 0) {
@@ -42018,9 +42323,13 @@ var init_cancel = __esm({
42018
42323
  },
42019
42324
  children: {
42020
42325
  type: "string",
42021
- description: "Child handling mode: block (default), cascade, or orphan",
42326
+ description: "Child handling mode: block (default), cascade (cancel subtree), or reparent (move children under --to)",
42022
42327
  default: "block"
42023
42328
  },
42329
+ to: {
42330
+ type: "string",
42331
+ description: "Target parent ID for --children reparent (T11811): children move under this epic"
42332
+ },
42024
42333
  force: {
42025
42334
  type: "boolean",
42026
42335
  description: "Required waiver for cascade cancellation above the subtree threshold",
@@ -42040,6 +42349,7 @@ var init_cancel = __esm({
42040
42349
  taskId: args.taskId,
42041
42350
  reason: args.reason,
42042
42351
  children: args.children,
42352
+ reparentTo: typeof args.to === "string" && args.to.length > 0 ? args.to : void 0,
42043
42353
  force: args.force === true,
42044
42354
  cascadeThreshold: typeof args.cascadeThreshold === "string" && args.cascadeThreshold.length > 0 ? Number.parseInt(args.cascadeThreshold, 10) : void 0
42045
42355
  },
@@ -43668,6 +43978,7 @@ var init_complete = __esm({
43668
43978
  }
43669
43979
  },
43670
43980
  async run({ args }) {
43981
+ if (maybeEmitDescribe("mutate", "tasks", "complete", { command: "complete" })) return;
43671
43982
  const response = await dispatchRaw("mutate", "tasks", "complete", {
43672
43983
  taskId: args.taskId,
43673
43984
  notes: args.notes,
@@ -47097,14 +47408,19 @@ var init_graph2 = __esm({
47097
47408
  format: {
47098
47409
  type: "string",
47099
47410
  description: "Output format: json (default) | dot."
47411
+ },
47412
+ backlinks: {
47413
+ type: "boolean",
47414
+ description: "Hydrate the persisted docs_wikilinks backlink graph (T11826) \u2014 adds bidirectional shares-topic doc\u2194doc edges and any persisted backlinks not surfaced by the on-the-fly BFS. Obsidian-grade graph on existing data."
47100
47415
  }
47101
47416
  },
47102
47417
  async run({ args }) {
47103
47418
  const root = String(args.root);
47104
47419
  const depth = parseDepth(args.depth);
47105
47420
  const format = parseFormat(args.format);
47421
+ const hydrateWikilinks = Boolean(args.backlinks);
47106
47422
  try {
47107
- const graph = await buildDocProvenanceGraph({ root, depth });
47423
+ const graph = await buildDocProvenanceGraph({ root, depth, hydrateWikilinks });
47108
47424
  const payload = { ...graph };
47109
47425
  if (format === "dot") {
47110
47426
  payload["dot"] = renderProvenanceGraphAsDot(graph);
@@ -47925,6 +48241,7 @@ __export(docs_exports, {
47925
48241
  import { appendFile, mkdir as mkdir3, readdir, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
47926
48242
  import { dirname as dirname8, isAbsolute as isAbsolute2, join as join21, resolve as resolve5 } from "node:path";
47927
48243
  import { pushWarning as pushWarning3 } from "@cleocode/core";
48244
+ import { createDocsReadModel as createDocsReadModel2 } from "@cleocode/core/docs/docs-read-model";
47928
48245
  import {
47929
48246
  CleoError as CleoError4,
47930
48247
  CounterMismatchError,
@@ -47938,12 +48255,21 @@ import {
47938
48255
  resolveWorktreeFilePath,
47939
48256
  resolveWorktreeRouting as resolveWorktreeRouting4
47940
48257
  } from "@cleocode/core/internal";
47941
- import { describeOperation } from "@cleocode/lafs";
48258
+ import { describeOperation as describeOperation2 } from "@cleocode/lafs";
47942
48259
  async function dispatchDocsRaw(gateway, operation, params) {
47943
48260
  const response = await dispatchRaw(gateway, "docs", operation, params);
47944
48261
  handleRawError(response, { command: "docs", operation: `docs.${operation}` });
47945
48262
  return response.data;
47946
48263
  }
48264
+ async function readDocBodyFromStdin() {
48265
+ if (process.stdin.isTTY) return "";
48266
+ process.stdin.setEncoding("utf-8");
48267
+ let buf = "";
48268
+ for await (const chunk of process.stdin) {
48269
+ buf += chunk;
48270
+ }
48271
+ return buf.replace(/\r?\n$/, "");
48272
+ }
47947
48273
  async function getScriptNames(projectRoot) {
47948
48274
  const scriptsDir = join21(projectRoot, "scripts");
47949
48275
  try {
@@ -48094,7 +48420,7 @@ var init_docs3 = __esm({
48094
48420
  addCommand6 = defineCommand({
48095
48421
  meta: {
48096
48422
  name: "add",
48097
- description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --title <text> Human-readable title \u2014 REQUIRED for --type adr when --slug is omitted (T10360)\n --type <kind> Taxonomy classification \u2014 run `cleo docs schema` for kinds\n --allow-similar Bypass the slug-similarity warn \u2014 every bypass is audited\n to .cleo/audit/similar-bypass.jsonl (T10361)\n --strict Enforce body-schema (requiredSections) \u2014 fail with\n E_DOC_SCHEMA_MISMATCH instead of warning (T10160)\n' + docsOutputFlagHelp + "\n\nValidation behaviors:\n \u2022 Unknown flags \u2192 E_UNKNOWN_FLAG with did-you-mean suggestions (T10359)\n \u2022 Slug collision \u2192 E_SLUG_RESERVED + 3 alternative slugs (T10386)\n \u2022 Near-duplicate slug \u2192 W_SLUG_SIMILAR warning unless --allow-similar (T10361)\n \u2022 For --type adr without --slug, slug auto-allocates as `adr-NNN-<kebab-title>` via the\n central allocator (T10360 \u2014 closes T10153). --title is required in this case."
48423
+ description: "Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url/--content is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --content <text> Inline document body \u2014 author without a file (T10965); '-' reads stdin\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: \"human\")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --title <text> Human-readable title \u2014 REQUIRED for --type adr when --slug is omitted (T10360)\n --type <kind> Taxonomy classification \u2014 run `cleo docs schema` for kinds\n --allow-similar Bypass the slug-similarity warn \u2014 every bypass is audited\n to .cleo/audit/similar-bypass.jsonl (T10361)\n --strict Enforce body-schema (requiredSections) \u2014 fail with\n E_DOC_SCHEMA_MISMATCH instead of warning (T10160)\n" + docsOutputFlagHelp + "\n\nValidation behaviors:\n \u2022 Unknown flags \u2192 E_UNKNOWN_FLAG with did-you-mean suggestions (T10359)\n \u2022 Slug collision \u2192 E_SLUG_RESERVED + 3 alternative slugs (T10386)\n \u2022 Near-duplicate slug \u2192 W_SLUG_SIMILAR warning unless --allow-similar (T10361)\n \u2022 For --type adr without --slug, slug auto-allocates as `adr-NNN-<kebab-title>` via the\n central allocator (T10360 \u2014 closes T10153). --title is required in this case."
48098
48424
  },
48099
48425
  args: {
48100
48426
  "owner-id": {
@@ -48111,6 +48437,10 @@ var init_docs3 = __esm({
48111
48437
  type: "string",
48112
48438
  description: "Remote URL to attach (instead of a local file)"
48113
48439
  },
48440
+ content: {
48441
+ type: "string",
48442
+ description: "Inline document body \u2014 author a doc without a pre-existing file (T10965). Pass '-' to read the body from stdin. Mutually exclusive with the file positional and --url."
48443
+ },
48114
48444
  desc: {
48115
48445
  type: "string",
48116
48446
  description: "Free-text description of this attachment"
@@ -48163,14 +48493,27 @@ var init_docs3 = __esm({
48163
48493
  const ownerId = args["owner-id"];
48164
48494
  const fileArg = args.file ?? void 0;
48165
48495
  const url = args.url ?? void 0;
48496
+ const contentArg = typeof args.content === "string" ? args.content : void 0;
48166
48497
  const allowSimilar = args["allow-similar"] === true;
48167
- if (!fileArg && !url) {
48168
- cliError("provide a file path (positional argument) or --url <url>", 6, {
48498
+ const sourceCount = (fileArg ? 1 : 0) + (url ? 1 : 0) + (contentArg !== void 0 ? 1 : 0);
48499
+ if (sourceCount === 0) {
48500
+ cliError("provide a file path (positional), --url <url>, or --content <text>", 6, {
48169
48501
  name: "E_VALIDATION",
48170
- fix: 'Example: cleo docs add T123 docs/rfc.md --desc "RFC draft" \u2014 or \u2014 cleo docs add T123 --url https://example.com/spec'
48502
+ fix: 'Example: cleo docs add T123 docs/rfc.md --desc "RFC draft" \u2014 or \u2014 cleo docs add T123 --content "# Note" --slug my-note'
48171
48503
  });
48172
48504
  process.exit(6);
48173
48505
  }
48506
+ if (sourceCount > 1) {
48507
+ cliError("the file positional, --url, and --content are mutually exclusive", 6, {
48508
+ name: "E_VALIDATION",
48509
+ fix: "Pass exactly one source: a file path, --url <url>, or --content <text>."
48510
+ });
48511
+ process.exit(6);
48512
+ }
48513
+ let content = contentArg;
48514
+ if (content === "-") {
48515
+ content = await readDocBodyFromStdin();
48516
+ }
48174
48517
  if (args.type === "adr" && !args.slug && !args.title) {
48175
48518
  cliError(
48176
48519
  "--title <text> is required when --type adr is used without --slug \u2014 the allocator needs a title to assemble adr-NNN-<kebab-title>",
@@ -48290,6 +48633,7 @@ var init_docs3 = __esm({
48290
48633
  ownerId,
48291
48634
  ...resolvedFile ? { file: resolvedFile } : {},
48292
48635
  ...url ? { url } : {},
48636
+ ...content !== void 0 ? { content } : {},
48293
48637
  ...args.desc ? { desc: args.desc } : {},
48294
48638
  ...args.labels ? { labels: args.labels } : {},
48295
48639
  ...args["attached-by"] ? { attachedBy: args["attached-by"] } : {},
@@ -48404,14 +48748,26 @@ var init_docs3 = __esm({
48404
48748
  fetchCommand = defineCommand({
48405
48749
  meta: {
48406
48750
  name: "fetch",
48407
- description: "Retrieve attachment metadata and bytes by attachment ID (att_*) or SHA-256 hex. Files <= 1 MB are returned base64-encoded inline; larger files report the storage path only. Output flags: --json and --output envelope|id|table|count|silent are accepted consistently."
48751
+ description: "Retrieve attachment metadata and bytes by slug, attachment ID (att_*), or SHA-256 hex. Files <= 1 MB are returned base64-encoded inline; larger files report the storage path only. Pass --content (alias --decoded) to emit the decoded UTF-8 document body to stdout instead of the LAFS envelope \u2014 the agent-friendly shortcut over piping bytesBase64 through base64 -d (T10970). Output flags: --json and --output envelope|id|table|count|silent are accepted consistently."
48408
48752
  },
48409
48753
  args: {
48410
48754
  "attachment-ref": {
48411
48755
  type: "positional",
48412
- description: "Attachment ID (att_*) or SHA-256 hex",
48756
+ description: "Slug, attachment ID (att_*), or SHA-256 hex",
48413
48757
  required: true
48414
48758
  },
48759
+ // T10970 — decoded-text content mode. An explicit opt-out from the
48760
+ // default envelope contract (ADR-086) that streams the raw UTF-8 body
48761
+ // to stdout, mirroring the other text-payload commands (export,
48762
+ // llm-output, view --render markdown).
48763
+ content: {
48764
+ type: "boolean",
48765
+ description: "Emit the decoded UTF-8 document body to stdout instead of the LAFS envelope (text docs only). Replaces the `--field /data/bytesBase64 | base64 -d` two-step (T10970)."
48766
+ },
48767
+ decoded: {
48768
+ type: "boolean",
48769
+ description: "Alias for --content (T10970)."
48770
+ },
48415
48771
  // T9922 — MVI record projection opt-out flags (surfaced for --help).
48416
48772
  verbose: {
48417
48773
  type: "boolean",
@@ -48424,11 +48780,35 @@ var init_docs3 = __esm({
48424
48780
  ...docsOutputArgs
48425
48781
  },
48426
48782
  async run({ args }) {
48783
+ const ref = String(args["attachment-ref"]);
48784
+ if (args.content === true || args.decoded === true) {
48785
+ const model = createDocsReadModel2();
48786
+ const result = await model.fetchDecoded(ref);
48787
+ if (!result.ok) {
48788
+ if (result.reason === "not-found") {
48789
+ cliError(`Doc not found: ${ref}`, 4 /* NOT_FOUND */, {
48790
+ name: "E_NOT_FOUND",
48791
+ fix: "List available docs with: cleo docs list"
48792
+ });
48793
+ } else {
48794
+ cliError(`Content not retrievable: ${ref}`, 4 /* NOT_FOUND */, {
48795
+ name: "E_NOT_FOUND",
48796
+ fix: "The doc metadata exists but its blob may be missing. Try: cleo docs publish <slug>"
48797
+ });
48798
+ }
48799
+ process.exit(4 /* NOT_FOUND */);
48800
+ }
48801
+ process.stdout.write(result.content);
48802
+ if (!result.content.endsWith("\n")) {
48803
+ process.stdout.write("\n");
48804
+ }
48805
+ return;
48806
+ }
48427
48807
  await dispatchFromCli(
48428
48808
  "query",
48429
48809
  "docs",
48430
48810
  "fetch",
48431
- { attachmentRef: args["attachment-ref"] },
48811
+ { attachmentRef: ref },
48432
48812
  { command: "docs fetch" }
48433
48813
  );
48434
48814
  }
@@ -49176,7 +49556,7 @@ var init_docs3 = __esm({
49176
49556
  if (docsUpdateOperation === void 0) {
49177
49557
  throw new Error("docs.update operation is missing from the registry");
49178
49558
  }
49179
- docsUpdateSchema = describeOperation(docsUpdateOperation, {
49559
+ docsUpdateSchema = describeOperation2(docsUpdateOperation, {
49180
49560
  includeGates: false,
49181
49561
  includeExamples: true
49182
49562
  });
@@ -50088,6 +50468,158 @@ var init_doctor_db_substrate = __esm({
50088
50468
  }
50089
50469
  });
50090
50470
 
50471
+ // packages/cleo/src/cli/commands/doctor-exodus-residue.ts
50472
+ var doctor_exodus_residue_exports = {};
50473
+ __export(doctor_exodus_residue_exports, {
50474
+ doctorExodusResidueCommand: () => doctorExodusResidueCommand
50475
+ });
50476
+ import {
50477
+ archiveStrandedResidue,
50478
+ buildExodusPlan,
50479
+ detectStrandedResidue
50480
+ } from "@cleocode/core/store/exodus/index.js";
50481
+ var doctorExodusResidueCommand;
50482
+ var init_doctor_exodus_residue = __esm({
50483
+ "packages/cleo/src/cli/commands/doctor-exodus-residue.ts"() {
50484
+ "use strict";
50485
+ init_define_cli_command();
50486
+ init_renderers();
50487
+ doctorExodusResidueCommand = defineCommand({
50488
+ meta: {
50489
+ name: "exodus-residue",
50490
+ description: "Detect legacy exodus source DBs still present after a cutover (stranded residue that re-arms the exodus-on-open corruption trigger). Use --fix to archive them into _archive/ (reversible move, never deletes)."
50491
+ },
50492
+ args: {
50493
+ fix: {
50494
+ type: "boolean",
50495
+ description: "Archive stranded legacy source DBs into _archive/ (move, never delete)",
50496
+ default: false
50497
+ }
50498
+ },
50499
+ run({ args }) {
50500
+ const fix = args.fix === true;
50501
+ const cwd = process.cwd();
50502
+ const plan = buildExodusPlan(cwd);
50503
+ const stranded = detectStrandedResidue(plan.sources, cwd);
50504
+ if (stranded.length === 0) {
50505
+ cliOutput(
50506
+ {
50507
+ kind: "generic",
50508
+ ok: true,
50509
+ strandedCount: 0,
50510
+ stranded: [],
50511
+ fixed: false
50512
+ },
50513
+ {
50514
+ command: "doctor exodus-residue",
50515
+ message: "No stranded legacy exodus source DBs (clean cutover or pre-migration install)."
50516
+ }
50517
+ );
50518
+ return;
50519
+ }
50520
+ for (const entry of stranded) {
50521
+ humanInfo(` STRANDED [${entry.scope}] ${entry.name} \u2192 ${entry.path}`);
50522
+ }
50523
+ if (!fix) {
50524
+ cliOutput(
50525
+ {
50526
+ kind: "generic",
50527
+ ok: false,
50528
+ strandedCount: stranded.length,
50529
+ stranded: stranded.map((s) => ({ name: s.name, path: s.path, scope: s.scope })),
50530
+ fixed: false
50531
+ },
50532
+ {
50533
+ command: "doctor exodus-residue",
50534
+ message: `${stranded.length} stranded legacy source DB(s) found. Run \`cleo doctor exodus-residue --fix\` to archive them.`
50535
+ }
50536
+ );
50537
+ process.exitCode = 1;
50538
+ return;
50539
+ }
50540
+ const archived = archiveStrandedResidue(stranded, plan.sources, cwd);
50541
+ const movedCount = archived.filter((a) => a.action === "archived").length;
50542
+ humanInfo(` Archived ${movedCount} stranded source DB(s) \u2192 _archive/.`);
50543
+ cliOutput(
50544
+ {
50545
+ kind: "generic",
50546
+ ok: true,
50547
+ strandedCount: stranded.length,
50548
+ stranded: stranded.map((s) => ({ name: s.name, path: s.path, scope: s.scope })),
50549
+ fixed: true,
50550
+ archived: archived.map((a) => ({
50551
+ name: a.name,
50552
+ action: a.action,
50553
+ archivedTo: a.archivedTo
50554
+ }))
50555
+ },
50556
+ {
50557
+ command: "doctor exodus-residue",
50558
+ message: `Archived ${movedCount} stranded legacy source DB(s) into _archive/.`
50559
+ }
50560
+ );
50561
+ }
50562
+ });
50563
+ }
50564
+ });
50565
+
50566
+ // packages/cleo/src/cli/commands/doctor-exodus.ts
50567
+ var doctor_exodus_exports = {};
50568
+ __export(doctor_exodus_exports, {
50569
+ doctorExodusCommand: () => doctorExodusCommand
50570
+ });
50571
+ import { buildExodusHealth } from "@cleocode/core/store/exodus/index.js";
50572
+ function fmtBytes2(n) {
50573
+ if (n < 1024) return `${n} B`;
50574
+ if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
50575
+ if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
50576
+ return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
50577
+ }
50578
+ var doctorExodusCommand;
50579
+ var init_doctor_exodus = __esm({
50580
+ "packages/cleo/src/cli/commands/doctor-exodus.ts"() {
50581
+ "use strict";
50582
+ init_define_cli_command();
50583
+ init_renderers();
50584
+ doctorExodusCommand = defineCommand({
50585
+ meta: {
50586
+ name: "exodus-health",
50587
+ description: "Read-only exodus health report: per-scope migration state, legacy DB sizes, completion markers, disk headroom, and the kill-switch \u2014 with recommended next steps."
50588
+ },
50589
+ run() {
50590
+ const health = buildExodusHealth(process.cwd());
50591
+ for (const sc of [health.project, health.global]) {
50592
+ humanInfo(
50593
+ ` [${sc.scope}] state=${sc.state} consolidated=${sc.consolidatedExists ? "yes" : "no"} marker=${sc.markerPresent ? "yes" : "no"}`
50594
+ );
50595
+ for (const s of sc.legacySources) {
50596
+ humanInfo(
50597
+ ` ${s.present ? "\u2713" : "\xB7"} ${s.name.padEnd(18)} ${s.present ? fmtBytes2(s.bytes) : "-"}${s.large ? " \u26A0 LARGE" : ""}`
50598
+ );
50599
+ }
50600
+ }
50601
+ humanInfo(
50602
+ ` disk: ${fmtBytes2(health.availableBytes)} free / ${fmtBytes2(health.requiredBytes)} required \u2014 ${health.diskHeadroomOk ? "OK" : "LOW"}`
50603
+ );
50604
+ humanInfo(
50605
+ ` kill-switch (CLEO_DISABLE_EXODUS_ON_OPEN): ${health.killSwitchSet ? "SET" : "off"}`
50606
+ );
50607
+ if (health.recommendations.length > 0) {
50608
+ humanInfo(" recommendations:");
50609
+ for (const r of health.recommendations) humanInfo(` \u2022 ${r}`);
50610
+ }
50611
+ cliOutput(
50612
+ { kind: "generic", ...health },
50613
+ {
50614
+ command: "doctor exodus",
50615
+ message: `exodus health: project=${health.project.state}, global=${health.global.state}${health.dataParityOk ? "" : `, ${health.dataDeficits} DEFICIT(S)`}.`
50616
+ }
50617
+ );
50618
+ }
50619
+ });
50620
+ }
50621
+ });
50622
+
50091
50623
  // packages/cleo/src/cli/commands/doctor-legacy-backups.ts
50092
50624
  var doctor_legacy_backups_exports = {};
50093
50625
  __export(doctor_legacy_backups_exports, {
@@ -50570,6 +51102,78 @@ var init_doctor_release_readiness = __esm({
50570
51102
  }
50571
51103
  });
50572
51104
 
51105
+ // packages/cleo/src/cli/commands/doctor-repair.ts
51106
+ var doctor_repair_exports = {};
51107
+ __export(doctor_repair_exports, {
51108
+ doctorRepairCommand: () => doctorRepairCommand
51109
+ });
51110
+ import { getLogger as getLogger20, getProjectRoot as getProjectRoot41 } from "@cleocode/core";
51111
+ import { repairMalformedDbs } from "@cleocode/core/store/repair-malformed-dbs.js";
51112
+ var doctorRepairCommand;
51113
+ var init_doctor_repair = __esm({
51114
+ "packages/cleo/src/cli/commands/doctor-repair.ts"() {
51115
+ "use strict";
51116
+ init_src2();
51117
+ init_define_cli_command();
51118
+ init_renderers();
51119
+ doctorRepairCommand = defineCommand({
51120
+ meta: {
51121
+ name: "repair",
51122
+ description: "Detect malformed CLEO databases (PRAGMA quick_check) and restore each from its freshest validated snapshot via the recovery pipeline (quarantine \u2192 restore \u2192 verify). Defaults to every present DB; use --role to narrow, --dry-run to plan without mutating."
51123
+ },
51124
+ args: {
51125
+ role: {
51126
+ type: "string",
51127
+ description: `Repair only this DB role (one of: ${DB_INVENTORY.map((e) => e.role).join(", ")})`,
51128
+ default: ""
51129
+ },
51130
+ "dry-run": {
51131
+ type: "boolean",
51132
+ description: "Detect + plan only \u2014 report what would be repaired without quarantining/restoring",
51133
+ default: false
51134
+ }
51135
+ },
51136
+ run({ args }) {
51137
+ const roleArg = typeof args.role === "string" ? args.role.trim() : "";
51138
+ const dryRun = args["dry-run"] === true;
51139
+ if (roleArg.length > 0 && !DB_INVENTORY.some((e) => e.role === roleArg)) {
51140
+ const validRoles = DB_INVENTORY.map((e) => e.role).join(", ");
51141
+ cliError(
51142
+ `Unknown DB role "${roleArg}". Valid roles: ${validRoles}.`,
51143
+ 6 /* VALIDATION_ERROR */,
51144
+ {
51145
+ name: "E_VALIDATION",
51146
+ fix: "Run `cleo doctor repair --help` for the list of valid roles."
51147
+ },
51148
+ { command: "doctor repair" }
51149
+ );
51150
+ process.exitCode = 6 /* VALIDATION_ERROR */;
51151
+ return;
51152
+ }
51153
+ const result = repairMalformedDbs({
51154
+ projectRoot: getProjectRoot41(),
51155
+ roles: roleArg.length > 0 ? [roleArg] : void 0,
51156
+ dryRun,
51157
+ logger: getLogger20("doctor-repair")
51158
+ });
51159
+ for (const r of result.roles) {
51160
+ if (!r.healthy) {
51161
+ humanInfo(` [${r.action.toUpperCase()}] ${r.role} \u2014 ${r.detail}`);
51162
+ }
51163
+ }
51164
+ const verb = dryRun ? "would repair" : "repaired";
51165
+ cliOutput(result, {
51166
+ command: "doctor repair",
51167
+ message: result.malformedCount === 0 ? `All ${result.roles.length} inspected DB(s) healthy \u2014 nothing to repair.` : `${result.malformedCount} malformed DB(s): ${verb} ${result.repairedCount}, ${result.failedCount} failed.`
51168
+ });
51169
+ if (result.failedCount > 0) {
51170
+ process.exitCode = 1 /* GENERAL_ERROR */;
51171
+ }
51172
+ }
51173
+ });
51174
+ }
51175
+ });
51176
+
50573
51177
  // packages/cleo/src/cli/progress.ts
50574
51178
  import { stderr } from "node:process";
50575
51179
  function createSelfUpdateProgress(enabled) {
@@ -50692,97 +51296,6 @@ ${this.prefix}: \u2717 ${message}
50692
51296
  }
50693
51297
  });
50694
51298
 
50695
- // packages/cleo/src/cli/commands/doctor-exodus-residue.ts
50696
- import {
50697
- archiveStrandedResidue,
50698
- buildExodusPlan,
50699
- detectStrandedResidue
50700
- } from "@cleocode/core/store/exodus/index.js";
50701
- var doctorExodusResidueCommand;
50702
- var init_doctor_exodus_residue = __esm({
50703
- "packages/cleo/src/cli/commands/doctor-exodus-residue.ts"() {
50704
- "use strict";
50705
- init_define_cli_command();
50706
- init_renderers();
50707
- doctorExodusResidueCommand = defineCommand({
50708
- meta: {
50709
- name: "exodus-residue",
50710
- description: "Detect legacy exodus source DBs still present after a cutover (stranded residue that re-arms the exodus-on-open corruption trigger). Use --fix to archive them into _archive/ (reversible move, never deletes)."
50711
- },
50712
- args: {
50713
- fix: {
50714
- type: "boolean",
50715
- description: "Archive stranded legacy source DBs into _archive/ (move, never delete)",
50716
- default: false
50717
- }
50718
- },
50719
- run({ args }) {
50720
- const fix = args.fix === true;
50721
- const cwd = process.cwd();
50722
- const plan = buildExodusPlan(cwd);
50723
- const stranded = detectStrandedResidue(plan.sources, cwd);
50724
- if (stranded.length === 0) {
50725
- cliOutput(
50726
- {
50727
- kind: "generic",
50728
- ok: true,
50729
- strandedCount: 0,
50730
- stranded: [],
50731
- fixed: false
50732
- },
50733
- {
50734
- command: "doctor exodus-residue",
50735
- message: "No stranded legacy exodus source DBs (clean cutover or pre-migration install)."
50736
- }
50737
- );
50738
- return;
50739
- }
50740
- for (const entry of stranded) {
50741
- humanInfo(` STRANDED [${entry.scope}] ${entry.name} \u2192 ${entry.path}`);
50742
- }
50743
- if (!fix) {
50744
- cliOutput(
50745
- {
50746
- kind: "generic",
50747
- ok: false,
50748
- strandedCount: stranded.length,
50749
- stranded: stranded.map((s) => ({ name: s.name, path: s.path, scope: s.scope })),
50750
- fixed: false
50751
- },
50752
- {
50753
- command: "doctor exodus-residue",
50754
- message: `${stranded.length} stranded legacy source DB(s) found. Run \`cleo doctor exodus-residue --fix\` to archive them.`
50755
- }
50756
- );
50757
- process.exitCode = 1;
50758
- return;
50759
- }
50760
- const archived = archiveStrandedResidue(stranded, plan.sources, cwd);
50761
- const movedCount = archived.filter((a) => a.action === "archived").length;
50762
- humanInfo(` Archived ${movedCount} stranded source DB(s) \u2192 _archive/.`);
50763
- cliOutput(
50764
- {
50765
- kind: "generic",
50766
- ok: true,
50767
- strandedCount: stranded.length,
50768
- stranded: stranded.map((s) => ({ name: s.name, path: s.path, scope: s.scope })),
50769
- fixed: true,
50770
- archived: archived.map((a) => ({
50771
- name: a.name,
50772
- action: a.action,
50773
- archivedTo: a.archivedTo
50774
- }))
50775
- },
50776
- {
50777
- command: "doctor exodus-residue",
50778
- message: `Archived ${movedCount} stranded legacy source DB(s) into _archive/.`
50779
- }
50780
- );
50781
- }
50782
- });
50783
- }
50784
- });
50785
-
50786
51299
  // packages/cleo/src/cli/commands/migrate-agents-v2.ts
50787
51300
  var migrate_agents_v2_exports = {};
50788
51301
  __export(migrate_agents_v2_exports, {
@@ -50798,7 +51311,7 @@ import { join as join23 } from "node:path";
50798
51311
  import {
50799
51312
  ensureGlobalAgentRegistryDb,
50800
51313
  getGlobalAgentRegistryNativeDb,
50801
- getProjectRoot as getProjectRoot41,
51314
+ getProjectRoot as getProjectRoot42,
50802
51315
  installAgentFromCant
50803
51316
  } from "@cleocode/core/internal";
50804
51317
  function sha256Hex(bytes) {
@@ -50986,7 +51499,7 @@ var init_migrate_agents_v2 = __esm({
50986
51499
  }
50987
51500
  },
50988
51501
  async run({ args }) {
50989
- const projectRoot = getProjectRoot41();
51502
+ const projectRoot = getProjectRoot42();
50990
51503
  const verbose = args.quiet !== true;
50991
51504
  if (verbose) {
50992
51505
  humanInfo("Scanning .cleo/cant/agents/ and .cleo/agents/ for unregistered agents...");
@@ -51030,7 +51543,7 @@ __export(doctor_exports, {
51030
51543
  });
51031
51544
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
51032
51545
  import { join as join24 } from "node:path";
51033
- import { getProjectRoot as getProjectRoot42, pushWarning as pushWarning5 } from "@cleocode/core";
51546
+ import { getProjectRoot as getProjectRoot43, pushWarning as pushWarning5 } from "@cleocode/core";
51034
51547
  import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
51035
51548
  import {
51036
51549
  quarantineRogueCleoDir,
@@ -51147,10 +51660,12 @@ var init_doctor = __esm({
51147
51660
  init_progress();
51148
51661
  init_renderers();
51149
51662
  init_doctor_db_substrate();
51663
+ init_doctor_exodus();
51150
51664
  init_doctor_exodus_residue();
51151
51665
  init_doctor_legacy_backups();
51152
51666
  init_doctor_projects();
51153
51667
  init_doctor_release_readiness();
51668
+ init_doctor_repair();
51154
51669
  init_migrate_agents_v2();
51155
51670
  FIXTURE_ID_PATTERNS = [/^E\d+$/, /^T\d+EP$/];
51156
51671
  FIXTURE_TITLE_KEYWORDS = [
@@ -51168,6 +51683,10 @@ var init_doctor = __esm({
51168
51683
  "legacy-backups": doctorLegacyBackupsCommand,
51169
51684
  // T11777 / Saga T11242 / Epic T11249 — exodus stranded-residue check (+ --fix)
51170
51685
  "exodus-residue": doctorExodusResidueCommand,
51686
+ // T11837 / Saga T11242 / Epic T11833 — read-only exodus health report
51687
+ "exodus-health": doctorExodusCommand,
51688
+ // T11829 / Saga T11242 / Epic T11833 — DHQ-060 malformed-DB repair entry point
51689
+ repair: doctorRepairCommand,
51171
51690
  // T10458 / Saga T10431 / Epic T10436 — Release-readiness preflight
51172
51691
  "release-readiness": doctorReleaseReadinessCommand
51173
51692
  },
@@ -51372,7 +51891,7 @@ var init_doctor = __esm({
51372
51891
  const { join: pathJoin } = await import("node:path");
51373
51892
  const { existsSync: existsSync22 } = await import("node:fs");
51374
51893
  const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
51375
- const projectRoot = getProjectRoot42();
51894
+ const projectRoot = getProjectRoot43();
51376
51895
  let gitRoot = projectRoot;
51377
51896
  try {
51378
51897
  gitRoot = execFile2("git", ["rev-parse", "--show-toplevel"], {
@@ -51424,7 +51943,7 @@ var init_doctor = __esm({
51424
51943
  }
51425
51944
  if (args.brain) {
51426
51945
  const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
51427
- const projectRoot = getProjectRoot42();
51946
+ const projectRoot = getProjectRoot43();
51428
51947
  const dashboard = await computeBrainHealthDashboard(projectRoot);
51429
51948
  cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
51430
51949
  if (dashboard.hasP0Failure) {
@@ -51433,7 +51952,7 @@ var init_doctor = __esm({
51433
51952
  return;
51434
51953
  }
51435
51954
  if (args["scan-test-fixtures-in-prod"]) {
51436
- const projectRoot = getProjectRoot42();
51955
+ const projectRoot = getProjectRoot43();
51437
51956
  const matches = await scanTestFixturesInProd(projectRoot);
51438
51957
  const dryRun = args["dry-run"] !== false && args.quarantine !== true;
51439
51958
  const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
@@ -51521,7 +52040,7 @@ var init_doctor = __esm({
51521
52040
  progress.complete("Comprehensive diagnostics complete");
51522
52041
  } else if (args["scan-rogue-cleo-dirs"]) {
51523
52042
  progress.step(0, "Scanning for rogue .cleo/ directories");
51524
- const projectRoot = getProjectRoot42();
52043
+ const projectRoot = getProjectRoot43();
51525
52044
  const reports = scanRogueCleoDirs(projectRoot);
51526
52045
  progress.complete(
51527
52046
  `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
@@ -51530,7 +52049,7 @@ var init_doctor = __esm({
51530
52049
  } else if (args["quarantine-rogue-cleo-dirs"]) {
51531
52050
  const isDryRun = args["dry-run"] === true;
51532
52051
  progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
51533
- const projectRoot = getProjectRoot42();
52052
+ const projectRoot = getProjectRoot43();
51534
52053
  const reports = scanRogueCleoDirs(projectRoot);
51535
52054
  if (reports.length === 0) {
51536
52055
  progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
@@ -51584,7 +52103,7 @@ var init_doctor = __esm({
51584
52103
  const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
51585
52104
  const { getCleoHome: getCleoHome6 } = await import("@cleocode/core");
51586
52105
  const cleoHome = getCleoHome6();
51587
- const projectRoot = getProjectRoot42();
52106
+ const projectRoot = getProjectRoot43();
51588
52107
  const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
51589
52108
  const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
51590
52109
  const isDryRun = args["dry-run"] === true;
@@ -51617,7 +52136,7 @@ var init_doctor = __esm({
51617
52136
  } else if (args["audit-worktree-orphans"]) {
51618
52137
  progress.step(0, "Comprehensive worktree anomaly audit (T9808 / council D009)");
51619
52138
  const { auditWorktreeOrphansComprehensive, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
51620
- const projectRoot = getProjectRoot42();
52139
+ const projectRoot = getProjectRoot43();
51621
52140
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
51622
52141
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
51623
52142
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -51674,7 +52193,7 @@ var init_doctor = __esm({
51674
52193
  `${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
51675
52194
  );
51676
52195
  const { pruneWorktreeOrphans, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
51677
- const projectRoot = getProjectRoot42();
52196
+ const projectRoot = getProjectRoot43();
51678
52197
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
51679
52198
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
51680
52199
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -51753,7 +52272,7 @@ var init_doctor = __esm({
51753
52272
  `${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
51754
52273
  );
51755
52274
  const { migrateWorktreeIncludeFile } = await import("@cleocode/core");
51756
- const projectRoot = getProjectRoot42();
52275
+ const projectRoot = getProjectRoot43();
51757
52276
  const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
51758
52277
  progress.complete(`Migration ${result.action}`);
51759
52278
  cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
@@ -51772,7 +52291,7 @@ var init_doctor = __esm({
51772
52291
  const stepLabel = isFocusedAlias ? "Auditing Saga hierarchy for ADR-073 invariants" : "Walking central INVARIANTS_REGISTRY";
51773
52292
  progress.step(0, stepLabel);
51774
52293
  const { auditInvariantRegistry } = await import("@cleocode/core/doctor/invariant-audit.js");
51775
- const projectRoot = getProjectRoot42();
52294
+ const projectRoot = getProjectRoot43();
51776
52295
  const result = await auditInvariantRegistry(projectRoot, { adrFilter });
51777
52296
  const operation = isFocusedAlias ? "doctor.audit-sagas" : "doctor.audit-invariants";
51778
52297
  const summary = `Invariant audit complete \u2014 ${result.totalCount} entries walked, ${result.errorCount} error / ${result.warningCount} warning / ${result.infoCount} info violation(s), ${result.notApplicableCount} not-applicable, ${result.documentedCount} documented`;
@@ -51794,7 +52313,7 @@ var init_doctor = __esm({
51794
52313
  { command: "doctor", operation: "admin.health" }
51795
52314
  );
51796
52315
  try {
51797
- const projectRoot = getProjectRoot42();
52316
+ const projectRoot = getProjectRoot43();
51798
52317
  const conflicts = readMigrationConflicts(projectRoot);
51799
52318
  if (conflicts.length > 0) {
51800
52319
  progress.complete(
@@ -51825,7 +52344,7 @@ var init_doctor = __esm({
51825
52344
  progress.complete("Health check complete");
51826
52345
  }
51827
52346
  try {
51828
- const projectRoot = getProjectRoot42();
52347
+ const projectRoot = getProjectRoot43();
51829
52348
  const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
51830
52349
  const sagaAudit = await auditSagaHierarchy(projectRoot);
51831
52350
  if (sagaAudit.sagas.length === 0) {
@@ -52295,14 +52814,16 @@ import { resolveDualScopeDbPath } from "@cleocode/core/store/dual-scope-db.js";
52295
52814
  import {
52296
52815
  archiveMigratedSources,
52297
52816
  buildExodusPlan as buildExodusPlan2,
52817
+ hasExodusCompleteMarker,
52298
52818
  runExodusMigrate,
52299
52819
  runExodusStatus,
52300
52820
  runExodusVerify,
52821
+ sealExodus,
52301
52822
  sourcesPresent,
52302
52823
  verifyMigration
52303
52824
  } from "@cleocode/core/store/exodus/index.js";
52304
52825
  import { isDataContinuityOk } from "@cleocode/core/store/exodus/on-open.js";
52305
- function fmtBytes2(n) {
52826
+ function fmtBytes3(n) {
52306
52827
  if (n < 1024) return `${n} B`;
52307
52828
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
52308
52829
  return `${(n / 1024 / 1024).toFixed(1)} MB`;
@@ -52327,7 +52848,7 @@ function showStatus() {
52327
52848
  }
52328
52849
  cliOutput(result, { command: "exodus status" });
52329
52850
  }
52330
- var migrateSubCommand, verifySubCommand, statusSubCommand, exodusCommand;
52851
+ var migrateSubCommand, verifySubCommand, sealSubCommand, statusSubCommand, exodusCommand;
52331
52852
  var init_exodus = __esm({
52332
52853
  "packages/cleo/src/cli/commands/exodus.ts"() {
52333
52854
  "use strict";
@@ -52350,23 +52871,52 @@ var init_exodus = __esm({
52350
52871
  type: "boolean",
52351
52872
  description: "Skip schema-version guard (AC9 \u2014 use with care)",
52352
52873
  default: false
52874
+ },
52875
+ scope: {
52876
+ type: "string",
52877
+ description: "Which scope to migrate: 'global', 'project', or 'both' (default = full fleet)",
52878
+ default: "both"
52353
52879
  }
52354
52880
  },
52355
52881
  async run({ args }) {
52356
52882
  const dryRun = args["dry-run"] === true;
52357
52883
  const forceCrossVersion = args["force-cross-version"] === true;
52358
- const plan = buildExodusPlan2(process.cwd());
52884
+ const scope = args.scope ?? "both";
52885
+ if (scope !== "both" && scope !== "project" && scope !== "global") {
52886
+ cliError(
52887
+ `Invalid --scope '${scope}'. Use 'global', 'project', or 'both'.`,
52888
+ 6 /* VALIDATION_ERROR */,
52889
+ { name: "E_INVALID_SCOPE" },
52890
+ { operation: "exodus.migrate" }
52891
+ );
52892
+ process.exitCode = 6 /* VALIDATION_ERROR */;
52893
+ return;
52894
+ }
52895
+ const fullPlan = buildExodusPlan2(process.cwd());
52896
+ const plan = scope === "both" ? fullPlan : { ...fullPlan, sources: fullPlan.sources.filter((s) => s.targetScope === scope) };
52897
+ if (scope !== "both" && hasExodusCompleteMarker(scope) && !dryRun) {
52898
+ cliOutput(
52899
+ { kind: "generic", ok: true, alreadySealed: true, scope },
52900
+ {
52901
+ command: "exodus migrate",
52902
+ message: `Scope '${scope}' already migrated + sealed (completion marker present) \u2014 nothing to do.`
52903
+ }
52904
+ );
52905
+ return;
52906
+ }
52359
52907
  humanInfo(`Exodus migration plan:`);
52360
52908
  humanInfo(
52361
- ` Source DBs (${plan.sources.length} total, ${fmtBytes2(plan.totalSourceBytes)} combined):`
52909
+ ` Source DBs (${plan.sources.length} total, ${fmtBytes3(plan.totalSourceBytes)} combined):`
52362
52910
  );
52363
52911
  for (const s of plan.sources) {
52364
52912
  humanInfo(` [${s.targetScope.padEnd(7)}] ${s.name.padEnd(20)} ${s.path}`);
52365
52913
  }
52366
52914
  humanInfo(` Target project cleo.db: ${plan.projectDbPath}`);
52367
52915
  humanInfo(` Target global cleo.db: ${plan.globalDbPath}`);
52368
- humanInfo(` Available disk: ${fmtBytes2(plan.availableBytes)}`);
52369
- humanInfo(` Required (3\xD7): ${fmtBytes2(3 * plan.totalSourceBytes)}`);
52916
+ humanInfo(` Available disk: ${fmtBytes3(plan.availableBytes)}`);
52917
+ humanInfo(
52918
+ ` Required (1.2\xD7 largest ${fmtBytes3(plan.largestSourceBytes)} + consolidated): ${fmtBytes3(plan.requiredBytes)}`
52919
+ );
52370
52920
  humanInfo(` Disk pre-flight: ${plan.diskPreflight ? "PASS" : "FAIL"}`);
52371
52921
  if (plan.resumeFromStaging) {
52372
52922
  humanInfo(` Resuming from existing staging: ${plan.stagingDir}`);
@@ -52383,6 +52933,8 @@ var init_exodus = __esm({
52383
52933
  targetScope: s.targetScope
52384
52934
  })),
52385
52935
  totalSourceBytes: plan.totalSourceBytes,
52936
+ largestSourceBytes: plan.largestSourceBytes,
52937
+ requiredBytes: plan.requiredBytes,
52386
52938
  availableBytes: plan.availableBytes,
52387
52939
  diskPreflight: plan.diskPreflight,
52388
52940
  stagingDir: plan.stagingDir,
@@ -52406,8 +52958,9 @@ var init_exodus = __esm({
52406
52958
  return;
52407
52959
  }
52408
52960
  if (!plan.diskPreflight) {
52961
+ const shortfall = Math.max(0, plan.requiredBytes - plan.availableBytes);
52409
52962
  cliError(
52410
- `Insufficient disk space for exodus. Need \u22653\xD7 source size (${fmtBytes2(plan.totalSourceBytes)}), have ${fmtBytes2(plan.availableBytes)}.`,
52963
+ `Insufficient disk space for exodus. Need \u2265${fmtBytes3(plan.requiredBytes)} (\u22481.2\xD7 largest source ${fmtBytes3(plan.largestSourceBytes)} + consolidated estimate ${fmtBytes3(plan.totalSourceBytes)}), have ${fmtBytes3(plan.availableBytes)} \u2014 ${fmtBytes3(shortfall)} short. Free up space (e.g. \`cleo backup prune\`) or move .cleo/ to a larger volume.`,
52411
52964
  6 /* VALIDATION_ERROR */,
52412
52965
  { name: "E_DISK_PREFLIGHT_FAIL" },
52413
52966
  { operation: "exodus.migrate" }
@@ -52544,6 +53097,67 @@ Passing tables (${passing.length}):`);
52544
53097
  }
52545
53098
  }
52546
53099
  });
53100
+ sealSubCommand = defineCommand({
53101
+ meta: {
53102
+ name: "seal",
53103
+ description: "Certify an already-migrated install: count-parity gate (no digest) \u2192 archive legacy source DBs (reversible) + write the completion marker so exodus-on-open stops re-firing."
53104
+ },
53105
+ args: {
53106
+ scope: {
53107
+ type: "string",
53108
+ description: "Which scope to seal: 'global', 'project', or 'both' (default)",
53109
+ default: "both"
53110
+ }
53111
+ },
53112
+ run({ args }) {
53113
+ const scope = args.scope ?? "both";
53114
+ if (scope !== "both" && scope !== "project" && scope !== "global") {
53115
+ cliError(
53116
+ `Invalid --scope '${scope}'. Use 'global', 'project', or 'both'.`,
53117
+ 6 /* VALIDATION_ERROR */,
53118
+ { name: "E_INVALID_SCOPE" },
53119
+ { operation: "exodus.seal" }
53120
+ );
53121
+ process.exitCode = 6 /* VALIDATION_ERROR */;
53122
+ return;
53123
+ }
53124
+ const plan = buildExodusPlan2(process.cwd());
53125
+ const result = sealExodus(plan, scope, process.cwd());
53126
+ if (!result.ok) {
53127
+ cliError(
53128
+ result.refusedReason ?? "Seal refused \u2014 parity deficit.",
53129
+ 1 /* GENERAL_ERROR */,
53130
+ { name: "E_EXODUS_SEAL_DEFICIT" },
53131
+ { operation: "exodus.seal" }
53132
+ );
53133
+ process.exitCode = 1 /* GENERAL_ERROR */;
53134
+ return;
53135
+ }
53136
+ for (const sc of result.scopes) {
53137
+ const moved = sc.archived.filter((a) => a.action === "archived").length;
53138
+ humanInfo(
53139
+ ` [${sc.scope}] ${sc.alreadySealed ? "re-sealed" : "sealed"} \u2014 archived ${moved} legacy DB(s), marker: ${sc.markerPath}`
53140
+ );
53141
+ }
53142
+ cliOutput(
53143
+ {
53144
+ kind: "generic",
53145
+ ok: true,
53146
+ scopesSealed: result.scopes.map((s) => s.scope),
53147
+ tablesVerified: result.parity.checked,
53148
+ archived: result.scopes.flatMap(
53149
+ (s) => s.archived.filter((a) => a.action === "archived").map((a) => ({ scope: s.scope, name: a.name, archivedTo: a.archivedTo }))
53150
+ )
53151
+ },
53152
+ {
53153
+ command: "exodus seal",
53154
+ message: `Sealed ${result.scopes.map((s) => s.scope).join(
53155
+ " + "
53156
+ )} \u2014 ${result.parity.checked} tables count-verified, legacy DBs archived (reversible).`
53157
+ }
53158
+ );
53159
+ }
53160
+ });
52547
53161
  statusSubCommand = defineCommand({
52548
53162
  meta: {
52549
53163
  name: "status",
@@ -52561,6 +53175,7 @@ Passing tables (${passing.length}):`);
52561
53175
  subCommands: {
52562
53176
  migrate: migrateSubCommand,
52563
53177
  verify: verifySubCommand,
53178
+ seal: sealSubCommand,
52564
53179
  status: statusSubCommand
52565
53180
  },
52566
53181
  async run({ cmd, rawArgs }) {
@@ -52939,6 +53554,7 @@ var init_find = __esm({
52939
53554
  }
52940
53555
  },
52941
53556
  async run({ args }) {
53557
+ if (maybeEmitDescribe("query", "tasks", "find", { command: "find" })) return;
52942
53558
  const limit = args.limit !== void 0 ? Number.parseInt(args.limit, 10) : void 0;
52943
53559
  const offset = args.offset !== void 0 ? Number.parseInt(args.offset, 10) : void 0;
52944
53560
  const params = {};
@@ -53314,7 +53930,7 @@ var go_exports = {};
53314
53930
  __export(go_exports, {
53315
53931
  goCommand: () => goCommand
53316
53932
  });
53317
- import { getProjectRoot as getProjectRoot43, go } from "@cleocode/core";
53933
+ import { getProjectRoot as getProjectRoot44, go } from "@cleocode/core";
53318
53934
  var goCommand;
53319
53935
  var init_go = __esm({
53320
53936
  "packages/cleo/src/cli/commands/go.ts"() {
@@ -53339,7 +53955,7 @@ var init_go = __esm({
53339
53955
  }
53340
53956
  },
53341
53957
  async run({ args }) {
53342
- const projectRoot = getProjectRoot43();
53958
+ const projectRoot = getProjectRoot44();
53343
53959
  const result = await go.cleoGo({
53344
53960
  sagaId: typeof args.saga === "string" && args.saga.length > 0 ? args.saga : void 0,
53345
53961
  headless: args.headless === true,
@@ -53356,7 +53972,7 @@ var goal_exports = {};
53356
53972
  __export(goal_exports, {
53357
53973
  goalCommand: () => goalCommand
53358
53974
  });
53359
- import { getProjectRoot as getProjectRoot44, goal } from "@cleocode/core";
53975
+ import { getProjectRoot as getProjectRoot45, goal } from "@cleocode/core";
53360
53976
  function resolveGoalKind(task) {
53361
53977
  if (typeof task === "string" && task.length > 0) {
53362
53978
  if (!isValidGoalTargetTaskId(task)) {
@@ -53403,7 +54019,7 @@ var init_goal2 = __esm({
53403
54019
  }
53404
54020
  const record = await goal.createGoal(
53405
54021
  { goalKind: kindResult.kind, intent, turnBudget: resolveTurnBudget(args.turns) },
53406
- getProjectRoot44()
54022
+ getProjectRoot45()
53407
54023
  );
53408
54024
  cliOutput(record, { command: "goal set", operation: "goal.set" });
53409
54025
  }
@@ -53414,7 +54030,7 @@ var init_goal2 = __esm({
53414
54030
  description: "Show the current agent's active goal (per-agent scoped)."
53415
54031
  },
53416
54032
  async run() {
53417
- const record = await goal.getActiveGoal(getProjectRoot44());
54033
+ const record = await goal.getActiveGoal(getProjectRoot45());
53418
54034
  cliOutput(record ?? { active: null }, { command: "goal status", operation: "goal.status" });
53419
54035
  }
53420
54036
  });
@@ -53436,7 +54052,7 @@ var init_goal2 = __esm({
53436
54052
  });
53437
54053
  return;
53438
54054
  }
53439
- const cwd = getProjectRoot44();
54055
+ const cwd = getProjectRoot45();
53440
54056
  const parent = await goal.getActiveGoal(cwd);
53441
54057
  if (!parent) {
53442
54058
  cliError(
@@ -53484,7 +54100,7 @@ var init_goal2 = __esm({
53484
54100
  });
53485
54101
  return;
53486
54102
  }
53487
- const cwd = getProjectRoot44();
54103
+ const cwd = getProjectRoot45();
53488
54104
  const result = await goal.advanceGoalWithPersist(goalId, { cwd });
53489
54105
  if (!result) {
53490
54106
  cliError(`Goal '${goalId}' not found.`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
@@ -53509,7 +54125,7 @@ var init_goal2 = __esm({
53509
54125
  });
53510
54126
  return;
53511
54127
  }
53512
- const cwd = getProjectRoot44();
54128
+ const cwd = getProjectRoot45();
53513
54129
  const active = await goal.getActiveGoal(cwd);
53514
54130
  if (!active) {
53515
54131
  cliError(
@@ -54498,7 +55114,7 @@ var hygiene_exports = {};
54498
55114
  __export(hygiene_exports, {
54499
55115
  hygieneCommand: () => hygieneCommand
54500
55116
  });
54501
- import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
55117
+ import { getProjectRoot as getProjectRoot46 } from "@cleocode/core";
54502
55118
  import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
54503
55119
  var hygieneCommand;
54504
55120
  var init_hygiene = __esm({
@@ -54527,7 +55143,7 @@ var init_hygiene = __esm({
54527
55143
  }
54528
55144
  },
54529
55145
  async run({ args }) {
54530
- const projectRoot = args["project-root"] || getProjectRoot45() || process.cwd();
55146
+ const projectRoot = args["project-root"] || getProjectRoot46() || process.cwd();
54531
55147
  const worktreePath = args["worktree-path"];
54532
55148
  await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
54533
55149
  }
@@ -55651,6 +56267,7 @@ var init_list3 = __esm({
55651
56267
  meta: { name: "list", description: "List tasks with optional filters" },
55652
56268
  args: listArgs,
55653
56269
  async run({ args }) {
56270
+ if (maybeEmitDescribe("query", "tasks", "list", { command: "list" })) return;
55654
56271
  const limit = args["limit"] !== void 0 ? parseInt(args["limit"], 10) : void 0;
55655
56272
  const offset = args["offset"] !== void 0 ? parseInt(args["offset"], 10) : void 0;
55656
56273
  const params = {};
@@ -55689,7 +56306,7 @@ var llm_cost_exports = {};
55689
56306
  __export(llm_cost_exports, {
55690
56307
  costCommand: () => costCommand
55691
56308
  });
55692
- import { getProjectRoot as getProjectRoot46 } from "@cleocode/core/internal";
56309
+ import { getProjectRoot as getProjectRoot47 } from "@cleocode/core/internal";
55693
56310
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
55694
56311
  function resolveSessionId(raw) {
55695
56312
  if (raw === "current") {
@@ -55762,7 +56379,7 @@ var init_llm_cost = __esm({
55762
56379
  process.exit(6);
55763
56380
  }
55764
56381
  const sessionId = resolveSessionId(rawSessionId);
55765
- const projectRoot = getProjectRoot46(process.cwd());
56382
+ const projectRoot = getProjectRoot47(process.cwd());
55766
56383
  let breakdown;
55767
56384
  try {
55768
56385
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -57336,7 +57953,7 @@ var memory_exports = {};
57336
57953
  __export(memory_exports, {
57337
57954
  memoryCommand: () => memoryCommand
57338
57955
  });
57339
- import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
57956
+ import { getProjectRoot as getProjectRoot48 } from "@cleocode/core";
57340
57957
  import {
57341
57958
  getBrainDb as getBrainDb2,
57342
57959
  getDreamStatus,
@@ -58269,7 +58886,7 @@ var init_memory3 = __esm({
58269
58886
  },
58270
58887
  args: {},
58271
58888
  async run() {
58272
- const root = getProjectRoot47();
58889
+ const root = getProjectRoot48();
58273
58890
  try {
58274
58891
  const result = await runConsolidation(root);
58275
58892
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -58293,7 +58910,7 @@ var init_memory3 = __esm({
58293
58910
  }
58294
58911
  },
58295
58912
  async run({ args }) {
58296
- const root = getProjectRoot47();
58913
+ const root = getProjectRoot48();
58297
58914
  if (args.status) {
58298
58915
  try {
58299
58916
  const status = await getDreamStatus(root);
@@ -58330,7 +58947,7 @@ var init_memory3 = __esm({
58330
58947
  }
58331
58948
  },
58332
58949
  async run({ args }) {
58333
- const root = getProjectRoot47();
58950
+ const root = getProjectRoot48();
58334
58951
  try {
58335
58952
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
58336
58953
  const observerResult = await runObserver(root, args.session, {
@@ -58370,7 +58987,7 @@ var init_memory3 = __esm({
58370
58987
  }
58371
58988
  },
58372
58989
  async run({ args }) {
58373
- const root = getProjectRoot47();
58990
+ const root = getProjectRoot48();
58374
58991
  try {
58375
58992
  await getBrainDb2(root);
58376
58993
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -58416,7 +59033,7 @@ var init_memory3 = __esm({
58416
59033
  async run({ args }) {
58417
59034
  const sourceDir = args.from;
58418
59035
  const isDryRun = !!args["dry-run"];
58419
- const projectRoot = getProjectRoot47();
59036
+ const projectRoot = getProjectRoot48();
58420
59037
  try {
58421
59038
  const result = await importMemoryFiles({
58422
59039
  sourceDir,
@@ -58567,7 +59184,7 @@ var init_memory3 = __esm({
58567
59184
  },
58568
59185
  args: {},
58569
59186
  async run() {
58570
- const root = getProjectRoot47();
59187
+ const root = getProjectRoot48();
58571
59188
  try {
58572
59189
  await getBrainDb2(root);
58573
59190
  const result = await getTierStats(root);
@@ -58610,7 +59227,7 @@ var init_memory3 = __esm({
58610
59227
  }
58611
59228
  },
58612
59229
  async run({ args }) {
58613
- const root = getProjectRoot47();
59230
+ const root = getProjectRoot48();
58614
59231
  const targetTier = args.to;
58615
59232
  const reason = args.reason;
58616
59233
  const validTiers = ["medium", "long"];
@@ -58676,7 +59293,7 @@ var init_memory3 = __esm({
58676
59293
  }
58677
59294
  },
58678
59295
  async run({ args }) {
58679
- const root = getProjectRoot47();
59296
+ const root = getProjectRoot48();
58680
59297
  const targetTier = args.to;
58681
59298
  const reason = args.reason;
58682
59299
  const validTiers = ["short", "medium"];
@@ -59139,7 +59756,7 @@ var migrate_claude_mem_exports = {};
59139
59756
  __export(migrate_claude_mem_exports, {
59140
59757
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
59141
59758
  });
59142
- import { getProjectRoot as getProjectRoot48, migrateClaudeMem } from "@cleocode/core/internal";
59759
+ import { getProjectRoot as getProjectRoot49, migrateClaudeMem } from "@cleocode/core/internal";
59143
59760
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
59144
59761
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
59145
59762
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -59202,7 +59819,7 @@ var init_migrate_claude_mem = __esm({
59202
59819
  }
59203
59820
  },
59204
59821
  async run({ args }) {
59205
- const root = getProjectRoot48();
59822
+ const root = getProjectRoot49();
59206
59823
  try {
59207
59824
  const result = await migrateClaudeMem(root, {
59208
59825
  sourcePath: args.source,
@@ -59251,7 +59868,7 @@ var init_migrate_claude_mem = __esm({
59251
59868
  }
59252
59869
  },
59253
59870
  async run({ args }) {
59254
- const projectRoot = getProjectRoot48();
59871
+ const projectRoot = getProjectRoot49();
59255
59872
  try {
59256
59873
  const db = await getDb2(projectRoot);
59257
59874
  const rcasdFlag = Boolean(args.rcasd);
@@ -59369,7 +59986,7 @@ __export(nexus_exports, {
59369
59986
  import { appendFile as appendFile2, mkdir as mkdir4 } from "node:fs/promises";
59370
59987
  import { homedir as homedir5 } from "node:os";
59371
59988
  import path4 from "node:path";
59372
- import { getProjectRoot as getProjectRoot49 } from "@cleocode/core";
59989
+ import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
59373
59990
  import { getSymbolImpact } from "@cleocode/core/nexus";
59374
59991
  import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
59375
59992
  import { exportNexusGraph } from "@cleocode/core/nexus/export.js";
@@ -59484,7 +60101,7 @@ var init_nexus3 = __esm({
59484
60101
  async run({ args }) {
59485
60102
  applyJsonFlag2(args.json);
59486
60103
  const projectIdOverride = args["project-id"];
59487
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
60104
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
59488
60105
  const startTime = Date.now();
59489
60106
  try {
59490
60107
  const [{ getNexusDb, nexusSchema }, { getIndexStats }] = await Promise.all([
@@ -59999,7 +60616,7 @@ var init_nexus3 = __esm({
59999
60616
  applyJsonFlag2(args.json);
60000
60617
  const startTime = Date.now();
60001
60618
  const projectIdOverride = args["project-id"];
60002
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
60619
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60003
60620
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60004
60621
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
60005
60622
  const durationMs = Date.now() - startTime;
@@ -60043,7 +60660,7 @@ var init_nexus3 = __esm({
60043
60660
  applyJsonFlag2(args.json);
60044
60661
  const startTime = Date.now();
60045
60662
  const projectIdOverride = args["project-id"];
60046
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
60663
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60047
60664
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60048
60665
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
60049
60666
  const durationMs = Date.now() - startTime;
@@ -60086,7 +60703,7 @@ var init_nexus3 = __esm({
60086
60703
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
60087
60704
  const startTime = Date.now();
60088
60705
  const projectIdOverride = args["project-id"];
60089
- const repoPath = getProjectRoot49();
60706
+ const repoPath = getProjectRoot50();
60090
60707
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60091
60708
  const limit = parseInt(args.limit, 10);
60092
60709
  const symbolName = args.symbol;
@@ -60149,7 +60766,7 @@ var init_nexus3 = __esm({
60149
60766
  const startTime = Date.now();
60150
60767
  const whyFlag = !!args.why;
60151
60768
  const projectIdOverride = args["project-id"];
60152
- const repoPath = getProjectRoot49();
60769
+ const repoPath = getProjectRoot50();
60153
60770
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60154
60771
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
60155
60772
  const symbolName = args.symbol;
@@ -60221,7 +60838,7 @@ var init_nexus3 = __esm({
60221
60838
  const projectIdOverride = args["project-id"];
60222
60839
  const isIncremental = !!args.incremental;
60223
60840
  const ctx = getFormatContext();
60224
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
60841
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60225
60842
  humanInfo(`[nexus] Analyzing: ${repoPath}${isIncremental ? " (incremental)" : ""}`);
60226
60843
  if (!isIncremental) humanInfo("[nexus] Clearing existing index for project...");
60227
60844
  try {
@@ -60324,7 +60941,7 @@ var init_nexus3 = __esm({
60324
60941
  async run({ args }) {
60325
60942
  applyJsonFlag2(args.json);
60326
60943
  const startTime = Date.now();
60327
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
60944
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60328
60945
  const name = args.name;
60329
60946
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
60330
60947
  path: repoPath,
@@ -60682,7 +61299,7 @@ var init_nexus3 = __esm({
60682
61299
  applyJsonFlag2(args.json);
60683
61300
  const startTime = Date.now();
60684
61301
  const projectIdOverride = args["project-id"];
60685
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
61302
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60686
61303
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60687
61304
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
60688
61305
  repoPath,
@@ -60788,7 +61405,7 @@ var init_nexus3 = __esm({
60788
61405
  async run({ args }) {
60789
61406
  applyJsonFlag2(args.json);
60790
61407
  const startTime = Date.now();
60791
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
61408
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60792
61409
  const projectIdOverride = args["project-id"];
60793
61410
  const beforeRef = args.before ?? "HEAD~1";
60794
61411
  const afterRef = args.after ?? "HEAD";
@@ -60906,7 +61523,7 @@ var init_nexus3 = __esm({
60906
61523
  applyJsonFlag2(args.json);
60907
61524
  const startTime = Date.now();
60908
61525
  const projectIdOverride = args["project-id"];
60909
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
61526
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60910
61527
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60911
61528
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
60912
61529
  const durationMs = Date.now() - startTime;
@@ -60962,7 +61579,7 @@ var init_nexus3 = __esm({
60962
61579
  const startTime = Date.now();
60963
61580
  const routeSymbol = args.routeSymbol;
60964
61581
  const projectIdOverride = args["project-id"];
60965
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
61582
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
60966
61583
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
60967
61584
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
60968
61585
  const durationMs = Date.now() - startTime;
@@ -61352,7 +61969,7 @@ var init_nexus3 = __esm({
61352
61969
  async run({ args }) {
61353
61970
  applyJsonFlag2(args.json);
61354
61971
  const startTime = Date.now();
61355
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
61972
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
61356
61973
  const projectIdOverride = args["project-id"];
61357
61974
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
61358
61975
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -61456,7 +62073,7 @@ var init_nexus3 = __esm({
61456
62073
  async run({ args }) {
61457
62074
  applyJsonFlag2(args.json);
61458
62075
  const startTime = Date.now();
61459
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot49();
62076
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot50();
61460
62077
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
61461
62078
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
61462
62079
  projectId,
@@ -61537,7 +62154,7 @@ var init_nexus3 = __esm({
61537
62154
  const isIncremental = !!args.incremental;
61538
62155
  try {
61539
62156
  const result = await runNexusWiki({
61540
- projectRoot: getProjectRoot49(),
62157
+ projectRoot: getProjectRoot50(),
61541
62158
  outputDir,
61542
62159
  communityFilter,
61543
62160
  incremental: isIncremental
@@ -61887,7 +62504,7 @@ __export(orchestrate_exports, {
61887
62504
  });
61888
62505
  import { execFileSync as execFileSync3 } from "node:child_process";
61889
62506
  import { orchestration } from "@cleocode/core";
61890
- import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot50 } from "@cleocode/core/internal";
62507
+ import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot51 } from "@cleocode/core/internal";
61891
62508
  function formatRollupTable(rollup) {
61892
62509
  const waves = "waves" in rollup ? rollup.waves : [rollup];
61893
62510
  const lines = [];
@@ -62030,7 +62647,7 @@ var init_orchestrate3 = __esm({
62030
62647
  },
62031
62648
  async run({ args }) {
62032
62649
  const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
62033
- const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot50(), {
62650
+ const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot51(), {
62034
62651
  ...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
62035
62652
  });
62036
62653
  cliOutput(metrics, {
@@ -64235,7 +64852,7 @@ var refresh_memory_exports = {};
64235
64852
  __export(refresh_memory_exports, {
64236
64853
  refreshMemoryCommand: () => refreshMemoryCommand
64237
64854
  });
64238
- import { getProjectRoot as getProjectRoot51 } from "@cleocode/core";
64855
+ import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
64239
64856
  var refreshMemoryCommand;
64240
64857
  var init_refresh_memory = __esm({
64241
64858
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -64248,7 +64865,7 @@ var init_refresh_memory = __esm({
64248
64865
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
64249
64866
  },
64250
64867
  async run() {
64251
- const projectDir = getProjectRoot51();
64868
+ const projectDir = getProjectRoot52();
64252
64869
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
64253
64870
  const result = await writeMemoryBridge(projectDir);
64254
64871
  if (result.written) {
@@ -65775,7 +66392,7 @@ import fs3 from "node:fs";
65775
66392
  import path5 from "node:path";
65776
66393
  import {
65777
66394
  CleoError as CleoError8,
65778
- getProjectRoot as getProjectRoot52,
66395
+ getProjectRoot as getProjectRoot53,
65779
66396
  getTaskAccessor as getTaskAccessor3,
65780
66397
  parseConflictReport,
65781
66398
  setAtPath
@@ -65796,7 +66413,7 @@ var init_restore = __esm({
65796
66413
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
65797
66414
  },
65798
66415
  async run() {
65799
- const projectRoot = getProjectRoot52();
66416
+ const projectRoot = getProjectRoot53();
65800
66417
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME3, RESTORE_CONFLICTS_MD);
65801
66418
  if (!fs3.existsSync(reportPath)) {
65802
66419
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -66718,8 +67335,8 @@ var init_saga = __esm({
66718
67335
  }
66719
67336
  },
66720
67337
  async run({ args }) {
66721
- const { sagas: sagas2, getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
66722
- const projectRoot = getProjectRoot58();
67338
+ const { sagas: sagas2, getProjectRoot: getProjectRoot59 } = await import("@cleocode/core");
67339
+ const projectRoot = getProjectRoot59();
66723
67340
  const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
66724
67341
  const result = await sagas2.sagaNext(projectRoot, { sagaId });
66725
67342
  cliOutput(result.success ? result.data : result, { command: "saga", operation: "saga.next" });
@@ -66756,7 +67373,7 @@ __export(schema_exports, {
66756
67373
  schemaCommand: () => schemaCommand2
66757
67374
  });
66758
67375
  import { getInputContract } from "@cleocode/core";
66759
- import { describeOperation as describeOperation2 } from "@cleocode/lafs";
67376
+ import { describeOperation as describeOperation3 } from "@cleocode/lafs";
66760
67377
  function resolveOperationDef(operationArg) {
66761
67378
  const dotIdx = operationArg.indexOf(".");
66762
67379
  if (dotIdx === -1) {
@@ -66892,7 +67509,7 @@ var init_schema = __esm({
66892
67509
  );
66893
67510
  return;
66894
67511
  }
66895
- const schema2 = describeOperation2(def, {
67512
+ const schema2 = describeOperation3(def, {
66896
67513
  includeGates,
66897
67514
  includeExamples
66898
67515
  });
@@ -68461,7 +69078,7 @@ var sequence_exports = {};
68461
69078
  __export(sequence_exports, {
68462
69079
  sequenceCommand: () => sequenceCommand
68463
69080
  });
68464
- import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/internal";
69081
+ import { getProjectRoot as getProjectRoot54 } from "@cleocode/core/internal";
68465
69082
  var showCommand13, checkCommand7, repairCommand2, sequenceCommand;
68466
69083
  var init_sequence = __esm({
68467
69084
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -68497,7 +69114,7 @@ var init_sequence = __esm({
68497
69114
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
68498
69115
  async run() {
68499
69116
  const { repairSequence } = await import("@cleocode/core/internal");
68500
- const projectRoot = getProjectRoot53();
69117
+ const projectRoot = getProjectRoot54();
68501
69118
  const repair = await repairSequence(projectRoot);
68502
69119
  const result = {
68503
69120
  repaired: repair.repaired,
@@ -68952,8 +69569,8 @@ var init_session4 = __esm({
68952
69569
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
68953
69570
  },
68954
69571
  async run({ args }) {
68955
- const { detectSessionDrift, getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
68956
- const projectRoot = await getProjectRoot58();
69572
+ const { detectSessionDrift, getProjectRoot: getProjectRoot59 } = await import("@cleocode/core");
69573
+ const projectRoot = await getProjectRoot59();
68957
69574
  const scope = args["audit-scope"] === "local" ? "local" : "global";
68958
69575
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
68959
69576
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -71650,13 +72267,13 @@ var init_telemetry2 = __esm({
71650
72267
  // packages/cleo/src/cli/commands/templates/lib.ts
71651
72268
  import { readFileSync as readFileSync15 } from "node:fs";
71652
72269
  import { isAbsolute as isAbsolute3, resolve as resolve8 } from "node:path";
71653
- import { getProjectRoot as getProjectRoot54 } from "@cleocode/core";
72270
+ import { getProjectRoot as getProjectRoot55 } from "@cleocode/core";
71654
72271
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
71655
72272
  function resolveProjectRoot6(raw) {
71656
72273
  if (typeof raw === "string" && raw.length > 0) {
71657
72274
  return isAbsolute3(raw) ? raw : resolve8(process.cwd(), raw);
71658
72275
  }
71659
- return getProjectRoot54();
72276
+ return getProjectRoot55();
71660
72277
  }
71661
72278
  function readTemplateSource(entry) {
71662
72279
  const sourceAbsolute = resolveSourcePathAbsolute(entry);
@@ -72440,7 +73057,7 @@ __export(token_exports, {
72440
73057
  tokenCommand: () => tokenCommand
72441
73058
  });
72442
73059
  import { readFileSync as readFileSync19 } from "node:fs";
72443
- import { getProjectRoot as getProjectRoot55, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
73060
+ import { getProjectRoot as getProjectRoot56, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
72444
73061
  function readPayload(args, textKey, fileKey) {
72445
73062
  const text = args[textKey];
72446
73063
  const file = args[fileKey];
@@ -72604,7 +73221,7 @@ var init_token = __esm({
72604
73221
  domain: args.domain,
72605
73222
  operation: args.operation
72606
73223
  };
72607
- const result = args.record ? await recordTokenExchange2(getProjectRoot55(), input2) : await measureTokenExchange(input2);
73224
+ const result = args.record ? await recordTokenExchange2(getProjectRoot56(), input2) : await measureTokenExchange(input2);
72608
73225
  cliOutput(result, {
72609
73226
  command: "token",
72610
73227
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -72640,7 +73257,7 @@ __export(transcript_exports, {
72640
73257
  });
72641
73258
  import { homedir as homedir6 } from "node:os";
72642
73259
  import { join as join34 } from "node:path";
72643
- import { getProjectRoot as getProjectRoot56 } from "@cleocode/core";
73260
+ import { getProjectRoot as getProjectRoot57 } from "@cleocode/core";
72644
73261
  import {
72645
73262
  parseDurationMs,
72646
73263
  pruneTranscripts,
@@ -72670,7 +73287,7 @@ var init_transcript = __esm({
72670
73287
  async run({ args }) {
72671
73288
  if (args.pending) {
72672
73289
  try {
72673
- const projectRoot = getProjectRoot56();
73290
+ const projectRoot = getProjectRoot57();
72674
73291
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
72675
73292
  const pending = await scanPendingTranscripts(projectRoot);
72676
73293
  cliOutput(
@@ -72767,7 +73384,7 @@ var init_transcript = __esm({
72767
73384
  async run({ args }) {
72768
73385
  const tier = args.tier ?? "warm";
72769
73386
  const dryRun = args["dry-run"] ?? false;
72770
- const projectRoot = getProjectRoot56();
73387
+ const projectRoot = getProjectRoot57();
72771
73388
  try {
72772
73389
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
72773
73390
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -72879,7 +73496,7 @@ var init_transcript = __esm({
72879
73496
  const dryRun = args["dry-run"] ?? false;
72880
73497
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
72881
73498
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
72882
- const projectRoot = getProjectRoot56();
73499
+ const projectRoot = getProjectRoot57();
72883
73500
  try {
72884
73501
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
72885
73502
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -73302,6 +73919,7 @@ var init_update = __esm({
73302
73919
  }
73303
73920
  },
73304
73921
  async run({ args, cmd }) {
73922
+ if (maybeEmitDescribe("mutate", "tasks", "update", { command: "update" })) return;
73305
73923
  const paramsArg = args.params;
73306
73924
  const paramsFileArg = args["params-file"];
73307
73925
  if (paramsArg !== void 0 || paramsFileArg !== void 0) {
@@ -74353,9 +74971,9 @@ var init_workgraph2 = __esm({
74353
74971
  },
74354
74972
  async run({ args }) {
74355
74973
  const { generatePlanningDoc } = await import("@cleocode/core/workgraph");
74356
- const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
74974
+ const { getProjectRoot: getProjectRoot59 } = await import("@cleocode/core");
74357
74975
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
74358
- const projectRoot = getProjectRoot58();
74976
+ const projectRoot = getProjectRoot59();
74359
74977
  const audience = String(args.audience) === "agent" ? "agent" : "maintainer";
74360
74978
  const result = await generatePlanningDoc(projectRoot, {
74361
74979
  sagaId: String(args.sagaId),
@@ -74372,9 +74990,9 @@ var init_workgraph2 = __esm({
74372
74990
  async run() {
74373
74991
  const { validateWorkGraphStructure } = await import("@cleocode/core/workgraph");
74374
74992
  const { taskList: taskList2 } = await import("@cleocode/core/internal");
74375
- const { getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
74993
+ const { getProjectRoot: getProjectRoot59 } = await import("@cleocode/core");
74376
74994
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
74377
- const projectRoot = getProjectRoot58();
74995
+ const projectRoot = getProjectRoot59();
74378
74996
  const listResult = await taskList2(projectRoot, { limit: 5e3 });
74379
74997
  const tasks = listResult.success ? listResult.data?.tasks ?? [] : [];
74380
74998
  const nodes = tasks.map((t) => ({
@@ -74393,9 +75011,9 @@ var init_workgraph2 = __esm({
74393
75011
  description: "One-shot saga-to-saga workgraph dashboard (tracking checklist)"
74394
75012
  },
74395
75013
  async run() {
74396
- const { sagas: sagas2, getProjectRoot: getProjectRoot58 } = await import("@cleocode/core");
75014
+ const { sagas: sagas2, getProjectRoot: getProjectRoot59 } = await import("@cleocode/core");
74397
75015
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
74398
- const projectRoot = getProjectRoot58();
75016
+ const projectRoot = getProjectRoot59();
74399
75017
  const listResult = await sagas2.sagaList(projectRoot);
74400
75018
  if (!listResult.success) {
74401
75019
  cliOutput2(listResult, { command: "workgraph", operation: "workgraph.status" });
@@ -74461,7 +75079,7 @@ __export(worktree_exports, {
74461
75079
  worktreeCommand: () => worktreeCommand
74462
75080
  });
74463
75081
  import readline4 from "node:readline";
74464
- import { getProjectRoot as getProjectRoot57, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
75082
+ import { getProjectRoot as getProjectRoot58, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
74465
75083
  async function promptYesNo2(question) {
74466
75084
  return new Promise((resolve11) => {
74467
75085
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -74566,7 +75184,7 @@ var init_worktree3 = __esm({
74566
75184
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
74567
75185
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
74568
75186
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
74569
- const projectRoot = getProjectRoot57();
75187
+ const projectRoot = getProjectRoot58();
74570
75188
  const listResult = await listWorktrees2({
74571
75189
  projectRoot,
74572
75190
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -74805,6 +75423,7 @@ var init_worktree3 = __esm({
74805
75423
 
74806
75424
  // packages/cleo/src/cli/index.ts
74807
75425
  init_dist();
75426
+ init_describe_context();
74808
75427
  init_field_context();
74809
75428
  init_format_context();
74810
75429
  import { readFileSync as readFileSync21 } from "node:fs";
@@ -75132,6 +75751,18 @@ var COMMAND_MANIFEST = [
75132
75751
  description: "Walk every DB in the inventory + report integrity, row counts, orphan dirs. ",
75133
75752
  load: async () => (await Promise.resolve().then(() => (init_doctor_db_substrate(), doctor_db_substrate_exports))).doctorDbSubstrateCommand
75134
75753
  },
75754
+ {
75755
+ exportName: "doctorExodusResidueCommand",
75756
+ name: "exodus-residue",
75757
+ description: "Detect legacy exodus source DBs still present after a cutover (stranded residue that ",
75758
+ load: async () => (await Promise.resolve().then(() => (init_doctor_exodus_residue(), doctor_exodus_residue_exports))).doctorExodusResidueCommand
75759
+ },
75760
+ {
75761
+ exportName: "doctorExodusCommand",
75762
+ name: "exodus-health",
75763
+ description: "Read-only exodus health report: per-scope migration state, legacy DB sizes, completion ",
75764
+ load: async () => (await Promise.resolve().then(() => (init_doctor_exodus(), doctor_exodus_exports))).doctorExodusCommand
75765
+ },
75135
75766
  {
75136
75767
  exportName: "doctorLegacyBackupsCommand",
75137
75768
  name: "legacy-backups",
@@ -75150,6 +75781,12 @@ var COMMAND_MANIFEST = [
75150
75781
  description: "Pre-flight release readiness check \u2014 lint matrix + changelog + changeset + npm OIDC + tag-trigger sanity (T10458)",
75151
75782
  load: async () => (await Promise.resolve().then(() => (init_doctor_release_readiness(), doctor_release_readiness_exports))).doctorReleaseReadinessCommand
75152
75783
  },
75784
+ {
75785
+ exportName: "doctorRepairCommand",
75786
+ name: "repair",
75787
+ description: "Detect malformed CLEO databases (PRAGMA quick_check) and restore each from its ",
75788
+ load: async () => (await Promise.resolve().then(() => (init_doctor_repair(), doctor_repair_exports))).doctorRepairCommand
75789
+ },
75153
75790
  {
75154
75791
  exportName: "doctorCommand",
75155
75792
  name: "doctor",
@@ -76051,6 +76688,7 @@ async function startCli() {
76051
76688
  let verboseFlag = false;
76052
76689
  let outputModeRaw;
76053
76690
  let summaryFlag = false;
76691
+ let describeFlag = false;
76054
76692
  for (let i = 0; i < argv.length; i++) {
76055
76693
  const arg = argv[i];
76056
76694
  if (arg === "--json") rawOpts["json"] = true;
@@ -76062,6 +76700,7 @@ async function startCli() {
76062
76700
  else if (arg === "--verbose" || arg === "--full") verboseFlag = true;
76063
76701
  else if (arg === "--output" && i + 1 < argv.length) outputModeRaw = argv[++i];
76064
76702
  else if (arg === "--summary") summaryFlag = true;
76703
+ else if (arg === "--describe") describeFlag = true;
76065
76704
  }
76066
76705
  const interactiveTty = isInteractiveInvocation(argv) && process.stdout.isTTY === true;
76067
76706
  const formatResolution = resolveFormat(rawOpts, void 0, interactiveTty);
@@ -76091,6 +76730,7 @@ Valid modes: ${validModes.join(", ")}
76091
76730
  setOutputMode(resolvedMode);
76092
76731
  }
76093
76732
  setSummaryMode(summaryFlag);
76733
+ setDescribeMode(describeFlag);
76094
76734
  const isHelpOrVersion = argv.length === 0 || argv[0] === "--help" || argv[0] === "-h" || argv[0] === "--version" || argv[0] === "-V" || argv[0] === "help";
76095
76735
  if (argv[0] === "--version" || argv[0] === "-V") {
76096
76736
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
@@ -76139,7 +76779,8 @@ Valid modes: ${validModes.join(", ")}
76139
76779
  }
76140
76780
  }
76141
76781
  }
76142
- await runMainWithLafsEnvelope(main, argv, customShowUsage);
76782
+ const dispatchArgv = describeFlag && !isHelpOrVersion ? [...argv, "__cleo_describe__"] : argv;
76783
+ await runMainWithLafsEnvelope(main, dispatchArgv, customShowUsage);
76143
76784
  }
76144
76785
  function asCittyCliError(value) {
76145
76786
  if (!(value instanceof Error)) return null;
@@ -76198,8 +76839,8 @@ async function runStartupMaintenance() {
76198
76839
  detectAndRemoveLegacyGlobalFiles,
76199
76840
  detectAndRemoveStrayProjectNexus,
76200
76841
  getGlobalSalt,
76201
- getLogger: getLogger20,
76202
- getProjectRoot: getProjectRoot58,
76842
+ getLogger: getLogger21,
76843
+ getProjectRoot: getProjectRoot59,
76203
76844
  isCleanupMarkerSet,
76204
76845
  migrateSignaldockToConduit,
76205
76846
  needsSignaldockToConduitMigration,
@@ -76208,7 +76849,7 @@ async function runStartupMaintenance() {
76208
76849
  } = await import("@cleocode/core/internal");
76209
76850
  let projectRootForCleanup = "";
76210
76851
  try {
76211
- projectRootForCleanup = getProjectRoot58();
76852
+ projectRootForCleanup = getProjectRoot59();
76212
76853
  } catch {
76213
76854
  }
76214
76855
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -76224,11 +76865,11 @@ async function runStartupMaintenance() {
76224
76865
  }
76225
76866
  setCleanupMarker(CLI_VERSION, projectRootForCleanup);
76226
76867
  }
76227
- const _startupLog = getLogger20("cli-startup");
76868
+ const _startupLog = getLogger21("cli-startup");
76228
76869
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
76229
76870
  if (!isInitInvocation) {
76230
76871
  try {
76231
- const _projectRootForMigration = getProjectRoot58();
76872
+ const _projectRootForMigration = getProjectRoot59();
76232
76873
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
76233
76874
  const migrationResult = await migrateSignaldockToConduit(_projectRootForMigration);
76234
76875
  if (migrationResult.status === "failed") {