cohorte 3.0.0-dev.6 → 3.0.0-dev.7

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 (94) hide show
  1. package/assets/manifest.json +14 -4
  2. package/assets/prompts/agents/brainstormer.md +3 -0
  3. package/assets/prompts/agents/spec-author.md +3 -0
  4. package/assets/schemas/commands.schema.json +7 -0
  5. package/dist/bundle-manifest.json +72 -50
  6. package/dist/chunks/align-ds-r_X_1aQ_.mjs +93 -0
  7. package/dist/chunks/align-ds-r_X_1aQ_.mjs.map +1 -0
  8. package/dist/chunks/audit-B4ZWQ_DI.mjs +179 -0
  9. package/dist/chunks/audit-B4ZWQ_DI.mjs.map +1 -0
  10. package/dist/chunks/brainstorm-DasVwI1D.mjs +123 -0
  11. package/dist/chunks/brainstorm-DasVwI1D.mjs.map +1 -0
  12. package/dist/chunks/build-crOld8gE.mjs +19 -0
  13. package/dist/chunks/build-crOld8gE.mjs.map +1 -0
  14. package/dist/chunks/{catalogue-DzsslCSN.mjs → catalogue-IaCJdfB8.mjs} +4 -4
  15. package/dist/chunks/{catalogue-DzsslCSN.mjs.map → catalogue-IaCJdfB8.mjs.map} +1 -1
  16. package/dist/chunks/{compose-ckM7eAJ_.mjs → compose-DRKjQcn0.mjs} +42 -23
  17. package/dist/chunks/compose-DRKjQcn0.mjs.map +1 -0
  18. package/dist/chunks/{config-DcGPL3i7.mjs → config-Cqu5XQoP.mjs} +2 -2
  19. package/dist/chunks/{config-DcGPL3i7.mjs.map → config-Cqu5XQoP.mjs.map} +1 -1
  20. package/dist/chunks/{contract-DiWla5G9.mjs → contract-DjssDPpS.mjs} +45 -25
  21. package/dist/chunks/contract-DjssDPpS.mjs.map +1 -0
  22. package/dist/chunks/{diff-D_0hBwHl.mjs → diff-Qw0II0sj.mjs} +2 -2
  23. package/dist/chunks/{diff-D_0hBwHl.mjs.map → diff-Qw0II0sj.mjs.map} +1 -1
  24. package/dist/chunks/{discover-BBiluyl4.mjs → discover-BZPolSZG.mjs} +2 -2
  25. package/dist/chunks/{discover-BBiluyl4.mjs.map → discover-BZPolSZG.mjs.map} +1 -1
  26. package/dist/chunks/{doctor-BAcemCDr.mjs → doctor-DcDFPvQM.mjs} +6 -6
  27. package/dist/chunks/{doctor-BAcemCDr.mjs.map → doctor-DcDFPvQM.mjs.map} +1 -1
  28. package/dist/chunks/fix-B_oGzGVn.mjs +82 -0
  29. package/dist/chunks/fix-B_oGzGVn.mjs.map +1 -0
  30. package/dist/chunks/fleet-yWHQY2ya.mjs +297 -0
  31. package/dist/chunks/fleet-yWHQY2ya.mjs.map +1 -0
  32. package/dist/chunks/{init-DfOKw-rD.mjs → init--FxxkrcT.mjs} +2 -2
  33. package/dist/chunks/{init-DfOKw-rD.mjs.map → init--FxxkrcT.mjs.map} +1 -1
  34. package/dist/chunks/intake-Dd1KVXnO.mjs +12 -0
  35. package/dist/chunks/intake-Dd1KVXnO.mjs.map +1 -0
  36. package/dist/chunks/loop-BWsUpyus.mjs +212 -0
  37. package/dist/chunks/loop-BWsUpyus.mjs.map +1 -0
  38. package/dist/chunks/{migrate-D3-4beNR.mjs → migrate-DuYCAbE3.mjs} +2 -2
  39. package/dist/chunks/{migrate-D3-4beNR.mjs.map → migrate-DuYCAbE3.mjs.map} +1 -1
  40. package/dist/chunks/{obsidian-D1jf1sTR.mjs → obsidian-BHLkXx_H.mjs} +50 -6
  41. package/dist/chunks/obsidian-BHLkXx_H.mjs.map +1 -0
  42. package/dist/chunks/patch-sAgVqjpx.mjs +50 -0
  43. package/dist/chunks/patch-sAgVqjpx.mjs.map +1 -0
  44. package/dist/chunks/{policy-Y65MYKzn.mjs → policy-Du7WVBFX.mjs} +4 -4
  45. package/dist/chunks/{policy-Y65MYKzn.mjs.map → policy-Du7WVBFX.mjs.map} +1 -1
  46. package/dist/chunks/{reconcile-B6mGZWtp.mjs → reconcile-BHn66X3C.mjs} +3 -3
  47. package/dist/chunks/{reconcile-B6mGZWtp.mjs.map → reconcile-BHn66X3C.mjs.map} +1 -1
  48. package/dist/chunks/refactor-CoNoqLZr.mjs +153 -0
  49. package/dist/chunks/refactor-CoNoqLZr.mjs.map +1 -0
  50. package/dist/chunks/retro-Dr-2RTNN.mjs +78 -0
  51. package/dist/chunks/retro-Dr-2RTNN.mjs.map +1 -0
  52. package/dist/chunks/review-ZsBqp3vZ.mjs +35 -0
  53. package/dist/chunks/review-ZsBqp3vZ.mjs.map +1 -0
  54. package/dist/chunks/{run-BInPXOcm.mjs → run-NGAxdsIX.mjs} +28 -5
  55. package/dist/chunks/run-NGAxdsIX.mjs.map +1 -0
  56. package/dist/chunks/{schema-hSyIURjN.mjs → schema-Bq9qtgsd.mjs} +2 -2
  57. package/dist/chunks/{schema-hSyIURjN.mjs.map → schema-Bq9qtgsd.mjs.map} +1 -1
  58. package/dist/chunks/ship-BizfUe62.mjs +140 -0
  59. package/dist/chunks/ship-BizfUe62.mjs.map +1 -0
  60. package/dist/chunks/spec-C2h3U64g.mjs +65 -0
  61. package/dist/chunks/spec-C2h3U64g.mjs.map +1 -0
  62. package/dist/chunks/spec-path-tptqR7W8.mjs +10 -0
  63. package/dist/chunks/spec-path-tptqR7W8.mjs.map +1 -0
  64. package/dist/chunks/{src-C7hs8Bjw.mjs → src-Bfr1yzsn.mjs} +3 -3
  65. package/dist/chunks/{src-C7hs8Bjw.mjs.map → src-Bfr1yzsn.mjs.map} +1 -1
  66. package/dist/chunks/{src-Daa5lIcP.mjs → src-CPW2_Ons.mjs} +101 -17
  67. package/dist/chunks/src-CPW2_Ons.mjs.map +1 -0
  68. package/dist/chunks/{src-DMrQ5m6I.mjs → src-DNsLSxgm.mjs} +2 -2
  69. package/dist/chunks/{src-DMrQ5m6I.mjs.map → src-DNsLSxgm.mjs.map} +1 -1
  70. package/dist/chunks/{src-BnlNkd3S.mjs → src-DbS9gkJy.mjs} +2 -2
  71. package/dist/chunks/{src-BnlNkd3S.mjs.map → src-DbS9gkJy.mjs.map} +1 -1
  72. package/dist/chunks/{src-s7YRvk0t.mjs → src-yi5whv3n.mjs} +4 -2
  73. package/dist/chunks/src-yi5whv3n.mjs.map +1 -0
  74. package/dist/chunks/update-pipeline-Du-Gu1Pl.mjs +56 -0
  75. package/dist/chunks/update-pipeline-Du-Gu1Pl.mjs.map +1 -0
  76. package/dist/cli.mjs +29 -19
  77. package/dist/cli.mjs.map +1 -1
  78. package/package.json +1 -1
  79. package/dist/chunks/brainstorm-kBUiZLce.mjs +0 -7
  80. package/dist/chunks/brainstorm-kBUiZLce.mjs.map +0 -1
  81. package/dist/chunks/compose-ckM7eAJ_.mjs.map +0 -1
  82. package/dist/chunks/contract-DiWla5G9.mjs.map +0 -1
  83. package/dist/chunks/fix-D4Tj8RVA.mjs +0 -18
  84. package/dist/chunks/fix-D4Tj8RVA.mjs.map +0 -1
  85. package/dist/chunks/obsidian-D1jf1sTR.mjs.map +0 -1
  86. package/dist/chunks/review-BDdjb6kB.mjs +0 -17
  87. package/dist/chunks/review-BDdjb6kB.mjs.map +0 -1
  88. package/dist/chunks/run-BInPXOcm.mjs.map +0 -1
  89. package/dist/chunks/ship-DTuLGoaJ.mjs +0 -19
  90. package/dist/chunks/ship-DTuLGoaJ.mjs.map +0 -1
  91. package/dist/chunks/spec-MVP9y8dN.mjs +0 -20
  92. package/dist/chunks/spec-MVP9y8dN.mjs.map +0 -1
  93. package/dist/chunks/src-Daa5lIcP.mjs.map +0 -1
  94. package/dist/chunks/src-s7YRvk0t.mjs.map +0 -1
