@mrciphersmith/keryx 0.2.70 → 0.2.72

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 (192) hide show
  1. package/dist/cli.js +25237 -17483
  2. package/docs/README.md +54 -0
  3. package/docs/requirements/shared-agent-context/README.md +104 -0
  4. package/package.json +3 -2
  5. package/src/gdskills/bundled/rules/core/code-review-learned-profile.mdc +81 -0
  6. package/src/gdskills/bundled/rules/core/jobs-documentation.mdc +1 -1
  7. package/src/gdskills/bundled/rules/core/model-selection.mdc +184 -31
  8. package/src/gdskills/bundled/rules/core/review-strict-profile.mdc +8 -4
  9. package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +36 -0
  10. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.codex.md +1 -1
  11. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.cursor.md +1 -1
  12. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.md +2 -1
  13. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.opencode.md +1 -1
  14. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.zed.md +1 -1
  15. package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.codex.md +3 -3
  16. package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.cursor.md +3 -3
  17. package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.md +3 -3
  18. package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.opencode.md +3 -3
  19. package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.zed.md +3 -3
  20. package/src/gdskills/bundled/skills/orchestration/context-collector/orchestrator-prompt.md +2 -2
  21. package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.codex.md +4 -4
  22. package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.cursor.md +4 -4
  23. package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.md +4 -4
  24. package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.opencode.md +4 -4
  25. package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.zed.md +4 -4
  26. package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.codex.md +2 -2
  27. package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.cursor.md +2 -2
  28. package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +3 -3
  29. package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +80 -21
  30. package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.codex.md +1 -1
  31. package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.cursor.md +1 -1
  32. package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.md +1 -1
  33. package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.opencode.md +1 -1
  34. package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.zed.md +1 -1
  35. package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.codex.md +2 -2
  36. package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.cursor.md +2 -2
  37. package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.md +3 -2
  38. package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.opencode.md +2 -2
  39. package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.zed.md +2 -2
  40. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.codex.md +997 -509
  41. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.cursor.md +997 -509
  42. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +968 -513
  43. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.opencode.md +997 -509
  44. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.zed.md +997 -509
  45. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/input-contract.schema.json +38 -28
  46. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/orchestrator-prompt.md +98 -66
  47. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/output-contract.schema.json +27 -5
  48. package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.codex.md +20 -2
  49. package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.cursor.md +20 -2
  50. package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +21 -2
  51. package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.opencode.md +20 -2
  52. package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.zed.md +20 -2
  53. package/src/gdskills/bundled/skills/orchestration/task-implementer/input-contract.schema.json +1 -1
  54. package/src/gdskills/bundled/skills/planning/autodoc-analyst/SKILL.md +2 -1
  55. package/src/gdskills/bundled/skills/planning/autodoc-architect/SKILL.md +3 -1
  56. package/src/gdskills/bundled/skills/planning/autodoc-assembler/SKILL.md +2 -1
  57. package/src/gdskills/bundled/skills/planning/autodoc-orchestrator/SKILL.md +2 -1
  58. package/src/gdskills/bundled/skills/planning/autodoc-scanner/SKILL.md +2 -1
  59. package/src/gdskills/bundled/skills/planning/autodoc-writer/SKILL.md +2 -1
  60. package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.codex.md +1 -1
  61. package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.cursor.md +1 -1
  62. package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.md +1 -1
  63. package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.codex.md +1 -1
  64. package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.cursor.md +1 -1
  65. package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.md +2 -1
  66. package/src/gdskills/bundled/skills/planning/docpack-orchestrator/SKILL.md +1 -1
  67. package/src/gdskills/bundled/skills/planning/docpack-review/SKILL.md +1 -1
  68. package/src/gdskills/bundled/skills/planning/interview/SKILL.codex.md +1 -1
  69. package/src/gdskills/bundled/skills/planning/interview/SKILL.cursor.md +1 -1
  70. package/src/gdskills/bundled/skills/planning/interview/SKILL.md +1 -1
  71. package/src/gdskills/bundled/skills/planning/interviewer/SKILL.codex.md +1 -1
  72. package/src/gdskills/bundled/skills/planning/interviewer/SKILL.cursor.md +1 -1
  73. package/src/gdskills/bundled/skills/planning/interviewer/SKILL.md +1 -1
  74. package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.codex.md +1 -1
  75. package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.cursor.md +1 -1
  76. package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.md +2 -1
  77. package/src/gdskills/bundled/skills/planning/planner/SKILL.codex.md +1 -1
  78. package/src/gdskills/bundled/skills/planning/planner/SKILL.cursor.md +1 -1
  79. package/src/gdskills/bundled/skills/planning/planner/SKILL.md +2 -1
  80. package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.codex.md +1 -1
  81. package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.cursor.md +1 -1
  82. package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.md +1 -1
  83. package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.opencode.md +1 -1
  84. package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.zed.md +1 -1
  85. package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.codex.md +1 -1
  86. package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.cursor.md +1 -1
  87. package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.md +2 -1
  88. package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.codex.md +1 -1
  89. package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.cursor.md +1 -1
  90. package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.md +2 -1
  91. package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.codex.md +1 -1
  92. package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.cursor.md +1 -1
  93. package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.md +2 -1
  94. package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.codex.md +1 -1
  95. package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.cursor.md +1 -1
  96. package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.md +2 -1
  97. package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.codex.md +1 -1
  98. package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.cursor.md +1 -1
  99. package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.md +1 -1
  100. package/src/gdskills/bundled/skills/platform/hookify/SKILL.codex.md +1 -1
  101. package/src/gdskills/bundled/skills/platform/hookify/SKILL.cursor.md +1 -1
  102. package/src/gdskills/bundled/skills/platform/hookify/SKILL.md +1 -1
  103. package/src/gdskills/bundled/skills/quality/changelog/SKILL.codex.md +1 -1
  104. package/src/gdskills/bundled/skills/quality/changelog/SKILL.cursor.md +1 -1
  105. package/src/gdskills/bundled/skills/quality/changelog/SKILL.md +1 -1
  106. package/src/gdskills/bundled/skills/quality/commit/SKILL.codex.md +1 -1
  107. package/src/gdskills/bundled/skills/quality/commit/SKILL.cursor.md +1 -1
  108. package/src/gdskills/bundled/skills/quality/commit/SKILL.md +1 -1
  109. package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.codex.md +1 -1
  110. package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.cursor.md +1 -1
  111. package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.md +1 -1
  112. package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.codex.md +1 -1
  113. package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.cursor.md +1 -1
  114. package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.md +1 -1
  115. package/src/gdskills/bundled/skills/quality/deploy/SKILL.codex.md +1 -1
  116. package/src/gdskills/bundled/skills/quality/deploy/SKILL.cursor.md +1 -1
  117. package/src/gdskills/bundled/skills/quality/deploy/SKILL.md +1 -1
  118. package/src/gdskills/bundled/skills/quality/metaproject-security/SKILL.md +1 -1
  119. package/src/gdskills/bundled/skills/quality/perf-check/SKILL.codex.md +1 -1
  120. package/src/gdskills/bundled/skills/quality/perf-check/SKILL.cursor.md +1 -1
  121. package/src/gdskills/bundled/skills/quality/perf-check/SKILL.md +1 -1
  122. package/src/gdskills/bundled/skills/quality/pr/SKILL.codex.md +1 -1
  123. package/src/gdskills/bundled/skills/quality/pr/SKILL.cursor.md +1 -1
  124. package/src/gdskills/bundled/skills/quality/pr/SKILL.md +1 -1
  125. package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.codex.md +1 -1
  126. package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.cursor.md +1 -1
  127. package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.md +1 -1
  128. package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.opencode.md +1 -1
  129. package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.zed.md +1 -1
  130. package/src/gdskills/bundled/skills/quality/push/SKILL.codex.md +1 -1
  131. package/src/gdskills/bundled/skills/quality/push/SKILL.cursor.md +1 -1
  132. package/src/gdskills/bundled/skills/quality/push/SKILL.md +1 -1
  133. package/src/gdskills/bundled/skills/quality/security-audit/SKILL.codex.md +1 -1
  134. package/src/gdskills/bundled/skills/quality/security-audit/SKILL.cursor.md +1 -1
  135. package/src/gdskills/bundled/skills/quality/security-audit/SKILL.md +1 -1
  136. package/src/gdskills/bundled/skills/quality/test-gen/SKILL.codex.md +1 -1
  137. package/src/gdskills/bundled/skills/quality/test-gen/SKILL.cursor.md +1 -1
  138. package/src/gdskills/bundled/skills/quality/test-gen/SKILL.md +1 -1
  139. package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.codex.md +1 -1
  140. package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.cursor.md +1 -1
  141. package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.md +1 -1
  142. package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.opencode.md +1 -1
  143. package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.zed.md +1 -1
  144. package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.codex.md +1 -1
  145. package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.cursor.md +1 -1
  146. package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.md +3 -3
  147. package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.opencode.md +1 -1
  148. package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.zed.md +1 -1
  149. package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.codex.md +252 -0
  150. package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.cursor.md +252 -0
  151. package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.md +243 -0
  152. package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.opencode.md +252 -0
  153. package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.zed.md +252 -0
  154. package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.codex.md +1 -1
  155. package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.cursor.md +1 -1
  156. package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.md +3 -2
  157. package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.opencode.md +1 -1
  158. package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.zed.md +1 -1
  159. package/src/gdskills/bundled/skills/review/code-style-review/SKILL.codex.md +1 -1
  160. package/src/gdskills/bundled/skills/review/code-style-review/SKILL.cursor.md +1 -1
  161. package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +2 -2
  162. package/src/gdskills/bundled/skills/review/code-style-review/SKILL.opencode.md +1 -1
  163. package/src/gdskills/bundled/skills/review/code-style-review/SKILL.zed.md +1 -1
  164. package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +38 -11
  165. package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +49 -15
  166. package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +50 -13
  167. package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +35 -3
  168. package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +34 -3
  169. package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +71 -30
  170. package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +35 -4
  171. package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +50 -16
  172. package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +41 -13
  173. package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +599 -30
  174. package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +7 -0
  175. package/src/gdskills/bundled/skills/review/review-orchestrator/verification-claim.schema.json +78 -0
  176. package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +44 -14
  177. package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +44 -19
  178. package/src/gdskills/bundled/skills/review/review-regression/SKILL.md +185 -0
  179. package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +45 -14
  180. package/src/gdskills/bundled/skills/review/review-style/SKILL.md +27 -7
  181. package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +36 -4
  182. package/src/gdskills/bundled/skills/review/review-verifier/SKILL.md +276 -0
  183. package/src/gdskills/bundled/skills/shared/git-merge-base.md +1 -1
  184. package/src/gdskills/contracts/review-finding.schema.json +119 -1
  185. package/src/gdskills/contracts/subagent-dispatch.schema.json +59 -3
  186. package/src/gdskills/bundled/rules/core/code-review-b091-profile.mdc +0 -48
  187. package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.codex.md +0 -209
  188. package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.cursor.md +0 -209
  189. package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.md +0 -208
  190. package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.opencode.md +0 -209
  191. package/src/gdskills/bundled/skills/review/code-b091-review/SKILL.zed.md +0 -209
  192. package/src/gdskills/bundled/skills/review/review-strict/SKILL.md +0 -328
