cc-codeconductor 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +20 -7
  2. package/dist/domain/product/entities.d.ts +1 -1
  3. package/dist/index.js +521 -246
  4. package/dist/library.js +47 -3
  5. package/dist/validation/schemas.d.ts +183 -21
  6. package/docs/generated/cli.md +8 -0
  7. package/package.json +1 -1
  8. package/presets/agy/workflows/cc-api-contract.md +4 -5
  9. package/presets/agy/workflows/cc-backlog.md +4 -5
  10. package/presets/agy/workflows/cc-clarify.md +4 -5
  11. package/presets/agy/workflows/cc-council.md +4 -5
  12. package/presets/agy/workflows/cc-db-migration.md +4 -5
  13. package/presets/agy/workflows/cc-explore.md +4 -5
  14. package/presets/agy/workflows/cc-feature.md +4 -5
  15. package/presets/agy/workflows/cc-fix.md +4 -5
  16. package/presets/agy/workflows/cc-handoff.md +8 -5
  17. package/presets/agy/workflows/cc-iterative.md +4 -5
  18. package/presets/agy/workflows/cc-odd.md +4 -3
  19. package/presets/agy/workflows/cc-openspec.md +5 -6
  20. package/presets/agy/workflows/cc-pagespeed.md +4 -5
  21. package/presets/agy/workflows/cc-prototype.md +4 -5
  22. package/presets/agy/workflows/cc-refactor.md +4 -5
  23. package/presets/agy/workflows/cc-review.md +4 -5
  24. package/presets/agy/workflows/cc-scorecard.md +4 -5
  25. package/presets/agy/workflows/cc-security.md +4 -5
  26. package/presets/agy/workflows/cc-spec-mutation.md +4 -5
  27. package/presets/agy/workflows/cc-tdd-cycle.md +4 -5
  28. package/presets/agy/workflows/cc-test-plan.md +4 -5
  29. package/presets/agy/workflows/cc-triage.md +4 -5
  30. package/presets/claude/CLAUDE.md +6 -5
  31. package/presets/claude/commands/cc/api-contract.md +4 -5
  32. package/presets/claude/commands/cc/backlog.md +4 -5
  33. package/presets/claude/commands/cc/clarify.md +4 -5
  34. package/presets/claude/commands/cc/council.md +4 -5
  35. package/presets/claude/commands/cc/db-migration.md +4 -5
  36. package/presets/claude/commands/cc/explore.md +4 -5
  37. package/presets/claude/commands/cc/feature.md +4 -5
  38. package/presets/claude/commands/cc/fix.md +4 -5
  39. package/presets/claude/commands/cc/handoff.md +8 -5
  40. package/presets/claude/commands/cc/iterative.md +4 -5
  41. package/presets/claude/commands/cc/odd.md +4 -3
  42. package/presets/claude/commands/cc/openspec.md +23 -7
  43. package/presets/claude/commands/cc/pagespeed.md +4 -5
  44. package/presets/claude/commands/cc/prototype.md +4 -5
  45. package/presets/claude/commands/cc/refactor.md +4 -5
  46. package/presets/claude/commands/cc/review.md +4 -5
  47. package/presets/claude/commands/cc/scorecard.md +4 -5
  48. package/presets/claude/commands/cc/security.md +4 -5
  49. package/presets/claude/commands/cc/spec-mutation.md +4 -5
  50. package/presets/claude/commands/cc/tdd-cycle.md +4 -5
  51. package/presets/claude/commands/cc/test-plan.md +4 -5
  52. package/presets/claude/commands/cc/triage.md +4 -5
  53. package/presets/claude/settings.json +32 -78
  54. package/presets/codex/config.toml +2 -0
  55. package/presets/codex/skills/cc-api-contract/SKILL.md +4 -5
  56. package/presets/codex/skills/cc-backlog/SKILL.md +4 -5
  57. package/presets/codex/skills/cc-clarify/SKILL.md +4 -5
  58. package/presets/codex/skills/cc-council/SKILL.md +10 -5
  59. package/presets/codex/skills/cc-db-migration/SKILL.md +4 -5
  60. package/presets/codex/skills/cc-explore/SKILL.md +4 -5
  61. package/presets/codex/skills/cc-feature/SKILL.md +4 -5
  62. package/presets/codex/skills/cc-fix/SKILL.md +4 -5
  63. package/presets/codex/skills/cc-handoff/SKILL.md +8 -5
  64. package/presets/codex/skills/cc-iterative/SKILL.md +4 -5
  65. package/presets/codex/skills/cc-odd/SKILL.md +4 -3
  66. package/presets/codex/skills/cc-openspec/SKILL.md +11 -6
  67. package/presets/codex/skills/cc-pagespeed/SKILL.md +4 -5
  68. package/presets/codex/skills/cc-prototype/SKILL.md +4 -5
  69. package/presets/codex/skills/cc-refactor/SKILL.md +4 -5
  70. package/presets/codex/skills/cc-review/SKILL.md +4 -5
  71. package/presets/codex/skills/cc-scorecard/SKILL.md +4 -5
  72. package/presets/codex/skills/cc-security/SKILL.md +4 -5
  73. package/presets/codex/skills/cc-spec-mutation/SKILL.md +4 -5
  74. package/presets/codex/skills/cc-tdd-cycle/SKILL.md +4 -5
  75. package/presets/codex/skills/cc-test-plan/SKILL.md +4 -5
  76. package/presets/codex/skills/cc-triage/SKILL.md +4 -5
  77. package/presets/cursor/commands/cc/api-contract.md +4 -5
  78. package/presets/cursor/commands/cc/backlog.md +4 -5
  79. package/presets/cursor/commands/cc/clarify.md +4 -5
  80. package/presets/cursor/commands/cc/council.md +4 -5
  81. package/presets/cursor/commands/cc/db-migration.md +4 -5
  82. package/presets/cursor/commands/cc/explore.md +4 -5
  83. package/presets/cursor/commands/cc/feature.md +4 -5
  84. package/presets/cursor/commands/cc/fix.md +4 -5
  85. package/presets/cursor/commands/cc/handoff.md +8 -5
  86. package/presets/cursor/commands/cc/iterative.md +4 -5
  87. package/presets/cursor/commands/cc/odd.md +4 -3
  88. package/presets/cursor/commands/cc/openspec.md +5 -6
  89. package/presets/cursor/commands/cc/pagespeed.md +4 -5
  90. package/presets/cursor/commands/cc/prototype.md +4 -5
  91. package/presets/cursor/commands/cc/refactor.md +4 -5
  92. package/presets/cursor/commands/cc/review.md +4 -5
  93. package/presets/cursor/commands/cc/scorecard.md +4 -5
  94. package/presets/cursor/commands/cc/security.md +4 -5
  95. package/presets/cursor/commands/cc/spec-mutation.md +4 -5
  96. package/presets/cursor/commands/cc/tdd-cycle.md +4 -5
  97. package/presets/cursor/commands/cc/test-plan.md +4 -5
  98. package/presets/cursor/commands/cc/triage.md +4 -5
  99. package/presets/gemini/commands/cc/api-contract.toml +4 -5
  100. package/presets/gemini/commands/cc/backlog.toml +4 -5
  101. package/presets/gemini/commands/cc/clarify.toml +4 -5
  102. package/presets/gemini/commands/cc/council.toml +4 -5
  103. package/presets/gemini/commands/cc/db-migration.toml +4 -5
  104. package/presets/gemini/commands/cc/explore.toml +4 -5
  105. package/presets/gemini/commands/cc/feature.toml +4 -5
  106. package/presets/gemini/commands/cc/fix.toml +4 -5
  107. package/presets/gemini/commands/cc/handoff.toml +8 -5
  108. package/presets/gemini/commands/cc/iterative.toml +4 -5
  109. package/presets/gemini/commands/cc/odd.toml +4 -3
  110. package/presets/gemini/commands/cc/openspec.toml +5 -6
  111. package/presets/gemini/commands/cc/pagespeed.toml +4 -5
  112. package/presets/gemini/commands/cc/prototype.toml +4 -5
  113. package/presets/gemini/commands/cc/refactor.toml +4 -5
  114. package/presets/gemini/commands/cc/review.toml +4 -5
  115. package/presets/gemini/commands/cc/scorecard.toml +4 -5
  116. package/presets/gemini/commands/cc/security.toml +4 -5
  117. package/presets/gemini/commands/cc/spec-mutation.toml +4 -5
  118. package/presets/gemini/commands/cc/tdd-cycle.toml +4 -5
  119. package/presets/gemini/commands/cc/test-plan.toml +4 -5
  120. package/presets/gemini/commands/cc/triage.toml +4 -5
  121. package/presets/opencode/commands/cc-api-contract.md +4 -5
  122. package/presets/opencode/commands/cc-backlog.md +4 -5
  123. package/presets/opencode/commands/cc-clarify.md +4 -5
  124. package/presets/opencode/commands/cc-council.md +4 -5
  125. package/presets/opencode/commands/cc-db-migration.md +4 -5
  126. package/presets/opencode/commands/cc-explore.md +4 -5
  127. package/presets/opencode/commands/cc-feature.md +4 -5
  128. package/presets/opencode/commands/cc-fix.md +4 -5
  129. package/presets/opencode/commands/cc-handoff.md +8 -5
  130. package/presets/opencode/commands/cc-iterative.md +4 -5
  131. package/presets/opencode/commands/cc-odd.md +4 -3
  132. package/presets/opencode/commands/cc-openspec.md +6 -7
  133. package/presets/opencode/commands/cc-pagespeed.md +4 -5
  134. package/presets/opencode/commands/cc-prototype.md +4 -5
  135. package/presets/opencode/commands/cc-refactor.md +4 -5
  136. package/presets/opencode/commands/cc-review.md +4 -5
  137. package/presets/opencode/commands/cc-scorecard.md +4 -5
  138. package/presets/opencode/commands/cc-security.md +4 -5
  139. package/presets/opencode/commands/cc-spec-mutation.md +4 -5
  140. package/presets/opencode/commands/cc-tdd-cycle.md +4 -5
  141. package/presets/opencode/commands/cc-test-plan.md +4 -5
  142. package/presets/opencode/commands/cc-triage.md +4 -5
  143. package/src/presets/manifests/codex.yml +3 -0
  144. package/src/presets/models/roles.yml +26 -28