@@ -1,9 +1,10 @@
1
1
  import { n as sha256Hex, t as canonicalJson } from "./canonical-C8UxeEmB.mjs";
2
2
  import { E as SpecId, I as isErrorCode, M as NotImplemented, N as errorOf, P as toErrorInfo, S as IsoInstant, T as Sha256, j as CohorteError, k as isSafeId, o as err, s as ok } from "./src-Cu3TxNob.mjs";
3
- import { f as HALTED_STATES, h as TERMINAL_STATES, i as canonicalCommandBody, l as ACTIVE_PIPELINE_STATES, m as SUSPENDED_STATES, n as isDurableEventType, p as PipelineProfile, t as catalogue } from "./src-s7YRvk0t.mjs";
4
- import { d as SandboxCapabilities, g as createRedactor, p as DEFAULT_DENY_GLOBS, r as RuntimePin, u as RuntimeCapabilities } from "./src-C7hs8Bjw.mjs";
3
+ import { c as AgentOutput, g as TERMINAL_STATES, h as SUSPENDED_STATES, i as canonicalCommandBody, l as ReviewResult, m as PipelineProfile, n as isDurableEventType, p as HALTED_STATES, t as catalogue, u as ACTIVE_PIPELINE_STATES } from "./src-yi5whv3n.mjs";
4
+ import { d as SandboxCapabilities, g as createRedactor, p as DEFAULT_DENY_GLOBS, r as RuntimePin, u as RuntimeCapabilities } from "./src-Bfr1yzsn.mjs";
5
5
  import { Type } from "typebox";