@@ -44,6 +44,13 @@
44
44
  "id": {
45
45
  "type": "string"
46
46
  },
47
+ "global_id": {
48
+ "title": "The finding's identity, unique across every review package",
49
+ "description": "`id` is per-report and collides across packages; `global_id` (`<reviewId>#<id>`) is the join key. A reviewer MINTS nothing: it emits this only when re-reporting a finding it was handed in `prior_findings`, and then it must be carried verbatim, because a re-minted key breaks the round-to-round join it exists to provide. The `pattern` enforces the shape a carried key must still have: anything else joins to nothing while looking like a key. Kept identical to src/gdskills/contracts/review-finding.schema.json. NOTE the deliberate asymmetry: that schema also declares `disposition` and this one does not, because a reviewer states what is wrong and never states what became of it — the same separation that keeps the pipeline's `classification` out of the finding record.",
50
+ "type": "string",
51
+ "minLength": 1,
52
+ "pattern": "^[^#]+#[^#]+$"
53
+ },
47
54
  "severity": {
48
55
  "type": "string",
49
56
  "enum": [
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "verification-claim",
4
+ "title": "Verifier Result and Verification Claims",
5
+ "description": "What `review-verifier` returns. It lives beside `reviewer-finding.schema.json` for the same reason that one does: the contract belongs to the consumer that merges it, not to the agent that emits it. The defining property of this shape is what it CANNOT express — there is no `severity`, no `problem`, no `suggested_fix`, no way to add a finding. A verifier can only delete, so the wire format it writes on has no field capable of raising anything. `additionalProperties: false` on a claim is therefore load-bearing rather than tidiness: it is where 'can only delete' stops being an instruction. The merge in src/review/verification.ts enforces the same rule again in code, because a schema is not run by every caller.",
6
+ "type": "object",
7
+ "required": ["status", "verifier", "verifications"],
8
+ "properties": {
9
+ "status": {
10
+ "type": "string",
11
+ "enum": ["DONE", "NEEDS_CONTEXT", "BLOCKED"],
12
+ "description": "No DONE_WITH_CONCERNS: a verifier has no concerns of its own to report. It checked what it was given, or it could not."
13
+ },
14
+ "verifier": {
15
+ "type": "string",
16
+ "description": "The reviewer performing verification. Refused when it equals the `reviewer` of a finding it claims: a finding is never verified by the reviewer that raised it (AC9)."
17
+ },
18
+ "summary": { "type": "string" },
19
+ "verifications": {
20
+ "type": "array",
21
+ "description": "One claim per finding checked. A finding that was not checked simply has no claim; absence is not a verdict and never removes anything.",
22
+ "items": {
23
+ "type": "object",
24
+ "additionalProperties": false,
25
+ "required": ["finding", "verdict", "method", "evidence"],
26
+ "properties": {
27
+ "finding": {
28
+ "type": "string",
29
+ "minLength": 1,
30
+ "description": "The `global_id` of the finding being checked (`<reviewId>#<id>`). The display `id` is accepted when it is unambiguous within the round, and refused when it is not — `F-001` denotes six different findings in the recorded corpus."
31
+ },
32
+ "verdict": {
33
+ "type": "string",
34
+ "enum": ["confirmed", "refuted", "unverifiable"],
35
+ "description": "`unverifiable` is the honest answer whenever nothing could be run, and it is expected to be the majority verdict. Only `refuted` removes anything, and only under verification_mode: filter."
36
+ },
37
+ "method": {
38
+ "type": "string",
39
+ "enum": ["execution", "site-check", "reasoning"],
40
+ "description": "How the verdict was reached, strongest first. `execution`: a command or test was run that FAILS IF THE FINDING IS REAL. `site-check`: the class_scope sites were searched for and either exist or do not. `reasoning`: neither was possible."
41
+ },
42
+ "evidence": {
43
+ "type": "string",
44
+ "minLength": 1,
45
+ "description": "The command and its result, or the search and its hits. A verdict with nothing behind it is discarded and the finding stays as reported."
46
+ },
47
+ "verifier": {
48
+ "type": "string",
49
+ "minLength": 1,
50
+ "description": "Per-claim override of the top-level verifier, for a batch produced by more than one agent. Written onto the finding so the never-self-verify rule can be audited after the fact, not only enforced at write time."
51
+ }
52
+ },
53
+ "if": {
54
+ "required": ["method"],
55
+ "properties": { "method": { "const": "reasoning" } }
56
+ },
57
+ "then": {
58
+ "properties": { "verdict": { "const": "unverifiable" } }
59
+ }
60
+ }
61
+ },
62
+ "needs_context": {
63
+ "type": "array",
64
+ "items": { "type": "string" }
65
+ },
66
+ "stats": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "properties": {
70
+ "confirmed": { "type": "integer", "minimum": 0 },
71
+ "refuted": { "type": "integer", "minimum": 0 },
72
+ "unverifiable": { "type": "integer", "minimum": 0 },
73
+ "not_checked": { "type": "integer", "minimum": 0 }
74
+ }
75
+ }
76
+ },
77
+ "additionalProperties": true
78
+ }
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: review-performance
3
+ model_tier: standard
3
4
  description: "Use when a performance review is requested, checking for N+1 queries, unnecessary re-renders, memory leaks, missing indexes, large bundle imports, and synchronous blocking in changed code. NOT for security, logic correctness, style, or architecture."
