cc-codeconductor 1.4.1 → 1.5.0

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 (219) hide show
  1. package/README.md +61 -13
  2. package/dist/core/verification/rdd-receipt.d.ts +39 -0
  3. package/dist/core/verification/verification-runner.d.ts +8 -2
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.js +1257 -330
  6. package/dist/library.js +267 -26
  7. package/dist/validation/schemas.d.ts +521 -26
  8. package/docs/generated/cli.md +20 -0
  9. package/package.json +1 -1
  10. package/presets/agy/AGENTS.md +6 -0
  11. package/presets/agy/README.md +1 -1
  12. package/presets/agy/hooks.json +1 -1
  13. package/presets/agy/scripts/invoke-hook.cjs +20 -5
  14. package/presets/agy/settings.json +1 -1
  15. package/presets/agy/skills/api-versioning/SKILL.md +394 -0
  16. package/presets/agy/skills/astro/SKILL.md +318 -0
  17. package/presets/agy/skills/auth-token-inspector/SKILL.md +30 -0
  18. package/presets/agy/skills/cc-pagespeed/SKILL.md +2 -3
  19. package/presets/agy/skills/code-review/SKILL.md +207 -0
  20. package/presets/agy/skills/django-orm/SKILL.md +460 -0
  21. package/presets/agy/skills/django-uv/SKILL.md +405 -0
  22. package/presets/agy/skills/drizzle-schema-architect/SKILL.md +50 -0
  23. package/presets/agy/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  24. package/presets/agy/skills/jpa-nplusone-detector/SKILL.md +45 -0
  25. package/presets/agy/skills/jpa-postgres/SKILL.md +623 -0
  26. package/presets/agy/skills/livewire-alpine-bridge/SKILL.md +35 -0
  27. package/presets/agy/skills/nextjs-typescript/SKILL.md +390 -0
  28. package/presets/agy/skills/python/SKILL.md +611 -0
  29. package/presets/agy/skills/seo-analytics-injector/SKILL.md +43 -0
  30. package/presets/agy/skills/spring-auth-auditor/SKILL.md +29 -0
  31. package/presets/agy/skills/spring-boot-feature/SKILL.md +563 -0
  32. package/presets/agy/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  33. package/presets/agy/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  34. package/presets/agy/skills/tdd-mutation-tester/SKILL.md +27 -0
  35. package/presets/agy/workflows/cc-handoff.md +2 -1
  36. package/presets/agy/workflows/cc-odd.md +15 -0
  37. package/presets/agy/workflows/cc-pagespeed.md +2 -3
  38. package/presets/agy/workflows/cc-review.md +31 -0
  39. package/presets/agy/workflows/cc-security.md +1 -1
  40. package/presets/claude/CLAUDE.md +6 -0
  41. package/presets/claude/commands/cc/handoff.md +2 -1
  42. package/presets/claude/commands/cc/odd.md +15 -0
  43. package/presets/claude/commands/cc/review.md +33 -0
  44. package/presets/claude/settings.json +2 -2
  45. package/presets/claude/skills/android/SKILL.md +1 -1
  46. package/presets/claude/skills/api-versioning/SKILL.md +1 -1
  47. package/presets/claude/skills/astro/SKILL.md +318 -0
  48. package/presets/claude/skills/auth-token-inspector/SKILL.md +30 -0
  49. package/presets/claude/skills/code-review/SKILL.md +207 -0
  50. package/presets/claude/skills/django-orm/SKILL.md +1 -1
  51. package/presets/claude/skills/django-testing/SKILL.md +1 -1
  52. package/presets/claude/skills/django-uv/SKILL.md +405 -0
  53. package/presets/claude/skills/drizzle-schema-architect/SKILL.md +50 -0
  54. package/presets/claude/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  55. package/presets/claude/skills/jpa-nplusone-detector/SKILL.md +45 -0
  56. package/presets/claude/skills/jpa-postgres/SKILL.md +1 -1
  57. package/presets/claude/skills/livewire-alpine-bridge/SKILL.md +35 -0
  58. package/presets/claude/skills/nextjs-typescript/SKILL.md +390 -0
  59. package/presets/claude/skills/pagespeed-perf/SKILL.md +1 -1
  60. package/presets/claude/skills/python/SKILL.md +1 -1
  61. package/presets/claude/skills/python-django-stack/SKILL.md +1 -1
  62. package/presets/claude/skills/python-fastapi-stack/SKILL.md +1 -1
  63. package/presets/claude/skills/security/SKILL.md +1 -1
  64. package/presets/claude/skills/seo-analytics-injector/SKILL.md +43 -0
  65. package/presets/claude/skills/spring-auth-auditor/SKILL.md +29 -0
  66. package/presets/claude/skills/spring-boot-feature/SKILL.md +1 -1
  67. package/presets/claude/skills/spring-boot-kotlin/SKILL.md +1 -1
  68. package/presets/claude/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  69. package/presets/claude/skills/sqlalchemy/SKILL.md +1 -1
  70. package/presets/claude/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  71. package/presets/claude/skills/tdd-mutation-tester/SKILL.md +27 -0
  72. package/presets/claude/skills/testing-strategy/SKILL.md +1 -1
  73. package/presets/codex/AGENTS.md +6 -0
  74. package/presets/codex/skills/android/SKILL.md +1 -1
  75. package/presets/codex/skills/api-versioning/SKILL.md +1 -1
  76. package/presets/codex/skills/astro/SKILL.md +318 -0
  77. package/presets/codex/skills/auth-token-inspector/SKILL.md +30 -0
  78. package/presets/codex/skills/cc-handoff/SKILL.md +3 -1
  79. package/presets/codex/skills/cc-odd/SKILL.md +25 -0
  80. package/presets/codex/skills/cc-openspec/SKILL.md +5 -1
  81. package/presets/codex/skills/cc-pagespeed/SKILL.md +2 -3
  82. package/presets/codex/skills/cc-review/SKILL.md +31 -0
  83. package/presets/codex/skills/cc-security/SKILL.md +1 -1
  84. package/presets/codex/skills/cc-spec-mutation/SKILL.md +5 -0
  85. package/presets/codex/skills/cc-tdd-cycle/SKILL.md +8 -0
  86. package/presets/codex/skills/code-review/SKILL.md +207 -0
  87. package/presets/codex/skills/django-orm/SKILL.md +1 -1
  88. package/presets/codex/skills/django-testing/SKILL.md +1 -1
  89. package/presets/codex/skills/django-uv/SKILL.md +405 -0
  90. package/presets/codex/skills/drizzle-schema-architect/SKILL.md +50 -0
  91. package/presets/codex/skills/fastapi-pydantic-strict/SKILL.md +43 -0
  92. package/presets/codex/skills/jpa-nplusone-detector/SKILL.md +45 -0
  93. package/presets/codex/skills/jpa-postgres/SKILL.md +1 -1
  94. package/presets/codex/skills/livewire-alpine-bridge/SKILL.md +35 -0
  95. package/presets/codex/skills/nextjs-typescript/SKILL.md +390 -0
  96. package/presets/codex/skills/pagespeed-perf/SKILL.md +1 -1
  97. package/presets/codex/skills/python/SKILL.md +1 -1
  98. package/presets/codex/skills/python-django-stack/SKILL.md +1 -1
  99. package/presets/codex/skills/python-fastapi-stack/SKILL.md +1 -1
  100. package/presets/codex/skills/security-ai-llm/SKILL.md +43 -0
  101. package/presets/codex/skills/security-blue-team/SKILL.md +43 -0
  102. package/presets/codex/skills/security-cloud/SKILL.md +43 -0
  103. package/presets/codex/skills/security-crypto/SKILL.md +43 -0
  104. package/presets/codex/skills/security-exploit-dev/SKILL.md +45 -0
  105. package/presets/codex/skills/security-grc/SKILL.md +43 -0
  106. package/presets/codex/skills/security-incident-response/SKILL.md +45 -0
  107. package/presets/codex/skills/security-log-analysis/SKILL.md +43 -0
  108. package/presets/codex/skills/security-malware-analysis/SKILL.md +44 -0
  109. package/presets/codex/skills/security-mobile/SKILL.md +43 -0
  110. package/presets/codex/skills/security-network/SKILL.md +43 -0
  111. package/presets/codex/skills/security-ot-ics/SKILL.md +43 -0
  112. package/presets/codex/skills/security-recon/SKILL.md +45 -0
  113. package/presets/codex/skills/security-red-team/SKILL.md +44 -0
  114. package/presets/codex/skills/security-reverse-engineering/SKILL.md +44 -0
  115. package/presets/codex/skills/security-soc-automation/SKILL.md +43 -0
  116. package/presets/codex/skills/security-threat-hunting/SKILL.md +43 -0
  117. package/presets/codex/skills/security-vuln-assessment/SKILL.md +45 -0
  118. package/presets/codex/skills/security-web/SKILL.md +44 -0
  119. package/presets/codex/skills/seo-analytics-injector/SKILL.md +43 -0
  120. package/presets/codex/skills/spring-auth-auditor/SKILL.md +29 -0
  121. package/presets/codex/skills/spring-boot-feature/SKILL.md +2 -2
  122. package/presets/codex/skills/spring-boot-kotlin/SKILL.md +1 -1
  123. package/presets/codex/skills/spring-boot-testing-strategy/SKILL.md +475 -0
  124. package/presets/codex/skills/sqlalchemy/SKILL.md +1 -1
  125. package/presets/codex/skills/tailwind-responsive-auditor/SKILL.md +29 -0
  126. package/presets/codex/skills/tdd-mutation-tester/SKILL.md +27 -0
  127. package/presets/codex/skills/testing-strategy/SKILL.md +1 -1
  128. package/presets/cursor/AGENTS.md +6 -0
  129. package/presets/cursor/commands/cc/handoff.md +3 -1
  130. package/presets/cursor/commands/cc/odd.md +20 -0
  131. package/presets/cursor/commands/cc/openspec.md +5 -1
  132. package/presets/cursor/commands/cc/pagespeed.md +2 -3
  133. package/presets/cursor/commands/cc/review.md +31 -0
  134. package/presets/cursor/commands/cc/security.md +1 -1
  135. package/presets/cursor/commands/cc/spec-mutation.md +5 -0
  136. package/presets/cursor/commands/cc/tdd-cycle.md +8 -0
  137. package/presets/cursor/skills/android/SKILL.md +1 -1
  138. package/presets/cursor/skills/api-versioning/SKILL.md +2 -1
  139. package/presets/cursor/skills/astro/SKILL.md +1 -1
  140. package/presets/cursor/skills/auth-token-inspector/SKILL.md +1 -1
  141. package/presets/cursor/skills/code-review/SKILL.md +1 -1
  142. package/presets/cursor/skills/django-orm/SKILL.md +3 -5
  143. package/presets/cursor/skills/django-testing/SKILL.md +1 -1
  144. package/presets/cursor/skills/django-uv/SKILL.md +1 -1
  145. package/presets/cursor/skills/drizzle-schema-architect/SKILL.md +1 -1
  146. package/presets/cursor/skills/fastapi-pydantic-strict/SKILL.md +1 -1
  147. package/presets/cursor/skills/jpa-nplusone-detector/SKILL.md +1 -1
  148. package/presets/cursor/skills/jpa-postgres/SKILL.md +2 -4
  149. package/presets/cursor/skills/livewire-alpine-bridge/SKILL.md +1 -1
  150. package/presets/cursor/skills/nextjs-typescript/SKILL.md +1 -1
  151. package/presets/cursor/skills/pagespeed-perf/SKILL.md +1 -1
  152. package/presets/cursor/skills/python/SKILL.md +6 -7
  153. package/presets/cursor/skills/python-django-stack/SKILL.md +1 -1
  154. package/presets/cursor/skills/python-fastapi-stack/SKILL.md +1 -1
  155. package/presets/cursor/skills/security/SKILL.md +1 -1
  156. package/presets/cursor/skills/seo-analytics-injector/SKILL.md +1 -1
  157. package/presets/cursor/skills/spring-auth-auditor/SKILL.md +1 -1
  158. package/presets/cursor/skills/spring-boot-feature/SKILL.md +2 -4
  159. package/presets/cursor/skills/spring-boot-kotlin/SKILL.md +1 -1
  160. package/presets/cursor/skills/spring-boot-testing-strategy/SKILL.md +1 -1
  161. package/presets/cursor/skills/sqlalchemy/SKILL.md +1 -1
  162. package/presets/cursor/skills/tailwind-responsive-auditor/SKILL.md +1 -1
  163. package/presets/cursor/skills/tdd-mutation-tester/SKILL.md +1 -1
  164. package/presets/gemini/GEMINI.md +6 -0
  165. package/presets/gemini/commands/cc/handoff.toml +3 -1
  166. package/presets/gemini/commands/cc/odd.toml +20 -0
  167. package/presets/gemini/commands/cc/openspec.toml +5 -1
  168. package/presets/gemini/commands/cc/pagespeed.toml +2 -3
  169. package/presets/gemini/commands/cc/review.toml +31 -0
  170. package/presets/gemini/commands/cc/security.toml +1 -1
  171. package/presets/gemini/commands/cc/spec-mutation.toml +5 -0
  172. package/presets/gemini/commands/cc/tdd-cycle.toml +8 -0
  173. package/presets/opencode/README.md +45 -52
  174. package/presets/opencode/agents/implementer.md +2 -0
  175. package/presets/opencode/agents/reviewer.md +2 -0
  176. package/presets/opencode/agents/tester.md +2 -0
  177. package/presets/opencode/commands/cc-handoff.md +2 -1
  178. package/presets/opencode/commands/cc-odd.md +15 -0
  179. package/presets/opencode/commands/cc-pagespeed.md +2 -3
  180. package/presets/opencode/commands/cc-review.md +31 -0
  181. package/presets/opencode/commands/cc-security.md +1 -1
  182. package/presets/opencode/opencode.jsonc +1 -1
  183. package/presets/opencode/skills/android/SKILL.md +1 -1
  184. package/presets/opencode/skills/api-versioning/SKILL.md +2 -1
  185. package/presets/opencode/skills/astro/SKILL.md +1 -1
  186. package/presets/opencode/skills/auth-token-inspector/SKILL.md +1 -1
  187. package/presets/opencode/skills/code-review/SKILL.md +1 -1
  188. package/presets/opencode/skills/django-orm/SKILL.md +3 -3
  189. package/presets/opencode/skills/django-testing/SKILL.md +1 -1
  190. package/presets/opencode/skills/django-uv/SKILL.md +1 -1
  191. package/presets/opencode/skills/drizzle-schema-architect/SKILL.md +1 -1
  192. package/presets/opencode/skills/fastapi-pydantic-strict/SKILL.md +1 -1
  193. package/presets/opencode/skills/jpa-nplusone-detector/SKILL.md +1 -1
  194. package/presets/opencode/skills/jpa-postgres/SKILL.md +2 -1
  195. package/presets/opencode/skills/livewire-alpine-bridge/SKILL.md +1 -1
  196. package/presets/opencode/skills/nextjs-typescript/SKILL.md +1 -1
  197. package/presets/opencode/skills/pagespeed-perf/SKILL.md +1 -1
  198. package/presets/opencode/skills/python/SKILL.md +6 -5
  199. package/presets/opencode/skills/python-django-stack/SKILL.md +1 -1
  200. package/presets/opencode/skills/python-fastapi-stack/SKILL.md +1 -1
  201. package/presets/opencode/skills/security/SKILL.md +1 -1
  202. package/presets/opencode/skills/seo-analytics-injector/SKILL.md +1 -1
  203. package/presets/opencode/skills/spring-auth-auditor/SKILL.md +1 -1
  204. package/presets/opencode/skills/spring-boot-feature/SKILL.md +2 -1
  205. package/presets/opencode/skills/spring-boot-kotlin/SKILL.md +1 -1
  206. package/presets/opencode/skills/spring-boot-testing-strategy/SKILL.md +1 -1
  207. package/presets/opencode/skills/sqlalchemy/SKILL.md +1 -1
  208. package/presets/opencode/skills/tailwind-responsive-auditor/SKILL.md +1 -1
  209. package/presets/opencode/skills/tdd-mutation-tester/SKILL.md +1 -1
  210. package/presets/pi/AGENTS.md +6 -0
  211. package/presets/seo-hotel/skills/astro-seo/SKILL.md +1 -1
  212. package/presets/seo-hotel/skills/geo-readiness/SKILL.md +1 -1
  213. package/presets/seo-hotel/skills/off-page/SKILL.md +1 -1
  214. package/presets/seo-hotel/skills/schema-validator/SKILL.md +1 -1
  215. package/presets/seo-hotel/skills/seo-audit/SKILL.md +1 -1
  216. package/presets/shared/invoke-hook.cjs +20 -5
  217. package/src/presets/models/roles.yml +28 -28
  218. package/src/presets/shared-skills.yml +58 -22
  219. package/src/presets/targets/pi.yml +1 -0
