canon-ai 3.12.0 → 3.13.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [3.13.0] — 2026-10-23
8
+
9
+ ### Added
10
+
11
+ - **Bug-fix tasks record red-first evidence in the handoff, and code review checks for it.** The handoff template has a Red-First Evidence section with one row per red-first acceptance criterion: the test command, the commit the pre-fix code was at, the failure it showed there, and the post-fix result. A `[wrong-premise]` blocker can stand in when the test cannot be made to fail for the reason the spec states. The implement prompts point at the section and say which pre-fix state to run against. The anchored code-review lens flags a red-first criterion with no pre-fix run as a spec-compliance gap, and a revision round can close the gap by running the test against the pre-fix commit without redoing the fix.
12
+ - **Claude sub-agents get their own metrics rows.** When a pipeline phase's Claude session spawns sub-agents, each top-level sub-agent gets a row with Agent `claude:<agent type>`, its duration, and its own cumulative tokens. For `code_review` that separates the anchored and cold reviewers from the foreman. The session's own row is unchanged.
13
+
14
+ ### Fixed
15
+
16
+ - **The spec_gap halt's fix hint names the amendment heading the next `--reroute` requires.** After a task's first reroute, it says `## Amendment Round N` instead of a bare `## Amendment` that `--reroute` refuses.
17
+ - **Implement auto-commit no longer fails on a gitignored generated file listed beside its generator.** The ignored file is not passed to `git add`. If staging fails partway, the index is restored to its state before the attempt.
18
+ - **A handoff row for one of the task's own artifacts no longer fails the coverage checks** when the pipeline rewrote it identical to the base. Another bundle member's artifact is still rejected.
19
+ - **The scaffold commit no longer fails when a telemetry file was removed with `git rm`**, and a committed rename's old path counts as deletion evidence at implement close.
20
+ - **The base-divergence and orphaned-branch messages name the actual branch** instead of a literal `<base>`, quoted when the name needs it, so the printed `git push` and `gh pr create` commands can be pasted as is.
21
+
7
22
  ## [3.12.0] — 2026-10-21
8
23
 
9
24
  ### Added
package/dist/cli/index.js CHANGED
@@ -1505,7 +1505,7 @@ function checkTemplates(cwd) {
1505
1505
  }
1506
1506
  function checkCanonVersion(cwd) {
1507
1507
  const versionPath = join(cwd, ".canon", "version");
1508
- const installedVersion = "3.12.0";
1508
+ const installedVersion = "3.13.0";
1509
1509
  if (!existsSync(versionPath)) {
1510
1510
  return { label: ".canon/version", status: "warn", detail: "missing \u2014 run `canon upgrade`" };
1511
1511
  }
@@ -2030,7 +2030,7 @@ function initCmd(_args) {
2030
2030
  }
2031
2031
  function writeCanonVersion(cwd) {
2032
2032
  const versionPath = join2(cwd, ".canon", "version");
2033
- const version = "3.12.0";
2033
+ const version = "3.13.0";
2034
2034
  mkdirSync(dirname2(versionPath), { recursive: true });
2035
2035
  writeFileSync(versionPath, version + "\n");
2036
2036
  }
@@ -3081,7 +3081,7 @@ function isInstalledSourcePath(sourcePath) {
3081
3081
  return sourcePath.includes("/node_modules/") || sourcePath.includes("\\node_modules\\") || sourcePath.includes("/_npx/") || sourcePath.includes("\\_npx\\");
3082
3082
  }
3083
3083
  function resolveCanonVersion(explicit) {
3084
- return explicit ?? "3.12.0" ?? "dev";
3084
+ return explicit ?? "3.13.0" ?? "dev";
3085
3085
  }
3086
3086
  function resolveOrchestratorCommit(repoRoot, upstreamCommit, runGitAt) {
3087
3087
  const ownToplevel = captureGitOutput(repoRoot, ["rev-parse", "--show-toplevel"], runGitAt);
@@ -3716,6 +3716,7 @@ function verifyHandoffAgainstDiffFromData(taskIds, inputs) {
3716
3716
  const files = handoffFilesByTask.get(taskId) ?? [];
3717
3717
  for (const filePath of files) {
3718
3718
  if (gitIgnored.has(filePath)) continue;
3719
+ if (isPipelineOwnedTaskArtifact(filePath, [taskId])) continue;
3719
3720
  if (!coveredPaths.has(filePath)) {
3720
3721
  issues.push(`[${taskId}] handoff\u2192diff: ${filePath} listed in handoff but not in diff \u2014 it has no committed change against the task base. If it was untouched or rewritten with identical content, drop the row`);
3721
3722
  }
@@ -5274,7 +5275,7 @@ function currentPinFromManifest(manifest) {
5274
5275
  return "unknown";
5275
5276
  }
5276
5277
  function bakedVersion() {
5277
- return "3.12.0";
5278
+ return "3.13.0";
5278
5279
  }
5279
5280
  function ownPackageName(pkgDir) {
5280
5281
  try {
@@ -5751,7 +5752,7 @@ function runUpgrade(cwd, pkgDir, options = {}) {
5751
5752
  cutoverWarnings.push(docsRefsCheckRel);
5752
5753
  }
5753
5754
  const versionPath = join5(cwd, ".canon", "version");
5754
- const newVersion = "3.12.0";
5755
+ const newVersion = "3.13.0";
5755
5756
  const currentVersion = existsSync5(versionPath) ? readFileSync4(versionPath, "utf8").trim() : null;
5756
5757
  if (currentVersion !== newVersion) {
5757
5758
  pending.push({ rel: ".canon/version", projectPath: versionPath, content: newVersion + "\n" });
@@ -6063,7 +6064,7 @@ Global:
6063
6064
  `);
6064
6065
  }
6065
6066
  function printVersion() {
6066
- console.log("3.12.0");
6067
+ console.log("3.13.0");
6067
6068
  }
6068
6069
  switch (command) {
6069
6070
  case "doctor":