4
5
  triggers:
5
6
  - "review performance"
@@ -12,8 +13,8 @@ metadata:
12
13
  author: "MrCipherSmith"
13
14
  version: "1.0.0"
14
15
  category: "review"
16
+ compatible_harnesses: "cursor,codex,zed,opencode,claude"
15
17
  license: "MIT"
16
- compatibility: "cursor,codex,zed,opencode,claude"
17
18
  ---
18
19
 
19
20
  # Review: Performance (Code-Level Bottlenecks)
@@ -208,10 +209,32 @@ Detectable from query patterns in changed code (not from DB schema directly):
208
209
 
209
210
  ## Iron Laws
210
211
 
211
- 1. **Only flag real performance issues, not premature optimization.** A pattern "that could be slow" without a concrete hot path or execution frequency is `info` only.
212
- 2. **Every `blocker` or `major` finding MUST cite the specific hot path or frequency that makes it a real problem.** "Runs on every keystroke", "called per list item (N=potentially thousands)", "executes on every render of a high-frequency parent" — be specific.
213
- 3. **"Might be slow" without evidence = INFO only, never blocker.** If you cannot articulate the execution frequency and expected data scale, do not escalate.
214
- 4. **Do not flag patterns outside the diff.** Review only changed code. Legacy issues outside the diff are `info` at most, with a note to track separately.
212
+ ### Shared laws (every reviewer)
213
+
214
+ 1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot
215
+ name the input, call, or condition that reaches the code, you have an
216
+ observation, not a finding. Report it as `info` and say what would settle it.
217
+ 2. **Never flag the theoretical.** The path you describe must exist in the code
218
+ under review. Do not report a safe API because it could be misused, or a
219
+ pattern because it is often wrong elsewhere.
220
+ 3. **One finding per class, not one per occurrence.** When the same shape appears
221
+ at several sites, report it once and list every site. Ten findings that are one
222
+ finding hide the other nine problems.
223
+
224
+ Severity levels are defined once, in `review-orchestrator/SKILL.md` →
225
+ **Severity (canonical)**. This reviewer does not restate them: `blocker` is the
226
+ four merge-blocking shapes named there and nothing else, and the `major`/`minor`
227
+ boundary is the trigger-and-outcome test.
228
+
229
+ ### Performance laws
230
+
231
+ 1. **Every `blocker` or `major` finding MUST cite the specific hot path or
232
+ frequency that makes it a real problem.** "Runs on every keystroke", "called
233
+ per list item (N = potentially thousands)", "executes on every render of a
234
+ high-frequency parent" — be specific. For this reviewer, the execution
235
+ frequency *is* the trigger shared law 1 asks for.
236
+ 2. **Do not flag patterns outside the diff.** Review only changed code. Legacy
237
+ issues outside the diff are `info` at most, with a note to track separately.
215
238
 
