synorch 0.2.0 → 0.3.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 (82) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/README.md +314 -28
  3. package/dist/application/doctor-service.d.ts +16 -0
  4. package/dist/application/doctor-service.d.ts.map +1 -1
  5. package/dist/application/doctor-service.js +230 -32
  6. package/dist/application/doctor-service.js.map +1 -1
  7. package/dist/application/generated-skill-doctor.d.ts +9 -0
  8. package/dist/application/generated-skill-doctor.d.ts.map +1 -0
  9. package/dist/application/generated-skill-doctor.js +433 -0
  10. package/dist/application/generated-skill-doctor.js.map +1 -0
  11. package/dist/application/project-discovery.d.ts +12 -0
  12. package/dist/application/project-discovery.d.ts.map +1 -1
  13. package/dist/application/project-discovery.js +65 -2
  14. package/dist/application/project-discovery.js.map +1 -1
  15. package/dist/application/safe-path.d.ts +19 -0
  16. package/dist/application/safe-path.d.ts.map +1 -0
  17. package/dist/application/safe-path.js +35 -0
  18. package/dist/application/safe-path.js.map +1 -0
  19. package/dist/application/size-ceiling.d.ts +15 -0
  20. package/dist/application/size-ceiling.d.ts.map +1 -0
  21. package/dist/application/size-ceiling.js +32 -0
  22. package/dist/application/size-ceiling.js.map +1 -0
  23. package/dist/application/structure-service.d.ts.map +1 -1
  24. package/dist/application/structure-service.js +10 -1
  25. package/dist/application/structure-service.js.map +1 -1
  26. package/dist/cli.js +10 -1
  27. package/dist/cli.js.map +1 -1
  28. package/dist/domain/canonical-contracts.d.ts +69 -0
  29. package/dist/domain/canonical-contracts.d.ts.map +1 -0
  30. package/dist/domain/canonical-contracts.js +92 -0
  31. package/dist/domain/canonical-contracts.js.map +1 -0
  32. package/dist/domain/generated-skill.d.ts +55 -0
  33. package/dist/domain/generated-skill.d.ts.map +1 -0
  34. package/dist/domain/generated-skill.js +90 -0
  35. package/dist/domain/generated-skill.js.map +1 -0
  36. package/dist/domain/generation.d.ts +15 -2
  37. package/dist/domain/generation.d.ts.map +1 -1
  38. package/dist/domain/observation-ledger.d.ts +118 -0
  39. package/dist/domain/observation-ledger.d.ts.map +1 -0
  40. package/dist/domain/observation-ledger.js +183 -0
  41. package/dist/domain/observation-ledger.js.map +1 -0
  42. package/dist/domain/product.d.ts +1 -1
  43. package/dist/domain/product.js +1 -1
  44. package/dist/domain/relative-path.d.ts +21 -0
  45. package/dist/domain/relative-path.d.ts.map +1 -0
  46. package/dist/domain/relative-path.js +43 -0
  47. package/dist/domain/relative-path.js.map +1 -0
  48. package/dist/domain/skill-packs.d.ts.map +1 -1
  49. package/dist/domain/skill-packs.js +1 -0
  50. package/dist/domain/skill-packs.js.map +1 -1
  51. package/dist/domain/zod-issues.d.ts +21 -0
  52. package/dist/domain/zod-issues.d.ts.map +1 -0
  53. package/dist/domain/zod-issues.js +27 -0
  54. package/dist/domain/zod-issues.js.map +1 -0
  55. package/dist/infrastructure/frontmatter.d.ts +25 -0
  56. package/dist/infrastructure/frontmatter.d.ts.map +1 -0
  57. package/dist/infrastructure/frontmatter.js +75 -0
  58. package/dist/infrastructure/frontmatter.js.map +1 -0
  59. package/dist/templates/agent-manifests.d.ts +19 -0
  60. package/dist/templates/agent-manifests.d.ts.map +1 -0
  61. package/dist/templates/agent-manifests.js +302 -0
  62. package/dist/templates/agent-manifests.js.map +1 -0
  63. package/dist/templates/base-skills.d.ts +23 -0
  64. package/dist/templates/base-skills.d.ts.map +1 -0
  65. package/dist/templates/base-skills.js +477 -0
  66. package/dist/templates/base-skills.js.map +1 -0
  67. package/dist/templates/skill-creator-skill.d.ts +23 -0
  68. package/dist/templates/skill-creator-skill.d.ts.map +1 -0
  69. package/dist/templates/skill-creator-skill.js +235 -0
  70. package/dist/templates/skill-creator-skill.js.map +1 -0
  71. package/dist/templates/skill-references.d.ts +13 -0
  72. package/dist/templates/skill-references.d.ts.map +1 -0
  73. package/dist/templates/skill-references.js +280 -0
  74. package/dist/templates/skill-references.js.map +1 -0
  75. package/dist/templates/structure-templates.d.ts.map +1 -1
  76. package/dist/templates/structure-templates.js +15 -139
  77. package/dist/templates/structure-templates.js.map +1 -1
  78. package/dist/templates/task-conductor-skill.d.ts +1 -1
  79. package/dist/templates/task-conductor-skill.d.ts.map +1 -1
  80. package/dist/templates/task-conductor-skill.js +50 -22
  81. package/dist/templates/task-conductor-skill.js.map +1 -1
  82. package/package.json +1 -1
