canon-ai 3.19.0 → 3.19.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.
package/CHANGELOG.md
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -2035,7 +2035,7 @@ function checkTemplates(cwd) {
|
|
|
2035
2035
|
}
|
|
2036
2036
|
function checkCanonVersion(cwd) {
|
|
2037
2037
|
const versionPath = join(cwd, ".canon", "version");
|
|
2038
|
-
const installedVersion = "3.19.
|
|
2038
|
+
const installedVersion = "3.19.1";
|
|
2039
2039
|
if (!existsSync(versionPath)) {
|
|
2040
2040
|
return { label: ".canon/version", status: "warn", detail: "missing \u2014 run `canon upgrade`" };
|
|
2041
2041
|
}
|
|
@@ -2579,7 +2579,7 @@ function initCmd(args2) {
|
|
|
2579
2579
|
}
|
|
2580
2580
|
function writeCanonVersion(cwd) {
|
|
2581
2581
|
const versionPath = join2(cwd, ".canon", "version");
|
|
2582
|
-
const version = "3.19.
|
|
2582
|
+
const version = "3.19.1";
|
|
2583
2583
|
mkdirSync(dirname2(versionPath), { recursive: true });
|
|
2584
2584
|
writeFileSync(versionPath, version + "\n");
|
|
2585
2585
|
}
|
|
@@ -3668,7 +3668,7 @@ function isInstalledSourcePath(sourcePath) {
|
|
|
3668
3668
|
return sourcePath.includes("/node_modules/") || sourcePath.includes("\\node_modules\\") || sourcePath.includes("/_npx/") || sourcePath.includes("\\_npx\\");
|
|
3669
3669
|
}
|
|
3670
3670
|
function resolveCanonVersion(explicit) {
|
|
3671
|
-
return explicit ?? "3.19.
|
|
3671
|
+
return explicit ?? "3.19.1" ?? "dev";
|
|
3672
3672
|
}
|
|
3673
3673
|
function resolveOrchestratorCommit(repoRoot, upstreamCommit, runGitAt) {
|
|
3674
3674
|
const ownToplevel = captureGitOutput(repoRoot, ["rev-parse", "--show-toplevel"], runGitAt);
|
|
@@ -5976,7 +5976,7 @@ function currentPinFromManifest(manifest) {
|
|
|
5976
5976
|
return "unknown";
|
|
5977
5977
|
}
|
|
5978
5978
|
function bakedVersion() {
|
|
5979
|
-
return "3.19.
|
|
5979
|
+
return "3.19.1";
|
|
5980
5980
|
}
|
|
5981
5981
|
function ownPackageName(pkgDir) {
|
|
5982
5982
|
try {
|
|
@@ -6473,7 +6473,7 @@ function runUpgrade(cwd, pkgDir, options = {}) {
|
|
|
6473
6473
|
cutoverWarnings.push(docsRefsCheckRel);
|
|
6474
6474
|
}
|
|
6475
6475
|
const versionPath = join5(cwd, ".canon", "version");
|
|
6476
|
-
const newVersion = "3.19.
|
|
6476
|
+
const newVersion = "3.19.1";
|
|
6477
6477
|
const currentVersion = existsSync5(versionPath) ? readFileSync4(versionPath, "utf8").trim() : null;
|
|
6478
6478
|
if (currentVersion !== newVersion) {
|
|
6479
6479
|
pending.push({ rel: ".canon/version", projectPath: versionPath, content: newVersion + "\n" });
|
|
@@ -7092,7 +7092,7 @@ Global:
|
|
|
7092
7092
|
Run 'canon <command> --help' for details.`);
|
|
7093
7093
|
}
|
|
7094
7094
|
function printVersion() {
|
|
7095
|
-
console.log("3.19.
|
|
7095
|
+
console.log("3.19.1");
|
|
7096
7096
|
}
|
|
7097
7097
|
switch (command) {
|
|
7098
7098
|
case "doctor":
|
|
@@ -6740,7 +6740,7 @@ var plan_reroute_default = "You are updating the implementation plan for {{taskS
|
|
|
6740
6740
|
var plan_default = "You are writing implementation plans for {{taskScope}} for {{projectName}}.\n\n{{{startup}}}\n\n{{{verdictLines}}}\n\nFor each task, read tasks/<id>/spec.md and tasks/<id>/spec-review.md. Address any `changes_requested` items before writing the plan. If the verdict is `approved_with_nits`, incorporate the nits into the plan \u2014 they don't require spec changes but should inform implementation decisions.\n\nWrite tasks/<id>/plan.md for each task with ordered implementation steps. Reference specific files, existing patterns, and code examples from the codebase. {{implementer}} implements directly from this plan.\n\n{{{feasibilityCheck}}}\n\nIf you encounter spec gaps, append to tasks/<id>/notes.md (prefix: [plan]).\n\nWhen done, run:\n{{{phaseCommands}}}\n";
|
|
6741
6741
|
|
|
6742
6742
|
// src/orchestrator/prompts/templates/qa.md
|
|
6743
|
-
var qa_default = 'You are writing QA summaries for {{taskScope}} for {{projectName}}.\n\n{{{startup}}}\n\nTasks:\n{{{taskLines}}}\n\nFor each task:\n1. **Use the Write tool** to create tasks/<id>/done.md \u2014 plain-English summary for the human. Include: what changed, files changed, how to test, test results, human verification required, judgment calls to confirm, decisions made, open questions.\n \u26A0\uFE0F CRITICAL: Use the `Write` tool \u2014 do NOT simply output the done.md content as text in your response. Content in your chat reply does not get saved to disk. The pipeline validates that done.md contains real content (not the template) before advancing. Write the file.\n - **Judgment Calls to Confirm**: add the section immediately before `## Decisions Made`. List every `Author` row from the spec\'s *Judgment Calls* section (the call, chosen option, and strongest alternative), or write `None.` if there are no such rows or no section.\n2. Read the latest `## Validation Outcomes` table in `tasks/<id>/handoff.md`, including any later iteration `### Re-run validation` tables. If any check\'s latest result is `human_pending`, include a **Human Verification Required** section in done.md that lists each pending check and its Notes. If none remain, write `None.` in that section. Do not hide `human_pending` checks inside the generic Test Results table.\n - If the human chooses to waive or defer a pending check later, the waiver line in done.md must begin with `Acknowledged:`. The `human_review` gate only treats that explicit prefix as a waiver.\n - Preserve `deferred_by_spec` rows in Test Results with the spec citation from Notes; do not translate them to `Pass`.\n3. Include a **Proposed Changelog** section in done.md \u2014 the changelog **entry text only**. Do **NOT** include a version number, a "Proposed version" line, or a bump tier (Patch/Minor/Major): the version is decided at the release step (`/canon-changelog` + human), never by QA.\n - **Canon release rules (non-negotiable)**: (1) Agents do not bump versions or land changelog edits without explicit scope authorization. (2) The QA step proposes a draft changelog entry text only \u2014 not the version number. (3) Changelog + version bump are committed separately from code changes (when a project versions its releases). (4) No major versioning surprises: if a task introduces a breaking change the spec didn\'t flag, raise it before shipping.\n - Read `docs/decisions.md` \xA7"Versioning and release policy" for this project\'s changelog **scope** (which changes warrant an entry). The bump tier / SemVer interpretation is the release step\'s call, not QA\'s \u2014 do not propose one.\n - If CHANGELOG.md exists, read the top of it (the most recent version section) to calibrate on scope and voice.\n - Apply the "would a user notice" test to every candidate bullet (or the project\'s equivalent scope test): if a candidate falls outside the project\'s defined changelog scope, omit it. If a task is entirely out of scope, say so explicitly ("no user-facing change \u2014 omit from changelog") rather than inventing a bullet.\n - Implementation mechanics belong in the "What Changed" section above \u2014 not in the proposed changelog.\n The human finalizes the changelog entry.\n4. **For single tasks only \u2014 use the Write tool** to create `tasks/<id>/pr-body.md` \u2014 the outward-facing PR body draft for `--pr`. Write it as if a human wrote it after doing the work.\n {{#prTemplate}}\n The repo has this PR template. Fill every section with specifics from what shipped. Keep the headings; replace every placeholder:\n\n {{{prTemplate}}}\n {{/prTemplate}}\n\n {{^prTemplate}}\n No PR template found. Use this structure:\n\n ## Summary\n 1\u20133 bullets: what changed and why.\n\n ## Changes\n Key files or areas touched, described for a reviewer.\n\n ## How to Test\n Steps a reviewer can follow to verify the change.\n\n ## Notes for Reviewer\n Any context, caveats, or follow-up items.\n {{/prTemplate}}\n For each `Author` row in the spec\'s *Judgment Calls* section, add a short note phrased in the engineer\'s voice as a call not explicitly confirmed during spec review. With no PR template, put the rows under "Notes for Reviewer". With a PR template, use its closest notes-like section, or append a short `Judgment calls` heading at the end if it has none. If there are no `Author` rows, add nothing to the PR body.\n \u26A0\uFE0F Write as the human engineer who did the work \u2014 not as the AI or tool that produced it ({{toolExamples}}). \u2705 e.g. "Fix the pagination off-by-one that dropped the last row." \u274C e.g. "\u{1F916} Generated with Claude Code."\n Skip this step entirely for bundle tasks \u2014 per-task bodies are not combined for bundle PRs.\n\n**Citing files in task artifacts:** cite every repository file by its full path from the repository root, including any workspace or package prefix \u2014 never a path relative to a package or to the current directory. For a file that does not exist \u2014 one this task deleted, or one only planned \u2014 use the markdown-link form `[path](path)` instead of backticks, because `docs-refs-check` reports a backticked path to a missing file as a broken reference.\n\nAfter writing all done.md files:\n- Read tasks/<id>/notes.md for each task. For each insight, ask: "would this have changed how a *different* task was approached?" If yes, **append** one new entry for *this* task to its own lessons fragment, using the entry format in docs/lessons-learned.md. The fragment holds only `###` entries: create it if it doesn\'t exist, and give it no title or other `#`/`##` heading. Do not edit docs/lessons-learned.md; `--ship` folds the fragments into it. If no, the detail stays in notes.md only. Append-only: never edit, prune, promote, reorganize, or delete existing entries \u2014 not this task\'s earlier entries, and never another task\'s. Promoting entries into permanent docs (patterns.md / decisions.md) and pruning the buffer is a **human-initiated, human-approved** action \u2014 never perform it during QA, and no entry count ever triggers it. (See docs/lessons-learned.md \u2192 "How to use this doc".)\n\n{{{lessonsFragments}}}\n\n- Add a `## Quality Log` section to done.md with the five judgment cells the pipeline cannot derive from status.json. Do **not** edit docs/task-quality-log.md directly \u2014 the qa \u2192 done transition writes or upserts that row automatically into each task\'s quality-log.md fragment from status.json plus this section. `--ship` folds it into the shared log.\n\n ```markdown\n ## Quality Log\n - Spec verdict: <the FIRST spec_review verdict this task ever received \u2014 approved / approved_with_nits / changes_requested; leave blank only if truly unknown>\n - Human reroute?: <Yes/No \u2014 did the human reroute this task at any phase, forcing rework? Do not infer this from any reroute counter; if this is a fresh QA pass with no human reroute yet, answer No>\n - Dropped ACs: <count of ACs the implementation missed, caught in code review>\n - Validation gaps: <count of validation checks that should have run but did not>\n - Notes: <one-line summary of anything notable \u2014 single line, no embedded line breaks>\n ```\n\n On a re-upsert after a reroute, only fill in cells that changed or that you are correcting \u2014 an omitted cell keeps its previously recorded value. In particular, do not overwrite an already-recorded `Spec verdict` with the current status.json verdict; that column means the first spec_review verdict, and status.json only retains the latest.\n\n- Add a `## Root Cause` section to done.md, after `## Quality Log`. It stays in done.md and is not copied to the quality log. For each blocking review finding, reroute, or dropped AC this task had, write one line `- <class>: <one-line cause>`, where class is one of `context-missing` (a doc or spec lacked a fact the agent needed), `context-conflicting` (docs, spec, or code said two different things, or a term was ambiguous), `spec-gap`, `plan-error`, `execution` (the context was adequate and the agent still got it wrong), or `unrequested-change` (the implementer changed or reinterpreted something the spec did not ask for). If the task had none, write `None.`\n\n**Handoff Validation pre-merge checklist** (include in `done.md` Human Verification section if any item cannot be confirmed):\n- [ ] Version correct (per project policy; skip if unversioned)\n- [ ] Changelog updated if needed (per project policy; skip if unversioned)\n- [ ] PR body current\n- [ ] Final CI/CD checks green\n- [ ] Final diff matches spec intent\n\n**Output Format for Human** \u2014 `done.md` must contain:\n1. One-paragraph plain-English summary\n2. Files changed\n3. How to test (product-level steps, not code)\n4. Test results table\n5. Judgment calls to confirm (`## Judgment Calls to Confirm`)\n6. Decisions made during implementation\n7. Open questions needing human input\n8. Root cause of each blocking finding, reroute, or dropped AC (`## Root Cause`)\n\n**Code is Canonical; Docs Reference Symbols**: Code is the source of truth for anything derivable from code: numbers, thresholds, file locations, function signatures, type shapes, observable behavior. Docs that restate these facts inline rot silently \u2014 reference the symbol or path; do not restate the value.\n\n**Commit Ownership** \u2014 three change categories:\n- Code changes \u2192 task branch, committed by the orchestrator after {{implementer}} static validation.\n- Pre-implement scaffold \u2192 base branch, committed by the orchestrator before first implement.\n- Changelog + version bump (if versioned) \u2192 separate commit, human + Claude, after human_review.\n\n- **Docs freshness \u2014 Two-checkpoint**: {{#docsEditable}}scan these docs ({{{docsEditable}}}) for references that {{docsScope}} *contradicts* \u2014 a renamed symbol, a moved file, a behavior this task changed \u2014 and correct those stale references. That is the only edit QA makes to permanent docs.{{/docsEditable}}{{^docsEditable}}no docs are configured for correction in this project, so QA makes no edits to permanent docs under this step.{{/docsEditable}} Do not add new lessons, pitfalls, or decisions here, and do not promote buffer entries \u2014 promotion is the human sweep, not Docs freshness.\n{{#docsFlagged}}\n- **Docs drift (flag only)**: also check {{{docsFlagged}}} for statements {{docsScope}} makes stale. Do **not** edit these docs. Report each stale statement in a `## Docs drift` section of done.md (doc, the stale statement, and what is now true). Omit the section if nothing is stale.\n{{/docsFlagged}}\n- **Buffer signal** (not an action): after appending, if docs/lessons-learned.md plus this task\'s lessons fragment now hold more than ~15 entries, add one line to this task\'s done.md \u2014 `Maintenance: lessons-learned.md plus this task\u2019s fragment have N entries; a human lessons sweep is due (see docs/lessons-learned.md \u2192 "How to use this doc").` Do not perform the sweep yourself.\n\nWhen done, run (use the Bash tool \u2014 do not just output the command as text):\n{{{phaseCommands}}}\n';
|
|
6743
|
+
var qa_default = 'You are writing QA summaries for {{taskScope}} for {{projectName}}.\n\n{{{startup}}}\n\nTasks:\n{{{taskLines}}}\n\nFor each task:\n1. **Use the Write tool** to create tasks/<id>/done.md \u2014 plain-English summary for the human. Include: what changed, files changed, how to test, test results, human verification required, judgment calls to confirm, decisions made, open questions.\n \u26A0\uFE0F CRITICAL: Use the `Write` tool \u2014 do NOT simply output the done.md content as text in your response. Content in your chat reply does not get saved to disk. The pipeline validates that done.md contains real content (not the template) before advancing. Write the file.\n - **Judgment Calls to Confirm**: add the section immediately before `## Decisions Made`. List every `Author` row from the spec\'s *Judgment Calls* section (the call, chosen option, and strongest alternative), or write `None.` if there are no such rows or no section.\n2. Read the latest `## Validation Outcomes` table in `tasks/<id>/handoff.md`, including any later iteration `### Re-run validation` tables. If any check\'s latest result is `human_pending`, include a **Human Verification Required** section in done.md that lists each pending check and its Notes. If none remain, write `None.` in that section. Do not hide `human_pending` checks inside the generic Test Results table.\n - If the human chooses to waive or defer a pending check later, the waiver line in done.md must begin with `Acknowledged:`. The `human_review` gate only treats that explicit prefix as a waiver.\n - Preserve `deferred_by_spec` rows in Test Results with the spec citation from Notes; do not translate them to `Pass`.\n3. Include a **Proposed Changelog** section in done.md \u2014 the changelog **entry text only**. Do **NOT** include a version number, a "Proposed version" line, or a bump tier (Patch/Minor/Major): the version is decided at the release step (`/canon-changelog` + human), never by QA.\n - **Canon release rules (non-negotiable)**: (1) Agents do not bump versions or land changelog edits without explicit scope authorization. (2) The QA step proposes a draft changelog entry text only \u2014 not the version number. (3) Changelog + version bump are committed separately from code changes (when a project versions its releases). (4) No major versioning surprises: if a task introduces a breaking change the spec didn\'t flag, raise it before shipping.\n - Read `docs/decisions.md` \xA7"Versioning and release policy" for this project\'s changelog **scope** (which changes warrant an entry). The bump tier / SemVer interpretation is the release step\'s call, not QA\'s \u2014 do not propose one.\n - If CHANGELOG.md exists, read the top of it (the most recent version section) to calibrate on scope and voice.\n - Apply the "would a user notice" test to every candidate bullet (or the project\'s equivalent scope test): if a candidate falls outside the project\'s defined changelog scope, omit it. If a task is entirely out of scope, say so explicitly ("no user-facing change \u2014 omit from changelog") rather than inventing a bullet.\n - Implementation mechanics belong in the "What Changed" section above \u2014 not in the proposed changelog.\n The human finalizes the changelog entry.\n4. **For single tasks only \u2014 use the Write tool** to create `tasks/<id>/pr-body.md` \u2014 the outward-facing PR body draft for `--pr`. Write it as if a human wrote it after doing the work. Start with the first section heading and keep every section heading. Do not add a title heading for the PR title or task id above it, since GitHub already shows the PR title above the body.\n {{#prTemplate}}\n The repo has this PR template. Fill every section with specifics from what shipped. Keep the headings; replace every placeholder:\n\n {{{prTemplate}}}\n {{/prTemplate}}\n\n {{^prTemplate}}\n No PR template found. Use this structure:\n\n ## Summary\n 1\u20133 bullets: what changed and why.\n\n ## Changes\n Key files or areas touched, described for a reviewer.\n\n ## How to Test\n Steps a reviewer can follow to verify the change.\n\n ## Notes for Reviewer\n Any context, caveats, or follow-up items.\n {{/prTemplate}}\n For each `Author` row in the spec\'s *Judgment Calls* section, add a short note phrased in the engineer\'s voice as a call not explicitly confirmed during spec review. With no PR template, put the rows under "Notes for Reviewer". With a PR template, use its closest notes-like section, or append a short `Judgment calls` heading at the end if it has none. If there are no `Author` rows, add nothing to the PR body.\n \u26A0\uFE0F Write as the human engineer who did the work \u2014 not as the AI or tool that produced it ({{toolExamples}}). \u2705 e.g. "Fix the pagination off-by-one that dropped the last row." \u274C e.g. "\u{1F916} Generated with Claude Code."\n Skip this step entirely for bundle tasks \u2014 per-task bodies are not combined for bundle PRs.\n\n**Citing files in task artifacts:** cite every repository file by its full path from the repository root, including any workspace or package prefix \u2014 never a path relative to a package or to the current directory. For a file that does not exist \u2014 one this task deleted, or one only planned \u2014 use the markdown-link form `[path](path)` instead of backticks, because `docs-refs-check` reports a backticked path to a missing file as a broken reference.\n\nAfter writing all done.md files:\n- Read tasks/<id>/notes.md for each task. For each insight, ask: "would this have changed how a *different* task was approached?" If yes, **append** one new entry for *this* task to its own lessons fragment, using the entry format in docs/lessons-learned.md. The fragment holds only `###` entries: create it if it doesn\'t exist, and give it no title or other `#`/`##` heading. Do not edit docs/lessons-learned.md; `--ship` folds the fragments into it. If no, the detail stays in notes.md only. Append-only: never edit, prune, promote, reorganize, or delete existing entries \u2014 not this task\'s earlier entries, and never another task\'s. Promoting entries into permanent docs (patterns.md / decisions.md) and pruning the buffer is a **human-initiated, human-approved** action \u2014 never perform it during QA, and no entry count ever triggers it. (See docs/lessons-learned.md \u2192 "How to use this doc".)\n\n{{{lessonsFragments}}}\n\n- Add a `## Quality Log` section to done.md with the five judgment cells the pipeline cannot derive from status.json. Do **not** edit docs/task-quality-log.md directly \u2014 the qa \u2192 done transition writes or upserts that row automatically into each task\'s quality-log.md fragment from status.json plus this section. `--ship` folds it into the shared log.\n\n ```markdown\n ## Quality Log\n - Spec verdict: <the FIRST spec_review verdict this task ever received \u2014 approved / approved_with_nits / changes_requested; leave blank only if truly unknown>\n - Human reroute?: <Yes/No \u2014 did the human reroute this task at any phase, forcing rework? Do not infer this from any reroute counter; if this is a fresh QA pass with no human reroute yet, answer No>\n - Dropped ACs: <count of ACs the implementation missed, caught in code review>\n - Validation gaps: <count of validation checks that should have run but did not>\n - Notes: <one-line summary of anything notable \u2014 single line, no embedded line breaks>\n ```\n\n On a re-upsert after a reroute, only fill in cells that changed or that you are correcting \u2014 an omitted cell keeps its previously recorded value. In particular, do not overwrite an already-recorded `Spec verdict` with the current status.json verdict; that column means the first spec_review verdict, and status.json only retains the latest.\n\n- Add a `## Root Cause` section to done.md, after `## Quality Log`. It stays in done.md and is not copied to the quality log. For each blocking review finding, reroute, or dropped AC this task had, write one line `- <class>: <one-line cause>`, where class is one of `context-missing` (a doc or spec lacked a fact the agent needed), `context-conflicting` (docs, spec, or code said two different things, or a term was ambiguous), `spec-gap`, `plan-error`, `execution` (the context was adequate and the agent still got it wrong), or `unrequested-change` (the implementer changed or reinterpreted something the spec did not ask for). If the task had none, write `None.`\n\n**Handoff Validation pre-merge checklist** (include in `done.md` Human Verification section if any item cannot be confirmed):\n- [ ] Version correct (per project policy; skip if unversioned)\n- [ ] Changelog updated if needed (per project policy; skip if unversioned)\n- [ ] PR body current\n- [ ] Final CI/CD checks green\n- [ ] Final diff matches spec intent\n\n**Output Format for Human** \u2014 `done.md` must contain:\n1. One-paragraph plain-English summary\n2. Files changed\n3. How to test (product-level steps, not code)\n4. Test results table\n5. Judgment calls to confirm (`## Judgment Calls to Confirm`)\n6. Decisions made during implementation\n7. Open questions needing human input\n8. Root cause of each blocking finding, reroute, or dropped AC (`## Root Cause`)\n\n**Code is Canonical; Docs Reference Symbols**: Code is the source of truth for anything derivable from code: numbers, thresholds, file locations, function signatures, type shapes, observable behavior. Docs that restate these facts inline rot silently \u2014 reference the symbol or path; do not restate the value.\n\n**Commit Ownership** \u2014 three change categories:\n- Code changes \u2192 task branch, committed by the orchestrator after {{implementer}} static validation.\n- Pre-implement scaffold \u2192 base branch, committed by the orchestrator before first implement.\n- Changelog + version bump (if versioned) \u2192 separate commit, human + Claude, after human_review.\n\n- **Docs freshness \u2014 Two-checkpoint**: {{#docsEditable}}scan these docs ({{{docsEditable}}}) for references that {{docsScope}} *contradicts* \u2014 a renamed symbol, a moved file, a behavior this task changed \u2014 and correct those stale references. That is the only edit QA makes to permanent docs.{{/docsEditable}}{{^docsEditable}}no docs are configured for correction in this project, so QA makes no edits to permanent docs under this step.{{/docsEditable}} Do not add new lessons, pitfalls, or decisions here, and do not promote buffer entries \u2014 promotion is the human sweep, not Docs freshness.\n{{#docsFlagged}}\n- **Docs drift (flag only)**: also check {{{docsFlagged}}} for statements {{docsScope}} makes stale. Do **not** edit these docs. Report each stale statement in a `## Docs drift` section of done.md (doc, the stale statement, and what is now true). Omit the section if nothing is stale.\n{{/docsFlagged}}\n- **Buffer signal** (not an action): after appending, if docs/lessons-learned.md plus this task\'s lessons fragment now hold more than ~15 entries, add one line to this task\'s done.md \u2014 `Maintenance: lessons-learned.md plus this task\u2019s fragment have N entries; a human lessons sweep is due (see docs/lessons-learned.md \u2192 "How to use this doc").` Do not perform the sweep yourself.\n\nWhen done, run (use the Bash tool \u2014 do not just output the command as text):\n{{{phaseCommands}}}\n';
|
|
6744
6744
|
|
|
6745
6745
|
// src/orchestrator/prompts/templates/spec.md
|
|
6746
6746
|
var spec_default = '{{{header}}}\n\n{{{startup}}}\n\n{{{instructions}}}\n{{{bundleNote}}}\n{{#doneNote}}\nNote: {{{doneNote}}}{{/doneNote}}\n\n{{#docsMapBlock}}\n{{{docsMapBlock}}}\n\n{{/docsMapBlock}}\n**Spec-writing rules of thumb** \u2014 apply when writing each spec:\n\n- **Name effects to DELETE** \u2014 frame supersession as replacement, not add-plus-remove. State: "replace `oldFn` with `newFn`; `oldFn` must not exist after" \u2014 not separate "Add" and "Remove" bullets.\n- **Prefer positive or structural assertions** over prose negations for load-bearing constraints. Back a "must not" with a grep AC or positive reframe; bare prose negation is fragile.\n- **Symbols named in ACs must exist** \u2014 grep for every function or symbol an AC names; verify its return shape matches the spec\'s assumed data contract before marking spec done.\n- **Enumerate every caller and classify its execution context before asserting how a mechanism works** \u2014 "counter X only increments on event Y" or "this writer can only be invoked from surface Z" is a control-flow claim, and control-flow claims need every caller traced. A helper named for one trigger routinely serves several, and whether a call site runs inside an agent\'s own session or in the orchestrator\'s process is invisible from the function body. Grep every caller of the function or counter \u2014 including skills and docs, not just source \u2014 and classify each site as in-agent-session or orchestrator-context before the spec asserts anything about it.\n- **Find sibling implementations, not just callers** \u2014 before settling Affected Files, search for every other place that implements the behavior the spec changes: a second listener or entry path, a parallel component, or a test or doc that asserts the current behavior. A change that reaches one of two implementations ships half-done, and the gap usually surfaces only at code review.\n- **Behavioral contracts, not mechanics** \u2014 ACs describe observable behavior; defer implementation mechanics (signatures, constant names, precise algorithms) to plan/implement. If review rounds start re-litigating literal regexes, exact file layouts, or verbatim command strings, the spec has dropped to code altitude and each round\'s "underspecified" finding just adds more reviewable surface: move the mechanics into a clearly-labeled non-binding *Implementation Notes* subsection owned by plan/implement, rather than wording the same mechanism more precisely.\n- **List every judgment call in *Judgment Calls*** \u2014 A judgment call is a choice between two or more defensible options where the choice changes behavior or scope. A choice a project doc already settles is not a judgment call: follow the doc and cite it. For each call record the chosen option, the strongest alternative, why the choice fits, and Decided by: `Human` only when the human explicitly chose it, otherwise `Author`. Listing them is your own obligation as author: on fast-tier (XS, non-delicate) tasks the `spec_review` checkpoint is skipped, so the author\'s list is the only check.\n- **Bug and flake-fix specs need a confirmed mechanism and red-first test** \u2014 For a bug or flake fix, the spec author must state, in *Problem*, both the confirmed mechanism and how it was confirmed \u2014 not merely a plausible cause. Evidence must match the mechanism class: a deterministic mechanism (fixed inputs hit the same wrong branch every run) may cite a trace with the verified trigger values; a runtime-dependent mechanism (race, timing, environment/config interaction) needs executed confirmation \u2014 a throwaway prototype-fix spike that makes the symptom vanish, or a deterministic forced repro. The author must satisfy that checkpoint before the spec is marked done; on fast-tier (XS, non-delicate) tasks the `spec_review` checkpoint is skipped, so no reviewer will catch an unverified mechanism. The *Acceptance Criteria* must include a red-first regression-test AC: a test that fails on the pre-fix code for the stated reason and passes after the fix. If the mechanism is environment-bound and a faithful repro is impractical, *Problem* must say so and name a deterministic alternative (integration fixture or documented manual repro) instead of skipping verification silently.\n- **At \u22653 spec_review iterations, read the rounds\' content, not the count** \u2014 label each round *edge-fine-tune* (it narrows an already-identified case \u2014 converging, safe to finish once the remaining findings are addressed) or *scope-expansion* (it names a **new** structural case the spec hadn\'t covered \u2014 a real design gap). Round count alone is not the signal; a 6-round run of successive fine-tunes is convergence, not churn. On genuine scope-expansion, don\'t refine again: check whether the last two rejections share one structural root, and whether an existing layer already owns the concern. Dropping the whole mechanism class \u2014 or deleting the mechanism in favor of the layer that already owns it \u2014 is usually cheaper than another round of hardening.\n- **Refactor specs need structural caps** \u2014 provide hard size caps, explicit deletion expectations per symbol, and an allow-list grep AC for any symbol that must disappear.\n- **Refactor specs need a correctness audit** \u2014 For each behavior a refactor declares preserved, record in Problem whether it is correct today, and state one outcome: correct as-is, fixed deliberately (with its own AC), split into a separate task, or kept as a named quirk. A behavior confirmed correct needs only a one-line record. N/A for features and bug fixes.\n- **Codebase-wide term renames: gate per string family, not per enumerated hit** \u2014 a hand-enumerated list of grep hits grows every review round, because each round surfaces a new label *family* rather than a missed instance. Before writing ACs, sweep the codebase once to split the old term into its distinct string families, and gate each family with a zero-result grep AC whose word-bounded pattern catches every separator variant and cannot match the new term. Where the old string is a substring of the new one, a zero-result grep cannot work: verify those surfaces with positive targeted ACs and say so in the spec, so reviewers don\'t read it as a gap. Before finalizing a zero-result AC, read each affected prose file for paraphrases of the retired claim, and fold hits the spec already tolerates elsewhere (historical docs, test fixtures) into a permitted-to-remain list inside the same AC.\n- **UI spatial / gesture tasks** \u2014 flag "visual positioning \u2014 expect human iteration" or "runtime debugging required" in *Known Risks*.\n- **Sensitive-surface escalation** \u2014 flag these categories with `canon task set <id> delicate true` and call them out in *Known Risks*: auth, billing / payments, privacy / data handling, destructive operations, schema / data-model migrations, analytics-event changes. The human spec gate is where such tasks stop for review.\n\n{{{selfCheck}}}\n\nWhen done, run (one per task):\n{{{phaseCommands}}}\n';
|
|
@@ -7283,7 +7283,7 @@ function isInstalledSourcePath(sourcePath) {
|
|
|
7283
7283
|
return sourcePath.includes("/node_modules/") || sourcePath.includes("\\node_modules\\") || sourcePath.includes("/_npx/") || sourcePath.includes("\\_npx\\");
|
|
7284
7284
|
}
|
|
7285
7285
|
function resolveCanonVersion(explicit) {
|
|
7286
|
-
return explicit ?? "3.19.
|
|
7286
|
+
return explicit ?? "3.19.1" ?? "dev";
|
|
7287
7287
|
}
|
|
7288
7288
|
function resolveOrchestratorCommit(repoRoot, upstreamCommit, runGitAt) {
|
|
7289
7289
|
const ownToplevel = captureGitOutput(repoRoot, ["rev-parse", "--show-toplevel"], runGitAt);
|
package/package.json
CHANGED