216
239
  ---
217
240
 
@@ -292,14 +315,21 @@ STATUS: DONE_WITH_CONCERNS
292
315
  [List categories with no findings, confirming they were checked]
293
316
  ```
294
317
 
295
- ### Severity definitions
318
+ ### Where performance conditions land
296
319
 
297
- | Severity | Meaning |
298
- |----------|---------|
299
- | `blocker` | Demonstrable performance regression on a critical path; will noticeably degrade UX or server capacity under expected load |
300
- | `major` | High-likelihood bottleneck on a frequently executed path; strongly recommended before merge |
301
- | `minor` | Inefficiency worth fixing but not on a hot path; can ship, should be tracked |
302
- | `info` | Pattern worth noting; no clear hot path or measurable impact in current code |
320
+ Severity comes from **Severity (canonical)** in `review-orchestrator/SKILL.md`.
321
+ This reviewer keeps no table of its own; what follows is where its recurring
322
+ conditions land under that rubric, not a second rubric.
323
+
324
+ | Condition | Severity | Why, under the canonical rubric |
325
+ |---|---|---|
326
+ | A cost that takes the process or request down — OOM, timeout, capacity exhausted at a stated load | `blocker` | Crash |
327
+ | Bottleneck on a path you can name, with the frequency or data scale that makes it a cost | `major` | Trigger and outcome are both named; slow is not one of the four shapes |
328
+ | Inefficiency off any hot path you can name | `minor` | Correct today; the cost is to whoever tunes it next |
329
+ | "Looks slow", no execution context | `info` | Shared law 1 — no reproducible path |
330
+
331
+ A performance finding is `blocker` only when the degradation *is* an outage.
332
+ "Noticeably degrades UX" is `major`: real, named, and not merge-blocking.
303
333
 
304
334
  ---
305
335
 
@@ -314,7 +344,7 @@ Stop and re-read these rules if you are thinking:
314
344
  | "Missing useMemo here is a performance issue" | useMemo has overhead; only flag when the computation is measurably expensive or the component re-renders at high frequency |
315
345
  | "I'll add a minor finding for every lodash default import" | Correct — but only flag if the library is large and the import is demonstrably not tree-shaken |
316
346
  | "The dataset could grow large, so I'll call it a blocker" | "Could grow" = minor or info; known to be large = major or blocker |
317
- | "Skipping the hot-path citation to keep the finding concise" | Iron Law 2: hot path is mandatory for blocker/major; omitting it means downgrading to info |
347
+ | "Skipping the hot-path citation to keep the finding concise" | Performance law 1: the hot path is mandatory for blocker/major; omitting it means downgrading to `info` |
318
348
 
319
349
  ---
320
350
 
@@ -338,7 +368,7 @@ If the file does not exist or is not provided, proceed normally — context is o
338
368
 
339
369
  ## Orchestrated Review Contract
340
370
 
341
- When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
371
+ When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
342
372
 
343
373
  ---
344
374
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: review-pr-feedback
3
+ model_tier: light
3
4
  description: |
4
5
  Use when: a developer has received PR review comments and wants to understand them,
5
6
  act on them, or extract patterns from them. Covers "analyze PR comments",
@@ -7,7 +8,6 @@ description: |
7
8
  or dispatched by review-orchestrator when a PR URL is provided.
8
9
  NOT for: reviewing code directly — this skill reads human or bot PR feedback and
9
10
  makes it actionable. To review code, use the domain review skills.
10
- version: "1.0.0"
11
11
  triggers:
12
12
  - "analyze PR comments"
13
13
  - "review PR feedback"
@@ -19,8 +19,8 @@ metadata:
19
19
  author: "MrCipherSmith"
20
20
  version: "1.0.0"
21
21
  category: "review"
22
+ compatible_harnesses: "cursor,codex,zed,opencode,claude"
22
23
  license: "MIT"
23
- compatibility: "cursor,codex,zed,opencode,claude"
24
24
  ---
25
25
 
26
26
  # Review — PR Feedback Analyzer
@@ -41,7 +41,7 @@ review-pr-feedback Progress:
41
41
  - [ ] Step 4: Group comments by author
42
42
  - [ ] Step 5: Classify comment types (blocker intent / suggestion / question / nitpick)
43
43
  - [ ] Step 6: Explain each comment + suggest concrete fix with code example
44
- - [ ] Step 7: Detect senior/boss reviewer comments — offer pattern extraction (with user consent)
44
+ - [ ] Step 7: Comments from configured learning authors — offer a learning proposal (with user consent)
45
45
  - [ ] Step 8: Emit structured report with action items checklist
46
46
  ```