package/dist/index.js CHANGED
@@ -72,7 +72,7 @@ var package_default;
72
72
  var init_package = __esm(() => {
73
73
  package_default = {
74
74
  name: "cc-codeconductor",
75
- version: "1.5.0",
75
+ version: "1.5.1",
76
76
  description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
77
77
  keywords: [
78
78
  "ai",
@@ -11216,9 +11216,11 @@ __export(exports_schemas, {
11216
11216
  ExecutionContextSchema: () => ExecutionContextSchema,
11217
11217
  ExecutionProfileNameSchema: () => ExecutionProfileNameSchema,
11218
11218
  ExecutionProfileSchema: () => ExecutionProfileSchema,
11219
+ FixIntakeOutputSchema: () => FixIntakeOutputSchema,
11219
11220
  GoalGraphSchema: () => GoalGraphSchema,
11220
11221
  GoalTaskSchema: () => GoalTaskSchema,
11221
11222
  GraphRelationSchema: () => GraphRelationSchema,
11223
+ HandoffEnvelopeSchema: () => HandoffEnvelopeSchema,
11222
11224
  HarnessCatalogEntrySchema: () => HarnessCatalogEntrySchema,
11223
11225
  HarnessCatalogSchema: () => HarnessCatalogSchema,
11224
11226
  HarnessComponentIdSchema: () => HarnessComponentIdSchema,
@@ -11439,7 +11441,7 @@ function validateProductEvent(data) {
11439
11441
  function validateSkillsRegistry(data) {
11440
11442
  return SkillsRegistrySchema.parse(data);
11441
11443
  }
11442
- var CouncilAgentSpecSchema, CouncilSpecSchema, ProjectProfileSchema, CompileCheckConfigSchema, LoopConfigSchema, CodeConductorConfigSchema, RunnerTargetSchema, InstallStrategySchema, ManifestEntrySchema, InstallManifestSchema, ToolProviderNamesSchema, PermissionProviderNamesSchema, ModelConfigSchema, SkillFrontmatterSchema, CommandFrontmatterSchema, TargetCapabilitiesSchema, ContractTargetSchema, ContractFormatSchema, AgentContractSchema, CouncilFindingSchema, CouncilVerdictInputSchema, ConsensusConfigSchema, CouncilVerdictSchema, ClaudeAgentFileSchema, OpenCodeAgentFileSchema, SentryStackFrameSchema, SentryWebhookSchema, MemoryPointerSchema, MemoryIndexSchema, GoalTaskSchema, GoalGraphSchema, ConfidenceLevelSchema, ProductNodeTypeSchema, GraphRelationSchema, KnowledgeEntitySchema, DecisionSchema, EvidenceSchema, CanonicalTaskCardStatusSchema, CanonicalTaskCardSchema, ProductGraphNodeSchema, ProductGraphEdgeSchema, ProductGraphSchema, ProductMetaSchema, ProductEventTypeSchema, ProductEventSchema, OperationalStateSchema, StrategicMemorySchema, ImpactReportSchema, BusinessReviewOutputSchema, VerificationReportSchema, BacklogStatusSchema, BacklogTypeSchema, BacklogPrioritySchema, BacklogGlobalSchema, BacklogItemSchema, BacklogDocumentSchema, OpenspecTaskCardPhaseSchema, OpenspecTaskCardStatusSchema, OpenspecTaskCardSchema, OpenspecStateSchema, SpecAnalyzeFindingSchema, SpecAnalyzeReportSchema, WorkflowCommandSchema, CcepOutputFormatSchema, CommandEnvelopeSchema, WorkflowPhaseSchema, WorkflowRiskRuleSchema, WorkflowProfileSchema, ExecutionContextSchema, PlannerOutputSchema, AgentArtifactSchema, AgentOutputSchema, ImplementerTestsSchema, ImplementerOutputSchema, ReviewAxisSchema, ReviewFindingSchema, ReviewerOutputSchema, TechnicalPlanOutputSchema, ScorecardVerdictSchema, ScorecardCriterionIdSchema, ScorecardCriterionSchema, ScorecardRecordSchema, TaskOutcomeSourceSchema, TaskOutcomeStatusSchema, DeliveryRouteSchema, TokenUsageSchema, DeliveryTelemetrySchema, DeliveryLedgerTaskSchema, DeliveryLedgerSchema, DeliveryLedgerRequestSchema, TaskOutcomeSchema, HarnessComponentIdSchema, HarnessComponentLayerSchema, HarnessToggleKindSchema, HarnessCatalogEntrySchema, HarnessCatalogSchema, HarnessOverlaySchema, HarnessExperimentSchema, HarnessSuiteTaskSchema, HarnessSuiteSchema, EvaluationIndexSchema, ExecutionProfileNameSchema, ExecutionProfileSchema, SkillsRegistrySchema;
11444
+ var CouncilAgentSpecSchema, CouncilSpecSchema, ProjectProfileSchema, CompileCheckConfigSchema, LoopConfigSchema, CodeConductorConfigSchema, RunnerTargetSchema, InstallStrategySchema, ManifestEntrySchema, InstallManifestSchema, ToolProviderNamesSchema, PermissionProviderNamesSchema, ModelConfigSchema, SkillFrontmatterSchema, CommandFrontmatterSchema, TargetCapabilitiesSchema, ContractTargetSchema, ContractFormatSchema, AgentContractSchema, CouncilFindingSchema, CouncilVerdictInputSchema, ConsensusConfigSchema, CouncilVerdictSchema, ClaudeAgentFileSchema, OpenCodeAgentFileSchema, SentryStackFrameSchema, SentryWebhookSchema, MemoryPointerSchema, MemoryIndexSchema, GoalTaskSchema, GoalGraphSchema, ConfidenceLevelSchema, ProductNodeTypeSchema, GraphRelationSchema, KnowledgeEntitySchema, DecisionSchema, EvidenceSchema, CanonicalTaskCardStatusSchema, CanonicalTaskCardSchema, ProductGraphNodeSchema, ProductGraphEdgeSchema, ProductGraphSchema, ProductMetaSchema, ProductEventTypeSchema, ProductEventSchema, OperationalStateSchema, StrategicMemorySchema, ImpactReportSchema, BusinessReviewOutputSchema, VerificationReportSchema, BacklogStatusSchema, BacklogTypeSchema, BacklogPrioritySchema, BacklogGlobalSchema, BacklogItemSchema, BacklogDocumentSchema, OpenspecTaskCardPhaseSchema, OpenspecTaskCardStatusSchema, OpenspecTaskCardSchema, OpenspecStateSchema, SpecAnalyzeFindingSchema, SpecAnalyzeReportSchema, WorkflowCommandSchema, CcepOutputFormatSchema, CommandEnvelopeSchema, WorkflowPhaseSchema, WorkflowRiskRuleSchema, WorkflowProfileSchema, ExecutionContextSchema, PlannerOutputSchema, AgentArtifactSchema, AgentOutputSchema, ImplementerTestsSchema, ImplementerOutputSchema, ReviewAxisSchema, ReviewFindingSchema, ReviewerOutputSchema, TechnicalPlanOutputSchema, FixIntakeOutputSchema, ScorecardVerdictSchema, ScorecardCriterionIdSchema, ScorecardCriterionSchema, ScorecardRecordSchema, TaskOutcomeSourceSchema, TaskOutcomeStatusSchema, DeliveryRouteSchema, TokenUsageSchema, DeliveryTelemetrySchema, DeliveryLedgerTaskSchema, DeliveryLedgerSchema, HandoffEnvelopeSchema, RepoRelativePathSchema, DeliveryLedgerRequestSchema, TaskOutcomeSchema, HarnessComponentIdSchema, HarnessComponentLayerSchema, HarnessToggleKindSchema, HarnessCatalogEntrySchema, HarnessCatalogSchema, HarnessOverlaySchema, HarnessExperimentSchema, HarnessSuiteTaskSchema, HarnessSuiteSchema, EvaluationIndexSchema, ExecutionProfileNameSchema, ExecutionProfileSchema, SkillsRegistrySchema;
11443
11445
  var init_schemas = __esm(() => {
11444
11446
  init_zod();
11445
11447
  init_runner_target();
@@ -11517,6 +11519,7 @@ var init_schemas = __esm(() => {
11517
11519
  "append",
11518
11520
  "merge-json",
11519
11521
  "merge-managed",
11522
+ "create-only",
11520
11523
  "skip"
11521
11524
  ]);
11522
11525
  ManifestEntrySchema = exports_external.object({
@@ -11821,7 +11824,8 @@ var init_schemas = __esm(() => {
11821
11824
  "goal.updated",
11822
11825
  "blocker.detected",
11823
11826
  "verification.completed",
11824
- "feedback.processed"
11827
+ "feedback.processed",
11828
+ "context.compiled"
11825
11829
  ]);
11826
11830
  ProductEventSchema = exports_external.object({
11827
11831
  id: exports_external.string(),
@@ -12166,6 +12170,11 @@ var init_schemas = __esm(() => {
12166
12170
  risks: exports_external.array(exports_external.string()).default([]),
12167
12171
  openQuestions: exports_external.array(exports_external.string()).optional()
12168
12172
  });
12173
+ FixIntakeOutputSchema = exports_external.object({
12174
+ actualBehavior: exports_external.string(),
12175
+ expectedBehavior: exports_external.string(),
12176
+ reproductionSteps: exports_external.array(exports_external.string())
12177
+ });
12169
12178
  ScorecardVerdictSchema = exports_external.enum(["PASS", "REVISE", "REJECT"]);
12170
12179
  ScorecardCriterionIdSchema = exports_external.enum([
12171
12180
  "acceptance",
@@ -12237,16 +12246,51 @@ var init_schemas = __esm(() => {
12237
12246
  nextStep: exports_external.string().min(1),
12238
12247
  memoryTopicKey: exports_external.string().min(1),
12239
12248
  workspace: exports_external.record(exports_external.string(), exports_external.string()),
12249
+ technicalPlanPath: exports_external.string().min(1).optional(),
12240
12250
  createdAt: exports_external.string().datetime(),
12241
12251
  updatedAt: exports_external.string().datetime()
12242
12252
  });
12253
+ HandoffEnvelopeSchema = exports_external.object({
12254
+ version: exports_external.literal(1),
12255
+ task: exports_external.object({
12256
+ id: exports_external.string().min(1),
12257
+ objective: exports_external.string().min(1),
12258
+ acceptanceCriteria: exports_external.array(exports_external.string().min(1)),
12259
+ status: CanonicalTaskCardStatusSchema
12260
+ }),
12261
+ decisions: exports_external.object({
12262
+ constraints: exports_external.array(exports_external.string()),
12263
+ unresolved: exports_external.array(exports_external.string())
12264
+ }),
12265
+ scope: exports_external.object({
12266
+ relevantFiles: exports_external.array(exports_external.string()),
12267
+ boundaries: exports_external.array(exports_external.string())
12268
+ }),
12269
+ verification: exports_external.object({
12270
+ evidence: exports_external.array(exports_external.string())
12271
+ }),
12272
+ change: exports_external.object({
12273
+ touchedFiles: exports_external.array(exports_external.string())
12274
+ }),
12275
+ next: exports_external.object({
12276
+ role: exports_external.string().min(1),
12277
+ objective: exports_external.string().min(1)
12278
+ }),
12279
+ sources: exports_external.object({
12280
+ deliveryLedger: exports_external.string().min(1),
12281
+ memoryTopicKey: exports_external.string().min(1),
12282
+ technicalPlanPath: exports_external.string().min(1).optional()
12283
+ })
12284
+ });
12285
+ RepoRelativePathSchema = exports_external.string().min(1).refine((path) => !/^([/\\]|[A-Za-z]:)/.test(path) && !path.split(/[/\\]/).includes(".."), 'Path must be relative to the repository and must not contain ".." segments');
12243
12286
  DeliveryLedgerRequestSchema = exports_external.object({
12244
12287
  id: exports_external.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/),
12245
12288
  authorized: exports_external.boolean(),
12246
12289
  route: DeliveryRouteSchema,
12247
12290
  taskCard: CanonicalTaskCardSchema,
12248
12291
  tasks: exports_external.array(DeliveryLedgerTaskSchema).min(1),
12249
- nextStep: exports_external.string().min(1)
12292
+ nextStep: exports_external.string().min(1),
12293
+ technicalPlanPath: RepoRelativePathSchema.optional()
12250
12294
  });
12251
12295
  TaskOutcomeSchema = exports_external.object({
12252
12296
  id: exports_external.string(),
@@ -13289,9 +13333,8 @@ function substituteToolNames(content, modelConfig) {
13289
13333
  }
13290
13334
  async function injectMcpServers(jsonString, filePath) {
13291
13335
  const isAgyMcpConfig = filePath.endsWith("mcp_config.json");
13292
- const isClaudeSettings = filePath.endsWith("settings.json");
13293
13336
  const isOpencodeJsonc = filePath.endsWith("opencode.jsonc") || filePath.endsWith("opencode.json");
13294
- if (!isAgyMcpConfig && !isClaudeSettings && !isOpencodeJsonc) {
13337
+ if (!isAgyMcpConfig && !isOpencodeJsonc) {
13295
13338
  return jsonString;
13296
13339
  }
13297
13340
  try {
@@ -13306,7 +13349,7 @@ async function injectMcpServers(jsonString, filePath) {
13306
13349
  mcpServers["token-savior-recall"] = {
13307
13350
  command: "token-savior",
13308
13351
  env: {
13309
- TOKEN_SAVIOR_CLIENT: isClaudeSettings ? "claude-code" : isOpencodeJsonc ? "opencode" : "agy"
13352
+ TOKEN_SAVIOR_CLIENT: isOpencodeJsonc ? "opencode" : "agy"
13310
13353
  }
13311
13354
  };
13312
13355
  }
@@ -13319,7 +13362,7 @@ async function injectMcpServers(jsonString, filePath) {
13319
13362
  if (Object.keys(mcpServers).length === 0) {
13320
13363
  return jsonString;
13321
13364
  }
13322
- if (isClaudeSettings || isAgyMcpConfig) {
13365
+ if (isAgyMcpConfig) {
13323
13366
  obj.mcpServers = mergeDeep(obj.mcpServers || {}, mcpServers);
13324
13367
  } else if (isOpencodeJsonc) {
13325
13368
  const opencodeMcp = {};
@@ -13363,7 +13406,7 @@ async function applySingleFile(srcPath, destPath, strategy, force, dryRun, isTem
13363
13406
  return { src: srcPath, dest: destPath, action: "error", error: String(error) };
13364
13407
  }
13365
13408
  }
13366
- if (strategy === "overwrite" && !force && await fileExists2(destPath)) {
13409
+ if ((strategy === "overwrite" && !force || strategy === "create-only") && await fileExists2(destPath)) {
13367
13410
  return { src: srcPath, dest: destPath, action: "skipped", dryRun };
13368
13411
  }
13369
13412
  let content;
@@ -14004,6 +14047,11 @@ ${spec.agents.map((a) => `- **${a.role}** (${a.id}): ${a.focus.join(", ")}`).joi
14004
14047
 
14005
14048
  ## Usage
14006
14049
  Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
14050
+ Use Sonnet 5.5 for the routine council pass. Share one concise evidence summary and
14051
+ the relevant diff with the necessary roles. Invoke council-architect with
14052
+ \`model: opus\` only for
14053
+ one unresolved business-logic question; return its short decision to Sonnet for
14054
+ the verdict. Do not run every council role on Opus or repeat full context.
14007
14055
 
14008
14056
  ## Context
14009
14057
  ${spec.outputContract}
@@ -14118,7 +14166,8 @@ function generateCodexFiles(spec) {
14118
14166
  files.push({
14119
14167
  path: ".codex/config.toml",
14120
14168
  content: generateCodexConfig(spec),
14121
- overwrite: false
14169
+ overwrite: false,
14170
+ mergeExisting: (existing) => mergeCodexCouncilConfig(existing, spec)
14122
14171
  });
14123
14172
  for (const agent of spec.agents) {
14124
14173
  files.push({
@@ -14134,17 +14183,32 @@ function generateCodexFiles(spec) {
14134
14183
  });
14135
14184
  return files;
14136
14185
  }
14137
- function generateCodexConfig(spec) {
14138
- const agentTables = spec.agents.map((agent) => {
14139
- const focusAreas = agent.focus.join(", ");
14140
- return `
14186
+ function agentTable(agent) {
14187
+ const focusAreas = agent.focus.join(", ");
14188
+ return `
14141
14189
  [agents.${agent.id}]
14142
14190
  description = "${agent.role} council agent. Focus: ${focusAreas}. Context: ${agent.context}. Model hint: ${agent.modelHint}."
14191
+ config_file = "agents/council_${agent.id}.toml"
14143
14192
  nickname_candidates = ["${agent.role}", "Council ${agent.role}"]`;
14144
- }).join(`
14193
+ }
14194
+ function mergeCodexCouncilConfig(existing, spec) {
14195
+ const missing = spec.agents.filter((agent) => !existing.split(`
14196
+ `).some((line) => line.trim() === `[agents.${agent.id}]`));
14197
+ if (missing.length === 0)
14198
+ return existing;
14199
+ return `${existing.trimEnd()}
14200
+ ${missing.map(agentTable).join(`
14201
+ `)}
14202
+ `;
14203
+ }
14204
+ function generateCodexConfig(spec) {
14205
+ const agentTables = spec.agents.map(agentTable).join(`
14145
14206
  `);
14146
14207
  return `# Codex Council Configuration
14147
14208
 
14209
+ model = "gpt-6.1-sol"
14210
+ model_reasoning_effort = "medium"
14211
+
14148
14212
  [project]
14149
14213
  name = "council"
14150
14214
  version = "${spec.version}"
@@ -14154,7 +14218,9 @@ ${agentTables}
14154
14218
  function generateCodexAgent(agent) {
14155
14219
  const focusAreas = agent.focus.join(", ");
14156
14220
  const checklist = checklistFor(agent.id).join("; ");
14157
- return `name = "${agent.role}"
14221
+ return `model = "gpt-6.1-sol"
14222
+ model_reasoning_effort = "medium"
14223
+ name = "${agent.role}"
14158
14224
  description = "${agent.role} council agent. Focus: ${focusAreas}. Context: ${agent.context}. Model hint: ${agent.modelHint}."
14159
14225
  nickname_candidates = ["${agent.role}", "Council ${agent.role}"]
14160
14226
  developer_instructions = "You are the ${agent.role} council agent. Your focus areas are: ${focusAreas}. Context: ${agent.context}. Apply ${agent.modelHint} reasoning to your analysis. Review checklist: ${checklist}. Categorize findings as CRITICAL (blocks the verdict), WARNING, or SUGGESTION."
@@ -14173,6 +14239,9 @@ ${spec.agents.map((a) => `- **${a.role}** (${a.id}): ${a.focus.join(", ")}`).joi
14173
14239
 
14174
14240
  ## Usage
14175
14241
  Use the council agents to get multi-perspective analysis on code changes, architecture decisions, and security reviews.
14242
+ Keep GPT-6.1 Sol at medium reasoning effort. Share a concise evidence summary
14243
+ and relevant diff with only the necessary council roles. Reuse findings in the
14244
+ final verdict instead of replaying the full transcript or repeating analysis.
14176
14245
  `;
14177
14246
  }
14178
14247
  var init_codex_council_generator = __esm(() => {
@@ -14725,7 +14794,8 @@ async function checkUpdates(basePath, isGlobal, includeConflicts = false) {
14725
14794
  let destContent;
14726
14795
  try {
14727
14796
  destContent = await readFile7(dest, "utf-8");
14728
- if (destContent.trim() !== f.content.trim()) {
14797
+ const expected = f.mergeExisting ? f.mergeExisting(destContent) : f.content;
14798
+ if (destContent.trim() !== expected.trim()) {
14729
14799
  changedFiles.push(dest);
14730
14800
  }
14731
14801
  } catch {
@@ -16910,7 +16980,7 @@ __export(exports_file_writer, {
16910
16980
  writeGeneratedFiles: () => writeGeneratedFiles,
16911
16981
  writeSingleFile: () => writeSingleFile
16912
16982
  });
16913
- import { access as access5 } from "node:fs/promises";
16983
+ import { access as access5, readFile as readFile11 } from "node:fs/promises";
16914
16984
  import { relative as relative4 } from "node:path";
16915
16985
  async function writeGeneratedFiles(files, options) {
16916
16986
  const results = [];
@@ -16937,7 +17007,15 @@ async function writeGeneratedFiles(files, options) {
16937
17007
  });
16938
17008
  continue;
16939
17009
  }
16940
- if (!options.force) {
17010
+ let content = file.content;
17011
+ let merged = false;
17012
+ if (file.mergeExisting) {
17013
+ try {
17014
+ content = file.mergeExisting(await readFile11(file.path, "utf-8"));
17015
+ merged = true;
17016
+ } catch {}
17017
+ }
17018
+ if (!options.force && !merged) {
16941
17019
  try {
16942
17020
  await access5(file.path);
16943
17021
  results.push({
@@ -16957,7 +17035,7 @@ async function writeGeneratedFiles(files, options) {
16957
17035
  continue;
16958
17036
  }
16959
17037
  try {
16960
- await writeContainedFile(options.projectRoot, relative4(options.projectRoot, file.path), file.content, { force: true });
17038
+ await writeContainedFile(options.projectRoot, relative4(options.projectRoot, file.path), content, { force: true });
16961
17039
  results.push({
16962
17040
  path: file.path,
16963
17041
  success: true
@@ -16997,7 +17075,7 @@ __export(exports_install_command, {
16997
17075
  installPresetCommand: () => installPresetCommand,
16998
17076
  verifyRenderedFiles: () => verifyRenderedFiles
16999
17077
  });
17000
- import { readFile as readFile11 } from "node:fs/promises";
17078
+ import { readFile as readFile12 } from "node:fs/promises";
17001
17079
  import { homedir as homedir7 } from "node:os";
17002
17080
  import { basename as basename5, dirname as dirname6, resolve as resolve12, sep as sep3 } from "node:path";
17003
17081
  async function installCommand(options) {
@@ -17130,7 +17208,7 @@ async function verifyRenderedFiles(manifest, baseDir, results) {
17130
17208
  continue;
17131
17209
  let content;
17132
17210
  try {
17133
- content = await readFile11(r.dest, "utf-8");
17211
+ content = await readFile12(r.dest, "utf-8");
17134
17212
  } catch {
17135
17213
  continue;
17136
17214
  }
@@ -18835,7 +18913,7 @@ var init_install_lsp_command = __esm(() => {
18835
18913
  });
18836
18914
 
18837
18915
  // src/core/install/update-transaction.ts
18838
- import { mkdir as mkdir7, readFile as readFile12, rm as rm2, unlink, writeFile as writeFile6 } from "node:fs/promises";
18916
+ import { mkdir as mkdir7, readFile as readFile13, rm as rm2, unlink, writeFile as writeFile6 } from "node:fs/promises";
18839
18917
  import { dirname as dirname7, join as join10, relative as relative5, resolve as resolve16 } from "node:path";
18840
18918
 
18841
18919
  class UpdateTransaction {
@@ -18852,7 +18930,7 @@ class UpdateTransaction {
18852
18930
  const snapshots = [];
18853
18931
  for (const destination of unique) {
18854
18932
  try {
18855
- const content = await readFile12(destination);
18933
+ const content = await readFile13(destination);
18856
18934
  snapshots.push({ path: destination, existed: true, content });
18857
18935
  const backupPath = join10(backupDir, relative5(basePath, destination));
18858
18936
  await mkdir7(dirname7(backupPath), { recursive: true });
@@ -18894,7 +18972,7 @@ __export(exports_update_command, {
18894
18972
  });
18895
18973
  import { homedir as homedir10 } from "node:os";
18896
18974
  import { resolve as resolve17, dirname as dirname8 } from "node:path";
18897
- import { mkdir as mkdir8, readFile as readFile13, writeFile as writeFile7, stat as stat3 } from "node:fs/promises";
18975
+ import { mkdir as mkdir8, readFile as readFile14, writeFile as writeFile7, stat as stat3 } from "node:fs/promises";
18898
18976
  async function updateCommand(options) {
18899
18977
  const { dryRun, force, global: isGlobal, output, projectRoot, check = false } = options;
18900
18978
  const basePath = isGlobal ? homedir10() : projectRoot;
@@ -19003,7 +19081,7 @@ async function updateCommand(options) {
19003
19081
  const localCouncil = resolve17(basePath, ".codeconductor", "presets", "council.yml");
19004
19082
  const bundledCouncil = resolve17(SRC_PRESETS_DIR, "council", "council.yml");
19005
19083
  try {
19006
- const content = await readFile13(bundledCouncil, "utf-8");
19084
+ const content = await readFile14(bundledCouncil, "utf-8");
19007
19085
  await mkdir8(dirname8(localCouncil), { recursive: true });
19008
19086
  await writeFile7(localCouncil, content, "utf-8");
19009
19087
  updated.push(localCouncil);
@@ -19014,7 +19092,7 @@ async function updateCommand(options) {
19014
19092
  if (updateResults.policy) {
19015
19093
  const localPolicy = resolve17(basePath, ".codeconductor", "presets", "policy.yml");
19016
19094
  try {
19017
- const content = await readFile13(POLICY_PATH, "utf-8");
19095
+ const content = await readFile14(POLICY_PATH, "utf-8");
19018
19096
  await mkdir8(dirname8(localPolicy), { recursive: true });
19019
19097
  await writeFile7(localPolicy, content, "utf-8");
19020
19098
  updated.push(localPolicy);
@@ -19172,7 +19250,7 @@ __export(exports_migrate_command, {
19172
19250
  migrateCommand: () => migrateCommand,
19173
19251
  migratePermissionRules: () => migratePermissionRules
19174
19252
  });
19175
- import { readFile as readFile14, readdir as readdir3, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
19253
+ import { readFile as readFile15, readdir as readdir3, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
19176
19254
  import { homedir as homedir11 } from "node:os";
19177
19255
  import { join as join11, resolve as resolve18 } from "node:path";
19178
19256
  function migratePermissionRules(settings) {
@@ -19255,7 +19333,7 @@ async function migrateCommand(options) {
19255
19333
  const settingsPath = resolveSettingsPath(options);
19256
19334
  let raw = null;
19257
19335
  try {
19258
- raw = await readFile14(settingsPath, "utf-8");
19336
+ raw = await readFile15(settingsPath, "utf-8");
19259
19337
  } catch (error) {
19260
19338
  if (error.code !== "ENOENT") {
19261
19339
  return {
@@ -19668,7 +19746,7 @@ var exports_debt_harvest_command = {};
19668
19746
  __export(exports_debt_harvest_command, {
19669
19747
  debtHarvestCommand: () => debtHarvestCommand
19670
19748
  });
19671
- import { readdir as readdir5, readFile as readFile15, writeFile as writeFile9, mkdir as mkdir9 } from "node:fs/promises";
19749
+ import { readdir as readdir5, readFile as readFile16, writeFile as writeFile9, mkdir as mkdir9 } from "node:fs/promises";
19672
19750
  import { join as join13, relative as relative6, extname } from "node:path";
19673
19751
  async function walkDir(dir, extensions) {
19674
19752
  const results = [];
@@ -19746,7 +19824,7 @@ async function debtHarvestCommand(options) {
19746
19824
  const files = await walkDir(targetDir, SOURCE_EXTENSIONS);
19747
19825
  const allEntries = [];
19748
19826
  for (const file of files) {
19749
- const content = await readFile15(file, "utf-8");
19827
+ const content = await readFile16(file, "utf-8");
19750
19828
  const entries = extractDefers(content, relative6(projectRoot, file));
19751
19829
  allEntries.push(...entries);
19752
19830
  }
@@ -20224,11 +20302,11 @@ __export(exports_graph_store, {
20224
20302
  saveGraph: () => saveGraph,
20225
20303
  upsertNode: () => upsertNode
20226
20304
  });
20227
- import { mkdir as mkdir10, readFile as readFile16, writeFile as writeFile10 } from "node:fs/promises";
20305
+ import { mkdir as mkdir10, readFile as readFile17, writeFile as writeFile10 } from "node:fs/promises";
20228
20306
  import { dirname as dirname9 } from "node:path";
20229
20307
  async function loadGraph(projectRoot) {
20230
20308
  try {
20231
- const raw = await readFile16(productGraphPath(projectRoot), "utf-8");
20309
+ const raw = await readFile17(productGraphPath(projectRoot), "utf-8");
20232
20310
  return ok(ProductGraphSchema.parse(JSON.parse(raw)));
20233
20311
  } catch (e) {
20234
20312
  if (e.code === "ENOENT") {
@@ -20410,7 +20488,7 @@ __export(exports_goal_state, {
20410
20488
  markTaskBlocked: () => markTaskBlocked,
20411
20489
  writeGoal: () => writeGoal
20412
20490
  });
20413
- import { mkdir as mkdir11, readFile as readFile17, writeFile as writeFile11 } from "node:fs/promises";
20491
+ import { mkdir as mkdir11, readFile as readFile18, writeFile as writeFile11 } from "node:fs/promises";
20414
20492
  import { resolve as resolve19 } from "node:path";
20415
20493
  function validateGoalGraph2(graph) {
20416
20494
  const ids = new Set(graph.tasks.map((t) => t.id));
@@ -20463,7 +20541,7 @@ async function writeGoal(projectRoot, graph) {
20463
20541
  async function loadGoal(projectRoot) {
20464
20542
  try {
20465
20543
  const filePath = resolve19(projectRoot, GOAL_FILE);
20466
- const content = await readFile17(filePath, "utf-8");
20544
+ const content = await readFile18(filePath, "utf-8");
20467
20545
  const data = $parse(content);
20468
20546
  const validated = GoalGraphSchema.parse(data);
20469
20547
  return validateGoalGraph2(validated);
@@ -20625,7 +20703,7 @@ var init_goal_command = __esm(() => {
20625
20703
  });
20626
20704
 
20627
20705
  // src/core/openspec/backlog-parser.ts
20628
- import { readFile as readFile18 } from "node:fs/promises";
20706
+ import { readFile as readFile19 } from "node:fs/promises";
20629
20707
  import { resolve as resolve20 } from "node:path";
20630
20708
  function parseBool(value) {
20631
20709
  const v = value.trim().toLowerCase();
@@ -20801,7 +20879,7 @@ function parseBacklogMarkdown(content) {
20801
20879
  async function loadBacklog(projectRoot) {
20802
20880
  try {
20803
20881
  const filePath = resolve20(projectRoot, BACKLOG_FILE);
20804
- const content = await readFile18(filePath, "utf-8");
20882
+ const content = await readFile19(filePath, "utf-8");
20805
20883
  return parseBacklogMarkdown(content);
20806
20884
  } catch (e) {
20807
20885
  return err(e instanceof Error ? e : new Error(String(e)));
@@ -20850,11 +20928,11 @@ function slugify(text) {
20850
20928
  }
20851
20929
 
20852
20930
  // src/core/knowledge/source-parsers.ts
20853
- import { readFile as readFile19 } from "node:fs/promises";
20931
+ import { readFile as readFile20 } from "node:fs/promises";
20854
20932
  import { basename as basename6, join as join15, relative as relative7, sep as sep5 } from "node:path";
20855
20933
  async function parseAdrFile(filePath) {
20856
20934
  try {
20857
- const content = await readFile19(filePath, "utf-8");
20935
+ const content = await readFile20(filePath, "utf-8");
20858
20936
  const base = basename6(filePath);
20859
20937
  const idMatch = base.match(/adr-(\d+)/i);
20860
20938
  const id = idMatch ? `adr-${idMatch[1]}` : slugify(base);
@@ -20903,7 +20981,7 @@ function adrToEntities(adr, source) {
20903
20981
  }
20904
20982
  async function parseReadmeEntities(projectRoot, productName) {
20905
20983
  try {
20906
- const content = await readFile19(join15(projectRoot, "README.md"), "utf-8");
20984
+ const content = await readFile20(join15(projectRoot, "README.md"), "utf-8");
20907
20985
  const firstPara = content.split(`
20908
20986
 
20909
20987
  `).find((p) => p.trim() && !p.startsWith("#") && !p.startsWith(">")) ?? "";
@@ -20924,7 +21002,7 @@ async function parseReadmeEntities(projectRoot, productName) {
20924
21002
  }
20925
21003
  async function parseGraphifyEntities(projectRoot) {
20926
21004
  try {
20927
- const raw = await readFile19(join15(projectRoot, "graphify-out", "graph.json"), "utf-8");
21005
+ const raw = await readFile20(join15(projectRoot, "graphify-out", "graph.json"), "utf-8");
20928
21006
  const graph = JSON.parse(raw);
20929
21007
  const entities = [];
20930
21008
  for (const node2 of graph.nodes ?? []) {
@@ -20980,7 +21058,7 @@ async function scanSrcComponents(projectRoot) {
20980
21058
  var init_source_parsers = () => {};
20981
21059
 
20982
21060
  // src/core/memory/episodic-store.ts
20983
- import { appendFile, mkdir as mkdir12, readFile as readFile20 } from "node:fs/promises";
21061
+ import { appendFile, mkdir as mkdir12, readFile as readFile21 } from "node:fs/promises";
20984
21062
  import { resolve as resolve21 } from "node:path";
20985
21063
  async function appendEvent(projectRoot, event) {
20986
21064
  try {
@@ -20999,7 +21077,7 @@ async function appendEvent(projectRoot, event) {
20999
21077
  }
21000
21078
  async function listEvents(projectRoot, since, type) {
21001
21079
  try {
21002
- const content = await readFile20(eventsPath(projectRoot), "utf-8");
21080
+ const content = await readFile21(eventsPath(projectRoot), "utf-8");
21003
21081
  const events = [];
21004
21082
  for (const line of content.split(`
21005
21083
  `)) {
@@ -21027,7 +21105,7 @@ var init_episodic_store = __esm(() => {
21027
21105
 
21028
21106
  // src/core/knowledge/ingest-pipeline.ts
21029
21107
  import { createHash as createHash3 } from "node:crypto";
21030
- import { readFile as readFile21 } from "node:fs/promises";
21108
+ import { readFile as readFile22 } from "node:fs/promises";
21031
21109
  import { join as join16, relative as relative8, sep as sep6 } from "node:path";
21032
21110
  import { mkdir as mkdir13, writeFile as writeFile12 } from "node:fs/promises";
21033
21111
  async function mapLimit(items, limit, fn) {
@@ -21049,7 +21127,7 @@ async function mapLimit(items, limit, fn) {
21049
21127
  }
21050
21128
  async function hashFile(path) {
21051
21129
  try {
21052
- const content = await readFile21(path, "utf-8");
21130
+ const content = await readFile22(path, "utf-8");
21053
21131
  return createHash3("sha256").update(content).digest("hex").slice(0, 16);
21054
21132
  } catch {
21055
21133
  return null;
@@ -21076,7 +21154,7 @@ async function collectDeferRisks(projectRoot) {
21076
21154
  await walk(join16(projectRoot, "src"));
21077
21155
  const perFile = await mapLimit(files, WALK_READ_CONCURRENCY, async (full) => {
21078
21156
  const entities = [];
21079
- const content = await readFile21(full, "utf-8");
21157
+ const content = await readFile22(full, "utf-8");
21080
21158
  const rel = relative8(projectRoot, full).split(sep6).join("/");
21081
21159
  const deferRe = new RegExp(DEFER_REGEX_SOURCE, "gm");
21082
21160
  let match;
@@ -21325,11 +21403,11 @@ var init_ingest_command = __esm(() => {
21325
21403
  });
21326
21404
 
21327
21405
  // src/core/memory/operational-state.ts
21328
- import { mkdir as mkdir14, readFile as readFile22, writeFile as writeFile13 } from "node:fs/promises";
21406
+ import { mkdir as mkdir14, readFile as readFile23, writeFile as writeFile13 } from "node:fs/promises";
21329
21407
  import { resolve as resolve22 } from "node:path";
21330
21408
  async function loadOperationalState(projectRoot) {
21331
21409
  try {
21332
- const raw = await readFile22(operationalStatePath(projectRoot), "utf-8");
21410
+ const raw = await readFile23(operationalStatePath(projectRoot), "utf-8");
21333
21411
  return ok(OperationalStateSchema.parse(JSON.parse(raw)));
21334
21412
  } catch (e) {
21335
21413
  if (e.code === "ENOENT") {
@@ -21386,11 +21464,11 @@ var init_operational_state = __esm(() => {
21386
21464
  });
21387
21465
 
21388
21466
  // src/core/memory/strategic-memory.ts
21389
- import { mkdir as mkdir15, readFile as readFile23, writeFile as writeFile14 } from "node:fs/promises";
21467
+ import { mkdir as mkdir15, readFile as readFile24, writeFile as writeFile14 } from "node:fs/promises";
21390
21468
  import { resolve as resolve23 } from "node:path";
21391
21469
  async function loadStrategicMemory(projectRoot) {
21392
21470
  try {
21393
- const raw = await readFile23(strategicPath(projectRoot), "utf-8");
21471
+ const raw = await readFile24(strategicPath(projectRoot), "utf-8");
21394
21472
  return ok(StrategicMemorySchema.parse(JSON.parse(raw)));
21395
21473
  } catch (e) {
21396
21474
  if (e.code === "ENOENT") {
@@ -21424,7 +21502,7 @@ var init_strategic_memory = __esm(() => {
21424
21502
  });
21425
21503
 
21426
21504
  // src/core/memory/memory-index.ts
21427
- import { mkdir as mkdir16, readFile as readFile24, writeFile as writeFile15 } from "node:fs/promises";
21505
+ import { mkdir as mkdir16, readFile as readFile25, writeFile as writeFile15 } from "node:fs/promises";
21428
21506
  import { resolve as resolve24 } from "node:path";
21429
21507
  function parseMarkdown(content) {
21430
21508
  const startIdx = content.indexOf(SENTINEL_START);
@@ -21445,7 +21523,7 @@ function parseMarkdown(content) {
21445
21523
  async function loadMemoryIndex(projectRoot) {
21446
21524
  try {
21447
21525
  const filePath = resolve24(projectRoot, MEMORY_FILE);
21448
- const content = await readFile24(filePath, "utf-8");
21526
+ const content = await readFile25(filePath, "utf-8");
21449
21527
  const parsed = parseMarkdown(content);
21450
21528
  if (!parsed) {
21451
21529
  return err(new Error("Failed to parse memory index from memory.md"));
@@ -21462,7 +21540,7 @@ var init_memory_index = __esm(() => {
21462
21540
  });
21463
21541
 
21464
21542
  // src/core/evaluation/outcome-store.ts
21465
- import { appendFile as appendFile2, mkdir as mkdir17, readFile as readFile25, readdir as readdir6, writeFile as writeFile16 } from "node:fs/promises";
21543
+ import { appendFile as appendFile2, mkdir as mkdir17, readFile as readFile26, readdir as readdir6, writeFile as writeFile16 } from "node:fs/promises";
21466
21544
  import { resolve as resolve25 } from "node:path";
21467
21545
  async function ensureEvaluationDir(projectRoot) {
21468
21546
  const dir = resolve25(projectRoot, EVAL_DIR);
@@ -21479,7 +21557,7 @@ async function appendOutcome(projectRoot, outcome) {
21479
21557
  const indexPath = resolve25(dir, INDEX_FILE);
21480
21558
  let index = { version: 1, lastOutcomeId: validated.id };
21481
21559
  try {
21482
- const raw = await readFile25(indexPath, "utf-8");
21560
+ const raw = await readFile26(indexPath, "utf-8");
21483
21561
  index = EvaluationIndexSchema.parse(JSON.parse(raw));
21484
21562
  index.lastOutcomeId = validated.id;
21485
21563
  } catch {}
@@ -21492,7 +21570,7 @@ async function appendOutcome(projectRoot, outcome) {
21492
21570
  async function listOutcomes(projectRoot, filter = {}) {
21493
21571
  try {
21494
21572
  const path = resolve25(projectRoot, EVAL_DIR, OUTCOMES_FILE);
21495
- const content = await readFile25(path, "utf-8");
21573
+ const content = await readFile26(path, "utf-8");
21496
21574
  const lines = content.split(`
21497
21575
  `).filter((l) => l.trim().length > 0);
21498
21576
  const outcomes = [];
@@ -21552,7 +21630,7 @@ async function listScorecards(projectRoot, filter = {}) {
21552
21630
  for (const file of files) {
21553
21631
  if (!file.endsWith(".json"))
21554
21632
  continue;
21555
- const parsed = ScorecardRecordSchema.parse(JSON.parse(await readFile25(resolve25(dir, file), "utf-8")));
21633
+ const parsed = ScorecardRecordSchema.parse(JSON.parse(await readFile26(resolve25(dir, file), "utf-8")));
21556
21634
  if (filter.backlogId && parsed.backlogId !== filter.backlogId)
21557
21635
  continue;
21558
21636
  if (filter.verdict && parsed.verdict !== filter.verdict)
@@ -21575,7 +21653,7 @@ async function hasPassingScorecard(projectRoot, backlogId) {
21575
21653
  async function loadScorecard(projectRoot, id) {
21576
21654
  try {
21577
21655
  const filePath = resolve25(projectRoot, EVAL_DIR, SCORECARDS_DIR, `${id}.json`);
21578
- const content = await readFile25(filePath, "utf-8");
21656
+ const content = await readFile26(filePath, "utf-8");
21579
21657
  return ok(ScorecardRecordSchema.parse(JSON.parse(content)));
21580
21658
  } catch (e) {
21581
21659
  return err(e instanceof Error ? e : new Error(String(e)));
@@ -21667,11 +21745,11 @@ var init_outcome_store = __esm(() => {
21667
21745
  });
21668
21746
 
21669
21747
  // src/core/feedback/feedback-ingestor.ts
21670
- import { readFile as readFile26 } from "node:fs/promises";
21748
+ import { readFile as readFile27 } from "node:fs/promises";
21671
21749
  import { join as join17 } from "node:path";
21672
21750
  async function parseChangelogLearnings(projectRoot) {
21673
21751
  try {
21674
- const content = await readFile26(join17(projectRoot, "CHANGELOG.md"), "utf-8");
21752
+ const content = await readFile27(join17(projectRoot, "CHANGELOG.md"), "utf-8");
21675
21753
  const unreleased = content.match(/## \[Unreleased\]([\s\S]*?)(?=## \[|\n## )/i);
21676
21754
  if (!unreleased)
21677
21755
  return [];
@@ -22275,7 +22353,7 @@ __export(exports_rdd_receipt, {
22275
22353
  verifyReceipt: () => verifyReceipt
22276
22354
  });
22277
22355
  import { createHash as createHash4 } from "node:crypto";
22278
- import { readdir as readdir7, readFile as readFile27 } from "node:fs/promises";
22356
+ import { readdir as readdir7, readFile as readFile28 } from "node:fs/promises";
22279
22357
  import { join as join18, relative as relative9, resolve as resolve26, sep as sep7 } from "node:path";
22280
22358
  function sha2562(content) {
22281
22359
  return createHash4("sha256").update(content).digest("hex");
@@ -22300,7 +22378,7 @@ async function fingerprint(projectRoot, paths) {
22300
22378
  }
22301
22379
  const result = [];
22302
22380
  for (const [path, absolute] of [...deduplicated.entries()].sort(([left], [right]) => left.localeCompare(right))) {
22303
- result.push({ path, hash: sha2562(await readFile27(absolute)) });
22381
+ result.push({ path, hash: sha2562(await readFile28(absolute)) });
22304
22382
  }
22305
22383
  return result;
22306
22384
  }
@@ -22360,7 +22438,7 @@ async function verifyReceipt(projectRoot, receipt) {
22360
22438
  for (const path of pathsToCheck) {
22361
22439
  try {
22362
22440
  const canonical = canonicalPath(projectRoot, path);
22363
- const hash = sha2562(await readFile27(canonical.absolute));
22441
+ const hash = sha2562(await readFile28(canonical.absolute));
22364
22442
  const currentEntry = { path: canonical.relative, hash };
22365
22443
  current.push(currentEntry);
22366
22444
  currentByPath.set(currentEntry.path, currentEntry);
@@ -22397,7 +22475,7 @@ var init_rdd_receipt = __esm(() => {
22397
22475
 
22398
22476
  // src/core/verification/verification-runner.ts
22399
22477
  import { existsSync as existsSync3 } from "node:fs";
22400
- import { readFile as readFile28 } from "node:fs/promises";
22478
+ import { readFile as readFile29 } from "node:fs/promises";
22401
22479
  import { dirname as dirname10, join as join19, resolve as resolve27 } from "node:path";
22402
22480
  import { mkdir as mkdir18, readdir as readdir8, writeFile as writeFile18 } from "node:fs/promises";
22403
22481
  function isPassingEvidence(ev) {
@@ -22460,7 +22538,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
22460
22538
  if (!file.endsWith(".json"))
22461
22539
  continue;
22462
22540
  try {
22463
- const raw = await readFile28(join19(evDir, file), "utf-8");
22541
+ const raw = await readFile29(join19(evDir, file), "utf-8");
22464
22542
  const ev = EvidenceSchema.parse(JSON.parse(raw));
22465
22543
  if (ev.relatedTask === taskId)
22466
22544
  records.push(ev);
@@ -22647,7 +22725,7 @@ async function loadTddSuiteEvidence(projectRoot, taskId, evidenceId) {
22647
22725
  return path;
22648
22726
  let raw;
22649
22727
  try {
22650
- raw = await readFile28(path.data, "utf-8");
22728
+ raw = await readFile29(path.data, "utf-8");
22651
22729
  } catch (e) {
22652
22730
  return err(e instanceof Error ? e : new Error(String(e)));
22653
22731
  }
@@ -23839,7 +23917,7 @@ __export(exports_rdd_command, {
23839
23917
  });
23840
23918
  import { execFile as execFile4 } from "node:child_process";
23841
23919
  import { existsSync as existsSync4 } from "node:fs";
23842
- import { mkdir as mkdir19, readFile as readFile29, readdir as readdir9, rename as rename3, writeFile as writeFile19, chmod } from "node:fs/promises";
23920
+ import { mkdir as mkdir19, readFile as readFile30, readdir as readdir9, rename as rename3, writeFile as writeFile19, chmod } from "node:fs/promises";
23843
23921
  import { dirname as dirname11, resolve as resolve28 } from "node:path";
23844
23922
  import { promisify as promisify4 } from "node:util";
23845
23923
  function receiptPath(projectRoot, id) {
@@ -23850,7 +23928,7 @@ function receiptPath(projectRoot, id) {
23850
23928
  return path;
23851
23929
  }
23852
23930
  async function loadReceipt(projectRoot, id) {
23853
- const raw = await readFile29(receiptPath(projectRoot, id), "utf-8");
23931
+ const raw = await readFile30(receiptPath(projectRoot, id), "utf-8");
23854
23932
  const evidence = EvidenceSchema.parse(JSON.parse(raw));
23855
23933
  if (evidence.type !== "rdd")
23856
23934
  throw new Error(`Evidence "${id}" is not an RDD receipt`);
@@ -23901,7 +23979,7 @@ async function installHooks(projectRoot) {
23901
23979
  const backup = resolve28(hooksDir, `${hook}.rdd-original`);
23902
23980
  const marker = "# codeconductor-rdd-hook";
23903
23981
  if (existsSync4(path)) {
23904
- const existing = await readFile29(path, "utf8");
23982
+ const existing = await readFile30(path, "utf8");
23905
23983
  if (existing.includes(marker)) {
23906
23984
  skipped.push(hook);
23907
23985
  continue;
@@ -24066,6 +24144,101 @@ function buildOpenspecPhaseContext(context, phase) {
24066
24144
  };
24067
24145
  }
24068
24146
 
24147
+ // src/core/ccep/output-validator.ts
24148
+ function resolveOutputSchemaName(schemaName, role) {
24149
+ if (schemaName !== "agent-output" && SCHEMA_REGISTRY[schemaName]) {
24150
+ return schemaName;
24151
+ }
24152
+ if (role === "implementer") {
24153
+ return "implementer-output";
24154
+ }
24155
+ if (role === "reviewer") {
24156
+ return "review-report";
24157
+ }
24158
+ if (role === "task-coach" || role === "architect") {
24159
+ return schemaName === "technical-plan" ? "technical-plan" : "planner-output";
24160
+ }
24161
+ return schemaName;
24162
+ }
24163
+ function validateResolvedOutputSchema(schemaName, data) {
24164
+ const schema = SCHEMA_REGISTRY[schemaName];
24165
+ if (!schema) {
24166
+ return {
24167
+ valid: false,
24168
+ schema: schemaName,
24169
+ errors: [`Unknown output schema: ${schemaName}`]
24170
+ };
24171
+ }
24172
+ const parsed = schema.safeParse(data);
24173
+ if (parsed.success) {
24174
+ return { valid: true, schema: schemaName, data: parsed.data };
24175
+ }
24176
+ return {
24177
+ valid: false,
24178
+ schema: schemaName,
24179
+ errors: parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
24180
+ };
24181
+ }
24182
+ function parseJsonInput(raw) {
24183
+ return JSON.parse(raw);
24184
+ }
24185
+ function validateOutputForRole(role, outputSchema, data) {
24186
+ const resolved = resolveOutputSchemaName(outputSchema, role);
24187
+ if (resolved === "implementer-output") {
24188
+ try {
24189
+ return { valid: true, schema: "implementer-output", data: validateImplementerOutput(data) };
24190
+ } catch (err3) {
24191
+ return {
24192
+ valid: false,
24193
+ schema: "implementer-output",
24194
+ errors: [String(err3)]
24195
+ };
24196
+ }
24197
+ }
24198
+ if (resolved === "review-report") {
24199
+ try {
24200
+ return { valid: true, schema: "review-report", data: validateReviewerOutput(data) };
24201
+ } catch (err3) {
24202
+ return {
24203
+ valid: false,
24204
+ schema: "review-report",
24205
+ errors: [String(err3)]
24206
+ };
24207
+ }
24208
+ }
24209
+ if (resolved === "planner-output") {
24210
+ try {
24211
+ return { valid: true, schema: "planner-output", data: validatePlannerOutput(data) };
24212
+ } catch (err3) {
24213
+ return {
24214
+ valid: false,
24215
+ schema: "planner-output",
24216
+ errors: [String(err3)]
24217
+ };
24218
+ }
24219
+ }
24220
+ return validateResolvedOutputSchema(resolved, data);
24221
+ }
24222
+ var SCHEMA_REGISTRY;
24223
+ var init_output_validator = __esm(() => {
24224
+ init_schemas();
24225
+ SCHEMA_REGISTRY = {
24226
+ "planner-output": PlannerOutputSchema,
24227
+ "implementer-output": ImplementerOutputSchema,
24228
+ "review-report": ReviewerOutputSchema,
24229
+ "technical-plan": TechnicalPlanOutputSchema,
24230
+ "fix-intake-output": FixIntakeOutputSchema,
24231
+ "council-verdict": CouncilVerdictSchema,
24232
+ "agent-output": AgentOutputSchema,
24233
+ taskcard: CanonicalTaskCardSchema,
24234
+ "test-plan": AgentOutputSchema,
24235
+ "complexity-audit": AgentOutputSchema,
24236
+ "api-contract": AgentOutputSchema,
24237
+ "pagespeed-report": AgentOutputSchema,
24238
+ "scorecard-record": ScorecardRecordSchema
24239
+ };
24240
+ });
24241
+
24069
24242
  // src/core/ccep/prompt-compiler.ts
24070
24243
  function buildSystemLayer() {
24071
24244
  return [
@@ -24078,24 +24251,22 @@ function buildSystemLayer() {
24078
24251
  ].join(`
24079
24252
  `);
24080
24253
  }
24081
- function buildAgentLayer(role, phase) {
24254
+ function buildAgentLayer(role, phase, outputSchema) {
24082
24255
  const label = ROLE_LABELS[role] ?? role;
24256
+ let instruction;
24083
24257
  if (role === "task-coach" && phase === "intake") {
24084
- return `You are the Planner / ${label} of CodeConductor.
24258
+ instruction = `You are the Planner / ${label} of CodeConductor.
24085
24259
  Convert product intent into a structured plan without writing code.`;
24086
- }
24087
- if (role === "implementer") {
24088
- return `You are the ${label}.
24089
- Execute only your assigned phase: ${phase}.
24090
- Write the minimal diff. Return implementer-output JSON only.`;
24091
- }
24092
- if (role === "reviewer") {
24093
- return `You are the ${label}.
24260
+ } else if (role === "implementer") {
24261
+ instruction = `You are the ${label}.
24094
24262
  Execute only your assigned phase: ${phase}.
24095
- Return review-report JSON only.`;
24096
- }
24097
- return `You are the ${label}.
24263
+ Write the minimal diff.`;
24264
+ } else {
24265
+ instruction = `You are the ${label}.
24098
24266
  Execute only your assigned phase: ${phase}.`;
24267
+ }
24268
+ return `${instruction}
24269
+ Return ${outputSchema} JSON only.`;
24099
24270
  }
24100
24271
  function buildTaskLayer(context, phase) {
24101
24272
  if (context.envelope.command === "openspec") {
@@ -24105,19 +24276,28 @@ function buildTaskLayer(context, phase) {
24105
24276
  command: context.envelope.command,
24106
24277
  intent: context.intent,
24107
24278
  phase,
24108
- userRequest: context.envelope.userRequest,
24109
24279
  project: context.project.name
24110
24280
  }, null, 2);
24111
24281
  }
24282
+ function scopeKnowledgeForRole(knowledge, role) {
24283
+ const keys = KNOWLEDGE_KEYS_BY_ROLE[role];
24284
+ if (!keys)
24285
+ return knowledge;
24286
+ if (Object.keys(knowledge).some((key) => !PRODUCT_GRAPH_KNOWLEDGE_KEYS.has(key))) {
24287
+ return knowledge;
24288
+ }
24289
+ return Object.fromEntries(keys.filter((key) => knowledge[key] !== undefined).map((key) => [key, knowledge[key]]));
24290
+ }
24112
24291
  function compilePrompt(options) {
24113
24292
  const { role, phase, context, promptVersion } = options;
24114
24293
  const phaseDef = context.profile.phases.find((p) => p.id === phase);
24115
- const schemaName = phaseDef?.outputSchema ?? context.outputSchema ?? "agent-output";
24294
+ const configuredSchemaName = phaseDef?.outputSchema ?? context.outputSchema ?? "agent-output";
24295
+ const schemaName = resolveOutputSchemaName(configuredSchemaName, role);
24116
24296
  const schemaBody = OUTPUT_SCHEMAS[schemaName] ?? OUTPUT_SCHEMAS["agent-output"];
24117
- const knowledge = context.envelope.command === "openspec" ? buildOpenspecPhaseContext(context, phase).knowledge : context.knowledge;
24297
+ const knowledge = context.envelope.command === "openspec" ? buildOpenspecPhaseContext(context, phase).knowledge : scopeKnowledgeForRole(context.knowledge, role);
24118
24298
  const layers = [
24119
24299
  { name: "system", content: buildSystemLayer() },
24120
- { name: "agent", content: buildAgentLayer(role, phase) },
24300
+ { name: "agent", content: buildAgentLayer(role, phase, schemaName) },
24121
24301
  {
24122
24302
  name: "policies",
24123
24303
  content: JSON.stringify({ ...context.policies, promptVersion }, null, 2)
@@ -24135,10 +24315,11 @@ ${schemaBody}`
24135
24315
  ${layer.content}`).join(`
24136
24316
 
24137
24317
  `);
24138
- return { layers, prompt };
24318
+ return { layers, prompt, outputSchema: schemaName };
24139
24319
  }
24140
- var ROLE_LABELS, OUTPUT_SCHEMAS;
24320
+ var ROLE_LABELS, OUTPUT_SCHEMAS, KNOWLEDGE_KEYS_BY_ROLE, PRODUCT_GRAPH_KNOWLEDGE_KEYS;
24141
24321
  var init_prompt_compiler = __esm(() => {
24322
+ init_output_validator();
24142
24323
  ROLE_LABELS = {
24143
24324
  "task-coach": "Task Coach",
24144
24325
  architect: "Architect",
@@ -24193,103 +24374,45 @@ var init_prompt_compiler = __esm(() => {
24193
24374
  "filesChanged": [{ "path": "", "summary": "" }],
24194
24375
  "tests": { "runner": "", "result": "passed" | "failed" }
24195
24376
  }`,
24196
- "agent-output": '{ "status": "success", "artifacts": [], "next_actions": [] }'
24197
- };
24198
- });
24199
-
24200
- // src/core/ccep/output-validator.ts
24201
- function resolveOutputSchemaName(schemaName, role) {
24202
- if (schemaName !== "agent-output" && SCHEMA_REGISTRY[schemaName]) {
24203
- return schemaName;
24204
- }
24205
- if (role === "implementer") {
24206
- return "implementer-output";
24207
- }
24208
- if (role === "reviewer") {
24209
- return "review-report";
24210
- }
24211
- if (role === "task-coach" || role === "architect") {
24212
- return schemaName === "technical-plan" ? "technical-plan" : "planner-output";
24213
- }
24214
- return schemaName;
24215
- }
24216
- function validateAgentOutputBySchema(schemaName, data, role) {
24217
- const resolved = resolveOutputSchemaName(schemaName, role);
24218
- const schema = SCHEMA_REGISTRY[resolved];
24219
- if (!schema) {
24220
- return {
24221
- valid: false,
24222
- schema: resolved,
24223
- errors: [`Unknown output schema: ${resolved}`]
24224
- };
24225
- }
24226
- const parsed = schema.safeParse(data);
24227
- if (parsed.success) {
24228
- return { valid: true, schema: resolved, data: parsed.data };
24229
- }
24230
- return {
24231
- valid: false,
24232
- schema: resolved,
24233
- errors: parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
24234
- };
24235
- }
24236
- function parseJsonInput(raw) {
24237
- return JSON.parse(raw);
24238
- }
24239
- function validateOutputForRole(role, outputSchema, data) {
24240
- if (role === "implementer") {
24241
- try {
24242
- return { valid: true, schema: "implementer-output", data: validateImplementerOutput(data) };
24243
- } catch (err3) {
24244
- return {
24245
- valid: false,
24246
- schema: "implementer-output",
24247
- errors: [String(err3)]
24248
- };
24249
- }
24250
- }
24251
- if (role === "reviewer") {
24252
- try {
24253
- return { valid: true, schema: "review-report", data: validateReviewerOutput(data) };
24254
- } catch (err3) {
24255
- return {
24256
- valid: false,
24257
- schema: "review-report",
24258
- errors: [String(err3)]
24259
- };
24260
- }
24261
- }
24262
- if (outputSchema === "planner-output" || role === "task-coach") {
24263
- try {
24264
- return { valid: true, schema: "planner-output", data: validatePlannerOutput(data) };
24265
- } catch (err3) {
24266
- return {
24267
- valid: false,
24268
- schema: "planner-output",
24269
- errors: [String(err3)]
24270
- };
24271
- }
24272
- }
24273
- return validateAgentOutputBySchema(outputSchema, data, role);
24274
- }
24275
- var SCHEMA_REGISTRY;
24276
- var init_output_validator = __esm(() => {
24277
- init_schemas();
24278
- SCHEMA_REGISTRY = {
24279
- "planner-output": PlannerOutputSchema,
24280
- "implementer-output": ImplementerOutputSchema,
24281
- "review-report": ReviewerOutputSchema,
24282
- "technical-plan": TechnicalPlanOutputSchema,
24283
- "fix-intake-output": AgentOutputSchema,
24284
- "council-verdict": CouncilVerdictSchema,
24285
- "agent-output": AgentOutputSchema,
24286
- taskcard: CanonicalTaskCardSchema,
24287
- "test-plan": AgentOutputSchema,
24288
- "complexity-audit": AgentOutputSchema,
24289
- "api-contract": AgentOutputSchema,
24290
- "pagespeed-report": AgentOutputSchema,
24291
- "scorecard-record": ScorecardRecordSchema
24292
- };
24377
+ "agent-output": `{
24378
+ "status": "success" | "failure" | "blocked" | "needs_clarification",
24379
+ "confidence": 0.0,
24380
+ "warnings": [],
24381
+ "artifacts": [],
24382
+ "next_actions": []
24383
+ }`,
24384
+ "scorecard-record": `{
24385
+ "id": "",
24386
+ "taskId": "",
24387
+ "agent": "",
24388
+ "contractVersion": "",
24389
+ "criteria": [],
24390
+ "weightedScore": 0.0,
24391
+ "verdict": "PASS" | "REVISE" | "REJECT",
24392
+ "findings": [],
24393
+ "createdAt": ""
24394
+ }`
24395
+ };
24396
+ KNOWLEDGE_KEYS_BY_ROLE = {
24397
+ "task-coach": ["productName", "domains", "requirements", "risks"],
24398
+ architect: ["productName", "domains", "decisions", "requirements", "risks"],
24399
+ tester: ["productName", "requirements", "risks"],
24400
+ implementer: ["productName", "decisions", "requirements"],
24401
+ reviewer: ["productName", "decisions", "requirements", "risks"],
24402
+ docs: ["productName", "decisions", "requirements"],
24403
+ "contract-builder": ["productName", "domains", "decisions", "requirements"],
24404
+ "complexity-auditor": ["productName", "decisions", "requirements", "risks"],
24405
+ orchestrator: ["productName", "domains", "decisions", "requirements", "risks"],
24406
+ "repo-explorer": ["productName", "domains", "requirements"]
24407
+ };
24408
+ PRODUCT_GRAPH_KNOWLEDGE_KEYS = new Set([
24409
+ "productName",
24410
+ "domains",
24411
+ "decisions",
24412
+ "risks",
24413
+ "requirements",
24414
+ "nodeCount"
24415
+ ]);
24293
24416
  });
24294
24417
 
24295
24418
  // src/core/ccep/command-parser.ts
@@ -24401,7 +24524,7 @@ var init_workflow_profile_loader = __esm(() => {
24401
24524
  // src/core/evaluation/harness-catalog.ts
24402
24525
  import { createHash as createHash5 } from "node:crypto";
24403
24526
  import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
24404
- import { copyFile as copyFile2, mkdir as mkdir20, readFile as readFile30, readdir as readdir10, rm as rm4, writeFile as writeFile20 } from "node:fs/promises";
24527
+ import { copyFile as copyFile2, mkdir as mkdir20, readFile as readFile31, readdir as readdir10, rm as rm4, writeFile as writeFile20 } from "node:fs/promises";
24405
24528
  import { dirname as dirname12, join as join21, resolve as resolve29 } from "node:path";
24406
24529
  function catalogIds(catalog = DEFAULT_HARNESS_CATALOG) {
24407
24530
  return catalog.components.map((c) => c.id);
@@ -24457,7 +24580,7 @@ function harnessFingerprint(disabled, contractVersion, ccepProfile = "feature",
24457
24580
  async function loadHarnessCatalog(projectRoot) {
24458
24581
  const overridePath = resolve29(projectRoot, EVAL_DIR2, CATALOG_FILE);
24459
24582
  try {
24460
- const raw = await readFile30(overridePath, "utf-8");
24583
+ const raw = await readFile31(overridePath, "utf-8");
24461
24584
  return HarnessCatalogSchema.parse($parse(raw));
24462
24585
  } catch {
24463
24586
  return DEFAULT_HARNESS_CATALOG;
@@ -24468,7 +24591,7 @@ function activeOverlayPath(projectRoot) {
24468
24591
  }
24469
24592
  async function readActiveOverlay(projectRoot) {
24470
24593
  try {
24471
- const raw = await readFile30(activeOverlayPath(projectRoot), "utf-8");
24594
+ const raw = await readFile31(activeOverlayPath(projectRoot), "utf-8");
24472
24595
  return HarnessOverlaySchema.parse($parse(raw));
24473
24596
  } catch {
24474
24597
  return null;
@@ -24725,7 +24848,7 @@ var init_harness_catalog = __esm(() => {
24725
24848
 
24726
24849
  // src/core/openspec/openspec-state.ts
24727
24850
  import { createHash as createHash6 } from "node:crypto";
24728
- import { mkdir as mkdir21, readFile as readFile31, rename as rename4, writeFile as writeFile21 } from "node:fs/promises";
24851
+ import { mkdir as mkdir21, readFile as readFile32, rename as rename4, writeFile as writeFile21 } from "node:fs/promises";
24729
24852
  import { resolve as resolve30 } from "node:path";
24730
24853
  function canTransition(from, to) {
24731
24854
  return ALLOWED_TRANSITIONS[from]?.includes(to) ?? false;
@@ -24753,7 +24876,7 @@ async function writeFileAtomic(path, content) {
24753
24876
  async function loadOpenspecState(projectRoot) {
24754
24877
  try {
24755
24878
  const filePath = resolve30(projectRoot, STATE_FILE);
24756
- const content = await readFile31(filePath, "utf-8");
24879
+ const content = await readFile32(filePath, "utf-8");
24757
24880
  const data = JSON.parse(content);
24758
24881
  return ok(OpenspecStateSchema.parse(data));
24759
24882
  } catch (e) {
@@ -24878,7 +25001,7 @@ var init_openspec_state = __esm(() => {
24878
25001
 
24879
25002
  // src/core/ccep/context-resolver.ts
24880
25003
  import { existsSync as existsSync7 } from "node:fs";
24881
- import { readFile as readFile32 } from "node:fs/promises";
25004
+ import { readFile as readFile33 } from "node:fs/promises";
24882
25005
  import { join as join22 } from "node:path";
24883
25006
  async function loadProductKnowledge(projectRoot) {
24884
25007
  if (isProductGraphDisabled(projectRoot)) {
@@ -24889,7 +25012,7 @@ async function loadProductKnowledge(projectRoot) {
24889
25012
  return {};
24890
25013
  }
24891
25014
  try {
24892
- const raw = await readFile32(graphPath, "utf-8");
25015
+ const raw = await readFile33(graphPath, "utf-8");
24893
25016
  const graph = ProductGraphSchema.parse(JSON.parse(raw));
24894
25017
  return {
24895
25018
  productName: graph.productName,
@@ -25459,6 +25582,11 @@ async function ccepCommand(options) {
25459
25582
  input,
25460
25583
  contextPath,
25461
25584
  promptVersion = "v1.0.0",
25585
+ view = "full",
25586
+ recordTelemetry = false,
25587
+ executionId,
25588
+ taskId,
25589
+ contextStrategy,
25462
25590
  config,
25463
25591
  rest
25464
25592
  } = options;
@@ -25509,6 +25637,28 @@ async function ccepCommand(options) {
25509
25637
  };
25510
25638
  }
25511
25639
  case "compile": {
25640
+ if (!["prompt", "layers", "full"].includes(view)) {
25641
+ return {
25642
+ code: 1,
25643
+ data: {
25644
+ success: false,
25645
+ command: "ccep compile",
25646
+ errors: [`Unknown compile view: ${view}`]
25647
+ }
25648
+ };
25649
+ }
25650
+ if (contextStrategy !== undefined && !CONTEXT_STRATEGIES.includes(contextStrategy)) {
25651
+ return {
25652
+ code: 1,
25653
+ data: {
25654
+ success: false,
25655
+ command: "ccep compile",
25656
+ errors: [
25657
+ `Invalid context strategy: ${contextStrategy}. Expected one of: ${CONTEXT_STRATEGIES.join(", ")}`
25658
+ ]
25659
+ }
25660
+ };
25661
+ }
25512
25662
  const parsed = parseWorkflowCommand(command);
25513
25663
  if (!parsed.ok) {
25514
25664
  return {
@@ -25559,12 +25709,69 @@ async function ccepCommand(options) {
25559
25709
  outputSchema: resolvedPhase.outputSchema
25560
25710
  };
25561
25711
  }
25712
+ const compileStartedAt = Date.now();
25562
25713
  const compiled = compilePrompt({
25563
25714
  role: agentRole,
25564
25715
  phase: phaseId,
25565
25716
  context,
25566
25717
  promptVersion
25567
25718
  });
25719
+ if (recordTelemetry) {
25720
+ const event = await appendEvent(projectRoot, {
25721
+ type: "context.compiled",
25722
+ timestamp: new Date().toISOString(),
25723
+ payload: {
25724
+ workflow: parsed.command,
25725
+ phase: phaseId,
25726
+ agent: agentRole,
25727
+ executionId: executionId ?? "unknown",
25728
+ taskId: taskId ?? "unknown",
25729
+ contextStrategy: contextStrategy ?? "unknown",
25730
+ promptVersion,
25731
+ view,
25732
+ source: "compiler",
25733
+ success: true,
25734
+ provider: "unknown",
25735
+ model: "unknown",
25736
+ effort: "unknown",
25737
+ sessionId: "unknown",
25738
+ parentSessionId: "unknown",
25739
+ requestedModel: "unknown",
25740
+ effectiveModel: "unknown",
25741
+ inputTokens: "unknown",
25742
+ outputTokens: "unknown",
25743
+ reasoningTokens: "unknown",
25744
+ cacheReadTokens: "unknown",
25745
+ cacheWriteTokens: "unknown",
25746
+ cachedTokens: "unknown",
25747
+ contextTokensEstimate: "unknown",
25748
+ filesRead: "unknown",
25749
+ uniqueFilesRead: "unknown",
25750
+ repeatedFileReads: "unknown",
25751
+ toolCalls: "unknown",
25752
+ retries: "unknown",
25753
+ compactions: "unknown",
25754
+ modelSwitches: "unknown",
25755
+ promptBytes: Buffer.byteLength(compiled.prompt, "utf-8"),
25756
+ layerBytes: Object.fromEntries(compiled.layers.map((layer) => [
25757
+ layer.name,
25758
+ Buffer.byteLength(layer.content, "utf-8")
25759
+ ])),
25760
+ durationMs: Date.now() - compileStartedAt
25761
+ }
25762
+ });
25763
+ if (!event.success) {
25764
+ return {
25765
+ code: 1,
25766
+ data: {
25767
+ success: false,
25768
+ command: "ccep compile",
25769
+ errors: [`Could not record compile telemetry: ${event.error.message}`]
25770
+ }
25771
+ };
25772
+ }
25773
+ }
25774
+ const representation = view === "prompt" ? { prompt: compiled.prompt } : view === "layers" ? { layers: compiled.layers } : { layers: compiled.layers, prompt: compiled.prompt };
25568
25775
  return {
25569
25776
  code: 0,
25570
25777
  data: {
@@ -25572,10 +25779,9 @@ async function ccepCommand(options) {
25572
25779
  command: "ccep compile",
25573
25780
  phase: phaseId,
25574
25781
  role: agentRole,
25575
- outputSchema: resolvedPhase.outputSchema,
25782
+ outputSchema: compiled.outputSchema,
25576
25783
  promptVersion,
25577
- layers: compiled.layers,
25578
- prompt: compiled.prompt
25784
+ ...representation
25579
25785
  }
25580
25786
  };
25581
25787
  }
@@ -25829,9 +26035,11 @@ async function ccepCommand(options) {
25829
26035
  };
25830
26036
  }
25831
26037
  }
26038
+ var CONTEXT_STRATEGIES;
25832
26039
  var init_ccep_command = __esm(() => {
25833
26040
  init_path_containment();
25834
26041
  init_prompt_compiler();
26042
+ init_episodic_store();
25835
26043
  init_output_validator();
25836
26044
  init_command_parser();
25837
26045
  init_context_resolver();
@@ -25839,6 +26047,7 @@ var init_ccep_command = __esm(() => {
25839
26047
  init_council_consensus();
25840
26048
  init_task_card_validator();
25841
26049
  init_schemas();
26050
+ CONTEXT_STRATEGIES = ["sticky", "isolated", "artifact", "compact", "fork", "full"];
25842
26051
  });
25843
26052
 
25844
26053
  // src/core/openspec/backlog-validator.ts
@@ -25981,7 +26190,7 @@ var init_backlog_validator = __esm(() => {
25981
26190
 
25982
26191
  // src/core/openspec/backlog-scanner.ts
25983
26192
  import { execFileSync } from "node:child_process";
25984
- import { readFile as readFile33 } from "node:fs/promises";
26193
+ import { readFile as readFile34 } from "node:fs/promises";
25985
26194
  import { resolve as resolve31 } from "node:path";
25986
26195
  function itemSnapshot(items) {
25987
26196
  const snap = {};
@@ -25993,7 +26202,7 @@ function itemSnapshot(items) {
25993
26202
  async function scanBacklog(projectRoot, previousSnapshot = {}) {
25994
26203
  try {
25995
26204
  const filePath = resolve31(projectRoot, BACKLOG_FILENAME);
25996
- const content = await readFile33(filePath, "utf-8");
26205
+ const content = await readFile34(filePath, "utf-8");
25997
26206
  const hash = hashContent(content);
25998
26207
  let fileChanged = true;
25999
26208
  try {
@@ -26403,7 +26612,7 @@ var init_openspec_generator = __esm(() => {
26403
26612
  });
26404
26613
 
26405
26614
  // src/core/openspec/spec-quality.ts
26406
- import { readdir as readdir11, readFile as readFile34 } from "node:fs/promises";
26615
+ import { readdir as readdir11, readFile as readFile35 } from "node:fs/promises";
26407
26616
  import { join as join23, relative as relative10, resolve as resolve33 } from "node:path";
26408
26617
  function uniqueIds(matches) {
26409
26618
  return [...new Set(matches ?? [])];
@@ -26560,13 +26769,13 @@ async function assessChangeFolder(projectRoot, changePath) {
26560
26769
  const extra = ["proposal.md", "design.md"].map((name) => join23(changeRoot, name));
26561
26770
  const reports = [];
26562
26771
  for (const file of specFiles) {
26563
- const content = await readFile34(file, "utf-8");
26772
+ const content = await readFile35(file, "utf-8");
26564
26773
  reports.push(assessSpecMarkdown(content, relative10(root, file).replace(/\\/g, "/")));
26565
26774
  }
26566
26775
  for (const file of extra) {
26567
26776
  let content;
26568
26777
  try {
26569
- content = await readFile34(file, "utf-8");
26778
+ content = await readFile35(file, "utf-8");
26570
26779
  } catch {
26571
26780
  continue;
26572
26781
  }
@@ -26621,7 +26830,7 @@ var init_spec_quality = __esm(() => {
26621
26830
  });
26622
26831
 
26623
26832
  // src/core/openspec/spec-analyzer.ts
26624
- import { readFile as readFile35, readdir as readdir12 } from "node:fs/promises";
26833
+ import { readFile as readFile36, readdir as readdir12 } from "node:fs/promises";
26625
26834
  import { join as join24, resolve as resolve34 } from "node:path";
26626
26835
  function unique(ids) {
26627
26836
  return [...new Set(ids)];
@@ -26659,7 +26868,7 @@ async function readDeltaSpecs(specDir) {
26659
26868
  if (entry.isDirectory()) {
26660
26869
  contents.push(await readDeltaSpecs(path));
26661
26870
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
26662
- contents.push(await readFile35(path, "utf-8"));
26871
+ contents.push(await readFile36(path, "utf-8"));
26663
26872
  }
26664
26873
  }
26665
26874
  return contents.filter(Boolean).join(`
@@ -26741,13 +26950,13 @@ async function analyzeChangeFolder(projectRoot, changePath, options) {
26741
26950
  const specMarkdown = await readDeltaSpecs(join24(changeRoot, "specs"));
26742
26951
  let tasksMarkdown = "";
26743
26952
  try {
26744
- tasksMarkdown = await readFile35(join24(changeRoot, "tasks.md"), "utf-8");
26953
+ tasksMarkdown = await readFile36(join24(changeRoot, "tasks.md"), "utf-8");
26745
26954
  } catch {
26746
26955
  tasksMarkdown = "";
26747
26956
  }
26748
26957
  let designMarkdown;
26749
26958
  try {
26750
- designMarkdown = await readFile35(join24(changeRoot, "design.md"), "utf-8");
26959
+ designMarkdown = await readFile36(join24(changeRoot, "design.md"), "utf-8");
26751
26960
  } catch {
26752
26961
  designMarkdown = undefined;
26753
26962
  }
@@ -26766,7 +26975,7 @@ var init_spec_analyzer = __esm(() => {
26766
26975
  });
26767
26976
 
26768
26977
  // src/core/openspec/spec-sync.ts
26769
- import { mkdir as mkdir23, readFile as readFile36, readdir as readdir13 } from "node:fs/promises";
26978
+ import { mkdir as mkdir23, readFile as readFile37, readdir as readdir13 } from "node:fs/promises";
26770
26979
  import { join as join25, relative as relative11, resolve as resolve35 } from "node:path";
26771
26980
  async function markdownFiles(dir) {
26772
26981
  let entries;
@@ -26865,7 +27074,7 @@ async function syncChangeSpecs(projectRoot, changePath) {
26865
27074
  }
26866
27075
  const writes = [];
26867
27076
  for (const file of files) {
26868
- const delta = await readFile36(file, "utf-8");
27077
+ const delta = await readFile37(file, "utf-8");
26869
27078
  const requirements = deltaRequirements(delta);
26870
27079
  if (requirements.length === 0) {
26871
27080
  return {
@@ -26879,7 +27088,7 @@ async function syncChangeSpecs(projectRoot, changePath) {
26879
27088
  let existing = `# ${relativeSpec.replace(/\\/g, "/")}
26880
27089
  `;
26881
27090
  try {
26882
- existing = await readFile36(target, "utf-8");
27091
+ existing = await readFile37(target, "utf-8");
26883
27092
  } catch {}
26884
27093
  const merged = upsertRequirements(existing, requirements, relative11(root, file));
26885
27094
  if (!merged.ok)
@@ -26908,7 +27117,7 @@ var exports_openspec_command = {};
26908
27117
  __export(exports_openspec_command, {
26909
27118
  openspecCommand: () => openspecCommand
26910
27119
  });
26911
- import { readFile as readFile37 } from "node:fs/promises";
27120
+ import { readFile as readFile38 } from "node:fs/promises";
26912
27121
  import { resolve as resolve36 } from "node:path";
26913
27122
  async function openspecCommand(options) {
26914
27123
  const { subcommand, itemId, projectRoot, output, reason } = options;
@@ -26965,7 +27174,7 @@ async function persistState(projectRoot, state) {
26965
27174
  return { ok: true };
26966
27175
  }
26967
27176
  async function readBacklogMarkdown(projectRoot) {
26968
- return readFile37(resolve36(projectRoot, BACKLOG_FILENAME), "utf-8");
27177
+ return readFile38(resolve36(projectRoot, BACKLOG_FILENAME), "utf-8");
26969
27178
  }
26970
27179
  async function transitionItem(projectRoot, item, to, progress) {
26971
27180
  const content = await readBacklogMarkdown(projectRoot);
@@ -27163,7 +27372,7 @@ async function handleAnalyze(projectRoot, itemId) {
27163
27372
  const policyParts = [];
27164
27373
  for (const name of ["AGENTS.md", "BACKLOG.md"]) {
27165
27374
  try {
27166
- policyParts.push(await readFile37(resolve36(projectRoot, name), "utf-8"));
27375
+ policyParts.push(await readFile38(resolve36(projectRoot, name), "utf-8"));
27167
27376
  } catch {}
27168
27377
  }
27169
27378
  const cards = itemCards(stateResult.data, targetId);
@@ -27595,9 +27804,44 @@ function resumeDecision(changedPaths) {
27595
27804
  }
27596
27805
  var init_context_assembly = () => {};
27597
27806
 
27807
+ // src/core/ccep/handoff-envelope.ts
27808
+ function buildHandoffEnvelope(ledger, changedPaths) {
27809
+ return HandoffEnvelopeSchema.parse({
27810
+ version: 1,
27811
+ task: {
27812
+ id: ledger.taskCard.id,
27813
+ objective: ledger.taskCard.objective,
27814
+ acceptanceCriteria: ledger.taskCard.acceptanceCriteria,
27815
+ status: ledger.taskCard.status
27816
+ },
27817
+ decisions: {
27818
+ constraints: ledger.taskCard.constraints,
27819
+ unresolved: ledger.tasks.filter((task) => task.status === "blocked").map((task) => task.title)
27820
+ },
27821
+ scope: {
27822
+ relevantFiles: ledger.taskCard.targetFiles,
27823
+ boundaries: ledger.taskCard.boundaries
27824
+ },
27825
+ verification: { evidence: ledger.evidence },
27826
+ change: { touchedFiles: [...new Set(changedPaths)].sort() },
27827
+ next: {
27828
+ role: ledger.taskCard.agentType,
27829
+ objective: ledger.nextStep
27830
+ },
27831
+ sources: {
27832
+ deliveryLedger: ledger.id,
27833
+ memoryTopicKey: ledger.memoryTopicKey,
27834
+ technicalPlanPath: ledger.technicalPlanPath
27835
+ }
27836
+ });
27837
+ }
27838
+ var init_handoff_envelope = __esm(() => {
27839
+ init_schemas();
27840
+ });
27841
+
27598
27842
  // src/core/delivery/delivery-ledger.ts
27599
27843
  import { createHash as createHash7 } from "node:crypto";
27600
- import { mkdir as mkdir24, readFile as readFile38, writeFile as writeFile23 } from "node:fs/promises";
27844
+ import { mkdir as mkdir24, readFile as readFile39, writeFile as writeFile23 } from "node:fs/promises";
27601
27845
  import { resolve as resolve37, sep as sep8 } from "node:path";
27602
27846
  function ledgerPath(projectRoot, id) {
27603
27847
  if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(id))
@@ -27614,7 +27858,7 @@ async function fingerprintWorkspace(projectRoot, paths) {
27614
27858
  continue;
27615
27859
  }
27616
27860
  try {
27617
- fingerprints[path] = createHash7("sha256").update(await readFile38(candidate)).digest("hex");
27861
+ fingerprints[path] = createHash7("sha256").update(await readFile39(candidate)).digest("hex");
27618
27862
  } catch {
27619
27863
  fingerprints[path] = "missing";
27620
27864
  }
@@ -27637,7 +27881,7 @@ function parseLedger(content) {
27637
27881
  return DeliveryLedgerSchema.parse($parse(match[1]));
27638
27882
  }
27639
27883
  async function loadDeliveryLedger(projectRoot, id) {
27640
- return parseLedger(await readFile38(ledgerPath(projectRoot, id), "utf-8"));
27884
+ return parseLedger(await readFile39(ledgerPath(projectRoot, id), "utf-8"));
27641
27885
  }
27642
27886
  async function createDeliveryLedger(projectRoot, input) {
27643
27887
  const request = DeliveryLedgerRequestSchema.parse(input);
@@ -27658,6 +27902,7 @@ async function createDeliveryLedger(projectRoot, input) {
27658
27902
  nextStep: request.nextStep,
27659
27903
  memoryTopicKey: `delivery:${request.id}`,
27660
27904
  workspace: await fingerprintWorkspace(projectRoot, request.taskCard.targetFiles),
27905
+ technicalPlanPath: request.technicalPlanPath,
27661
27906
  createdAt: now,
27662
27907
  updatedAt: now
27663
27908
  });
@@ -27689,6 +27934,28 @@ var exports_odd_command = {};
27689
27934
  __export(exports_odd_command, {
27690
27935
  oddCommand: () => oddCommand
27691
27936
  });
27937
+ async function reconcileForResume(projectRoot, id) {
27938
+ const result = await reconcileDeliveryLedger(projectRoot, id);
27939
+ const memory = await loadMemoryIndex(projectRoot);
27940
+ const { rddCommand: rddCommand2 } = await Promise.resolve().then(() => (init_rdd_command(), exports_rdd_command));
27941
+ const rdd = await rddCommand2({
27942
+ subcommand: "status",
27943
+ projectRoot,
27944
+ taskId: result.ledger.taskCard.id
27945
+ });
27946
+ const receipts = rdd.data.receipts ?? [];
27947
+ const staleReceipt = receipts.some((receipt) => receipt.valid === false);
27948
+ const changedPaths = staleReceipt ? [...result.changedPaths, "RDD receipt"].sort() : result.changedPaths;
27949
+ return {
27950
+ ...result,
27951
+ changedPaths,
27952
+ resume: resumeDecision(changedPaths),
27953
+ status: changedPaths.length === 0 ? "ready" : "conflict",
27954
+ rdd,
27955
+ memory: memory.success ? "available" : "unavailable",
27956
+ memoryPointers: memory.success ? memory.data.pointers.filter((pointer) => pointer.topic_key === result.ledger.memoryTopicKey) : []
27957
+ };
27958
+ }
27692
27959
  async function oddCommand(options) {
27693
27960
  if (options.subcommand === "create") {
27694
27961
  let input = options.input;
@@ -27722,28 +27989,25 @@ async function oddCommand(options) {
27722
27989
  return { code: 0, data: { success: true, ledger: await loadDeliveryLedger(options.projectRoot, options.id) } };
27723
27990
  }
27724
27991
  if (options.subcommand === "reconcile") {
27725
- const result = await reconcileDeliveryLedger(options.projectRoot, options.id);
27726
- const memory = await loadMemoryIndex(options.projectRoot);
27727
- const { rddCommand: rddCommand2 } = await Promise.resolve().then(() => (init_rdd_command(), exports_rdd_command));
27728
- const rdd = await rddCommand2({
27729
- subcommand: "status",
27730
- projectRoot: options.projectRoot,
27731
- taskId: result.ledger.taskCard.id
27732
- });
27733
- const receipts = rdd.data.receipts ?? [];
27734
- const staleReceipt = receipts.some((receipt) => receipt.valid === false);
27735
- const changedPaths = staleReceipt ? [...result.changedPaths, "RDD receipt"].sort() : result.changedPaths;
27992
+ const result = await reconcileForResume(options.projectRoot, options.id);
27736
27993
  return {
27737
27994
  code: 0,
27738
27995
  data: {
27739
27996
  success: true,
27740
- status: changedPaths.length === 0 ? "ready" : "conflict",
27741
- resume: resumeDecision(changedPaths),
27742
- rdd,
27743
- memory: memory.success ? "available" : "unavailable",
27744
- memoryPointers: memory.success ? memory.data.pointers.filter((pointer) => pointer.topic_key === result.ledger.memoryTopicKey) : [],
27745
- ...result,
27746
- changedPaths
27997
+ ...result
27998
+ }
27999
+ };
28000
+ }
28001
+ if (options.subcommand === "handoff") {
28002
+ const result = await reconcileForResume(options.projectRoot, options.id);
28003
+ return {
28004
+ code: 0,
28005
+ data: {
28006
+ success: true,
28007
+ status: result.status,
28008
+ changedPaths: result.changedPaths,
28009
+ resume: result.resume,
28010
+ handoff: buildHandoffEnvelope(result.ledger, result.changedPaths)
27747
28011
  }
27748
28012
  };
27749
28013
  }
@@ -27755,6 +28019,7 @@ async function oddCommand(options) {
27755
28019
  var init_odd_command = __esm(() => {
27756
28020
  init_memory_index();
27757
28021
  init_context_assembly();
28022
+ init_handoff_envelope();
27758
28023
  init_task_card_validator();
27759
28024
  init_workflow_profile_loader();
27760
28025
  init_delivery_ledger();
@@ -27959,7 +28224,7 @@ function isDestructiveRestore(command) {
27959
28224
  }
27960
28225
  var SENSITIVE_PATH, READ_LIKE, MSG_SECRET = "Bloqueado: intento de leer archivos sensibles", MSG_AUTHORITY = "Bloqueado: El agente no tiene autoridad sobre este comando.", MSG_POLICY = "Bloqueado: Command violated security policy";
27961
28226
  var init_hook_runner = __esm(() => {
27962
- SENSITIVE_PATH = /(?:\.env\b|secrets[/\\]|id_rsa|\.pem\b|\.key\b|(?:^|[/\\])\.ssh(?:[/\\]|$)|(?:^|[/\\])\.aws(?:[/\\]|$)|(?:^|[/\\])\.kube(?:[/\\]|$))/i;
28227
+ SENSITIVE_PATH = /(?:\.env(?!\.example(?:$|[/\\]))\b|secrets[/\\]|id_rsa|\.pem\b|\.key\b|(?:^|[/\\])\.ssh(?:[/\\]|$)|(?:^|[/\\])\.aws(?:[/\\]|$)|(?:^|[/\\])\.kube(?:[/\\]|$))/i;
27963
28228
  READ_LIKE = /(?:^|[\s;&|])(cat|less|more|head|tail|type|Get-Content|cp|copy|mv|move|scp)\b/i;
27964
28229
  });
27965
28230
 
@@ -28610,7 +28875,7 @@ var init_scorecard_signals = __esm(() => {
28610
28875
 
28611
28876
  // src/core/evaluation/harness-experiment.ts
28612
28877
  import { existsSync as existsSync9 } from "node:fs";
28613
- import { cp, mkdir as mkdir25, readFile as readFile39, readdir as readdir14, writeFile as writeFile24 } from "node:fs/promises";
28878
+ import { cp, mkdir as mkdir25, readFile as readFile40, readdir as readdir14, writeFile as writeFile24 } from "node:fs/promises";
28614
28879
  import { dirname as dirname14, join as join26, resolve as resolve39 } from "node:path";
28615
28880
  function experimentDir(projectRoot, experimentId) {
28616
28881
  return resolve39(projectRoot, EVAL_DIR2, EXPERIMENTS_DIR, experimentId);
@@ -28627,7 +28892,7 @@ async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
28627
28892
  if (!existsSync9(path))
28628
28893
  continue;
28629
28894
  try {
28630
- const suite = HarnessSuiteSchema.parse($parse(await readFile39(path, "utf-8")));
28895
+ const suite = HarnessSuiteSchema.parse($parse(await readFile40(path, "utf-8")));
28631
28896
  return ok({ ...suite, path });
28632
28897
  } catch (e) {
28633
28898
  return err(e instanceof Error ? e : new Error(String(e)));
@@ -28637,7 +28902,7 @@ async function loadHarnessSuite(projectRoot, suiteId, suitePath) {
28637
28902
  }
28638
28903
  async function loadExperiment(projectRoot, experimentId) {
28639
28904
  try {
28640
- const raw = await readFile39(experimentYamlPath(projectRoot, experimentId), "utf-8");
28905
+ const raw = await readFile40(experimentYamlPath(projectRoot, experimentId), "utf-8");
28641
28906
  return ok(HarnessExperimentSchema.parse($parse(raw)));
28642
28907
  } catch (e) {
28643
28908
  if (e.code === "ENOENT") {
@@ -28912,11 +29177,11 @@ var init_suite_run = __esm(() => {
28912
29177
  });
28913
29178
 
28914
29179
  // src/core/evaluation/execution-profile.ts
28915
- import { readFile as readFile40 } from "node:fs/promises";
29180
+ import { readFile as readFile41 } from "node:fs/promises";
28916
29181
  import { resolve as resolve41 } from "node:path";
28917
29182
  async function loadExecutionProfile(projectRoot, defaultTarget = "opencode") {
28918
29183
  try {
28919
- const content = await readFile40(resolve41(projectRoot, PROFILE_FILE), "utf-8");
29184
+ const content = await readFile41(resolve41(projectRoot, PROFILE_FILE), "utf-8");
28920
29185
  const data = $parse(content);
28921
29186
  return ExecutionProfileSchema.parse(data);
28922
29187
  } catch {
@@ -28996,7 +29261,7 @@ var init_execution_profile = __esm(() => {
28996
29261
  });
28997
29262
 
28998
29263
  // src/core/evaluation/prompt-diff.ts
28999
- import { readFile as readFile41, readdir as readdir15 } from "node:fs/promises";
29264
+ import { readFile as readFile42, readdir as readdir15 } from "node:fs/promises";
29000
29265
  import { join as join27, resolve as resolve42 } from "node:path";
29001
29266
  function normalizeVersion(v) {
29002
29267
  return v.startsWith("v") ? v : `v${v}`;
@@ -29056,7 +29321,7 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
29056
29321
  const f = join27(root, fromV);
29057
29322
  const t = join27(root, toV);
29058
29323
  try {
29059
- await readFile41(join27(f, "orchestrator.md"), "utf-8");
29324
+ await readFile42(join27(f, "orchestrator.md"), "utf-8");
29060
29325
  fromDir = f;
29061
29326
  toDir = t;
29062
29327
  break;
@@ -29067,7 +29332,7 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
29067
29332
  toDir = join27(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
29068
29333
  } else {
29069
29334
  try {
29070
- await readFile41(join27(toDir, "orchestrator.md"), "utf-8");
29335
+ await readFile42(join27(toDir, "orchestrator.md"), "utf-8");
29071
29336
  } catch {
29072
29337
  toDir = join27(ROOT_PRESETS_DIR, "opencode", "prompts", toV);
29073
29338
  }
@@ -29087,12 +29352,12 @@ async function diffPromptVersions(fromVersion, toVersion, options = {}) {
29087
29352
  let oldText = "";
29088
29353
  let newText = "";
29089
29354
  try {
29090
- oldText = await readFile41(join27(fromDir, name), "utf-8");
29355
+ oldText = await readFile42(join27(fromDir, name), "utf-8");
29091
29356
  } catch {
29092
29357
  oldText = "";
29093
29358
  }
29094
29359
  try {
29095
- newText = await readFile41(join27(toDir, name), "utf-8");
29360
+ newText = await readFile42(join27(toDir, name), "utf-8");
29096
29361
  } catch {
29097
29362
  newText = "";
29098
29363
  }
@@ -29132,12 +29397,12 @@ var init_prompt_diff = __esm(() => {
29132
29397
 
29133
29398
  // src/core/evaluation/regression-checklist.ts
29134
29399
  import { execFileSync as execFileSync3 } from "node:child_process";
29135
- import { mkdir as mkdir26, readFile as readFile42, writeFile as writeFile25 } from "node:fs/promises";
29400
+ import { mkdir as mkdir26, readFile as readFile43, writeFile as writeFile25 } from "node:fs/promises";
29136
29401
  import { dirname as dirname15, resolve as resolve43 } from "node:path";
29137
29402
  async function loadRegressionChecklist() {
29138
29403
  try {
29139
29404
  const path = resolve43(ROOT_PRESETS_DIR, "templates", "regression-checklist.yml");
29140
- const content = await readFile42(path, "utf-8");
29405
+ const content = await readFile43(path, "utf-8");
29141
29406
  const data = $parse(content);
29142
29407
  return data.checks ?? [];
29143
29408
  } catch {
@@ -29467,7 +29732,7 @@ var exports_scorecard_command = {};
29467
29732
  __export(exports_scorecard_command, {
29468
29733
  scorecardCommand: () => scorecardCommand
29469
29734
  });
29470
- import { readFile as readFile43 } from "node:fs/promises";
29735
+ import { readFile as readFile44 } from "node:fs/promises";
29471
29736
  import { resolve as resolve46 } from "node:path";
29472
29737
  function contractVersion() {
29473
29738
  return package_default.version;
@@ -29758,7 +30023,7 @@ async function handleCompareModels(projectRoot, options) {
29758
30023
  const markdown = generateModelComparisonMarkdown(outcomes, options.modelsFilter);
29759
30024
  const templatePath = resolve46(projectRoot, ".codeconductor/evaluation/model-comparison-last.md");
29760
30025
  try {
29761
- await readFile43(templatePath);
30026
+ await readFile44(templatePath);
29762
30027
  } catch {}
29763
30028
  const { writeFile: writeFile28, mkdir: mkdir28 } = await import("node:fs/promises");
29764
30029
  await mkdir28(resolve46(projectRoot, ".codeconductor/evaluation"), { recursive: true });
@@ -31625,6 +31890,7 @@ var COMMANDS = [
31625
31890
  { name: "ingest", group: "workflow", summary: "Ingest repository knowledge into the product graph.", usage: ["cc-codeconductor ingest"] },
31626
31891
  { name: "product", group: "workflow", summary: "Explore the product graph and memory.", usage: ["cc-codeconductor product <subcommand>"] },
31627
31892
  { name: "ccep", group: "workflow", summary: "Run CCEP contract workflows.", usage: ["cc-codeconductor ccep <subcommand>"] },
31893
+ { name: "odd", group: "workflow", summary: "Create, resume, and hand off tracked delivery work.", usage: ["cc-codeconductor odd <create|read|reconcile|handoff>"] },
31628
31894
  { name: "openspec", group: "workflow", summary: "Run the OpenSpec delivery loop.", usage: ["cc-codeconductor openspec <subcommand>"] },
31629
31895
  { name: "scorecard", group: "workflow", summary: "Record and aggregate outcomes.", usage: ["cc-codeconductor scorecard <subcommand>"] },
31630
31896
  { name: "orchestrate", group: "workflow", summary: "Run goal execution orchestration.", usage: ["cc-codeconductor orchestrate <subcommand>"] },
@@ -31814,6 +32080,7 @@ var OutputModeSchema = exports_external.enum(["json", "human"]);
31814
32080
  var SeoFormatSchema = exports_external.enum(["cli", "json", "markdown"]);
31815
32081
  var SeoFailOnSchema = exports_external.enum(["error", "warning", "never"]);
31816
32082
  var NonNegativeIntegerSchema = exports_external.coerce.number().int().nonnegative();
32083
+ var BOOLEAN_OPTIONS = new Set(["record-telemetry"]);
31817
32084
  function parseArgs(args) {
31818
32085
  const commandAcceptsOutputPath = args[0] === "seo";
31819
32086
  const flags = {
@@ -31884,6 +32151,9 @@ function parseArgs(args) {
31884
32151
  } else if (value !== undefined) {
31885
32152
  options[key] = value;
31886
32153
  consumed.add(i);
32154
+ } else if (BOOLEAN_OPTIONS.has(key)) {
32155
+ options[key] = true;
32156
+ consumed.add(i);
31887
32157
  } else if (remaining[i + 1] && !remaining[i + 1].startsWith("-")) {
31888
32158
  options[key] = remaining[++i];
31889
32159
  consumed.add(i - 1);
@@ -32241,6 +32511,11 @@ async function routeCommand(args, projectRoot) {
32241
32511
  input: options.input,
32242
32512
  contextPath: options.context || options.contextPath,
32243
32513
  promptVersion: options["prompt-version"] || options.promptVersion,
32514
+ view: options.view,
32515
+ recordTelemetry: options["record-telemetry"] === true || options["record-telemetry"] === "true",
32516
+ executionId: options["execution-id"],
32517
+ taskId: options["task-id"],
32518
+ contextStrategy: options["context-strategy"],
32244
32519
  config: options.config,
32245
32520
  rest: validateRest
32246
32521
  });
@@ -32281,7 +32556,7 @@ async function routeCommand(args, projectRoot) {
32281
32556
  });
32282
32557
  }
32283
32558
  case "odd": {
32284
- const validSubs = ["create", "read", "reconcile"];
32559
+ const validSubs = ["create", "read", "reconcile", "handoff"];
32285
32560
  if (!subcommand || !validSubs.includes(subcommand)) {
32286
32561
  return unknownSubcommand(command, subcommand ?? "", validSubs);
32287
32562
  }