@@ -0,0 +1,235 @@
1
+ import { createEmptyLedger } from "../domain/observation-ledger.js";
2
+ import { stringifyYaml } from "../infrastructure/serialization.js";
3
+ export const skillCreatorSkill = `---
4
+ name: skill-creator
5
+ description: Use at task completion to record non-obvious project discoveries as sourced observations, and to propose, author, review and activate a generated project skill once one observation has been confirmed by three distinct tasks or corrected by the user.
6
+ not_for: Mid-task use, first sessions, and cold repository scans. A trivial task may record observations but never proposes a skill.
7
+ version: 1.0.0
8
+ references:
9
+ - references/observation-ledger.md
10
+ - references/generated-skill-contract.md
11
+ - references/retirement.md
12
+ ---
13
+
14
+ # Skill Creator
15
+
16
+ The system earns a skill; it never assumes one. Observations are cheap and unattended. Promotion is rare, approved by the user, written by a worker and verified by an independent reviewer.
17
+
18
+ ## When this applies
19
+
20
+ - At the end of a completed task, while writing the final report, for every worker completion packet.
21
+ - When the user corrects an approach ("not that way, this way"): record the observation and propose immediately.
22
+ - When \`doctor\` reports stale evidence, or a worker identifies a stale or superseded project skill and a natural pause has arrived.
23
+
24
+ ## When it does not
25
+
26
+ - Mid-task. Recording is a completion step; proposing interrupts nothing that is still running.
27
+ - On a first session, or from a repository scan. Day one has facts, not procedures; the project record already holds the facts.
28
+ - For anything a bundled technology skill already covers, or for a discovery with no source path.
29
+ - Never propose more than one skill in one final report. If several are ready, take the highest \`count\` and leave the rest.
30
+
31
+ ## Required inputs
32
+
33
+ - The completed task's id, and the worker completion packets with their \`commands_run\`, \`decisions_made\` and source paths.
34
+ - \`.ai/tasks/observations.yaml\` (the ledger) and the current contents of \`.ai/skills/project/\`.
35
+ - For a proposal: the user's explicit approval, and the active project-skill count.
36
+
37
+ ## Procedure
38
+
39
+ 1. **Qualify.** An observation must be non-obvious, repeatable and carry at least one source path. No source, no observation. Discard anything a bundled skill already states.
40
+ 2. **Record.** Append or update the entry in \`.ai/tasks/observations.yaml\` — the orchestrator's only writable area, so this needs no constitutional change. Increment \`tasks_seen\` exactly once per completed task. Format and expiry: \`references/observation-ledger.md\`.
41
+ 3. **Confirm.** Add the task id to \`confirmed_by\` only if it is not already there. The same task hitting the same wall twice counts once. Set \`count\` to the number of distinct ids and \`last_seen_task_index\` to \`tasks_seen\`.
42
+ 4. **Decide.** At \`count\` 3, set \`status: ready-to-propose\`. A user correction sets \`origin: user-correction\` and is ready at once.
43
+ 5. **Budget.** Before proposing, count \`status: active\` skills under \`.ai/skills/project/\`. At 12, propose a retirement first and let the user choose; do not propose an addition alongside it.
44
+ 6. **Propose.** In the final report, state the claim, its sources and its confirming task ids, and ask. On approval continue; on refusal set \`status: declined\`, which is permanent — never ask again for that id.
45
+ 7. **Author.** Delegate to an implementer: write \`.ai/skills/project/<id>/SKILL.md\` against the contract in \`references/generated-skill-contract.md\`.
46
+ 8. **Review.** Delegate to an independent reviewer, never the author. The reviewer opens every \`source\`, confirms the claim it backs and recomputes its digest.
47
+ 9. **Activate.** Only after the review passes, and only through two writes: the implementer sets \`status: active\` in the skill's own frontmatter, and the orchestrator sets the observation to \`status: promoted\` with \`promoted_to: <id>\`. There is no registry entry to make — \`.ai/projects/<id>.skills.yaml\` is regenerated by every \`sync\` and sits outside \`.ai/tasks/**\`.
48
+ 10. **Maintain.** Apply stale-evidence and manually identified supersession signals from \`references/retirement.md\` at the next pause. The first slice has no skill-usage telemetry, so usage-based retirement is manual.
49
+
50
+ ## Tools
51
+
52
+ File reads for sources; the ledger write; \`syn doctor\` for the contract, budget, size and digest checks; delegation to an implementer and a reviewer. No model call inside the CLI, and no external skill import.
53
+
54
+ ## Verification
55
+
56
+ - \`syn doctor\` reports no \`generated.*\` error for the new skill.
57
+ - Every \`evidence\` entry names a file that exists inside the root and whose digest matches.
58
+ - The active project-skill count is at most 12 and the file is at most 15KB.
59
+ - The reviewer's report names each claim and the source it was checked against.
60
+
61
+ ## Stop and escalate
62
+
63
+ - Stop if a claim cannot be traced to a source, if the reviewer rejects any claim, or if the author and the reviewer are the same worker.
64
+ - Stop if the proposal would exceed the budget without an approved retirement.
65
+ - Stop and ask if the content would belong in a protocol or the constitution. A generated skill holds \`priority: skill\` only; it never overrides a core protocol and never claims constitutional authority.
66
+ - Never delete a skill. Retirement is proposed, then the implementer moves the file to \`RETIRED.md\` and sets \`status: retired\`, and the orchestrator records it in the ledger.
67
+
68
+ ## Output contract
69
+
70
+ Ledger entries are the ordinary output. A promotion additionally yields: one proposal paragraph in the final report; on approval, \`.ai/skills/project/<id>/SKILL.md\` with complete evidence frontmatter and \`status: active\`; a reviewer verdict per claim; and the observation moved to \`status: promoted\` with \`promoted_to\` naming the skill.
71
+ `;
72
+ const observationLedgerReference = `# Observation Ledger
73
+
74
+ \`.ai/tasks/observations.yaml\` is Git-tracked and lives inside the orchestrator's writable area. Per-task working directories under \`.ai/tasks/\` are not tracked.
75
+
76
+ ## Format
77
+
78
+ \`\`\`yaml
79
+ schema_version: 1
80
+ tasks_seen: 174
81
+ observations:
82
+ - id: api-test-execution
83
+ claim: >
84
+ API tests must run with cwd services/api and
85
+ TESTCONTAINERS_RYUK_DISABLED=true, or they fail on startup.
86
+ kind: command-behavior
87
+ sources:
88
+ - path: services/api/package.json
89
+ digest: sha256:9f2c1d3b4a5e6f708192a3b4c5d6e7f8
90
+ - path: .github/workflows/ci.yml
91
+ digest: sha256:41ab5c6d7e8f9012a3b4c5d6e7f80192
92
+ confirmed_by: [task-141, task-156, task-173]
93
+ count: 3
94
+ origin: worker-discovery
95
+ first_seen_at: 2026-09-14
96
+ last_seen_at: 2026-09-22
97
+ last_seen_task_index: 173
98
+ status: ready-to-propose
99
+ \`\`\`
100
+
101
+ ## Fields
102
+
103
+ - \`kind\` is one of \`command-behavior\`, \`convention\`, \`ordering-constraint\`, \`pitfall\`, \`boundary\`. It exists to make deduplication tractable: a new observation that shares a \`kind\` and a source path with an existing one updates it instead of adding a second entry.
104
+ - \`origin\` is \`worker-discovery\` or \`user-correction\`.
105
+ - \`status\` is one of \`collecting\`, \`ready-to-propose\`, \`proposed\`, \`promoted\`, \`declined\`, \`expired\`.
106
+ - \`promoted_to\` is optional and set only on promotion: the id of the generated skill this observation became. It is half of the activation record; the other half is \`status: active\` in that skill's own frontmatter. There is no third place, and no registry entry.
107
+ - \`digest\` is \`sha256:<hex>\` over the source file's bytes with line endings normalized to \`\\n\`. A prefix of at least 32 hex characters is accepted; anything shorter is not treated as a match.
108
+ - \`count\` must equal the number of distinct ids in \`confirmed_by\`.
109
+
110
+ ## The two counters
111
+
112
+ \`tasks_seen\` is a monotonic count of completed tasks. Increment it exactly once per completed task, in the same write that records or reconfirms observations. \`last_seen_task_index\` stores the value of \`tasks_seen\` at an observation's last confirmation.
113
+
114
+ That pair is what makes the task-based expiry rule decidable without a clock or a task history: an observation is \`20 tasks\` old when \`tasks_seen - last_seen_task_index >= 20\`.
115
+
116
+ ## Expiry
117
+
118
+ An unpromoted observation expires 90 days after \`last_seen_at\` or 20 tasks after \`last_seen_task_index\`, whichever comes first. \`syn sync\` prunes expired entries and reports how many it removed. \`promoted\` and \`declined\` entries are never pruned: \`declined\` is permanent so the user is not asked twice.
119
+
120
+ A one-off oddity is not a procedure. Expiry is the structural immunity against a ledger that turns into an incident log.
121
+ `;
122
+ const generatedSkillContractReference = `# Generated Skill Contract
123
+
124
+ A generated skill lives at \`.ai/skills/project/<id>/SKILL.md\`. \`syn sync\` never writes, overwrites or deletes anything in that namespace, even with \`--force\`.
125
+
126
+ ## Frontmatter
127
+
128
+ \`\`\`yaml
129
+ ---
130
+ name: api-test-execution
131
+ description: How to run and debug the API test suite in this repository.
132
+ version: 1.0.0
133
+ priority: skill
134
+ origin: generated
135
+ status: active
136
+ generated_at: 2026-09-22
137
+ verified_at: 2026-09-22
138
+ confirmations: 3
139
+ promotion: threshold
140
+ confirmed_by: [task-141, task-156, task-173]
141
+ evidence:
142
+ - claim: Tests require cwd services/api
143
+ source: services/api/package.json
144
+ digest: sha256:9f2c1d3b4a5e6f708192a3b4c5d6e7f8
145
+ - claim: TESTCONTAINERS_RYUK_DISABLED=true is required locally
146
+ source: .github/workflows/ci.yml
147
+ digest: sha256:41ab5c6d7e8f9012a3b4c5d6e7f80192
148
+ supersedes: []
149
+ ---
150
+ \`\`\`
151
+
152
+ \`promotion\` is \`threshold\` for the ordinary three-confirmation path, or \`user-correction\` for the fast path. It is the only way a skill may carry fewer than three confirmations, and it must be stated explicitly.
153
+
154
+ ## Blocking rules
155
+
156
+ 1. \`origin: generated\` requires a non-empty \`evidence\` list; every entry needs a \`claim\`, a \`source\` and a \`digest\`.
157
+ 2. Every \`source\` exists and stays inside the root under both lexical and realpath checks.
158
+ 3. \`priority\` is \`skill\`. \`constitutional\`, \`core\` and any protocol-level value are rejected.
159
+ 4. \`SKILL.md\` is at most 15KB.
160
+ 5. At most 12 project skills are \`active\`.
161
+ 6. Every id in \`confirmed_by\` appears in the observation ledger.
162
+
163
+ ## Body
164
+
165
+ The same sections every skill carries: When this applies, When it does not, Required inputs, Procedure, Tools, Verification, Stop and escalate, Output contract.
166
+
167
+ Write a repeatable procedure, not a story. Every factual claim in the body must be backed by an \`evidence\` entry; \`doctor\` warns on an unsourced path, on a missing activation condition and on past-tense incident narration.
168
+
169
+ ## Authoring and review
170
+
171
+ The implementer writes the file. A different worker reviews it, opening each \`source\` and confirming the claim it backs.
172
+
173
+ Activation is expressed in exactly two places, and nowhere else. The implementer sets \`status: active\` in this frontmatter, which is what \`doctor\` counts against the twelve-skill budget. The orchestrator then sets the observation to \`status: promoted\` and records \`promoted_to: <id>\`. There is no registry entry: \`.ai/projects/<id>.skills.yaml\` is regenerated by every \`sync\`, has no project-skill slot, and lies outside the orchestrator's \`.ai/tasks/**\` write scope. The orchestrator writes the ledger only — never the skill file itself.
174
+ `;
175
+ const retirementReference = `# Retirement
176
+
177
+ Nothing is ever deleted automatically. Every signal below produces a proposal at the next natural pause; the user decides.
178
+
179
+ ## Implemented signals
180
+
181
+ - **Stale.** \`doctor\` warns when a source digest changes. Re-verify at the next pause; when a worker confirms that the claim no longer holds, the implementer sets \`status: stale\`.
182
+ - **Unused.** The first slice does not track when a skill was loaded, so \`doctor\` cannot infer unused skills. The user or a worker may propose retirement manually.
183
+ - **Superseded.** A worker or reviewer identifies overlap with an existing skill. Propose a merge into the existing skill rather than a second skill, and record the lineage in \`supersedes\`.
184
+
185
+ ## Executing an approved retirement
186
+
187
+ 1. The implementer moves \`.ai/skills/project/<id>/SKILL.md\` to \`.ai/skills/project/<id>/RETIRED.md\` and sets \`status: retired\` in its frontmatter. That is what frees the budget slot: \`doctor\` counts \`status: active\` frontmatter, and nothing else.
188
+ 2. The orchestrator records the retirement in the ledger. There is no registry entry to drop — \`.ai/projects/<id>.skills.yaml\` is regenerated by every \`sync\` and never carries project skills.
189
+ 3. Leave the Git history alone. Nothing is deleted from it.
190
+
191
+ A retired skill frees a slot in the 12-skill budget. That budget is the only brake on accumulation, so retirement is a routine act, not a failure.
192
+ `;
193
+ const taskDirectoryIgnore = `# Per-task orchestrator working directories are local state, not shared history.
194
+ # The observation ledger is the exception: it is the distillation record and is tracked.
195
+ *
196
+ !.gitignore
197
+ !.gitkeep
198
+ !observations.yaml
199
+ `;
200
+ /**
201
+ * The reference documents of the `skill-creator` base skill. `BASE_SKILL_DOCUMENTS` in
202
+ * `base-skills.ts` is the single place that turns these into files, exactly as it does for
203
+ * every other base skill, so the skill and its references can never be emitted twice.
204
+ */
205
+ export const skillCreatorReferences = [
206
+ { fileName: "observation-ledger.md", content: observationLedgerReference },
207
+ { fileName: "generated-skill-contract.md", content: generatedSkillContractReference },
208
+ { fileName: "retirement.md", content: retirementReference },
209
+ ];
210
+ /**
211
+ * The control-plane files the distillation loop needs beside the skill itself: the Git-tracked
212
+ * observation ledger and the ignore rule that keeps per-task working directories out of history.
213
+ * They are canonical structure rather than skill content, so `createStructureFiles` emits them.
214
+ *
215
+ * The two carry different write policies on purpose. The ignore rule is pure canonical policy
216
+ * with no user state in it, so `--force` may refresh it. The ledger is the opposite: from the
217
+ * first completed task it holds approved, promoted and permanently declined observations that
218
+ * only the orchestrator and the user may change. It is therefore seeded once and never
219
+ * rewritten — design D12 and §9 forbid destroying user-approved state, and `syn init --force`
220
+ * is the documented migration command, so it must not be the command that erases it.
221
+ */
222
+ export const skillCreatorLedgerFiles = [
223
+ file(".ai/tasks/observations.yaml", stringifyYaml(createEmptyLedger()), "canonical", "create-only"),
224
+ file(".ai/tasks/.gitignore", taskDirectoryIgnore, "canonical"),
225
+ ];
226
+ /** Mirrors the private helper in structure-templates.ts; kept local so nothing private is imported. */
227
+ function file(relativePath, content, kind, writePolicy = "overwrite") {
228
+ return {
229
+ relativePath,
230
+ content: content.length === 0 || content.endsWith("\n") ? content : `${content}\n`,
231
+ kind,
232
+ writePolicy,
233
+ };
234
+ }
235
+ //# sourceMappingURL=skill-creator-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-creator-skill.js","sourceRoot":"","sources":["../../src/templates/skill-creator-skill.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAGnE,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoEhC,CAAC;AAEF,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDlC,CAAC;AAEF,MAAM,+BAA+B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDvC,CAAC;AAEF,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;CAiB3B,CAAC;AAEF,MAAM,mBAAmB,GAAG;;;;;;CAM3B,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsC;IACvE,EAAE,QAAQ,EAAE,uBAAuB,EAAE,OAAO,EAAE,0BAA0B,EAAE;IAC1E,EAAE,QAAQ,EAAE,6BAA6B,EAAE,OAAO,EAAE,+BAA+B,EAAE;IACrF,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,EAAE;CAC5D,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA8B;IAChE,IAAI,CACF,6BAA6B,EAC7B,aAAa,CAAC,iBAAiB,EAAE,CAAC,EAClC,WAAW,EACX,aAAa,CACd;IACD,IAAI,CAAC,sBAAsB,EAAE,mBAAmB,EAAE,WAAW,CAAC;CAC/D,CAAC;AAEF,uGAAuG;AACvG,SAAS,IAAI,CACX,YAAoB,EACpB,OAAe,EACf,IAA4B,EAC5B,cAA+B,WAAW;IAE1C,OAAO;QACL,YAAY;QACZ,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI;QAClF,IAAI;QACJ,WAAW;KACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Progressive-disclosure reference files for the canonical base skills.
3
+ *
4
+ * A reference costs nothing until a step in its skill actually needs it, so it
5
+ * carries the worked examples, catalogues and rubrics that would otherwise
6
+ * bloat a just-in-time `SKILL.md`. Each file is declared in its skill's
7
+ * `references` frontmatter and generated under the skill's own directory.
8
+ */
9
+ export declare const riskClassificationReference = "# Risk Classification \u2014 Worked Examples\n\nUse this file when a brief does not obviously land in one tier, or when someone\ndisputes a classification. The tier definitions live in\n`.ai/protocols/core/orchestration.md`; this file only shows how they are applied.\n\n## The deciding questions\n\nAsk them in order. The first \"yes\" sets the floor; nothing below it applies.\n\n1. Can this change corrupt, expose or lose data that already exists?\n2. Does it alter a contract someone outside this repository depends on?\n3. Does it touch authentication, authorization, secrets, payments or money?\n4. Does it change concurrency, ordering, retries or idempotency?\n5. Does it change behavior a user or another service can observe?\n6. Does it span more than one module, or more than one owner?\n\nQuestions 1\u20134 mean high-risk. Question 5 alone means standard. Question 6 alone\nmeans standard. None of them means trivial.\n\n## Worked examples\n\n| Brief | Tier | Why |\n| --- | --- | --- |\n| Fix a typo in a button label | trivial | No behavior, no contract, reversible in one line. |\n| Rename a private helper used in one file | trivial | No external name changes; the compiler proves the rename. |\n| Bump a patch version of a dev-only formatter | trivial | No runtime artifact changes. |\n| Add a nullable, unused column with a default | standard | Schema change, but no reader depends on it yet. |\n| Add a field to an existing API response | standard | Observable behavior; additive, so no consumer breaks. |\n| Extract a component used by three screens | standard | Multi-file, but behavior is meant to be identical. |\n| Change a cache expiry from 60s to 600s | standard | Observable staleness change, bounded blast radius. |\n| Add an index to a large production table | high-risk | Locking and write-path impact during migration. |\n| Change a password hash or token lifetime | high-risk | Authentication surface. |\n| Make a sequential job run in parallel | high-risk | New ordering and idempotency assumptions. |\n| Drop or rename a column still read by code | high-risk | Destructive and irreversible without a backup. |\n| Change the rounding of an invoice total | high-risk | Money, and every historical comparison shifts. |\n\n## Traps that misclassify\n\n- **\"It is only a config change.\"** Config that selects a code path is a code\n change with no test coverage. Tier it by what the path does.\n- **\"It is only one line.\"** Size is not risk. A one-line change to a permission\n check is high-risk; a hundred-line change to a test fixture is trivial.\n- **\"The tests pass.\"** Passing tests classify nothing. They tell you what is\n already covered, not what the change can break.\n- **\"We will verify it in production.\"** That is a decision to accept risk, not\n a reason to lower the tier. Record it as an accepted risk in the plan.\n- **\"It is a revert.\"** A revert of a migrated schema is not symmetrical with\n the migration. Tier it on what the revert itself does.\n\n## Escalating a tier mid-task\n\nEscalate, record the reason, and re-open approval when any of these appear:\n\n- A verified fact contradicts an assumption the plan rested on.\n- The change turns out to need a file the plan did not name.\n- A check fails for a reason no one predicted.\n- The worker asks for authority the packet did not grant.\n\nNever lower a tier because the work is taking longer than expected. Lower it\nonly when evidence removes the risk that set it, and say which evidence did.\n";
10
+ export declare const evidenceLadderReference = "# Evidence Ladder \u2014 Worked Examples\n\nThe rungs and the browser policy are defined in\n`.ai/protocols/core/verification.md`. This file shows which evidence actually\nproves which claim, and which evidence only looks like proof.\n\n## Claim to evidence\n\n| Claim | Sufficient evidence | Not sufficient |\n| --- | --- | --- |\n| \"The label now reads X.\" | The diff hunk showing the literal, plus a search proving no other copy exists. | \"I changed it.\" |\n| \"The function handles null.\" | A unit test asserting the null path, failing before the change. | Reading the new branch. |\n| \"No caller breaks.\" | A type check, or an exhaustive search of call sites with each one listed. | \"It is backwards compatible.\" |\n| \"The bug is fixed.\" | The original reproduction command, before and after, with output. | The test suite passing. |\n| \"Performance improved.\" | The same measurement command before and after, with both numbers. | A reasoned argument about complexity. |\n| \"The migration is safe.\" | A dry run against a copy of real-shaped data, plus the rollback path. | A review of the SQL. |\n| \"Nothing else changed.\" | The full diff, read hunk by hunk. | The summary of the diff. |\n| \"The endpoint returns 403 for anonymous users.\" | A request-level test asserting the status. | The presence of a guard annotation. |\n\n## Choosing the cheapest sufficient rung\n\nAsk: *what observation would change my mind?* Run that, and stop.\n\n- A claim about a literal is settled by a search. Running the test suite adds\n minutes and zero information.\n- A claim about a type boundary is settled by the type checker. A runtime test\n adds nothing the compiler did not already prove.\n- A claim about behavior at an integration seam is not settled by a unit test\n with the seam mocked. The mock encodes the assumption under test.\n- A claim about a rendered pixel, a focus order or a real browser event is the\n only case where a headed browser is the cheapest sufficient evidence \u2014 and it\n still requires the approval the protocol demands.\n\n## Recording evidence\n\nRecord, for every check: the exact command, the working directory, the outcome,\nand the reason for any check deliberately not run. Three failure modes to avoid:\n\n1. **Paraphrasing a command.** `pnpm test` and `pnpm test src/foo` are\n different evidence. Record what ran, not what it resembled.\n2. **Reporting a check that did not run.** If it was skipped, name it as\n skipped. An honest gap is cheaper than a false claim discovered later.\n3. **Reporting a pass that was not read.** A green exit code from a command\n that matched zero tests proves nothing. Confirm the check had subjects.\n\n## Worked example \u2014 a trivial change\n\nObjective: correct a misspelled key in one constant.\n\n1. Diff: one line, one file. **Rung 1.**\n2. Search for the old spelling across the repository: no other occurrence.\n3. Stop. No lint, no build, no test suite, no reviewer, no browser.\n4. Record: \"grep -r oldKey \u2192 0 hits; suite not run (unaffected).\"\n\n## Worked example \u2014 a standard change\n\nObjective: an API response gains an optional field.\n\n1. Diff read hunk by hunk. **Rung 1.**\n2. Type check and the serializer's own unit tests. **Rung 2.**\n3. One request-level test asserting the field is present and optional.\n4. Integration suite only if a consumer in this repository parses strictly.\n5. Independent review because the change crosses a published boundary.\n6. Record every command, plus \"end-to-end suite not run: no UI path changed.\"\n";
11
+ export declare const hypothesisPatternsReference = "# Hypothesis Patterns and Failure Catalogue\n\nOpen this file when the reproduction is in hand and the hypothesis list is\nshort, obvious and wrong. It exists to widen the candidate set before effort is\nspent confirming a favourite.\n\n## Writing a falsifiable hypothesis\n\nA usable hypothesis names a mechanism and predicts an observation.\n\n- Weak: \"something is wrong with the cache.\"\n- Usable: \"the cache key omits the tenant id, so tenant B reads tenant A's\n entry. If true, two requests differing only by tenant return the same body.\"\n\nEvery hypothesis must come with the cheapest observation that would **disprove**\nit. Rank by `likelihood / cost of disproof`, and test the cheapest first.\n\n## The failure catalogue\n\n### It works locally but not in the other environment\n\n- Configuration or secret differs, and the code falls back silently.\n- Version skew: a dependency resolved differently by an unpinned range.\n- Case-sensitive file system on one side, case-insensitive on the other.\n- Timezone or locale of the host changes parsing or formatting.\n- A build step runs in one environment and not the other.\n\n### It worked yesterday\n\n- A dependency floated to a new version; check the lockfile diff first.\n- A clock, an expiry or a certificate crossed a boundary.\n- Data grew past a limit: a page size, a timeout, an index that stopped being used.\n- A feature flag or remote configuration changed outside the repository.\n\n### It fails only sometimes\n\n- Order dependence between tests sharing mutable state.\n- A race between an async write and the read that follows it.\n- Time-of-day, date-boundary or leap-related arithmetic.\n- Retry logic masking a failure until the retry budget is exhausted.\n- Hash or set iteration order treated as stable.\n\n### The error message points at innocent code\n\n- The reported frame is where the bad value was *used*, not where it was made.\n Walk the value backwards to its origin.\n- A wrapper re-threw and lost the cause; find the original throw site.\n- A null or default was substituted upstream by a permissive parser.\n- The stack belongs to a different async context than the failure.\n\n### The fix does not stick\n\n- Two code paths do the same thing and only one was changed.\n- A cached, generated or committed artifact still holds the old value.\n- The test asserts the mock, not the code.\n- The change is correct but never runs: the branch condition is false.\n\n## Reduction techniques\n\n- **Bisect the input.** Halve the failing input until the minimal trigger remains.\n- **Bisect history.** Find the last good commit; the diff bounds the cause.\n- **Bisect the stack.** Assert the value at the midpoint between the origin and\n the symptom; each assertion halves the remaining search space.\n- **Invert.** Instead of asking why it fails, construct the closest case that\n succeeds and diff the two.\n\n## Before calling it a root cause\n\n1. You can state the mechanism in one sentence, cause to symptom.\n2. You can explain why it did not fail earlier, or elsewhere.\n3. A regression test fails before the fix and passes after it.\n4. The fix touches the cause, not the place the symptom was observed.\n\nIf any of the four is missing, you have a correlation. Say so, and escalate\nrather than shipping a fix whose mechanism you cannot state.\n";
12
+ export declare const severityRubricReference = "# Review Severity Rubric and Checklist\n\nOpen this file when classifying a finding, or when a review needs a systematic\npass rather than an impression. The verdict vocabulary is fixed so that\n\"blocking\" means the same thing to every reviewer.\n\n## Severity rubric\n\n| Severity | Definition | Reviewer action |\n| --- | --- | --- |\n| `blocking` | The change is incorrect, unsafe, or fails an approved acceptance criterion. Shipping it causes harm or rework. | Reject. Name the location, the mechanism and the consequence. |\n| `required` | Correct for the approved case, but leaves a defect that will surface under a stated, realistic condition. | Approve only with a named follow-up owner and task. |\n| `advisory` | A real improvement that is out of scope for the approved change. | Report; never block on it. |\n| `note` | Context a future reader will want. No action implied. | Report at most a handful. |\n\nA finding with no consequence is not a finding. If you cannot complete the\nsentence \"if this ships unchanged, then \u2026\", it is at most a note.\n\n## Blocking, by category\n\n- **Correctness.** The code does not do what the criterion says, on the inputs\n the criterion names.\n- **Regression.** An existing behavior covered by a test or a caller changes\n without being part of the approved scope.\n- **Security.** Missing authorization, injected input reaching an interpreter,\n a secret in the diff, a permission widened without justification.\n- **Data.** Irreversible migration without a rollback, a write that can partially\n apply, a unique constraint the code does not honour.\n- **Concurrency.** A read-modify-write without a guard, an await inside a lock, a\n shared mutable default.\n- **Evidence.** The packet reports a check that did not run, or the named\n evidence does not prove the claim it is attached to.\n\n## The checklist\n\nRun in order. Stop at the first section that produces a blocking finding, report\nit, and finish the remaining sections at low cost rather than in depth.\n\n1. **Scope.** Does every changed file appear in the approved ownership? Is any\n hunk unrelated to the objective?\n2. **Criteria.** For each acceptance criterion, name the hunk that satisfies it.\n A criterion with no hunk is blocking.\n3. **Edges.** For each new branch: what happens on empty, null, zero, one,\n duplicate, very large, and concurrent?\n4. **Errors.** Is every failure path either handled or deliberately propagated?\n Is any error swallowed into a default?\n5. **Boundaries.** Did a public type, route, schema, event or column change? Is\n the change additive?\n6. **Tests.** Does a new test fail without the change? Does it assert behavior\n rather than the shape of the implementation?\n7. **Evidence.** Re-run the cheapest reported command. Does it pass, and does it\n cover the change?\n8. **Leftovers.** Debug output, commented code, skipped tests, temporary files,\n unrelated formatting.\n\n## What not to raise\n\n- Preferences the project does not enforce in lint, formatter or existing code.\n- Rewrites of code the diff only moved.\n- Hypothetical scale the project has never stated a requirement for.\n- Duplicate findings: report the pattern once and list the locations.\n\n## Wording a finding\n\n`path:line` \u2014 severity \u2014 what is wrong \u2014 what happens if it ships \u2014 the\nsmallest change that resolves it. Four sentences at most. If a finding needs\nmore, the change needs a conversation, not a comment.\n";
13
+ //# sourceMappingURL=skill-references.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-references.d.ts","sourceRoot":"","sources":["../../src/templates/skill-references.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,2BAA2B,q8GA6DvC,CAAC;AAEF,eAAO,MAAM,uBAAuB,+/GAgEnC,CAAC;AAEF,eAAO,MAAM,2BAA2B,wxGA2EvC,CAAC;AAEF,eAAO,MAAM,uBAAuB,u7GAmEnC,CAAC"}
@@ -0,0 +1,280 @@
1
+ /**
2
+ * Progressive-disclosure reference files for the canonical base skills.
3
+ *
4
+ * A reference costs nothing until a step in its skill actually needs it, so it
5
+ * carries the worked examples, catalogues and rubrics that would otherwise
6
+ * bloat a just-in-time `SKILL.md`. Each file is declared in its skill's
7
+ * `references` frontmatter and generated under the skill's own directory.
8
+ */
9
+ export const riskClassificationReference = `# Risk Classification — Worked Examples
10
+
11
+ Use this file when a brief does not obviously land in one tier, or when someone
12
+ disputes a classification. The tier definitions live in
13
+ \`.ai/protocols/core/orchestration.md\`; this file only shows how they are applied.
14
+
15
+ ## The deciding questions
16
+
17
+ Ask them in order. The first "yes" sets the floor; nothing below it applies.
18
+
19
+ 1. Can this change corrupt, expose or lose data that already exists?
20
+ 2. Does it alter a contract someone outside this repository depends on?
21
+ 3. Does it touch authentication, authorization, secrets, payments or money?
22
+ 4. Does it change concurrency, ordering, retries or idempotency?
23
+ 5. Does it change behavior a user or another service can observe?
24
+ 6. Does it span more than one module, or more than one owner?
25
+
26
+ Questions 1–4 mean high-risk. Question 5 alone means standard. Question 6 alone
27
+ means standard. None of them means trivial.
28
+
29
+ ## Worked examples
30
+
31
+ | Brief | Tier | Why |
32
+ | --- | --- | --- |
33
+ | Fix a typo in a button label | trivial | No behavior, no contract, reversible in one line. |
34
+ | Rename a private helper used in one file | trivial | No external name changes; the compiler proves the rename. |
35
+ | Bump a patch version of a dev-only formatter | trivial | No runtime artifact changes. |
36
+ | Add a nullable, unused column with a default | standard | Schema change, but no reader depends on it yet. |
37
+ | Add a field to an existing API response | standard | Observable behavior; additive, so no consumer breaks. |
38
+ | Extract a component used by three screens | standard | Multi-file, but behavior is meant to be identical. |
39
+ | Change a cache expiry from 60s to 600s | standard | Observable staleness change, bounded blast radius. |
40
+ | Add an index to a large production table | high-risk | Locking and write-path impact during migration. |
41
+ | Change a password hash or token lifetime | high-risk | Authentication surface. |
42
+ | Make a sequential job run in parallel | high-risk | New ordering and idempotency assumptions. |
43
+ | Drop or rename a column still read by code | high-risk | Destructive and irreversible without a backup. |
44
+ | Change the rounding of an invoice total | high-risk | Money, and every historical comparison shifts. |
45
+
46
+ ## Traps that misclassify
47
+
48
+ - **"It is only a config change."** Config that selects a code path is a code
49
+ change with no test coverage. Tier it by what the path does.
50
+ - **"It is only one line."** Size is not risk. A one-line change to a permission
51
+ check is high-risk; a hundred-line change to a test fixture is trivial.
52
+ - **"The tests pass."** Passing tests classify nothing. They tell you what is
53
+ already covered, not what the change can break.
54
+ - **"We will verify it in production."** That is a decision to accept risk, not
55
+ a reason to lower the tier. Record it as an accepted risk in the plan.
56
+ - **"It is a revert."** A revert of a migrated schema is not symmetrical with
57
+ the migration. Tier it on what the revert itself does.
58
+
59
+ ## Escalating a tier mid-task
60
+
61
+ Escalate, record the reason, and re-open approval when any of these appear:
62
+
63
+ - A verified fact contradicts an assumption the plan rested on.
64
+ - The change turns out to need a file the plan did not name.
65
+ - A check fails for a reason no one predicted.
66
+ - The worker asks for authority the packet did not grant.
67
+
68
+ Never lower a tier because the work is taking longer than expected. Lower it
69
+ only when evidence removes the risk that set it, and say which evidence did.
70
+ `;
71
+ export const evidenceLadderReference = `# Evidence Ladder — Worked Examples
72
+
73
+ The rungs and the browser policy are defined in
74
+ \`.ai/protocols/core/verification.md\`. This file shows which evidence actually
75
+ proves which claim, and which evidence only looks like proof.
76
+
77
+ ## Claim to evidence
78
+
79
+ | Claim | Sufficient evidence | Not sufficient |
80
+ | --- | --- | --- |
81
+ | "The label now reads X." | The diff hunk showing the literal, plus a search proving no other copy exists. | "I changed it." |
82
+ | "The function handles null." | A unit test asserting the null path, failing before the change. | Reading the new branch. |
83
+ | "No caller breaks." | A type check, or an exhaustive search of call sites with each one listed. | "It is backwards compatible." |
84
+ | "The bug is fixed." | The original reproduction command, before and after, with output. | The test suite passing. |
85
+ | "Performance improved." | The same measurement command before and after, with both numbers. | A reasoned argument about complexity. |
86
+ | "The migration is safe." | A dry run against a copy of real-shaped data, plus the rollback path. | A review of the SQL. |
87
+ | "Nothing else changed." | The full diff, read hunk by hunk. | The summary of the diff. |
88
+ | "The endpoint returns 403 for anonymous users." | A request-level test asserting the status. | The presence of a guard annotation. |
89
+
90
+ ## Choosing the cheapest sufficient rung
91
+
92
+ Ask: *what observation would change my mind?* Run that, and stop.
93
+
94
+ - A claim about a literal is settled by a search. Running the test suite adds
95
+ minutes and zero information.
96
+ - A claim about a type boundary is settled by the type checker. A runtime test
97
+ adds nothing the compiler did not already prove.
98
+ - A claim about behavior at an integration seam is not settled by a unit test
99
+ with the seam mocked. The mock encodes the assumption under test.
100
+ - A claim about a rendered pixel, a focus order or a real browser event is the
101
+ only case where a headed browser is the cheapest sufficient evidence — and it
102
+ still requires the approval the protocol demands.
103
+
104
+ ## Recording evidence
105
+
106
+ Record, for every check: the exact command, the working directory, the outcome,
107
+ and the reason for any check deliberately not run. Three failure modes to avoid:
108
+
109
+ 1. **Paraphrasing a command.** \`pnpm test\` and \`pnpm test src/foo\` are
110
+ different evidence. Record what ran, not what it resembled.
111
+ 2. **Reporting a check that did not run.** If it was skipped, name it as
112
+ skipped. An honest gap is cheaper than a false claim discovered later.
113
+ 3. **Reporting a pass that was not read.** A green exit code from a command
114
+ that matched zero tests proves nothing. Confirm the check had subjects.
115
+
116
+ ## Worked example — a trivial change
117
+
118
+ Objective: correct a misspelled key in one constant.
119
+
120
+ 1. Diff: one line, one file. **Rung 1.**
121
+ 2. Search for the old spelling across the repository: no other occurrence.
122
+ 3. Stop. No lint, no build, no test suite, no reviewer, no browser.
123
+ 4. Record: "grep -r oldKey → 0 hits; suite not run (unaffected)."
124
+
125
+ ## Worked example — a standard change
126
+
127
+ Objective: an API response gains an optional field.
128
+
129
+ 1. Diff read hunk by hunk. **Rung 1.**
130
+ 2. Type check and the serializer's own unit tests. **Rung 2.**
131
+ 3. One request-level test asserting the field is present and optional.
132
+ 4. Integration suite only if a consumer in this repository parses strictly.
133
+ 5. Independent review because the change crosses a published boundary.
134
+ 6. Record every command, plus "end-to-end suite not run: no UI path changed."
135
+ `;
136
+ export const hypothesisPatternsReference = `# Hypothesis Patterns and Failure Catalogue
137
+
138
+ Open this file when the reproduction is in hand and the hypothesis list is
139
+ short, obvious and wrong. It exists to widen the candidate set before effort is
140
+ spent confirming a favourite.
141
+
142
+ ## Writing a falsifiable hypothesis
143
+
144
+ A usable hypothesis names a mechanism and predicts an observation.
145
+
146
+ - Weak: "something is wrong with the cache."
147
+ - Usable: "the cache key omits the tenant id, so tenant B reads tenant A's
148
+ entry. If true, two requests differing only by tenant return the same body."
149
+
150
+ Every hypothesis must come with the cheapest observation that would **disprove**
151
+ it. Rank by \`likelihood / cost of disproof\`, and test the cheapest first.
152
+
153
+ ## The failure catalogue
154
+
155
+ ### It works locally but not in the other environment
156
+
157
+ - Configuration or secret differs, and the code falls back silently.
158
+ - Version skew: a dependency resolved differently by an unpinned range.
159
+ - Case-sensitive file system on one side, case-insensitive on the other.
160
+ - Timezone or locale of the host changes parsing or formatting.
161
+ - A build step runs in one environment and not the other.
162
+
163
+ ### It worked yesterday
164
+
165
+ - A dependency floated to a new version; check the lockfile diff first.
166
+ - A clock, an expiry or a certificate crossed a boundary.
167
+ - Data grew past a limit: a page size, a timeout, an index that stopped being used.
168
+ - A feature flag or remote configuration changed outside the repository.
169
+
170
+ ### It fails only sometimes
171
+
172
+ - Order dependence between tests sharing mutable state.
173
+ - A race between an async write and the read that follows it.
174
+ - Time-of-day, date-boundary or leap-related arithmetic.
175
+ - Retry logic masking a failure until the retry budget is exhausted.
176
+ - Hash or set iteration order treated as stable.
177
+
178
+ ### The error message points at innocent code
179
+
180
+ - The reported frame is where the bad value was *used*, not where it was made.
181
+ Walk the value backwards to its origin.
182
+ - A wrapper re-threw and lost the cause; find the original throw site.
183
+ - A null or default was substituted upstream by a permissive parser.
184
+ - The stack belongs to a different async context than the failure.
185
+
186
+ ### The fix does not stick
187
+
188
+ - Two code paths do the same thing and only one was changed.
189
+ - A cached, generated or committed artifact still holds the old value.
190
+ - The test asserts the mock, not the code.
191
+ - The change is correct but never runs: the branch condition is false.
192
+
193
+ ## Reduction techniques
194
+
195
+ - **Bisect the input.** Halve the failing input until the minimal trigger remains.
196
+ - **Bisect history.** Find the last good commit; the diff bounds the cause.
197
+ - **Bisect the stack.** Assert the value at the midpoint between the origin and
198
+ the symptom; each assertion halves the remaining search space.
199
+ - **Invert.** Instead of asking why it fails, construct the closest case that
200
+ succeeds and diff the two.
201
+
202
+ ## Before calling it a root cause
203
+
204
+ 1. You can state the mechanism in one sentence, cause to symptom.
205
+ 2. You can explain why it did not fail earlier, or elsewhere.
206
+ 3. A regression test fails before the fix and passes after it.
207
+ 4. The fix touches the cause, not the place the symptom was observed.
208
+
209
+ If any of the four is missing, you have a correlation. Say so, and escalate
210
+ rather than shipping a fix whose mechanism you cannot state.
211
+ `;
212
+ export const severityRubricReference = `# Review Severity Rubric and Checklist
213
+
214
+ Open this file when classifying a finding, or when a review needs a systematic
215
+ pass rather than an impression. The verdict vocabulary is fixed so that
216
+ "blocking" means the same thing to every reviewer.
217
+
218
+ ## Severity rubric
219
+
220
+ | Severity | Definition | Reviewer action |
221
+ | --- | --- | --- |
222
+ | \`blocking\` | The change is incorrect, unsafe, or fails an approved acceptance criterion. Shipping it causes harm or rework. | Reject. Name the location, the mechanism and the consequence. |
223
+ | \`required\` | Correct for the approved case, but leaves a defect that will surface under a stated, realistic condition. | Approve only with a named follow-up owner and task. |
224
+ | \`advisory\` | A real improvement that is out of scope for the approved change. | Report; never block on it. |
225
+ | \`note\` | Context a future reader will want. No action implied. | Report at most a handful. |
226
+
227
+ A finding with no consequence is not a finding. If you cannot complete the
228
+ sentence "if this ships unchanged, then …", it is at most a note.
229
+
230
+ ## Blocking, by category
231
+
232
+ - **Correctness.** The code does not do what the criterion says, on the inputs
233
+ the criterion names.
234
+ - **Regression.** An existing behavior covered by a test or a caller changes
235
+ without being part of the approved scope.
236
+ - **Security.** Missing authorization, injected input reaching an interpreter,
237
+ a secret in the diff, a permission widened without justification.
238
+ - **Data.** Irreversible migration without a rollback, a write that can partially
239
+ apply, a unique constraint the code does not honour.
240
+ - **Concurrency.** A read-modify-write without a guard, an await inside a lock, a
241
+ shared mutable default.
242
+ - **Evidence.** The packet reports a check that did not run, or the named
243
+ evidence does not prove the claim it is attached to.
244
+
245
+ ## The checklist
246
+
247
+ Run in order. Stop at the first section that produces a blocking finding, report
248
+ it, and finish the remaining sections at low cost rather than in depth.
249
+
250
+ 1. **Scope.** Does every changed file appear in the approved ownership? Is any
251
+ hunk unrelated to the objective?
252
+ 2. **Criteria.** For each acceptance criterion, name the hunk that satisfies it.
253
+ A criterion with no hunk is blocking.
254
+ 3. **Edges.** For each new branch: what happens on empty, null, zero, one,
255
+ duplicate, very large, and concurrent?
256
+ 4. **Errors.** Is every failure path either handled or deliberately propagated?
257
+ Is any error swallowed into a default?
258
+ 5. **Boundaries.** Did a public type, route, schema, event or column change? Is
259
+ the change additive?
260
+ 6. **Tests.** Does a new test fail without the change? Does it assert behavior
261
+ rather than the shape of the implementation?
262
+ 7. **Evidence.** Re-run the cheapest reported command. Does it pass, and does it
263
+ cover the change?
264
+ 8. **Leftovers.** Debug output, commented code, skipped tests, temporary files,
265
+ unrelated formatting.
266
+
267
+ ## What not to raise
268
+
269
+ - Preferences the project does not enforce in lint, formatter or existing code.
270
+ - Rewrites of code the diff only moved.
271
+ - Hypothetical scale the project has never stated a requirement for.
272
+ - Duplicate findings: report the pattern once and list the locations.
273
+
274
+ ## Wording a finding
275
+
276
+ \`path:line\` — severity — what is wrong — what happens if it ships — the
277
+ smallest change that resolves it. Four sentences at most. If a finding needs
278
+ more, the change needs a conversation, not a comment.
279
+ `;
280
+ //# sourceMappingURL=skill-references.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-references.js","sourceRoot":"","sources":["../../src/templates/skill-references.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6D1C,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEtC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2E1C,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEtC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"structure-templates.d.ts","sourceRoot":"","sources":["../../src/templates/structure-templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK1D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,cAAc,EAAE,CA0DrF"}
1
+ {"version":3,"file":"structure-templates.d.ts","sourceRoot":"","sources":["../../src/templates/structure-templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAO1D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,cAAc,EAAE,CA2DrF"}