47
47
 
@@ -137,6 +137,12 @@ Organize all comments under each author, distinguishing line-specific from gener
137
137
 
138
138
  For each comment, classify intent before explaining:
139
139
 
140
+ This maps the **intent of an incoming human comment**, which is not a code
141
+ condition. It is not a second severity rubric: the levels themselves are defined
142
+ once, in `review-orchestrator/SKILL.md` → **Severity (canonical)**, and a mapped
143
+ value is a starting point that the canonical test overrides whenever the comment
144
+ names a concrete trigger and outcome.
145
+
140
146
  | Intent class | Description | Default severity mapping |
141
147
  |---|---|---|
142
148
  | `blocker` | Reviewer explicitly blocks or says "must fix", "won't approve until..." | blocker |
@@ -177,20 +183,39 @@ If confidence is Low, state both interpretations and ask the user which one appl
177
183
 
178
184
  ---
179
185
 
180
- ## Step 7: Senior / Boss Reviewer Handling
181
-
182
- **Detection**: if an author is identified as a senior or boss reviewer (by username, or by
183
- review authority markers such as "REQUEST_CHANGES from `boss`"), trigger this flow:
184
-
185
- 1. Notify the user: "This PR has comments from a senior reviewer (`<login>`)."
186
- 2. **NEVER update rules, CLAUDE.md, or any configuration without explicit user consent.**
187
- 3. Ask: "Should I analyze `<login>`'s comments for patterns and suggest updates to review rules?"
188
- 4. If the user agrees:
189
- - Identify recurring patterns in that reviewer's feedback (not one-off edge cases)
190
- - Propose specific additions to `.metaproject/rules/core/code-review-boss-profile.mdc` or the relevant rule file
191
- - Present the proposed changes to the user for approval before writing anything
192
- - After approval, update the rule file and note it in the output
193
- 5. Extract generalizable patterns only — not personal phrasing or one-off opinions
186
+ ## Step 7: Feed the comments back into the project's learned skill
187
+
188
+ **Detection is configuration, not judgement.** Which authors teach this project is
189
+ declared in `.metaproject/review-learning.config.json`, alongside the local skill
190
+ to teach and the repository to read. Do not decide that an author is senior,
191
+ authoritative, or worth learning from — the file decides, and an author it does
192
+ not name contributes nothing.
193
+
194
+ If the file is absent, this project does not learn. Say nothing about it and skip
195
+ this step; absence is a supported state, not a misconfiguration.
196
+
197
+ If the file is present and names at least one author who commented on this PR:
198
+
199
+ 1. Notify the user: "This PR has comments from `<login>`, a configured learning
200
+ source for `<module>/<skill>`."
201
+ 2. **NEVER apply a proposal without explicit user consent.**
202
+ 3. Ask: "Should I turn those comments into a learning proposal for
203
+ `<module>/<skill>`?"
204
+ 4. If the user agrees, run the two commands. The first writes a proposal and
205
+ changes nothing; the second is the only writer:
206
+ ```bash
207
+ keryx review learn --pr <n>
208
+ keryx skills learn apply .metaproject/data/gdskills/proposals/<id>.json
209
+ ```
210
+ 5. Present the proposal's lessons before applying. `learn` reads the record
211
+ `keryx review comments collect` already wrote and never re-fetches, so the
212
+ proposal shows exactly what would be written.
213
+
214
+ **The target is the project skill, never a rule file.** `.metaproject/rules/core/`
215
+ holds shipped templates that `keryx update` overwrites with force, and
216
+ `applyLearningProposal` refuses any target outside
217
+ `.metaproject/project-skills/` — a lesson written anywhere else is lost on the
218
+ next update, or refused outright.
194
219
 