package/dist/library.js CHANGED
@@ -149,7 +149,7 @@ function validateProductEvent(data) {
149
149
  function validateSkillsRegistry(data) {
150
150
  return SkillsRegistrySchema.parse(data);
151
151
  }
152
- 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, TaskOutcomeSchema, HarnessComponentIdSchema, HarnessComponentLayerSchema, HarnessToggleKindSchema, HarnessCatalogEntrySchema, HarnessCatalogSchema, HarnessOverlaySchema, HarnessExperimentSchema, HarnessSuiteTaskSchema, HarnessSuiteSchema, EvaluationIndexSchema, ExecutionProfileNameSchema, ExecutionProfileSchema, SkillsRegistrySchema;
152
+ 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;
153
153
  var init_schemas = __esm(() => {
154
154
  init_runner_target();
155
155
  CouncilAgentSpecSchema = z.object({
@@ -313,7 +313,8 @@ var init_schemas = __esm(() => {
313
313
  complianceVeto: z.boolean().optional(),
314
314
  confidence: z.number().min(0).max(1),
315
315
  findings: z.array(CouncilFindingSchema),
316
- summary: z.string()
316
+ summary: z.string(),
317
+ candidateHash: z.string().min(1).optional()
317
318
  });
318
319
  ConsensusConfigSchema = z.object({
319
320
  algorithm: z.enum(["majority", "unanimous"]),
@@ -321,7 +322,8 @@ var init_schemas = __esm(() => {
321
322
  allowComplianceVeto: z.boolean().optional(),
322
323
  expectedAgentIds: z.array(z.string().min(1).refine((id) => id.trim().length > 0)).min(1).refine((ids) => new Set(ids.map((id) => id.trim().toLowerCase())).size === ids.length).optional(),
323
324
  quorum: z.number().int().positive().optional(),
324
- criticalFindingsPolicy: z.enum(["escalate", "reject", "ignore"]).optional()
325
+ criticalFindingsPolicy: z.enum(["escalate", "reject", "ignore"]).optional(),
326
+ candidateHash: z.string().min(1).optional()
325
327
  }).refine((config) => config.algorithm !== "unanimous" || config.expectedAgentIds !== undefined, {
326
328
  message: "unanimous consensus requires a non-empty expectedAgentIds roster",
327
329
  path: ["expectedAgentIds"]
@@ -698,7 +700,8 @@ var init_schemas = __esm(() => {
698
700
  "prototype",
699
701
  "handoff",
700
702
  "clarify",
701
- "security"
703
+ "security",
704
+ "odd"
702
705
  ]);
703
706
  CcepOutputFormatSchema = z.enum(["taskcard", "plan", "verdict"]);
704
707
  CommandEnvelopeSchema = z.object({
@@ -914,6 +917,46 @@ var init_schemas = __esm(() => {
914
917
  "revise",
915
918
  "reject"
916
919
  ]);
920
+ DeliveryRouteSchema = z.enum(["read-only", "small", "tracked", "openspec"]);
921
+ TokenUsageSchema = z.union([
922
+ z.object({
923
+ status: z.literal("known"),
924
+ total: z.number().nonnegative()
925
+ }),
926
+ z.object({ status: z.literal("unknown") })
927
+ ]);
928
+ DeliveryTelemetrySchema = z.object({
929
+ route: DeliveryRouteSchema,
930
+ contextBytes: z.number().int().nonnegative().optional(),
931
+ handoffs: z.number().int().nonnegative().optional(),
932
+ checks: z.array(z.string().min(1)).optional(),
933
+ tokenUsage: TokenUsageSchema
934
+ });
935
+ DeliveryLedgerTaskSchema = z.object({
936
+ id: z.string().min(1),
937
+ title: z.string().min(1),
938
+ status: z.enum(["pending", "done", "blocked"])
939
+ });
940
+ DeliveryLedgerSchema = z.object({
941
+ version: z.literal(1),
942
+ id: z.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/),
943
+ taskCard: CanonicalTaskCardSchema,
944
+ tasks: z.array(DeliveryLedgerTaskSchema).min(1),
945
+ evidence: z.array(z.string().min(1)),
946
+ nextStep: z.string().min(1),
947
+ memoryTopicKey: z.string().min(1),
948
+ workspace: z.record(z.string(), z.string()),
949
+ createdAt: z.string().datetime(),
950
+ updatedAt: z.string().datetime()
951
+ });
952
+ DeliveryLedgerRequestSchema = z.object({
953
+ id: z.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/),
954
+ authorized: z.boolean(),
955
+ route: DeliveryRouteSchema,
956
+ taskCard: CanonicalTaskCardSchema,
957
+ tasks: z.array(DeliveryLedgerTaskSchema).min(1),
958
+ nextStep: z.string().min(1)
959
+ });
917
960
  TaskOutcomeSchema = z.object({
918
961
  id: z.string(),
919
962
  taskId: z.string(),
@@ -937,7 +980,8 @@ var init_schemas = __esm(() => {
937
980
  variantId: z.string().optional(),
938
981
  suiteTaskId: z.string().optional(),
939
982
  harnessFingerprint: z.string().optional(),
940
- disabledComponents: z.array(z.string()).optional()
983
+ disabledComponents: z.array(z.string()).optional(),
984
+ delivery: DeliveryTelemetrySchema.optional()
941
985
  });
942
986
  HarnessComponentIdSchema = z.enum([
943
987
  "wayfinding",
@@ -1342,8 +1386,8 @@ async function clearActiveTask(projectRoot, taskId) {
1342
1386
  // src/core/verification/verification-runner.ts
1343
1387
  init_schemas();
1344
1388
  import { existsSync } from "node:fs";
1345
- import { readFile as readFile6 } from "node:fs/promises";
1346
- import { dirname, join as join2, resolve as resolve5 } from "node:path";
1389
+ import { readFile as readFile7 } from "node:fs/promises";
1390
+ import { dirname, join as join3, resolve as resolve6 } from "node:path";
1347
1391
 
1348
1392
  // src/core/config/config-loader.ts
1349
1393
  import { readFile as readFile5 } from "node:fs/promises";
@@ -1659,7 +1703,128 @@ async function runCompileCheck(options) {
1659
1703
  }
1660
1704
  }
1661
1705
  // src/core/verification/verification-runner.ts
1662
- import { mkdir as mkdir5, readdir, writeFile as writeFile4 } from "node:fs/promises";
1706
+ import { mkdir as mkdir5, readdir as readdir2, writeFile as writeFile4 } from "node:fs/promises";
1707
+
1708
+ // src/core/verification/rdd-receipt.ts
1709
+ import { createHash } from "node:crypto";
1710
+ import { readdir, readFile as readFile6 } from "node:fs/promises";
1711
+ import { join as join2, relative, resolve as resolve5, sep } from "node:path";
1712
+ var EXCLUDED_DIRECTORIES = new Set([
1713
+ ".git",
1714
+ ".codeconductor",
1715
+ "node_modules",
1716
+ "dist",
1717
+ "coverage",
1718
+ "graphify-out"
1719
+ ]);
1720
+ function sha256(content) {
1721
+ return createHash("sha256").update(content).digest("hex");
1722
+ }
1723
+ function canonicalPath(projectRoot, input) {
1724
+ const root = resolve5(projectRoot);
1725
+ const absolute = resolve5(root, input);
1726
+ if (absolute !== root && !absolute.startsWith(`${root}${sep}`)) {
1727
+ throw new Error(`RDD receipt path "${input}" is outside the project root`);
1728
+ }
1729
+ const normalized = relative(root, absolute);
1730
+ if (!normalized || normalized === ".") {
1731
+ throw new Error("RDD receipts require file paths, not the project root");
1732
+ }
1733
+ return { absolute, relative: normalized.split(sep).join("/") };
1734
+ }
1735
+ async function fingerprint(projectRoot, paths) {
1736
+ const deduplicated = new Map;
1737
+ for (const path of paths) {
1738
+ const canonical = canonicalPath(projectRoot, path);
1739
+ deduplicated.set(canonical.relative, canonical.absolute);
1740
+ }
1741
+ const result = [];
1742
+ for (const [path, absolute] of [...deduplicated.entries()].sort(([left], [right]) => left.localeCompare(right))) {
1743
+ result.push({ path, hash: sha256(await readFile6(absolute)) });
1744
+ }
1745
+ return result;
1746
+ }
1747
+ function manifestHash(paths) {
1748
+ return sha256(paths.map((entry) => `${entry.path}\x00${entry.hash}`).join(`
1749
+ `));
1750
+ }
1751
+ function isRddReceipt(value) {
1752
+ if (!value || typeof value !== "object")
1753
+ return false;
1754
+ const receipt = value;
1755
+ return receipt.version === 1 && typeof receipt.taskId === "string" && typeof receipt.phase === "string" && Array.isArray(receipt.paths) && receipt.paths.every((entry) => Boolean(entry) && typeof entry.path === "string" && typeof entry.hash === "string") && (receipt.coverage === "paths" || receipt.coverage === "project") && typeof receipt.manifestHash === "string" && (receipt.outcome === "passed" || receipt.outcome === "failed") && typeof receipt.capturedAt === "string";
1756
+ }
1757
+ async function captureReceipt(projectRoot, input) {
1758
+ if (!input.taskId.trim())
1759
+ throw new Error("RDD receipts require a task id");
1760
+ if (input.paths.length === 0 && input.coverage !== "project") {
1761
+ throw new Error("RDD receipts require at least one protected path");
1762
+ }
1763
+ const paths = await fingerprint(projectRoot, input.paths);
1764
+ return {
1765
+ version: 1,
1766
+ taskId: input.taskId,
1767
+ phase: input.phase,
1768
+ paths,
1769
+ coverage: input.coverage ?? "paths",
1770
+ manifestHash: manifestHash(paths),
1771
+ command: input.command,
1772
+ outcome: input.outcome,
1773
+ capturedAt: new Date().toISOString()
1774
+ };
1775
+ }
1776
+ async function collectReceiptPaths(projectRoot) {
1777
+ const root = resolve5(projectRoot);
1778
+ const paths = [];
1779
+ async function visit(current) {
1780
+ const entries = await readdir(current, { withFileTypes: true });
1781
+ for (const entry of entries) {
1782
+ if (entry.isDirectory()) {
1783
+ if (!EXCLUDED_DIRECTORIES.has(entry.name))
1784
+ await visit(join2(current, entry.name));
1785
+ continue;
1786
+ }
1787
+ if (entry.isFile())
1788
+ paths.push(relative(root, join2(current, entry.name)).split(sep).join("/"));
1789
+ }
1790
+ }
1791
+ await visit(root);
1792
+ return paths.sort();
1793
+ }
1794
+ async function verifyReceipt(projectRoot, receipt) {
1795
+ const expected = new Map(receipt.paths.map((entry) => [entry.path, entry.hash]));
1796
+ const changedPaths = [];
1797
+ const current = [];
1798
+ const pathsToCheck = receipt.coverage === "project" ? await collectReceiptPaths(projectRoot) : receipt.paths.map((entry) => entry.path);
1799
+ const currentByPath = new Map;
1800
+ for (const path of pathsToCheck) {
1801
+ try {
1802
+ const canonical = canonicalPath(projectRoot, path);
1803
+ const hash = sha256(await readFile6(canonical.absolute));
1804
+ const currentEntry = { path: canonical.relative, hash };
1805
+ current.push(currentEntry);
1806
+ currentByPath.set(currentEntry.path, currentEntry);
1807
+ if (hash !== expected.get(currentEntry.path))
1808
+ changedPaths.push(currentEntry.path);
1809
+ } catch {
1810
+ changedPaths.push(path);
1811
+ }
1812
+ }
1813
+ for (const path of expected.keys()) {
1814
+ if (!currentByPath.has(path) && !changedPaths.includes(path))
1815
+ changedPaths.push(path);
1816
+ }
1817
+ changedPaths.sort();
1818
+ const actualHash = manifestHash(current.sort((left, right) => left.path.localeCompare(right.path)));
1819
+ return {
1820
+ valid: changedPaths.length === 0 && actualHash === receipt.manifestHash,
1821
+ expectedHash: receipt.manifestHash,
1822
+ actualHash,
1823
+ changedPaths
1824
+ };
1825
+ }
1826
+
1827
+ // src/core/verification/verification-runner.ts
1663
1828
  function isPassingEvidence(ev) {
1664
1829
  switch (ev.type) {
1665
1830
  case "verification":
@@ -1676,9 +1841,17 @@ function isPassingEvidence(ev) {
1676
1841
  return false;
1677
1842
  }
1678
1843
  }
1844
+ async function isCurrentPassingEvidence(projectRoot, ev) {
1845
+ if (!isPassingEvidence(ev))
1846
+ return false;
1847
+ const receipt = ev.data?.rddReceipt;
1848
+ if (!isRddReceipt(receipt))
1849
+ return false;
1850
+ return (await verifyReceipt(projectRoot, receipt)).valid;
1851
+ }
1679
1852
  function evidenceFilePath(evDir, id) {
1680
- const path = resolve5(evDir, `${id.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
1681
- if (dirname(path) !== resolve5(evDir)) {
1853
+ const path = resolve6(evDir, `${id.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
1854
+ if (dirname(path) !== resolve6(evDir)) {
1682
1855
  return err(new Error(`Refusing to write evidence for "${id}" outside ${evDir}`));
1683
1856
  }
1684
1857
  return ok(path);
@@ -1704,7 +1877,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
1704
1877
  return ok({ records, invalid });
1705
1878
  let files;
1706
1879
  try {
1707
- files = await readdir(evDir);
1880
+ files = await readdir2(evDir);
1708
1881
  } catch (e) {
1709
1882
  return err(e instanceof Error ? e : new Error(String(e)));
1710
1883
  }
@@ -1712,7 +1885,7 @@ async function collectTaskEvidence(projectRoot, taskId) {
1712
1885
  if (!file.endsWith(".json"))
1713
1886
  continue;
1714
1887
  try {
1715
- const raw = await readFile6(join2(evDir, file), "utf-8");
1888
+ const raw = await readFile7(join3(evDir, file), "utf-8");
1716
1889
  const ev = EvidenceSchema.parse(JSON.parse(raw));
1717
1890
  if (ev.relatedTask === taskId)
1718
1891
  records.push(ev);
@@ -1733,7 +1906,7 @@ async function validateEvidenceIds(projectRoot, taskId, evidenceIds) {
1733
1906
  if (!record) {
1734
1907
  return err(new Error(`Evidence "${id}" is not a record of task ${taskId}`));
1735
1908
  }
1736
- if (!isPassingEvidence(record)) {
1909
+ if (!await isCurrentPassingEvidence(projectRoot, record)) {
1737
1910
  return err(new Error(`Evidence "${id}" does not record a passing result`));
1738
1911
  }
1739
1912
  if (record.type === "verification")
@@ -1814,7 +1987,12 @@ async function runVerification(projectRoot, taskId, goal, options) {
1814
1987
  passed: collected.data.invalid === 0,
1815
1988
  message: collected.data.invalid === 0 ? "All evidence records are readable" : `${collected.data.invalid} unreadable evidence record(s)`
1816
1989
  });
1817
- const supporting = collected.data.records.filter((ev) => ev.type !== "verification" && isPassingEvidence(ev));
1990
+ const supporting = [];
1991
+ for (const candidate of collected.data.records) {
1992
+ if (candidate.type !== "verification" && await isCurrentPassingEvidence(projectRoot, candidate)) {
1993
+ supporting.push(candidate);
1994
+ }
1995
+ }
1818
1996
  evidenceIds.push(...supporting.map((ev) => ev.id));
1819
1997
  checks.push({
1820
1998
  name: "evidence_present",
@@ -1822,6 +2000,13 @@ async function runVerification(projectRoot, taskId, goal, options) {
1822
2000
  message: supporting.length > 0 ? `${supporting.length} passing evidence record(s) for task` : task.risk === "low" ? "Low risk task — evidence optional" : "No passing evidence records found for task"
1823
2001
  });
1824
2002
  const passed = checks.every((c) => c.passed);
2003
+ const receipt = await captureReceipt(projectRoot, {
2004
+ taskId,
2005
+ phase: "verification",
2006
+ paths: await collectReceiptPaths(projectRoot),
2007
+ outcome: passed ? "passed" : "failed",
2008
+ coverage: "project"
2009
+ });
1825
2010
  const evidence = {
1826
2011
  id: `ev-verify-${taskId}-${Date.now()}`,
1827
2012
  source: "cc verify",
@@ -1830,7 +2015,7 @@ async function runVerification(projectRoot, taskId, goal, options) {
1830
2015
  relatedTask: taskId,
1831
2016
  confidence: passed ? 0.9 : 0.3,
1832
2017
  summary: passed ? "Verification passed" : "Verification failed",
1833
- data: { passed, checks }
2018
+ data: { passed, checks, rddReceipt: receipt }
1834
2019
  };
1835
2020
  const persisted = await persistEvidence(projectRoot, evidence);
1836
2021
  if (!persisted.success)
@@ -1853,19 +2038,25 @@ async function gateTaskCompletion(projectRoot, taskId, evidenceRequired, evidenc
1853
2038
  if (collected.data.invalid > 0)
1854
2039
  return ok(false);
1855
2040
  const cited = evidenceIds ? new Set(evidenceIds) : undefined;
1856
- const hasPassing = (type) => collected.data.records.some((ev) => (!cited || cited.has(ev.id)) && ev.type === type && isPassingEvidence(ev));
2041
+ const hasPassing = async (type) => {
2042
+ for (const evidence of collected.data.records) {
2043
+ if ((!cited || cited.has(evidence.id)) && evidence.type === type && await isCurrentPassingEvidence(projectRoot, evidence))
2044
+ return true;
2045
+ }
2046
+ return false;
2047
+ };
1857
2048
  for (const req of evidenceRequired) {
1858
2049
  switch (req) {
1859
2050
  case "acceptance_criteria_met":
1860
- if (!hasPassing("verification"))
2051
+ if (!await hasPassing("verification"))
1861
2052
  return ok(false);
1862
2053
  break;
1863
2054
  case "tests_passed":
1864
- if (!hasPassing("test"))
2055
+ if (!await hasPassing("test"))
1865
2056
  return ok(false);
1866
2057
  break;
1867
2058
  case "review_approved":
1868
- if (!hasPassing("review"))
2059
+ if (!await hasPassing("review"))
1869
2060
  return ok(false);
1870
2061
  break;
1871
2062
  default:
@@ -1880,12 +2071,26 @@ async function captureTddSuiteEvidence(projectRoot, taskId, options) {
1880
2071
  if (!options.allowCompileCheck && !isAllowlistedTestCommand(options.command)) {
1881
2072
  return err(new Error("TDD suite command is not on the test allowlist. Re-run with --allow-compile-check to trust it."));
1882
2073
  }
2074
+ const paths = await collectReceiptPaths(projectRoot);
2075
+ const before = await captureReceipt(projectRoot, {
2076
+ taskId,
2077
+ phase: options.phase ?? "verification",
2078
+ paths,
2079
+ command: options.command,
2080
+ outcome: "failed",
2081
+ coverage: "project"
2082
+ });
1883
2083
  const result = await runCompileCheck({
1884
2084
  command: options.command,
1885
2085
  cwd: projectRoot
1886
2086
  });
1887
2087
  const suitePassed = result.success && !result.timedOut && result.exitCode === 0;
1888
2088
  const suiteFailed = !result.timedOut && result.exitCode !== 0;
2089
+ const receipt = { ...before, outcome: suitePassed ? "passed" : "failed" };
2090
+ const receiptResult = await verifyReceipt(projectRoot, receipt);
2091
+ if (!receiptResult.valid) {
2092
+ return err(new Error(`RDD candidate changed while the TDD suite ran: ${receiptResult.changedPaths.join(", ")}`));
2093
+ }
1889
2094
  const evidence = {
1890
2095
  id: `ev-tdd-${taskId}-${Date.now()}`,
1891
2096
  source: TDD_EVIDENCE_SOURCE,
@@ -1900,7 +2105,8 @@ async function captureTddSuiteEvidence(projectRoot, taskId, options) {
1900
2105
  suitePassed,
1901
2106
  exitCode: result.exitCode,
1902
2107
  timedOut: result.timedOut,
1903
- command: options.command
2108
+ command: options.command,
2109
+ rddReceipt: receipt
1904
2110
  }
1905
2111
  };
1906
2112
  const persisted = await persistEvidence(projectRoot, evidence);
@@ -1922,7 +2128,8 @@ async function captureTddSuiteEvidence(projectRoot, taskId, options) {
1922
2128
  return ok({
1923
2129
  evidenceId: evidence.id,
1924
2130
  suiteFailed,
1925
- suitePassed
2131
+ suitePassed,
2132
+ receipt
1926
2133
  });
1927
2134
  }
1928
2135
  async function loadTddSuiteEvidence(projectRoot, taskId, evidenceId) {
@@ -1932,7 +2139,7 @@ async function loadTddSuiteEvidence(projectRoot, taskId, evidenceId) {
1932
2139
  return path;
1933
2140
  let raw;
1934
2141
  try {
1935
- raw = await readFile6(path.data, "utf-8");
2142
+ raw = await readFile7(path.data, "utf-8");
1936
2143
  } catch (e) {
1937
2144
  return err(e instanceof Error ? e : new Error(String(e)));
1938
2145
  }
@@ -1954,13 +2161,37 @@ async function loadTddSuiteEvidence(projectRoot, taskId, evidenceId) {
1954
2161
  if (capturedBy !== TDD_CAPTURED_BY || typeof suiteFailed !== "boolean" || typeof suitePassed !== "boolean") {
1955
2162
  return err(new Error(`Evidence "${evidenceId}" was not captured by the verification runner`));
1956
2163
  }
1957
- return ok({ capturedBy, suiteFailed, suitePassed });
2164
+ const receipt = ev.data?.rddReceipt;
2165
+ if (!isRddReceipt(receipt)) {
2166
+ return err(new Error(`Evidence "${evidenceId}" has no valid RDD receipt`));
2167
+ }
2168
+ if (receipt.taskId !== taskId) {
2169
+ return err(new Error(`Evidence "${evidenceId}" receipt belongs to another task`));
2170
+ }
2171
+ const verified = await verifyReceipt(projectRoot, receipt);
2172
+ if (!verified.valid) {
2173
+ return err(new Error(`Evidence "${evidenceId}" RDD receipt is stale: ${verified.changedPaths.join(", ")}`));
2174
+ }
2175
+ return ok({ capturedBy, suiteFailed, suitePassed, receipt });
1958
2176
  }
1959
- async function hasTddRunnerEvidence(projectRoot, taskId) {
2177
+ async function hasTddRunnerEvidence(projectRoot, taskId, expectedPhase) {
1960
2178
  const collected = await collectTaskEvidence(projectRoot, taskId);
1961
2179
  if (!collected.success)
1962
2180
  return false;
1963
- return collected.data.records.some((ev) => ev.type === "tdd" && ev.source === TDD_EVIDENCE_SOURCE && ev.data?.capturedBy === TDD_CAPTURED_BY);
2181
+ for (const ev of collected.data.records) {
2182
+ if (ev.type !== "tdd" || ev.source !== TDD_EVIDENCE_SOURCE || ev.data?.capturedBy !== TDD_CAPTURED_BY) {
2183
+ continue;
2184
+ }
2185
+ const loaded = await loadTddSuiteEvidence(projectRoot, taskId, ev.id);
2186
+ if (!loaded.success)
2187
+ continue;
2188
+ if (expectedPhase === "red" && (!loaded.data.suiteFailed || loaded.data.suitePassed))
2189
+ continue;
2190
+ if (expectedPhase === "green" && (!loaded.data.suitePassed || loaded.data.suiteFailed))
2191
+ continue;
2192
+ return true;
2193
+ }
2194
+ return false;
1964
2195
  }
1965
2196
 
1966
2197
  // src/core/orchestrator/runtime-orchestrator.ts
@@ -2729,6 +2960,11 @@ export {
2729
2960
  CouncilVerdictInputSchema,
2730
2961
  CouncilVerdictSchema,
2731
2962
  DecisionSchema,
2963
+ DeliveryLedgerRequestSchema,
2964
+ DeliveryLedgerSchema,
2965
+ DeliveryLedgerTaskSchema,
2966
+ DeliveryRouteSchema,
2967
+ DeliveryTelemetrySchema,
2732
2968
  EvaluationIndexSchema,
2733
2969
  EvidenceSchema,
2734
2970
  ExecutionContextSchema,
@@ -2794,6 +3030,7 @@ export {
2794
3030
  TaskOutcomeSourceSchema,
2795
3031
  TaskOutcomeStatusSchema,
2796
3032
  TechnicalPlanOutputSchema,
3033
+ TokenUsageSchema,
2797
3034
  ToolProviderNamesSchema,
2798
3035
  VerificationReportSchema,
2799
3036
  WorkflowCommandSchema,
@@ -2802,7 +3039,9 @@ export {
2802
3039
  WorkflowRiskRuleSchema,
2803
3040
  advanceTddPhase,
2804
3041
  buildTaskEnvelope,
3042
+ captureReceipt,
2805
3043
  captureTddSuiteEvidence,
3044
+ collectReceiptPaths,
2806
3045
  completeTask,
2807
3046
  createInitialState,
2808
3047
  createInitialTddState,
@@ -2813,6 +3052,7 @@ export {
2813
3052
  getReadyTasks,
2814
3053
  goalTaskToCanonicalCard,
2815
3054
  hasTddRunnerEvidence,
3055
+ isRddReceipt,
2816
3056
  loadTddSuiteEvidence,
2817
3057
  loopStateMachine,
2818
3058
  rollbackTaskStatus,
@@ -2861,5 +3101,6 @@ export {
2861
3101
  validateSkillsRegistry,
2862
3102
  validateTargetCapabilities,
2863
3103
  validateTaskOutcome,
2864
- validateWorkflowProfile
3104
+ validateWorkflowProfile,
3105
+ verifyReceipt
2865
3106
  };