@mrciphersmith/keryx 0.2.73 → 0.2.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +33408 -32955
- package/package.json +1 -1
- package/src/gdskills/bundled/skills/core/reviewer-skill-creator/SKILL.md +214 -0
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +48 -1
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/input-contract.schema.json +70 -4
- package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/consistency-checker/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/patterns-researcher/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/planner/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/planner/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/planner/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/problem-definer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/project-discovery/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/spec-writer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/stack-advisor/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +33 -1
- package/src/gdskills/bundled/skills/review/review-layout/SKILL.md +217 -0
- package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +26 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +304 -2
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +644 -113
- package/src/gdskills/bundled/skills/review/review-pr-feedback/input-contract.schema.json +79 -0
- package/src/gdskills/bundled/skills/review/review-pr-feedback/output-contract.schema.json +375 -0
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +111 -1
- package/src/gdskills/bundled/skills/review/review-verifier/SKILL.md +25 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.74",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer-skill-creator
|
|
3
|
+
model_tier: standard
|
|
4
|
+
description: |
|
|
5
|
+
Use when asked to create a project-local reviewer for review-orchestrator, usually
|
|
6
|
+
from an existing source: a rules file, a review profile, a conventions doc, a
|
|
7
|
+
team's written review standard. Scaffolds the package under
|
|
8
|
+
.metaproject/project-skills/review/<name>/, records where the source came from
|
|
9
|
+
so drift is detectable later, writes the reviewer against the orchestrated review
|
|
10
|
+
contract, and confirms the orchestrator can see it.
|
|
11
|
+
NOT for: editing a bundled reviewer keryx ships (those live in the source tree and
|
|
12
|
+
change through a PR), and NOT for creating an ordinary entity project-skill
|
|
13
|
+
(entity-skill-creator).
|
|
14
|
+
triggers:
|
|
15
|
+
- "create a reviewer"
|
|
16
|
+
- "new reviewer for review-orchestrator"
|
|
17
|
+
- "make a reviewer from this profile"
|
|
18
|
+
- "создай ревьюера"
|
|
19
|
+
- "создай нового ревьюера на основании"
|
|
20
|
+
metadata:
|
|
21
|
+
author: "MrCipherSmith"
|
|
22
|
+
version: "1.0.0"
|
|
23
|
+
category: "core"
|
|
24
|
+
compatible_harnesses: "cursor,codex,zed,opencode,claude"
|
|
25
|
+
license: "MIT"
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Reviewer Skill Creator
|
|
29
|
+
|
|
30
|
+
Turn a written review standard into a reviewer the orchestrator will dispatch.
|
|
31
|
+
|
|
32
|
+
The request usually arrives as one sentence — *"create a reviewer for
|
|
33
|
+
review-orchestrator based on `<path>/rules/core/some-profile.mdc`"* — and it names two
|
|
34
|
+
things: a **destination** (the review lane) and a **source** (a file someone
|
|
35
|
+
else maintains). Both matter, and the second is the one that is usually
|
|
36
|
+
mishandled.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Where it goes, and why there
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
.metaproject/skills/gdskills/review/<name>/ <- reviewers keryx ships
|
|
44
|
+
.metaproject/project-skills/review/<name>/ <- reviewers this project defines
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The parallel is the whole convention. A project reviewer is a project-skill whose
|
|
48
|
+
**module is `review`**; nothing else marks it, and `keryx review reviewers`
|
|
49
|
+
finds it by that alone. Anyone who knows where bundled reviewers live knows where
|
|
50
|
+
these go.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Workflow
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
reviewer-skill-creator Progress:
|
|
58
|
+
- [ ] Step 1: Read the source in full, and say what it is
|
|
59
|
+
- [ ] Step 2: Scaffold the package, recording the source
|
|
60
|
+
- [ ] Step 3: Write the reviewer against the orchestrated contract
|
|
61
|
+
- [ ] Step 4: De-personalise
|
|
62
|
+
- [ ] Step 5: Verify, and confirm the orchestrator sees it
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Step 1 — read the source in full, and say what it is
|
|
66
|
+
|
|
67
|
+
Read the whole file before writing anything. A review profile is usually not
|
|
68
|
+
organised as a reviewer: it is a list of rules, or a transcript of preferences,
|
|
69
|
+
or a checklist mixed with examples from one specific repository.
|
|
70
|
+
|
|
71
|
+
Sort what you find into three piles, out loud, in your reply:
|
|
72
|
+
|
|
73
|
+
- **Method** — a way of establishing something. *Delete the gate and see whether
|
|
74
|
+
the suite stays green. Measure the rendered width. Read the producer at a
|
|
75
|
+
pinned SHA.* This is the valuable pile and it transfers.
|
|
76
|
+
- **Convention** — a rule true of the source's own codebase. *Stores go in
|
|
77
|
+
`src/*/store.ts`.* Keep it only if it is true of THIS project; verify, do not
|
|
78
|
+
assume.
|
|
79
|
+
- **Persona** — one person's voice, catchphrases, verdict vocabulary, and habits
|
|
80
|
+
of address. This pile is dropped whole. See Step 4.
|
|
81
|
+
|
|
82
|
+
If the source is mostly the third pile, say so and stop. A reviewer distilled
|
|
83
|
+
from someone's tone reviews tone.
|
|
84
|
+
|
|
85
|
+
### Step 2 — scaffold the package, recording the source
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
keryx skills create "<short target>" \
|
|
89
|
+
--module review \
|
|
90
|
+
--name <reviewer-name> \
|
|
91
|
+
--note "<one line: what this reviewer is for>" \
|
|
92
|
+
--origin <path to the source file>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Three fields, three different jobs, and mixing them is the recorded failure mode:
|
|
96
|
+
|
|
97
|
+
- `<short target>` is a **routing key** — a path, a symbol, or a short concept.
|
|
98
|
+
`keryx skills route` matches queries against it. Never a sentence.
|
|
99
|
+
- `--note` is the prose. It renders under Purpose and touches nothing that routes.
|
|
100
|
+
- `--origin` is the source file's path, stored verbatim and hashed. This is what
|
|
101
|
+
makes the next question answerable.
|
|
102
|
+
|
|
103
|
+
**Always pass `--origin` when a source file exists.** The source is maintained
|
|
104
|
+
somewhere else and will move on; without the hash, a reviewer built from last
|
|
105
|
+
month's version reads as current forever, and nobody finds out until its findings
|
|
106
|
+
disagree with the standard it claims to encode. With it,
|
|
107
|
+
`keryx review reviewers` reports `drift: changed` the moment the file differs.
|
|
108
|
+
|
|
109
|
+
Quote the path if it starts with `~` and you want it stored that way; an
|
|
110
|
+
unquoted `~` is expanded by the shell before keryx sees it. Either is fine —
|
|
111
|
+
both resolve — but the stored form is what a human reads later.
|
|
112
|
+
|
|
113
|
+
### Step 3 — write the reviewer against the orchestrated contract
|
|
114
|
+
|
|
115
|
+
The scaffold is a generic entity-skill template. Replace its body. A reviewer
|
|
116
|
+
that does not conform is handled by the Sub-Agent Report Quality Gate exactly as
|
|
117
|
+
a bundled one would be — local authorship is not evidence.
|
|
118
|
+
|
|
119
|
+
Required, all of it in `SKILL.md`:
|
|
120
|
+
|
|
121
|
+
- **Scope** — what this reviewer owns, and explicitly what it does not. Name the
|
|
122
|
+
neighbouring reviewers that own the excluded parts. A lane that does not say
|
|
123
|
+
where it stops duplicates three others.
|
|
124
|
+
- **Checklist** — the method pile from Step 1, as checks that can be performed.
|
|
125
|
+
- **Severity** — do **not** write a rubric. Point at
|
|
126
|
+
`review-orchestrator/SKILL.md` → **Severity (canonical)** and add one table
|
|
127
|
+
saying where this reviewer's recurring conditions land under it. Ten private
|
|
128
|
+
rubrics feeding one sort produce a ranking that means ten things at once.
|
|
129
|
+
- **Shared laws** — copy the three verbatim from the orchestrator: no
|
|
130
|
+
unreproducible harm claim above `info`, never flag the theoretical, one finding
|
|
131
|
+
per class.
|
|
132
|
+
- **Class scope** — `blocker` and `major` carry every site holding the shape and
|
|
133
|
+
the enumeration method that found them.
|
|
134
|
+
- **Orchestrated Review Contract** — return `REVIEW_RESULT` per
|
|
135
|
+
`reviewer-finding.schema.json`, with a finding-id prefix of your own.
|
|
136
|
+
|
|
137
|
+
If the source's method needs a command to be worth anything — a mutation, a
|
|
138
|
+
measurement, a probe — say so as an iron law, and say what the finding is worth
|
|
139
|
+
without it. A method nobody runs is a preference.
|
|
140
|
+
|
|
141
|
+
### Step 4 — de-personalise
|
|
142
|
+
|
|
143
|
+
Keep the method. Drop the person.
|
|
144
|
+
|
|
145
|
+
Strip names and handles, catchphrases, verdict vocabulary, forms of address, and
|
|
146
|
+
anything whose meaning depends on knowing the author. A rule that reads as one
|
|
147
|
+
person's taste will be followed as taste; the same rule stated as a procedure
|
|
148
|
+
with a stated reason will be followed as a procedure.
|
|
149
|
+
|
|
150
|
+
This is not politeness, it is transferability, and keryx enforces the same line
|
|
151
|
+
on its shipped tree: `bundled-eval.ts` fails a bundled skill that names the
|
|
152
|
+
reviewer it was learned from or reuses their phrases. Project-skills are not
|
|
153
|
+
scanned by that check — which makes this step your responsibility rather than
|
|
154
|
+
the gate's.
|
|
155
|
+
|
|
156
|
+
For every rule you keep, write the **reason** beside it. A reason survives being
|
|
157
|
+
transplanted into a codebase the author never saw; an assertion does not.
|
|
158
|
+
|
|
159
|
+
### Step 5 — verify, and confirm the orchestrator sees it
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
keryx skills verify review/<reviewer-name>
|
|
163
|
+
keryx review reviewers
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The second is the one that matters: it is the same call
|
|
167
|
+
`review-orchestrator` makes, so its output is proof the reviewer will be
|
|
168
|
+
dispatched rather than a hope. Check the row shows your reviewer with
|
|
169
|
+
`drift: clean`.
|
|
170
|
+
|
|
171
|
+
Then say, in your reply, which of the three piles from Step 1 you kept, which you
|
|
172
|
+
dropped, and what you could not verify against this project.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Iron Laws
|
|
177
|
+
|
|
178
|
+
1. **`--origin` whenever a source file exists.** A reviewer built from a file
|
|
179
|
+
nobody can trace back is a reviewer nobody can update.
|
|
180
|
+
2. **The target is a routing key, the note is the prose.** A sentence in the
|
|
181
|
+
target produces a skill that matches no query and verifies as permanently
|
|
182
|
+
stale. This is a recorded failure, not a hypothetical.
|
|
183
|
+
3. **No private severity rubric.** Point at the canonical one.
|
|
184
|
+
4. **Drop the persona, keep the method, state the reason.**
|
|
185
|
+
5. **Do not claim the reviewer is wired until `keryx review reviewers` shows
|
|
186
|
+
it.** Creating files is not registration, and registration is not discovery.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Refreshing a reviewer whose source moved on
|
|
191
|
+
|
|
192
|
+
`keryx review reviewers` reporting `drift: changed` means the source file differs
|
|
193
|
+
from what was imported. It does **not** mean the reviewer is wrong.
|
|
194
|
+
|
|
195
|
+
Re-read the source, diff it against what the skill encodes, and then decide per
|
|
196
|
+
change: fold it in, or record in the skill why this project deliberately differs.
|
|
197
|
+
Re-run Step 2's command with the same `--name` to re-record the hash once the
|
|
198
|
+
skill matches the source again.
|
|
199
|
+
|
|
200
|
+
A deliberate divergence that is written down is a decision. The same divergence
|
|
201
|
+
undocumented is drift that will be silently "fixed" by whoever refreshes next.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Scope Boundaries
|
|
206
|
+
|
|
207
|
+
| Concern | This skill | Use instead |
|
|
208
|
+
|---|---|---|
|
|
209
|
+
| Create a project-local reviewer | YES | — |
|
|
210
|
+
| Refresh one whose origin drifted | YES | — |
|
|
211
|
+
| Create an entity/module project-skill | NO | `entity-skill-creator` |
|
|
212
|
+
| Change a reviewer keryx ships | NO | edit `src/gdskills/bundled/skills/review/` and open a PR |
|
|
213
|
+
| Update a skill from review findings | NO | `entity-skill-learner`, `keryx skills learn` |
|
|
214
|
+
| Decide which reviewers a round dispatches | NO | `review-orchestrator` |
|
|
@@ -12,7 +12,7 @@ triggers:
|
|
|
12
12
|
- "managed implementation"
|
|
13
13
|
metadata:
|
|
14
14
|
author: "MrCipherSmith"
|
|
15
|
-
version: "1.
|
|
15
|
+
version: "1.4.0"
|
|
16
16
|
category: "orchestration"
|
|
17
17
|
compatible_harnesses: "cursor,codex,zed,opencode,claude"
|
|
18
18
|
license: "MIT"
|
|
@@ -418,12 +418,59 @@ How should this flow end?
|
|
|
418
418
|
Preserve the base branch recorded during initialization. Do not mark the
|
|
419
419
|
flow implemented or complete before the PR is merged into that branch.
|
|
420
420
|
|
|
421
|
+
### A dispatched run answers the question from its input
|
|
422
|
+
|
|
423
|
+
The choice above is the USER's, and a subagent has no user to ask. When this
|
|
424
|
+
skill is dispatched by another skill the answer arrives in the input, and asking
|
|
425
|
+
anyway is how a dispatched run stalls forever on a prompt nobody will read.
|
|
426
|
+
|
|
427
|
+
Read it from the **typed fields**, and validate them first:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
keryx skills contracts validate <dispatch.json> --schema flow-orchestrator-input
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
`base_branch`, `completion_outcome` and `operator_confirmed` are properties of
|
|
434
|
+
that contract, not constraint strings. The distinction is the whole point:
|
|
435
|
+
nothing parses `constraints[]`, so a load-bearing value misspelled there is
|
|
436
|
+
dropped in silence and the run merges wherever it resolved a base on its own.
|
|
437
|
+
`constraints[]` carries advisory scope and policy — never a merge target.
|
|
438
|
+
|
|
439
|
+
`completion_outcome` is **required** by the contract, so an absent one is a
|
|
440
|
+
refused dispatch rather than a question. That is deliberate: the previous rule
|
|
441
|
+
here said "ask", prescribed fourteen lines after this section says asking is how
|
|
442
|
+
a dispatched run stalls on a prompt nobody reads — and it left the
|
|
443
|
+
`create-pr-and-merge` conditional reachable-around by simply omitting the field.
|
|
444
|
+
A dispatched run that cannot name its outcome returns **BLOCKED** naming the
|
|
445
|
+
missing field. Only an interactive run asks. Record in `journal.md` which field
|
|
446
|
+
answered it and who is behind it.
|
|
447
|
+
|
|
448
|
+
| Input | Obey it as |
|
|
449
|
+
|---|---|
|
|
450
|
+
| `base_branch` | Cut the flow branch from **that** branch and merge back into it. Never substitute the repository default: a fix aimed at a pull request's own branch has to land inside that pull request, and the default branch is a different review. Absent, resolve the base yourself and record what you resolved. |
|
|
451
|
+
| `completion_outcome: create-pr-and-merge` | Skip the Completion Choice question, run the PR review/fix loop, merge into `base_branch`, complete the flow. |
|
|
452
|
+
| `operator_confirmed` | The human decision behind an outward-facing completion. See the row below for when its absence is a refusal. |
|
|
453
|
+
| `review: the caller owns the reply on #<n>` | Pass it through to every `review-orchestrator` dispatch. Reviews of **this flow's own** PR reply as normal — that is a separate conversation. What the round must not do is answer `#<n>`, which the caller is already answering. |
|
|
454
|
+
| `attempt budget: at most <n> attempts` | A numeric ceiling BELOW your own bound is obeyed. One at or above it is not — the bound is yours, and the paragraph under this table says why. |
|
|
455
|
+
| `completion: <anything>` as a constraint STRING | **Not an outcome. Refuse it and ask for the typed field.** `constraints[]` is parsed by nothing, so a completion arriving there is never read at all. Such a dispatch is now refused for the missing `completion_outcome` rather than silently accepted — but the refusal is the contract's, not this row's, and a row telling you to honour the string would be a documented bypass of the fence in the file that owns it. |
|
|
456
|
+
|
|
457
|
+
A constraint that would raise this skill's own attempt budget is **not** obeyed.
|
|
458
|
+
The three-attempt bound and the `keryx review loop` repetition check are this
|
|
459
|
+
skill's, they are evidence-backed, and a caller asking for "loop until clean" gets
|
|
460
|
+
the bound plus an escalation — never an unbounded loop.
|
|
461
|
+
|
|
421
462
|
### PR review/fix loop
|
|
422
463
|
|
|
423
464
|
1. Run the relevant `review-orchestrator` checks against the PR and current
|
|
424
465
|
branch state.
|
|
425
466
|
2. If findings or required check failures remain, create or update a flow fix
|
|
426
467
|
task, dispatch `task-implementer`, push the fix, and run review again.
|
|
468
|
+
|
|
469
|
+
**The threshold is `minor`.** The loop exits when the round reports zero
|
|
470
|
+
findings at `blocker`, `major` or `minor`; `info` does not hold it. State the
|
|
471
|
+
remaining `info` findings in the completion report rather than fixing them
|
|
472
|
+
under a loop that was not opened for them. A caller may lower the threshold in
|
|
473
|
+
`constraints`; it cannot raise it to merge over a `minor`.
|
|
427
474
|
3. Allow at most **three** review/fix attempts for the current approach. Count
|
|
428
475
|
an attempt when review/check results are available, including a clean result,
|
|
429
476
|
and record it with `keryx flow task attempt <id> <Tn> --outcome ...` so the
|
package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/input-contract.schema.json
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
"title": "FlowOrchestratorInput",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"additionalProperties": false,
|
|
7
|
-
"required": [
|
|
7
|
+
"required": [
|
|
8
|
+
"request",
|
|
9
|
+
"completion_outcome"
|
|
10
|
+
],
|
|
8
11
|
"properties": {
|
|
9
12
|
"request": {
|
|
10
13
|
"type": "string",
|
|
@@ -21,13 +24,76 @@
|
|
|
21
24
|
},
|
|
22
25
|
"mode": {
|
|
23
26
|
"type": "string",
|
|
24
|
-
"enum": [
|
|
27
|
+
"enum": [
|
|
28
|
+
"init",
|
|
29
|
+
"execute",
|
|
30
|
+
"complete",
|
|
31
|
+
"resume",
|
|
32
|
+
"auto"
|
|
33
|
+
],
|
|
25
34
|
"default": "auto"
|
|
26
35
|
},
|
|
27
36
|
"constraints": {
|
|
28
37
|
"type": "array",
|
|
29
|
-
"items": {
|
|
30
|
-
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"default": [],
|
|
42
|
+
"description": "Advisory scope and policy for this run, one per string. Anything that decides where the work LANDS belongs in a typed property above, not here: nothing parses this array, so a misspelled constraint is silently dropped."
|
|
43
|
+
},
|
|
44
|
+
"base_branch": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"minLength": 1,
|
|
47
|
+
"description": "The branch the flow branch is cut from and merged back into. Typed rather than left to a constraint string because this is the field that decides WHERE the work lands: a fix aimed at a pull request's own head branch that merges to the repository default instead is a change nobody reviewed, reported as success. Absent, the orchestrator resolves the base itself and records it."
|
|
48
|
+
},
|
|
49
|
+
"completion_outcome": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": [
|
|
52
|
+
"create-pr-and-merge",
|
|
53
|
+
"verified-handoff",
|
|
54
|
+
"keep-open"
|
|
55
|
+
],
|
|
56
|
+
"description": "Answers the Phase 4 Completion Choice for a dispatched run, which has no user to ask. REQUIRED: an absent outcome used to mean 'ask', prescribed by the same section that says asking is how a dispatched run stalls on a prompt nobody reads \u2014 and it left the create-pr-and-merge conditional below unreachable by simply omitting the field. A dispatch that cannot name its outcome is BLOCKED, not questioned."
|
|
57
|
+
},
|
|
58
|
+
"operator_confirmed": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": false,
|
|
61
|
+
"required": [
|
|
62
|
+
"confirmed_by",
|
|
63
|
+
"confirmed_at",
|
|
64
|
+
"plan_digest"
|
|
65
|
+
],
|
|
66
|
+
"description": "The human decision behind an outward-facing completion. Required by callers whose work merges third-party content \u2014 see review-pr-feedback --fix. What `plan_digest` is worth is stated on the field itself; do not infer a replay defence from its presence here.",
|
|
67
|
+
"properties": {
|
|
68
|
+
"confirmed_by": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"minLength": 1
|
|
71
|
+
},
|
|
72
|
+
"confirmed_at": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"minLength": 1
|
|
75
|
+
},
|
|
76
|
+
"plan_digest": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"minLength": 1,
|
|
79
|
+
"description": "A record of WHICH plan the human said they read \u2014 not a control. Nothing in this tree computes or verifies a digest, and the schema constrains it only to a non-empty string, so an agent composing the dispatch chooses the value and a plan mutated after approval carries the same one. `operator_confirmed`'s PRESENCE is enforced; this field's VALUE is not. Making it a control means hashing the rendered plan and having the receiver recompute over what it got."
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"if": {
|
|
85
|
+
"required": [
|
|
86
|
+
"completion_outcome"
|
|
87
|
+
],
|
|
88
|
+
"properties": {
|
|
89
|
+
"completion_outcome": {
|
|
90
|
+
"const": "create-pr-and-merge"
|
|
91
|
+
}
|
|
31
92
|
}
|
|
93
|
+
},
|
|
94
|
+
"then": {
|
|
95
|
+
"required": [
|
|
96
|
+
"operator_confirmed"
|
|
97
|
+
]
|
|
32
98
|
}
|
|
33
99
|
}
|
|
@@ -211,9 +211,41 @@ Flags:
|
|
|
211
211
|
|
|
212
212
|
Flags:
|
|
213
213
|
- Redundant comment restating the code — **minor**
|
|
214
|
-
- Stale comment contradicting the code — **
|
|
214
|
+
- Stale comment contradicting the code — **minor** (misleads the next reader; it
|
|
215
|
+
names no runtime trigger, so the canonical rubric puts it here. It was
|
|
216
|
+
**major** in this file until that was reconciled against
|
|
217
|
+
`review-orchestrator/SKILL.md` → **Severity (canonical)**, which reviewers may
|
|
218
|
+
not override. If the comment's inaccuracy *causes* a defect — someone relied on
|
|
219
|
+
it and the code does otherwise — that defect is the finding, at its own severity)
|
|
215
220
|
- Commented-out code block — **minor** (use git history, not comments, to preserve old code)
|
|
216
221
|
|
|
222
|
+
#### C1a. Documentation drift — the shapes worth searching for
|
|
223
|
+
|
|
224
|
+
Stale comments are not found by reading comments; they are found by reading each
|
|
225
|
+
comment **against the statement it sits above**. Three shapes recur, and they are
|
|
226
|
+
the cheapest real findings in a multi-round review:
|
|
227
|
+
|
|
228
|
+
- **A doc describing the rule a later round replaced.** A prop's JSDoc says the
|
|
229
|
+
tooltip drops the split "unless both are known"; the live rule is that both must
|
|
230
|
+
be greater than zero. The behaviour changed, the sentence did not. Check every
|
|
231
|
+
doc comment on every symbol the diff touched, not only the ones the diff edited.
|
|
232
|
+
- **A comment detached from its statement.** A `const` gets inserted between a
|
|
233
|
+
comment and the expression it explained, so the comment now reads as an
|
|
234
|
+
explanation of the insertion. The text is unchanged and is now wrong. Look for
|
|
235
|
+
this wherever the diff adds a line inside an existing block.
|
|
236
|
+
- **Two files documenting one field oppositely.** One says a cell is the valid
|
|
237
|
+
percentage, another computes `100 - cell` and calls it the invalid percentage.
|
|
238
|
+
Only one is right, and the diff just made the field load-bearing.
|
|
239
|
+
|
|
240
|
+
Where an issue or PR is cited, check that it is the right one and still says what
|
|
241
|
+
the comment claims — a closed *issue* cited in place of the *PR* that shipped the
|
|
242
|
+
work sends the next reader to the wrong page.
|
|
243
|
+
|
|
244
|
+
A comment that describes a behaviour with **no code path at all** — including one
|
|
245
|
+
left behind by a review finding that was later withdrawn — is the same class: it
|
|
246
|
+
should state the defensiveness it actually provides, not assert a path that does
|
|
247
|
+
not exist.
|
|
248
|
+
|
|
217
249
|
#### C2. Comments That Compensate for Bad Names
|
|
218
250
|
|
|
219
251
|
A comment whose entire purpose is to explain a poorly-named identifier is a sign to improve the name, not add a comment.
|