195
220
  ---
196
221
 
@@ -312,7 +337,7 @@ If provided and the file exists, read it before fetching PR comments. If absent,
312
337
 
313
338
  | Rationalization | Why it is wrong |
314
339
  |----------------|-----------------|
315
- | "I'll update the rule file based on the boss's comments without asking" | NEVER auto-update rules; always ask first — rules affect all future reviews |
340
+ | "I'll write these comments into a rule file without asking" | NEVER apply a learning proposal unsupervised, and never target a rule file — `keryx skills learn apply` refuses anything outside `.metaproject/project-skills/` |
316
341
  | "The reviewer's question is just curiosity, not a real concern" | Questions often hide concerns; classify carefully |
317
342
  | "I'll skip the 'praise' comments — they're not actionable" | Positive patterns help developers understand what to repeat |
318
343
  | "Confidence High for an ambiguous comment" | Low confidence is honest; false confidence leads to wrong fixes |
@@ -321,7 +346,7 @@ If provided and the file exists, read it before fetching PR comments. If absent,
321
346
 
322
347
  ## Orchestrated Review Contract
323
348
 
324
- When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
349
+ When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
325
350
 
326
351
  ---
327
352
 
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: review-regression
3
+ model_tier: deep
4
+ description: |
5
+ Use when: reviewing the BLAST RADIUS of a change — the code a change can break,
6
+ as opposed to the change itself. Dispatched by review-orchestrator under scope B
7
+ of a deep round, over the set `keryx review blast-radius` computes.
8
+ NOT for: reviewing the diff (that is scope A and the ordinary reviewers), and
9
+ NOT for style, naming or architecture in code the change did not touch.
10
+ triggers:
11
+ - "review regression"
12
+ - "does this change break anything"
13
+ - "blast radius review"
14
+ - "dispatched by review-orchestrator"
15
+ metadata:
16
+ author: "MrCipherSmith"
17
+ version: "1.0.0"
18
+ category: "review"
19
+ compatible_harnesses: "cursor,codex,zed,opencode,claude"
20
+ license: "MIT"
21
+ ---
22
+
23
+ # Review: Regression
24
+
25
+ You are reviewing **scope B** of a deep round. The files you are given are not
26
+ under review. They are under **regression check**.
27
+
28
+ ## The one question
29
+
30
+ > Does this change break an existing behaviour here?
31
+
32
+ Not "is this code good". Not "would I have written it this way". The blast-radius
33
+ set is code that already worked; your job is to find where the change stops it
34
+ working.
35
+
36
+ This is enforced, not requested. `keryx review ingest` runs
37
+ `screenBlastRadiusFindings` over the findings this scope returns and refuses
38
+ three shapes outright:
39
+
40
+ - `outside-set` — anchored to a file that is in neither the computed set nor the
41
+ changed set. A file-less finding survives this only when its `class_scope.sites`
42
+ name something in the set.
43
+ - `non-regression-severity` — below `major`. A break in existing behaviour names
44
+ a trigger and an outcome; `minor` and `info` state by definition that it does
45
+ not.
46
+ - `no-link-to-change` — nothing in the finding names a changed file, module or
47
+ symbol. A regression claim asserts that THE CHANGE broke this site. **A
48
+ `blocker` is exempt from this rule; a `major` is not.** The rule is a substring
49
+ match over your prose — the only one of the three that can be wrong about a
50
+ true claim — and it may not be the thing that deletes a merge-blocking
51
+ regression. So: when you report a `major` about a **dependent**, name the
52
+ changed file, module or symbol whose behaviour moved. The anchor alone is not
53
+ enough, because every finding the first rule admits is anchored, most of them
54
+ at code the change never touched.
55
+
56
+ The exemption is not a free pass, it is a recorded one. A `blocker` admitted
57
+ without naming the change is listed in `scope.md` under **Admitted without being
58
+ judged**, counted next to `accepted:`, and printed on the terminal — so the
59
+ record never claims that rule 3 passed on a finding rule 3 never read.
60
+
61
+ A refused finding does not reach `findings.json`. It is listed by id in the
62
+ package's `scope.md` under `## Scope B rejections`, with the rule that refused it
63
+ and why, and printed on the terminal by `keryx review ingest` — so a round spent
64
+ on them is a round wasted, visibly, and an observation raised under the wrong
65
+ scope survives to be filed where it belongs. What the completion gate never sees
66
+ is a refused finding, deliberately: it is a claim this round has declined to
67
+ make, and the gate blocking on it is the failure this screen exists to remove.
68
+
69
+ Every rejection RULE judges the CLAIM. None of the three reads the reviewer's
70
+ name: a reviewer whose usual question is "is this code good" can still notice a
71
+ break, and it is accepted on its merits. What the name decides is **membership**
72
+ — which findings the screen judges at all. `review-finding.schema.json` carries
73
+ no `scope` property, so the reviewer name is the only surviving record of which
74
+ question a finding was dispatched under, and `isBlastRadiusScopedFinding` reads
75
+ it to tell scope B's findings from scope A's. Screening scope A by scope B's
76
+ rules would reject every legitimate `minor` on a changed file. The distinction is
77
+ the whole of it: the name selects the jury, never the verdict.
78
+
79
+ If the round has no computed blast-radius record to screen against, the ingest is
80
+ refused rather than recorded unscreened. The orchestrator supplies it with
81
+ `keryx review ingest --blast-radius <file>` — the `--json` output it kept from
82
+ Step 3b.
83
+
84
+ ## What you are given
85
+
86
+ - the diff — what changed;
87
+ - the blast-radius set, each entry with its dependency path back to the change,
88
+ computed from the code graph rather than chosen by a model;
89
+ - the flow's frozen acceptance criteria;
90
+ - the previous round's findings.
91
+
92
+ The set is bounded by edge distance and a file cap, and **everything the cap
93
+ dropped is recorded**. If the record says files were dropped, say so in your
94
+ summary rather than implying the set was complete.
95
+
96
+ ## How to look
97
+
98
+ Start from the dependency path, not from the file. The path tells you *how* the
99
+ change reaches this code, and that is the shape of the break: a changed
100
+ signature reaching a caller, a narrowed return type reaching a consumer, a
101
+ removed branch reaching a case that relied on it, a changed default reaching
102
+ something that never passed the argument.
103
+
104
+ Read the caller before the callee. The break is almost always at the boundary,
105
+ and the boundary is where the caller's assumption meets the change's new
106
+ behaviour.
107
+
108
+ ## `class_scope` names the caller, not the changed line
109
+
110
+ When you report, the site a human has to open is the code that **breaks**, not
111
+ the code that changed. The changed line is already in the diff and already
112
+ reviewed by scope A. Anchor the finding where the damage lands.
113
+
114
+ ## What is not a regression, however true
115
+
116
+ - The code in the blast radius was already imperfect. Not yours.
117
+ - The change makes an existing weakness easier to reach, but the weakness is
118
+ unreachable in this codebase. That is `info` under law 1.
119
+ - A test in the set is thin. Say it under scope A if the change touched it;
120
+ otherwise it is not a regression.
121
+
122
+ ## What you cannot see, and must not pretend to
123
+
124
+ The blast radius is a **code graph**. It does not carry runtime edges: a spawned
125
+ process, a file handoff, a string-keyed registry lookup, a hook. It walks
126
+ dependents only, so a narrowed contract that breaks something the change
127
+ *depends on* is outside your set. And a change to a non-code file — a skill, a
128
+ rule, a schema — has an empty radius, recorded as unresolved rather than clean.
129
+
130
+ If the change is of that shape, say the radius could not answer the question.
131
+ That is a useful result. Silence that reads as "nothing found" is not.
132
+
133
+ ## Class scope — required for `blocker` and `major`
134
+
135
+ Every `blocker` and `major` finding must carry `class_scope`: **every** site that
136
+ holds the shape you found, and **how you enumerated them** — the grep or query
137
+ you ran, or the guard that derives the set.
138
+
139
+ For a regression the sites are the **callers that break**, not the changed line.
140
+ A finding anchored to one caller is a claim that exactly one caller breaks —
141
+ and a change that breaks one consumer of an interface usually breaks its
142
+ siblings. The blast-radius set is already the candidate list: enumerate over it.
143
+
144
+ ```yaml
145
+ class_scope:
146
+ sites: ["src/session/store.ts:133", "src/flow/service.ts:412"]
147
+ enumeration_method: "every entry in the blast radius importing the changed symbol; 6 callers, 2 pass the removed argument"
148
+ ```
149
+
150
+ "I checked the others" is not an enumeration method. A single-entry `sites` list
151
+ is a claim that the class has exactly one member — make it deliberately, because
152
+ `review-finding.schema.json` accepts it and the next round tests it.
153
+
154
+ `minor` and `info` may omit it — though under scope B a finding below `major` is
155
+ rejected anyway, so in practice every finding you report carries one.
156
+
157
+ ```markdown
158
+ ### [F-NNN] Title
159
+
160
+ - **Severity**: blocker | major | minor | info
161
+ - **File**: path/to/file.ts:line
162
+ - **Problem**: what is wrong
163
+ - **Why it matters**: impact (data corruption / crash / silent wrong result / spec gap)
164
+ - **Fix**: concrete suggestion
165
+ ```
166
+
167
+ Severity comes from **Severity (canonical)** in `review-orchestrator/SKILL.md`.
168
+ This reviewer keeps no table of its own.
169
+
170
+ ### Shared laws (every reviewer)
171
+
172
+ 1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot
173
+ name the input, call, or condition that reaches the code, you have an
174
+ observation, not a finding. Report it as `info` and say what would settle it.
175
+ 2. **Never flag the theoretical.** The path you describe must exist in the code
176
+ under review. Do not report a safe API because it could be misused, or a
177
+ pattern because it is often wrong elsewhere.
178
+ 3. **One finding per class, not one per occurrence.** When the same shape appears
179
+ at several sites, report it once and list every site. Ten findings that are one
180
+ finding hide the other nine problems.
181
+
182
+ Severity levels are defined once, in `review-orchestrator/SKILL.md` →
183
+ **Severity (canonical)**. This reviewer does not restate them: `blocker` is the
184
+ four merge-blocking shapes named there and nothing else, and the `major`/`minor`
185
+ boundary is the trigger-and-outcome test.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: review-security-code
3
+ model_tier: standard
3
4
  description: "Use when a code-level security review is requested, checking for injection vulnerabilities, auth gaps, insecure cryptography, secrets, and OWASP Top 10 patterns in changed code. NOT for infrastructure, deployment, or dependency audits."