6
6
  import { Compile } from "typebox/compile";
7
+ import { Value } from "typebox/value";
7
8
  //#region ../../packages/core/src/agents/lifecycle.ts
8
9
  /** the four edges spawning|running|waiting|paused -> spawning are legal REINCARNATION sources */
9
10
  const REINCARNATE_SOURCES = [
@@ -2038,12 +2039,22 @@ async function closePhaseAndAdvance(args) {
2038
2039
  const now = deps.clock.now();
2039
2040
  const from = runState.run.state;
2040
2041
  const phaseChecks = "checks" in outcome ? outcome.checks ?? [] : [];
2042
+ const review = outcome.kind === "passed" && outcome.output !== null && typeof outcome.output === "object" && !Array.isArray(outcome.output) && "review" in outcome.output && typeof outcome.output.review === "object" && outcome.output.review !== null ? outcome.output.review : outcome.kind === "failed" && openPhase.state === "REVIEW" ? {
2043
+ clean: false,
2044
+ kept: outcome.failure.findings
2045
+ } : void 0;
2041
2046
  const outcomeFacts = {
2042
2047
  ...facts,
2043
2048
  "checks.all-passed": outcome.kind === "passed" && phaseChecks.every((check) => check.status === "passed" || check.status === "skipped"),
2044
2049
  "checks.digest-equals-integration": outcome.kind === "passed" || phaseChecks.length > 0,
2045
2050
  "checks.failed-non-environmental": outcome.kind === "failed" && phaseChecks.some((check) => check.status === "failed"),
2046
- "loop.may-continue": facts["loop.may-continue"] === true || outcome.kind === "failed" && phaseChecks.some((check) => check.status === "failed")
2051
+ "review.nothing-to-fix": review ? review.clean === true : true,
2052
+ "review.no-unreviewed": review ? (review.unreviewed?.length ?? 0) === 0 : true,
2053
+ "review.leftovers-parked-or-waived": review ? (review.deferred?.length ?? 0) === 0 : true,
2054
+ "review.has-fix-items": review ? review.clean !== true && (review.kept?.length ?? 0) > 0 : false,
2055
+ "review.contract-change": false,
2056
+ "review.leftovers-routed-ask": review ? (review.deferred?.length ?? 0) > 0 : false,
2057
+ "loop.may-continue": facts["loop.may-continue"] === true || outcome.kind === "failed" && outcome.failure.code !== "agent-dead" && openPhase.iteration < 10
2047
2058
  };
2048
2059
  const guardOutcomes = evaluateGuards(step.guards, {
2049
2060
  run: runState,
@@ -3379,6 +3390,8 @@ function calculateReview(findings, unreviewed, changedFiles = /* @__PURE__ */ ne
3379
3390
  //#endregion
3380
3391
  //#region ../../packages/core/src/phases/contracts/index.ts
3381
3392
  const SUPPORTED_PHASES = [
3393
+ "BRAINSTORM",
3394
+ "SPEC",
3382
3395
  "PREFLIGHT",
3383
3396
  "BUILD",
3384
3397
  "TEST",
@@ -3401,6 +3414,8 @@ const RETRY = {
3401
3414
  }
3402
3415
  };
3403
3416
  const OBJECTIVES = {
3417
+ BRAINSTORM: "challenge the idea from product, UX, architecture and delivery perspectives and produce a structured brief",
3418
+ SPEC: "turn the reviewed brief into a complete, testable and frozen feature specification",
3404
3419
  PREFLIGHT: "validate readiness, specification completeness and surface ownership",
3405
3420
  BUILD: "implement the frozen specification in isolated surface worktrees",
3406
3421
  TEST: "run the project checks against the integration tree",
@@ -3420,7 +3435,7 @@ function surfacesOf(ctx) {
3420
3435
  ])].sort();
3421
3436
  }
3422
3437
  function toolsFor(role) {
3423
- if (role === "reviewer" || role === "security-reviewer") return [
3438
+ if (role === "brainstormer" || role === "spec-author" || role === "reviewer" || role === "security-reviewer") return [
3424
3439
  "read_file",
3425
3440
  "list_files",
3426
3441
  "search",
@@ -3439,24 +3454,24 @@ function toolsFor(role) {
3439
3454
  ];
3440
3455
  }
3441
3456
  function planFor(role, surface, state) {
3442
- const ownedPaths = [`${surface}/**`];
3457
+ const ownedPaths = surface ? [`${surface}/**`] : [];
3443
3458
  const tools = toolsFor(role);
3444
- const readOnly = role === "reviewer";
3459
+ const readOnly = role === "brainstormer" || role === "spec-author" || role === "reviewer";
3445
3460
  const task = {
3446
3461
  role,
3447
3462
  objective: OBJECTIVES[state],
3448
- stablePrefix: `cohorte ${state.toLowerCase()} task for surface ${surface}`,
3463
+ stablePrefix: `cohorte ${state.toLowerCase()} task${surface ? ` for surface ${surface}` : ""}`,
3449
3464
  ownedPaths,
3450
3465
  facts: {
3451
3466
  phase: state,
3452
- surface
3467
+ ...surface ? { surface } : {}
3453
3468
  }
3454
3469
  };
3455
3470
  return {
3456
- agentId: `agt_${role}_${surface}`,
3471
+ agentId: `agt_${role}_${surface ?? "project"}`,
3457
3472
  role,
3458
- surface,
3459
- owner: surface,
3473
+ ...surface ? { surface } : {},
3474
+ owner: surface ?? "project",
3460
3475
  promptId: `agents/${role}`,
3461
3476
  task,
3462
3477
  context: {
@@ -3476,21 +3491,63 @@ function planFor(role, surface, state) {
3476
3491
  ...readOnly ? { readOnlyPaths: ownedPaths } : {},
3477
3492
  tools
3478
3493
  },
3479
- modelTier: role === "reviewer" ? "reasoning" : "coding",
3494
+ modelTier: readOnly ? "reasoning" : "coding",
3480
3495
  budget: { maxEngineRetries: 0 },
3481
- workspace: readOnly ? {
3496
+ workspace: surface ? readOnly ? {
3482
3497
  kind: "readonly-ref",
3483
3498
  ref: "review-ref"
3484
3499
  } : {
3485
3500
  kind: "slot",
3486
3501
  slot: surface
3487
- }
3502
+ } : { kind: "none" }
3488
3503
  };
3489
3504
  }
3490
3505
  function budgetFor(run, state) {
3491
3506
  return run.budgets.find((budget) => budget.level === "phase" && budget.scopeId === state)?.limit ?? {};
3492
3507
  }
3508
+ /**
3509
+ * The phase handoff is persisted and consumed by the next phase. Keeping the
3510
+ * result envelope closed here is important: `Type.Unknown()` would validate a
3511
+ * malformed supervisor result and defer the failure to a later transition,
3512
+ * where it is much harder to attribute to the producing agent.
3513
+ */
3514
+ const AGENT_RESULT = Type.Object({
3515
+ agent: Type.Object({
3516
+ agentId: Type.String(),
3517
+ role: Type.String(),
3518
+ surface: Type.Optional(Type.String())
3519
+ }),
3520
+ outcome: Type.Enum({
3521
+ completed: "completed",
3522
+ failed: "failed",
3523
+ cancelled: "cancelled"
3524
+ }),
3525
+ output: Type.Optional(AgentOutput),
3526
+ error: Type.Optional(Type.Object({
3527
+ code: Type.String(),
3528
+ class: Type.String(),
3529
+ message: Type.String(),
3530
+ impact: Type.String(),
3531
+ retryable: Type.Boolean(),
3532
+ remediation: Type.String()
3533
+ })),
3534
+ artifacts: Type.Array(Type.Object({
3535
+ artifactId: Type.Optional(Type.String()),
3536
+ path: Type.String(),
3537
+ kind: Type.String(),
3538
+ sha256: Type.Optional(Type.String())
3539
+ })),
3540
+ usage: Type.Record(Type.String(), Type.Number())
3541
+ });
3493
3542
  function contractFor(state) {
3543
+ const outputSchema = state === "REVIEW" ? Type.Object({
3544
+ phase: Type.Literal(state),
3545
+ results: Type.Array(AGENT_RESULT),
3546
+ review: ReviewResult
3547
+ }) : Type.Object({
3548
+ phase: Type.Literal(state),
3549
+ results: Type.Array(AGENT_RESULT)
3550
+ });
3494
3551
  return {
3495
3552
  id: state.toLowerCase(),
3496
3553
  version: 1,
@@ -3513,10 +3570,12 @@ function contractFor(state) {
3513
3570
  planAgents(input, ctx) {
3514
3571
  const surfaces = input && typeof input === "object" && "surfaces" in input && Array.isArray(input.surfaces) ? input.surfaces.filter((surface) => typeof surface === "string").sort() : surfacesOf(ctx);
3515
3572
  if (state === "TEST" || state === "PREFLIGHT" || state === "SHIP") return [];
3573
+ if (state === "BRAINSTORM") return [planFor("brainstormer", void 0, state)];
3574
+ if (state === "SPEC") return [planFor("spec-author", void 0, state)];
3516
3575
  const role = state === "BUILD" ? "implementer" : state === "REVIEW" ? "reviewer" : "fixer";
3517
3576
  return surfaces.map((surface) => planFor(role, surface, state));
3518
3577
  },
3519
- outputSchema: Type.Unknown(),
3578
+ outputSchema,
3520
3579
  checks: [],
3521
3580
  budget: (run) => budgetFor(run, state),
3522
3581
  stop: [],
@@ -3674,6 +3733,31 @@ function createPhaseExecutor$1(deps) {
3674
3733
  }
3675
3734
  const assembled = contract.assemble(resolved.value, results, ctx);
3676
3735
  if (!assembled.ok) return failed("outputs-invalid", assembled.error);
3736
+ if (!Value.Check(contract.outputSchema, assembled.value)) return failed("outputs-invalid", error("validation/phase-output-invalid", `Phase ${ctx.phase.state} produced an output that does not match contract ${contract.id}@${contract.version}.`, "Inspect the phase handoff and retry it with a valid structured output."));
3737
+ if (ctx.phase.state === "REVIEW" && deps.store && deps.redactor) {
3738
+ const redactor = deps.redactor;
3739
+ const findings = results.flatMap((result) => result.output?.findings.map((finding) => ({
3740
+ result,
3741
+ finding
3742
+ })) ?? []);
3743
+ if (findings.length > 0) await deps.store.transact({ runId: ctx.run.run.runId }, ctx.lease, (tx) => {
3744
+ for (const { result, finding } of findings) {
3745
+ const findingId = `fnd_${sha256Hex(JSON.stringify(finding)).slice(0, 16)}`;
3746
+ tx.putFinding({
3747
+ runId: ctx.run.run.runId,
3748
+ findingId,
3749
+ phaseRunId: ctx.phase.phaseRunId,
3750
+ agentId: result.agent.agentId,
3751
+ severity: finding.severity,
3752
+ status: finding.scope === "deferred" ? "deferred" : "open",
3753
+ finding: redactor.sealJson(finding).value,
3754
+ createdAt: ctx.now,
3755
+ updatedAt: ctx.now
3756
+ });
3757
+ }
3758
+ });
3759
+ }
3760
+ for (const check of contract.checks) if (!check.evaluate(resolved.value, assembled.value, ctx)) return failed("outputs-invalid", error(`validation/phase-check-${check.id}`, `Phase check ${check.id} failed for ${ctx.phase.state}.`, "Resolve the failed phase check and retry the phase."));
3677
3761
  if (ctx.phase.state === "REVIEW" && typeof assembled.value === "object" && assembled.value !== null && "review" in assembled.value && typeof assembled.value.review === "object" && assembled.value.review !== null && "clean" in assembled.value.review && assembled.value.review.clean === false) {
3678
3762
  const review = assembled.value.review;
3679
3763
  return failed("checks-red", error("validation/review-findings", `Review found ${review.kept?.length ?? 0} finding(s).`, "Run the FIX phase and review again."), review.kept ?? []);
@@ -3831,7 +3915,7 @@ const hasSpec = (ctx) => ctx.run.run.specId.length > 0 && ctx.run.run.specSha256
3831
3915
  /** Guards with a local, deterministic derivation. All other guards consume a boolean fact and fail closed. */
3832
3916
  const DERIVED = {
3833
3917
  "input.is-idea": factGuard("input.is-idea"),
3834
- "phase.available": () => outcome("phase.available", false, "BRAINSTORM/SPEC executors are not available in V3.0"),
3918
+ "phase.available": () => outcome("phase.available", true),
3835
3919
  "brainstorm.output-valid": factGuard("brainstorm.output-valid"),
3836
3920
  "spec.schema-valid": derived("spec.schema-valid", hasSpec, "run has no valid spec identity"),
3837
3921
  "spec.frozen": derived("spec.frozen", hasSpec, "run has no frozen spec identity"),
@@ -5400,4 +5484,4 @@ function createPhaseExecutor(deps) {
5400
5484
  //#endregion
5401
5485
  export { resolveTable as _, createToolHost as a, createApprovalService as b, createResumer as c, createPipelineGuards as d, createFactCollector as f, createEngine as g, createEventWriter as h, createRunSnapshotter as i, verifyProjectionAgainstEvents as l, createGrantComputer as m, createAgentSupervisor as n, createTransitionEffectRunner as o, createPhaseContracts as p, createProvisioner as r, createWorktreeService as s, createPhaseExecutor as t, initialRunState as u, createLeaseManager as v, createToolHostReplay as x, createEffectJournal as y };
5402
5486
 
5403
- //# sourceMappingURL=src-Daa5lIcP.mjs.map
5487
+ //# sourceMappingURL=src-CPW2_Ons.mjs.map