4
5
  triggers:
5
6
  - "review security"
@@ -12,8 +13,8 @@ metadata:
12
13
  author: "MrCipherSmith"
13
14
  version: "1.0.0"
14
15
  category: "review"
16
+ compatible_harnesses: "cursor,codex,zed,opencode,claude"
15
17
  license: "MIT"
16
- compatibility: "cursor,codex,zed,opencode,claude"
17
18
  ---
18
19
 
19
20
  # Review: Security Code (Code-Level Vulnerabilities)
@@ -211,10 +212,29 @@ Attack vector template: _"Attacker sends `filename=../../etc/passwd`, reading ar
211
212
 
212
213
  ## Iron Laws
213
214
 
214
- 1. **Every security finding MUST state the attack vector explicitly.** Name the attacker action, the entry point, and the impact. No attack vector → no finding above INFO.
215
- 2. **A finding without a reproducible code path is INFO, not blocker.** "Could theoretically..." = INFO. "Attacker sends X to endpoint Y, which executes Z" = blocker/major.
216
- 3. **Never flag theoretical vulnerabilities.** The vulnerable code path must exist in the changed diff. Do not report hypothetical misuse of safe APIs.
217
- 4. **Do not flag the same pattern twice.** If the same class of issue (e.g., missing `@UseGuards`) appears in five files, group them under one finding with all locations listed.
215
+ ### Shared laws (every reviewer)
216
+
217
+ 1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot
218
+ name the input, call, or condition that reaches the code, you have an
219
+ observation, not a finding. Report it as `info` and say what would settle it.
220
+ 2. **Never flag the theoretical.** The path you describe must exist in the code
221
+ under review. Do not report a safe API because it could be misused, or a
222
+ pattern because it is often wrong elsewhere.
223
+ 3. **One finding per class, not one per occurrence.** When the same shape appears
224
+ at several sites, report it once and list every site. Ten findings that are one
225
+ finding hide the other nine problems.
226
+
227
+ Severity levels are defined once, in `review-orchestrator/SKILL.md` →
228
+ **Severity (canonical)**. This reviewer does not restate them: `blocker` is the
229
+ four merge-blocking shapes named there and nothing else, and the `major`/`minor`
230
+ boundary is the trigger-and-outcome test.
231
+
232
+ ### Security-specific law
233
+
234
+ 1. **Every security finding MUST state the attack vector explicitly.** Name the
235
+ attacker action, the entry point, and the impact. No attack vector → no finding
236
+ above `info`. This one does not generalise — a style reviewer has no attacker
237
+ — so it stays here and only here.
218
238
 
219
239
  ---
220
240
 
@@ -295,14 +315,24 @@ STATUS: DONE_WITH_CONCERNS
295
315
  [List categories with no findings, confirming they were checked]
296
316
  ```
297
317
 
298
- ### Severity definitions
318
+ ### Where security conditions land
319
+
320
+ Severity comes from **Severity (canonical)** in `review-orchestrator/SKILL.md`.
321
+ This reviewer keeps no table of its own; what follows is where its recurring
322
+ conditions land under that rubric, not a second rubric.
323
+
324
+ | Condition | Severity | Why, under the canonical rubric |
325
+ |---|---|---|
326
+ | Exploitable vulnerability in the current code path, with the attack vector stated | `blocker` | Named shape 3 |
327
+ | A real weakness whose exploitation needs a precondition the diff does not establish — an internal-only endpoint, an authenticated caller, a value not yet attacker-controlled | `major` | Trigger and outcome are named, but the path to exploitation is not complete |
328
+ | Hardening or defence-in-depth on code that is not currently exploitable | `minor` | The code behaves correctly; the cost is to whoever hardens it later |
329
+ | A pattern with no attack vector in the current code | `info` | Security-specific law, and shared law 1 |
299
330
 
300
- | Severity | Meaning |
301
- |----------|---------|
302
- | `blocker` | Exploitable vulnerability in the current code path; must fix before merge |
303
- | `major` | High-likelihood risk with a plausible attack scenario; strongly recommended before merge |
304
- | `minor` | Hardening improvement or defense-in-depth; can ship but should be tracked |
305
- | `info` | Pattern worth noting; no clear attack vector in current code |
331
+ **"Plausible attack scenario" is not a severity.** A scenario you can state and
332
+ reach is `blocker`; a scenario you can state but cannot reach is `major`; a
333
+ scenario you cannot state is `info`. Being the security reviewer does not raise
334
+ any of them — see the canonical rubric on severity being a property of the
335
+ outcome, not of the domain.
306
336
 
307
337
  ---
308
338
 
@@ -317,7 +347,8 @@ Stop and re-read these rules if you are thinking:
317
347
  | "MD5 is used for caching keys, not passwords — it's fine" | State it as INFO, but do not silently skip it; it often drifts |
318
348
  | "I'll downgrade to minor to avoid friction" | Severity reflects real risk, not social dynamics |
319
349
  | "The code uses an ORM so SQL injection is not possible" | ORMs have raw-query escape hatches; verify parameterization |
320
- | "No attack vector found — I'll call it major anyway" | No attack vector = INFO only, per Iron Law 1 |
350
+ | "No attack vector found — I'll call it major anyway" | No attack vector = `info` only, per the security-specific law |
351
+ | "It's a security finding, so it's a blocker" | `blocker` is the four shapes in **Severity (canonical)**. An unreachable weakness is `major` however alarming its name |
321
352
  | "It's outside the diff but the pattern is clearly wrong" | Only flag changed code; flag legacy via INFO with note to track separately |
322
353
 
323
354
  ---
@@ -342,7 +373,7 @@ If the file does not exist or is not provided, proceed normally — context is o
342
373
 
343
374
  ## Orchestrated Review Contract
344
375
 
345
- When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
376
+ When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
346
377
 
347
378
  ---
348
379