@openora/create 0.4.1-canary.186 → 0.4.1-canary.187
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/.tsbuildinfo +1 -1
- package/dist/generated/core-version.d.ts +1 -1
- package/dist/generated/core-version.js +1 -1
- package/package.json +2 -2
- package/template/README.md.tpl +1 -1
- package/template/__dot__gitignore +2 -0
- package/template/__dot__rulesync/hooks/guard-subagent.mjs +4 -0
- package/template/__dot__rulesync/rules/conventions.md +5 -1
- package/template/__dot__rulesync/rules/oss-boundaries.md.tpl +4 -1
- package/template/__dot__rulesync/rules/overview.md +3 -2
- package/template/__dot__rulesync/skills/create-plugin/SKILL.md.tpl +1 -1
- package/template/__dot__rulesync/skills/review/SKILL.md.tpl +84 -30
- package/template/__dot__rulesync/subagents/compliance-reviewer.md +78 -0
- package/template/__dot__rulesync/subagents/quality-reviewer.md.tpl +37 -8
- package/template/__dot__rulesync/subagents/security-reviewer.md.tpl +21 -7
- package/template/__dot__rulesync/sync.json.tpl +5 -0
- package/template/docs/agents/forge.md.tpl +2 -0
- package/template/package.json.tpl +1 -0
- package/template/tools/review-precheck.mjs +479 -0
- package/template/tools/sync-agents.mjs +1 -0
|
@@ -12,30 +12,52 @@ Checklist - tick as you go:
|
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
- [ ] 1. Parse args (--agents / --base / MR# / paths / --fix / --post / --yes / --ci)
|
|
15
|
-
- [ ] 2.
|
|
15
|
+
- [ ] 2. Run the precheck: scope, mechanical facts, domain hits; if empty, ask (or APPROVED under --ci)
|
|
16
|
+
- [ ] 2a. Previous review? Go incremental from its SHA and carry its findings
|
|
16
17
|
- [ ] 3. Collect task context (ticket AC + MR discussion)
|
|
17
18
|
- [ ] 3a. Paired OSS change? Review the OSS diff by the OSS rules + cross-check the contract (§2c)
|
|
18
19
|
- [ ] 3c. Trace each changed entry point end to end + check the blast radius
|
|
19
|
-
- [ ] 4.
|
|
20
|
+
- [ ] 4. Cover all seven dimensions; small diff -> review inline, else spawn the fixed roster in ONE message
|
|
20
21
|
- [ ] 5. Dedup + apply the evidence gate
|
|
21
|
-
- [ ] 6. Report one verdict (+ apply fixes only if --fix)
|
|
22
|
+
- [ ] 6. Report one DIMENSION line per dimension + one verdict (+ apply fixes only if --fix)
|
|
22
23
|
- [ ] 7. Post to the MR as inline comments + summary (only if --post)
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
## 1. Parse `$ARGUMENTS`
|
|
26
27
|
|
|
27
|
-
- `--agents N` - parallel reviewers (
|
|
28
|
+
- `--agents N` - parallel reviewers (4-5); default 4 (§5).
|
|
28
29
|
- `--base <ref>` - diff base; default `{{mrTarget}}`.
|
|
30
|
+
- `--full` - ignore the previous review (§2a) and review the whole change.
|
|
29
31
|
- `<number>` - a pull request: read its patch and intent with the commands in `docs/agents/forge.md`.
|
|
30
32
|
- paths - restrict review to those files/dirs.
|
|
31
33
|
- `--fix` - apply BLOCK/WARN fixes after the review; default report-only.
|
|
32
34
|
- `--post` - publish findings to the pull request as inline diff-line comments + a one-line summary verdict (§8). Requires a pull-request number. Draft-and-confirm by default.
|
|
33
35
|
- `--yes` - with `--post`, skip the confirmation and publish straight away.
|
|
34
|
-
- `--ci` - non-interactive: never ask, never post, never fix; print only the §7 machine block. The model cannot set the process exit code; the CI job derives it from the
|
|
36
|
+
- `--ci` - non-interactive: never ask, never post, never fix; print only the §7 machine block. Implies `--full`: a gate never trusts a prior-review marker, since anyone who can comment on the pull request can post one for the current head. The model cannot set the process exit code; the CI job derives it from the output, e.g. `claude -p '/review --ci' > review.txt; [ "$(grep -c '^DIMENSION: ' review.txt)" -eq 7 ] && grep -q '^VERDICT: APPROVED' review.txt` - a review that skipped a dimension fails the job even when it approves. An empty diff is APPROVED with zero findings.
|
|
35
37
|
|
|
36
38
|
## 2. Scope the diff
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
**Reviewing a pull request by number:** reviewers need files to open, and the working tree is not theirs to switch. Fetch the source branch and add a detached worktree: `git fetch origin <src-branch> && git worktree add --detach .claude/worktrees/review-<n> FETCH_HEAD`. Pass the worktree path to every reviewer and remove it with `git worktree remove` after §7.
|
|
41
|
+
|
|
42
|
+
**Run the precheck before anything else reads code.** From the directory under review (the review worktree, or the working tree), run the main checkout's script - it is rendered and gitignored, so a worktree lacks it: `node <main-checkout>/tools/review-precheck.mjs --base origin/<base>` (add `--since <sha>` from §2a). It costs no tokens beyond its output and replaces what reviewers used to derive by reading:
|
|
43
|
+
|
|
44
|
+
- `SCOPE:` - mode (`full` / `incremental`) and the reviewable changed-line count that picks the path in §4.
|
|
45
|
+
- `REVIEWABLE:` - the only file list reviewers get. Group these by app/package so reviewers and any file split share one map.
|
|
46
|
+
- `SKIPPED:` - lockfiles, locale data, tests, generated files. No reviewer opens them; the precheck's i18n facts and CI's frozen-lockfile install stand in. List them in the report so nothing is silently dropped.
|
|
47
|
+
- `PRECHECK:` - mechanical hits on added lines (casts, widened maps, hardcoded limits, hand memo, banned classes, locale parity, missing keys). Reviewers judge these; they never re-derive them.
|
|
48
|
+
- `DOMAIN:` / `DOMAIN-HIT:` - security and compliance keyword hits; they pick each reviewer's mode in §5.
|
|
49
|
+
|
|
50
|
+
No `REVIEWABLE:` and no `SKIPPED:` lines: fall back to `git status -s`; if still empty, ask (under `--ci`: APPROVED, zero findings).
|
|
51
|
+
|
|
52
|
+
**Rule docs live in the main checkout, not the review worktree.** `.claude/rules/`, `.rulesync/rules/`, `docs/standards/`, and `docs/agents/` are rendered by `pnpm sync:agents` + `pnpm gen:agents` and gitignored, so a fresh worktree has none of them. Pass reviewers the absolute main-checkout path for every rule doc. When the render has not run (a CI job that skips `prepare`), run `pnpm sync:agents && pnpm gen:agents` before reviewing.
|
|
53
|
+
|
|
54
|
+
## 2a. Previous review - review only what changed since
|
|
55
|
+
|
|
56
|
+
A pull request is reviewed round after round; re-reading the whole change each round is the biggest waste. Unless `--full` or `--ci`:
|
|
57
|
+
|
|
58
|
+
1. Read `.claude/reviews/<pr>.json` in the main checkout (`{ "sha", "base", "verdict", "findings": [...], "dimensions": [...] }`; no PR number: key it by branch name). Absent and a PR number given: find the latest note carrying `<!-- review:sha=<sha> -->` per `docs/agents/forge.md` and take its SHA; its findings are the inline threads still unresolved.
|
|
59
|
+
2. Found: run the precheck with `--since <sha>`. `mode incremental` narrows `REVIEWABLE:`, its line counts, `PRECHECK:`, and `DOMAIN-HIT:` to what changed since that review (base-branch merges excluded). A `NOTE: --since ... not an ancestor` (force push, rebase) means a full review - say so.
|
|
60
|
+
3. Split the prior findings: those on a file in the new `REVIEWABLE:` set go to the owning reviewer to re-verify; the rest carry over unchanged.
|
|
39
61
|
|
|
40
62
|
## 2b. Collect task context (mandatory - this is the spec axis)
|
|
41
63
|
|
|
@@ -43,7 +65,8 @@ Distill everything here into ONE context block of at most ~40 lines; it is the o
|
|
|
43
65
|
|
|
44
66
|
- **Ticket - read it whole, per `docs/agents/issue-tracker.md`.** Resolve the `{{trackerKey}}-n` key from the MR description (`Closes {{trackerKey}}-n`), MR title, branch, or commit subjects. Read: description + AC, every comment, every attached image viewed as pixels, parent epic, linked issues, and every wiki page the ticket links (their images and comments too). Use a reader that returns image bytes (for Jira + Confluence: the `atlassian-read` skill - `read.py issue {{trackerKey}}-n`, then `page <id>` per linked page - or REST); the Atlassian MCP returns none, so it is never enough on its own. A chat thread is optional: read it (via `slack-reader` when available) only when the ticket or MR points at one ("shared in chat", a Slack link) and the AC depend on it.
|
|
45
67
|
- **Distill:** goal in one line; AC quoted verbatim as bullets (a `CRITERION:` line needs the exact bullet); decisions and open questions from comments (who, when); design references (which screenshot shows what); out-of-scope lines.
|
|
46
|
-
- **Pull-request discussion.** If reviewing one: read its
|
|
68
|
+
- **Pull-request discussion.** If reviewing one: read its description and every thread, resolved ones included, per `docs/agents/forge.md`. Distill to stated intent, open reviewer asks, and the decisions resolved threads settled (quote who asked for what and what was agreed), so the review doesn't repeat or contradict them. No pull request: use branch commit subjects as intent.
|
|
69
|
+
- **Reviewers have no forge access.** You own the description checks: the manual-verification evidence and the "Tests to add" list (§3c). Report them yourself; never hand them to a reviewer.
|
|
47
70
|
- **No key** -> write `no ticket` in the report and judge against the MR description only. **Fetch failed** -> write `no access`. Never skip silently, never invent AC.
|
|
48
71
|
- A UI change whose ticket carries design screenshots is judged against them: compare the rendered UI (`playwright-cli` screenshot when the stack is up) with the reference; when you cannot, the CRITERION is `not verifiable`, never `met`.
|
|
49
72
|
- The MR description is the author's claim, not the spec. Where it contradicts the ticket or the diff, that contradiction is a finding.
|
|
@@ -61,7 +84,7 @@ No match: write `no paired OSS change` in the report and move on.
|
|
|
61
84
|
|
|
62
85
|
**Read the OSS code without touching the main checkout.** Case 1: `pnpm oss:worktree <branch>` (idempotent) and read from that worktree. Case 2: `git -C {{ossDir}} show <sha>:<path>`. Never `git checkout` in `{{ossDir}}` - other sessions build against it.
|
|
63
86
|
|
|
64
|
-
**Review the OSS diff by the OSS rules.** Read `<worktree>/docs/standards/skills/review.md` and every `<worktree>/.rulesync/rules/*.md`. Run their request trace and dimensions on `git -C <worktree> diff origin/dev...HEAD`. OSS files join §4 as their own file group, handed to `quality-reviewer` (plus `security-reviewer` for money, wallet,
|
|
87
|
+
**Review the OSS diff by the OSS rules.** Read `<worktree>/docs/standards/skills/review.md` and every `<worktree>/.rulesync/rules/*.md`. Run their request trace and dimensions on `git -C <worktree> diff origin/dev...HEAD`. OSS files join §4 as their own file group, handed to `quality-reviewer` (plus `security-reviewer` for auth paths and `compliance-reviewer` for money, wallet, KYC, or RG paths) with the worktree path. Their findings are prefixed `[oss]`, cite the OSS rule or ADR, and pass the same evidence gate (§6).
|
|
65
88
|
|
|
66
89
|
**Cross-check the contract** - what neither repo's review sees alone:
|
|
67
90
|
|
|
@@ -77,13 +100,11 @@ Report `[oss]` findings and one `TRACE:` line per OSS entry point alongside the
|
|
|
77
100
|
|
|
78
101
|
## 3. Ground every reviewer (mandatory)
|
|
79
102
|
|
|
80
|
-
Each reviewer MUST read the changed code AND the rule docs owning its dimension before judging - never infer behavior from a diff hunk; if a finding depends on a called function, open it.
|
|
103
|
+
Each reviewer MUST read the changed code AND the rule docs owning its dimension before judging - never infer behavior from a diff hunk; if a finding depends on a called function, open it. Each agent file carries a reading map: the few docs its focus needs, not every rule. Pass the main-checkout paths; the reviewer reads only its map, and a `docs/standards/` deep dive only for the row a finding depends on.
|
|
81
104
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- `.claude/rules/db-conventions.md` + `docs/standards/database.md` - SQL/Drizzle rules for overlay tables.
|
|
86
|
-
- `.claude/rules/overview.md` (and `.claude/rules/workflow.md` when this repo ships one) - how this repo operates.
|
|
105
|
+
You read `CLAUDE.md` / `AGENTS.md` (the rendered `overview` rule) and `.claude/rules/workflow.md` once, for §2b and the `rollout` and `spec` dimensions. Reviewers get the distilled context block, never those files.
|
|
106
|
+
|
|
107
|
+
No rule doc covers performance, scalability, or most security concerns. There a finding cites the named, established principle it breaks instead (N+1, unbounded list, silent truncation, authz enforced only client-side, unvalidated URL rendered to players) - §6 accepts that citation.
|
|
87
108
|
|
|
88
109
|
## 3b. Stance - assume the change is broken
|
|
89
110
|
|
|
@@ -98,6 +119,8 @@ Review to falsify, not to confirm. Every reviewer (and you, on the fast path) st
|
|
|
98
119
|
|
|
99
120
|
Applies to every change that crosses a layer: an oRPC route, a service, a Drizzle query, a table, an event, or a job. Skip only for a change inside one pure function, a test, a doc, or a type. Money, wallet, payment, auth/session, KYC, and RG paths always get a trace.
|
|
100
121
|
|
|
122
|
+
**UI-only diff** (no route, service, query, table, event, or job changed in this repo): trace each changed data hook to the platform route it calls - hops 1, 2, and 7 only (input schema, guard, response fields) - and say so in the `TRACE:` line. The full walk is for layers this repo owns.
|
|
123
|
+
|
|
101
124
|
**Walk the hops.** For each changed route or entry point, list the hops in order and open the code at each one - the diff hunk is never enough:
|
|
102
125
|
|
|
103
126
|
1. Contract - the input schema is the only input; every field the handler reads is declared and validated.
|
|
@@ -124,38 +147,66 @@ Applies to every change that crosses a layer: an oRPC route, a service, a Drizzl
|
|
|
124
147
|
|
|
125
148
|
**Report the trace.** One `TRACE:` line per entry point (format in §7). A missing hop, an unfiltered query, a write outside the transaction, or a caller that no longer holds is a `[BLOCK]`. A hop that could not be traced is a finding, not a silent pass.
|
|
126
149
|
|
|
127
|
-
## 4. Dimensions
|
|
150
|
+
## 4. Dimensions - all seven, every review
|
|
128
151
|
|
|
129
|
-
|
|
152
|
+
Every review covers every dimension below, whatever the diff touches. Relevance is decided by looking, not by guessing from file names: a dimension that does not apply still runs its search and reports `n/a` with what it checked. Owners - never `general-purpose`:
|
|
130
153
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
| Dimension | Owner | Covers |
|
|
155
|
+
| ------------- | ----------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
156
|
+
| `conventions` | `quality-reviewer` (focus `conventions`) | correctness, boundaries, conventions, UI quality (i18n, a11y, states), dependencies |
|
|
157
|
+
| `performance` | `quality-reviewer` (focus `performance`) | performance and scalability at production scale |
|
|
158
|
+
| `reliability` | `quality-reviewer` (focus `performance`) | races, double submit, retries, partial failure, cache invalidation, error handling |
|
|
159
|
+
| `security` | `security-reviewer` | authz, secrets and PII, input validation, URLs |
|
|
160
|
+
| `compliance` | `compliance-reviewer` | responsible gambling, KYC/age/geo gates, ledger and money paths, audit trail |
|
|
161
|
+
| `rollout` | orchestrator | §3c migrations, destructive seeds, event and payload compatibility, new env/config |
|
|
162
|
+
| `spec` | orchestrator | AC (§2b), ticket scope, manual-verification evidence and "Tests to add" (§3c) |
|
|
134
163
|
|
|
135
|
-
|
|
164
|
+
`expert` is not a reviewer; ask it only when an AC is ambiguous enough to block a `CRITERION:` line.
|
|
165
|
+
|
|
166
|
+
**Small-diff fast path (<= 150 reviewable changed lines per `SCOPE:`): no subagents, same seven dimensions.** Read `.claude/agents/quality-reviewer.md`, `security-reviewer.md`, and `compliance-reviewer.md` IN FULL, then work each checklist yourself under the §3b stance. The fast path changes who reviews, never what is covered.
|
|
136
167
|
|
|
137
168
|
## 5. Allocate to `--agents N` (large diffs only)
|
|
138
169
|
|
|
139
|
-
- N unset:
|
|
140
|
-
- N
|
|
141
|
-
- N <
|
|
170
|
+
- N unset or 4: `quality-reviewer` (focus `conventions`), `quality-reviewer` (focus `performance`), `security-reviewer`, `compliance-reviewer`.
|
|
171
|
+
- N = 5: the fifth is another `quality-reviewer` (focus `conventions`), the file groups split between the two (state the split; never silently drop files).
|
|
172
|
+
- N < 4: refuse the reduction - run the four and say so in the report. Merging dimensions into fewer reviewers is how they get skipped.
|
|
173
|
+
|
|
174
|
+
**Mode per reviewer, from the precheck.** `security-reviewer` with `DOMAIN: security hits 0`, and `compliance-reviewer` with `DOMAIN: compliance hits 0`, run in `confirm` mode: 5 tool calls to confirm no sensitive path is touched, returning `n/a` - or `escalate` with the file that is. On `escalate`, spawn that reviewer again in `full` mode. With hits, `full` mode, the `DOMAIN-HIT:` lines as starting points.
|
|
175
|
+
|
|
176
|
+
**Tool-call budget per reviewer** (the reviewer stops and reports `partial` when it runs out): `conventions` 30, `performance` 25, `security` 20, `compliance` 20, `confirm` mode 5. Budgets scale with the change: double them when `REVIEWABLE:` changed lines exceed 3000.
|
|
177
|
+
|
|
178
|
+
**Model per reviewer:** each agent file's `model` by default. A per-focus override (the Agent tool's `model` parameter) is set here only after a benchmark shows the cheaper model keeps every finding of the default on the same change - none is set yet.
|
|
142
179
|
|
|
143
|
-
Spawn all reviewers in a SINGLE message (parallel). Pass each
|
|
180
|
+
Spawn all reviewers in a SINGLE message (parallel). Pass each, and nothing more:
|
|
181
|
+
|
|
182
|
+
- its focus, mode, budget, and the `DIMENSION:` names it owns (§4);
|
|
183
|
+
- its `REVIEWABLE:` lines, copied verbatim from the precheck (pre-grouped - reviewers never re-scope; never hand-typed paths or globs);
|
|
184
|
+
- the `PRECHECK:` lines for its dimension (conventions: casts, hand memo, banned classes, i18n; performance: hardcoded limits) or its `DOMAIN-HIT:` lines;
|
|
185
|
+
- the prior findings on its files to re-verify (§2a);
|
|
186
|
+
- the review worktree path, the main-checkout path for its reading map, the base ref, the §2b context block, the §3b stance verbatim, and the §3c trace for its file group;
|
|
187
|
+
- hard caps: never open a `SKIPPED:` file; read changed files + only the callees a finding depends on; batch reads (several files in one shell call); max 10 findings; compact `[SEV] file:line - finding - evidence - fix` lines, no prose; do NOT run `/check`/tests.
|
|
144
188
|
|
|
145
189
|
## 6. Evidence gate (cut false positives)
|
|
146
190
|
|
|
147
191
|
Every reviewer applies this before returning; re-apply it yourself when synthesizing:
|
|
148
192
|
|
|
149
|
-
- Every `[BLOCK]`/`[WARN]` cites a concrete `file:line` AND the rule doc violated -
|
|
193
|
+
- Every `[BLOCK]`/`[WARN]` cites a concrete `file:line` AND the rule doc violated, or - where no rule doc covers it (§3) - the named principle plus the traced trigger. Otherwise downgrade to `[INFO]` or drop.
|
|
150
194
|
- High-confidence findings only; unsure = downgrade or omit. Few actionable findings beat flooding.
|
|
151
195
|
- No invented runtime failures - state the trigger path or don't raise it.
|
|
152
196
|
- Don't duplicate what tooling enforces (oxlint, the `/check` gate); for a suspected lint/boundary issue say "confirm with `pnpm check:lint`" - flag only what the gates miss.
|
|
197
|
+
- A `PRECHECK:` line a reviewer confirmed is evidence for its finding. One no reviewer addressed goes into the report as `[INFO] ... (precheck, unconfirmed)` - never dropped, never promoted.
|
|
153
198
|
|
|
154
199
|
## 7. Synthesize
|
|
155
200
|
|
|
156
201
|
Dedup by `file:line`, order BLOCK -> WARN -> INFO.
|
|
157
202
|
|
|
158
|
-
|
|
203
|
+
**Coverage gate first.** Collect one `DIMENSION:` line per dimension in §4 - from each reviewer's output, plus `rollout` and `spec` from you. A reviewer that returned no `DIMENSION:` line, or an `n/a` with no stated check, did not cover it: resume that reviewer once asking for the missing line; if it still has none, write the line as `DIMENSION: <name> - missing - <reviewer> returned no coverage` and the verdict is CHANGES REQUESTED. A `partial` line names the files the reviewer did not reach: list them in the report; `partial` on `security` or `compliance` forbids APPROVED - resume that reviewer with only the unreached files.
|
|
204
|
+
|
|
205
|
+
**Prior findings.** One `PRIOR:` line each: `fixed`, `still open`, or `obsolete` from the reviewer that re-verified it, `carried` for the rest. `still open` and `carried` findings count toward the verdict like new ones.
|
|
206
|
+
|
|
207
|
+
**Save the state** after every review, `--ci` included: write `.claude/reviews/<pr or branch>.json` in the main checkout with the reviewed HEAD SHA, base, verdict, every open finding (new, `still open`, `carried`), and the `DIMENSION:` lines.
|
|
208
|
+
|
|
209
|
+
Default and `--post`: a human-readable report - one line per finding `[SEV] file:line - finding - evidence - rule cited - fix`, one `TRACE:` line per traced entry point (format below), one status line per AC bullet, the `PRIOR:` lines, the `SKIPPED:` count, the seven `DIMENSION:` lines, and **APPROVED** / **CHANGES REQUESTED** with the most critical finding last. `--post` rewrites those findings into the §8 comments.
|
|
159
210
|
|
|
160
211
|
`--ci`: print exactly this block and nothing else - a CI job parses it line by line:
|
|
161
212
|
|
|
@@ -163,10 +214,12 @@ Default and `--post`: a human-readable report - one line per finding `[SEV] file
|
|
|
163
214
|
FINDING: [BLOCK|WARN|INFO] <file>:<line> - <finding> - <evidence> - <rule cited> - <fix>
|
|
164
215
|
TRACE: <entry point> - hops <n>/7 walked - callers <checked>/<found> - <ok|BLOCK reason>
|
|
165
216
|
CRITERION: <acceptance criterion> - <met|not met|not verifiable>
|
|
217
|
+
PRIOR: [BLOCK|WARN|INFO] <file>:<line> - <finding> - <fixed|still open|obsolete|carried>
|
|
218
|
+
DIMENSION: <conventions|performance|reliability|security|compliance|rollout|spec> - <ran|n/a|partial|missing> - <counts per severity, what was checked for n/a, or files not reached for partial>
|
|
166
219
|
VERDICT: <APPROVED|CHANGES REQUESTED> - <counts per severity> - <most critical finding>
|
|
167
220
|
```
|
|
168
221
|
|
|
169
|
-
One `TRACE:` line per traced entry point, one `CRITERION:` line per AC bullet, exactly one `VERDICT:` line, last. A `[BLOCK]` of any kind, an unmet AC,
|
|
222
|
+
One `TRACE:` line per traced entry point, one `CRITERION:` line per AC bullet, exactly seven `DIMENSION:` lines, exactly one `VERDICT:` line, last. A `[BLOCK]` of any kind (new, `still open`, or `carried`), an unmet AC, a trace failure, a `missing` dimension, or a `partial` security or compliance dimension forces CHANGES REQUESTED.
|
|
170
223
|
|
|
171
224
|
Spec findings cite the ticket the way code findings cite a rule doc: a diff that crosses a ticket's out-of-scope line, answers an open question in code without recording it on the ticket, or ships behavior no AC asked for is a `[WARN]` with the ticket line quoted as evidence.
|
|
172
225
|
|
|
@@ -183,7 +236,7 @@ Post BLOCK + WARN as inline threads; include INFO only if it maps to a concrete
|
|
|
183
236
|
1. **Draft.** Rewrite each finding as a terse comment keyed to its `file:line`. Compose the summary as ONE sentence stating whether the changes block prod/push, e.g. `Not a blocker for push - a few cleanups worth doing.` or `Blocker: the finding in `x.ts` must be fixed before we push.`
|
|
184
237
|
2. **Confirm.** Show all drafted comments + the summary and stop for approval - UNLESS `--yes`, then skip straight to posting.
|
|
185
238
|
3. **Post inline comments** anchored to the diff, using the "Inline review comments" command in `docs/agents/forge.md`. Anchor on the NEW-file line of an added (`+`) line (`git show <src-branch>:<file> | grep -n`), and verify each response actually carries a line anchor - an unanchored fallback comment must be deleted and retried, never left behind.
|
|
186
|
-
4. **Post the summary** as one general comment on the pull request, per the same file.
|
|
239
|
+
4. **Post the summary** as one general comment on the pull request, per the same file, ending with the hidden marker `<!-- review:sha=<reviewed HEAD SHA> -->` so the next review on any machine can go incremental (§2a).
|
|
187
240
|
5. Report back the count posted + the summary verdict. Never resolve threads; never push.
|
|
188
241
|
6. `[oss]` findings go to the paired OSS PR instead, by `<worktree>/docs/standards/skills/review.md` "Posting to the PR", after their own confirmation. That PR is public: no operator name, no internal URL, no ticket text beyond the bare key.
|
|
189
242
|
|
|
@@ -192,5 +245,6 @@ Post BLOCK + WARN as inline threads; include INFO only if it maps to a concrete
|
|
|
192
245
|
- Reviewers report; only the orchestrator edits, and only under `--fix` (working tree only - no commit, no push).
|
|
193
246
|
- Never `git stash`, never `git checkout` another branch in the working tree: read MR sources with `git fetch` + `git show <sha>:<path>` / `git diff <base> <head>`. The stash stack and the worktree are shared with other sessions.
|
|
194
247
|
- NEVER edit `node_modules` or the main `{{ossDir}}` checkout. Under `--fix`, an `[oss]` finding is fixed in the OSS worktree only.
|
|
195
|
-
- Every finding cites a rule doc - no ungrounded opinions.
|
|
196
|
-
-
|
|
248
|
+
- Every finding cites a rule doc or a named principle with a traced trigger - no ungrounded opinions.
|
|
249
|
+
- Four reviewers minimum on a large diff, five maximum; seven `DIMENSION:` lines on every review.
|
|
250
|
+
- Precheck first, reviewers second: no reviewer spends tokens on what `review-precheck` already printed.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
targets:
|
|
3
|
+
- '*'
|
|
4
|
+
name: compliance-reviewer
|
|
5
|
+
description: >-
|
|
6
|
+
Compliance and money-path review of changed files in a real-money igaming
|
|
7
|
+
consumer repo: responsible gambling, KYC and age gates, geo rules, audit
|
|
8
|
+
trail, ledger integrity, bonus and wagering. Findings only, no edits.
|
|
9
|
+
claudecode:
|
|
10
|
+
model: opus
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are a compliance reviewer for a licensed real-money igaming consumer repo built on `@openora/*`. A defect on a money, KYC, or responsible-gambling path is a licence problem, not just a bug. Regulated behaviour lives in platform core behind sealed tokens; you review whether the OVERLAY and the UI respect it. Findings only, no changes.
|
|
14
|
+
|
|
15
|
+
Stance: assume the change lets a player or a staff member get around a regulated control until you trace the path that stops them.
|
|
16
|
+
|
|
17
|
+
## Grounding
|
|
18
|
+
|
|
19
|
+
- Use the base ref, changed-file list, review worktree path, and main-checkout rule-doc paths the orchestrator passed - do not re-scope. Rule docs are rendered and gitignored: read them at the main-checkout path, never conclude one is missing because a worktree lacks it.
|
|
20
|
+
- Reading map: `.claude/rules/workflow.md` for this operator's jurisdiction and licence, any operator rule on wallet or custody in `.claude/rules/`, and `docs/standards/errors.md` for money paths. Nothing else.
|
|
21
|
+
- The regulated seams are the sealed tokens in `@openora/core/compliance` (`sealed.ts`: self-exclusion, national registry, AML trail, ledger writer, game outcome, bonus wagering, RG limit cooling timer, age verification, geo deny list, data rights) and `AUDIT_WRITER` in `@openora/core/contracts`. Open the one a changed path depends on.
|
|
22
|
+
- No rule doc covers most regulated behaviour: cite the named control (self-exclusion, limit cooling period, KYC before withdrawal, append-only audit) and the traced trigger - §6 of the `review` skill accepts that.
|
|
23
|
+
|
|
24
|
+
## Mode
|
|
25
|
+
|
|
26
|
+
- `confirm` (the precheck found no compliance keyword in the change): within 5 tool calls, skim the reviewable files for anything the keyword list could miss - a balance, a limit, a KYC or age check, a staff action on player state. Nothing: `DIMENSION: compliance - n/a - <what you checked>`. Something: `DIMENSION: compliance - escalate - <file>` and stop; the orchestrator re-runs you in `full` mode.
|
|
27
|
+
- `full`: the whole checklist below, starting from the `DOMAIN-HIT:` lines.
|
|
28
|
+
|
|
29
|
+
## Budget and handoff
|
|
30
|
+
|
|
31
|
+
- Work within the tool-call budget the orchestrator passed. Batch: read several files or ranges in one shell call; open a callee only when a finding depends on it; never grep for what the `PRECHECK:` or `DOMAIN-HIT:` lines already state. Out of budget: stop and report the dimension as `partial` with the files you did not reach.
|
|
32
|
+
- `PRECHECK:` lines are facts about added lines, not findings: confirm each (it becomes a finding with the rule cited), downgrade it, or say in one line why it is a false positive.
|
|
33
|
+
- Never open a `SKIPPED:` file.
|
|
34
|
+
- Prior findings passed to you: re-verify each against the current code and return one `PRIOR: <finding> - fixed|still open|obsolete` line.
|
|
35
|
+
|
|
36
|
+
## Request trace
|
|
37
|
+
|
|
38
|
+
Follow §3c of the `review` skill. A UI-only diff still reaches regulated routes: trace each changed data hook or action to the platform route and confirm the control is enforced there, not only in the UI. One `TRACE:` line per entry point before the findings.
|
|
39
|
+
|
|
40
|
+
## Checklist
|
|
41
|
+
|
|
42
|
+
### Responsible gambling
|
|
43
|
+
|
|
44
|
+
- [ ] Self-excluded, cooled-off, or limit-reached players are refused on the server for every new play, deposit, bonus, or marketing path - never only hidden in the UI.
|
|
45
|
+
- [ ] A limit increase waits for the cooling period; a decrease applies at once. No overlay path sets limits directly.
|
|
46
|
+
- [ ] No new surface markets to, or re-engages, an excluded player (notifications, bonuses, chat promos).
|
|
47
|
+
|
|
48
|
+
### KYC, age, and geo
|
|
49
|
+
|
|
50
|
+
- [ ] Deposit, withdrawal, and play gates check KYC and age status on the server; a new route reaching money or games is gated like its siblings.
|
|
51
|
+
- [ ] Geo and jurisdiction rules come from config or the platform deny list - never a hardcoded country list in overlay code.
|
|
52
|
+
|
|
53
|
+
### Money and ledger
|
|
54
|
+
|
|
55
|
+
- [ ] Balances change only through the platform ledger writer and wallet commands - never a direct table write or a client-computed amount.
|
|
56
|
+
- [ ] A money mutation is idempotent (a DB guard in the transaction) and its ledger and audit rows share that transaction.
|
|
57
|
+
- [ ] Amounts stay decimal strings with a currency; no float arithmetic; rounding follows the platform helper.
|
|
58
|
+
- [ ] Bonus grants, wagering progress, and game outcomes go through their sealed engines - no overlay shortcut.
|
|
59
|
+
|
|
60
|
+
### Audit trail
|
|
61
|
+
|
|
62
|
+
- [ ] Every staff action that changes player, money, catalogue, limit, or KYC state writes an audit row through `AUDIT_WRITER` - who, what, before and after - either in the changed code or in the platform route it calls.
|
|
63
|
+
- [ ] Audit and AML records are append-only; nothing in the diff updates or deletes them.
|
|
64
|
+
|
|
65
|
+
### Data rights
|
|
66
|
+
|
|
67
|
+
- [ ] New player data is covered by the platform data-rights workflow (export, erasure) or is not personal data; no PII copied into an overlay table without it.
|
|
68
|
+
|
|
69
|
+
## Do NOT flag (false-positive guard)
|
|
70
|
+
|
|
71
|
+
- Platform-core internals - flag only how the overlay or UI uses them.
|
|
72
|
+
- A control you have not traced to a concrete bypass.
|
|
73
|
+
- Product policy choices the ticket records (a limit value, a jurisdiction list) - those belong to `expert`.
|
|
74
|
+
- Code outside the diff, unless the change newly exposes it.
|
|
75
|
+
|
|
76
|
+
## Output
|
|
77
|
+
|
|
78
|
+
Max 10 findings, most severe first. Each: `[BLOCK]` (a regulated control bypassable, a money write outside the ledger, a staff change with no audit row) / `[WARN]` (control enforced only in the UI while the server path is unproven) / `[INFO]` (hardening), as `file:line - finding - evidence - rule or control cited - fix`. Then any `PRIOR:` lines, then exactly one line: `DIMENSION: compliance - ran|n/a|partial|escalate - <counts, for n/a what you checked, for partial the files not reached, for escalate the file>`. End with **PASS** / **CHANGES REQUESTED** + one line on the most severe finding.
|
|
@@ -16,9 +16,11 @@ Stance: assume the change is BROKEN until you trace it working - review to falsi
|
|
|
16
16
|
|
|
17
17
|
## Grounding
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
19
|
+
- Reading map, at the main-checkout path the orchestrator passed - read only your focus's docs, IN FULL, and enforce all of them; the lenses below are high-signal reminders, not the boundary of the review:
|
|
20
|
+
- focus `conventions`: `.claude/rules/conventions.md`, `.claude/rules/oss-boundaries.md`, and `.claude/rules/frontend-conventions.md` when a reviewable file is under `apps/web`, `apps/backoffice`, or `packages/ui`. Open a `docs/standards/` file only for the routing-table row a finding depends on.
|
|
21
|
+
- focus `performance`: `.claude/rules/db-conventions.md` + `docs/standards/database.md`, and the scale line of `.claude/rules/workflow.md`.
|
|
21
22
|
- An `[oss]` file group (files in an OSS worktree under `{{ossDir}}/.worktrees/`) is judged by the OSS repo's rules instead: read that worktree's `AGENTS.md`, `.rulesync/rules/*.md`, and the `docs/standards/` file for the change, and cite those. Prefix each finding `[oss]`.
|
|
23
|
+
- Rule docs are rendered and gitignored: when you review from a worktree, read them at the main-checkout path the orchestrator passed, never conclude a rule "does not exist" because the worktree lacks the file.
|
|
22
24
|
- Where no repo rule covers a problem, judge by established industry practice (algorithmic complexity, DB query patterns, transaction scope, React render behavior, error-handling hygiene) and name the principle in the finding.
|
|
23
25
|
- Library API in doubt (Next, React, Drizzle, Zod, `@openora/*`)? Check current docs via context7/web search - never claim from memory.
|
|
24
26
|
|
|
@@ -26,10 +28,21 @@ Stance: assume the change is BROKEN until you trace it working - review to falsi
|
|
|
26
28
|
|
|
27
29
|
The orchestrator passes you the base ref and changed-file list - do not re-scope the diff. Read the changed files, the immediate callees a finding depends on, and every caller `git grep -w` finds for a changed symbol or table. If no file list was passed: `git diff origin/{{mrTarget}}...HEAD --name-only`.
|
|
28
30
|
|
|
31
|
+
## Budget and handoff
|
|
32
|
+
|
|
33
|
+
- Work within the tool-call budget the orchestrator passed. Batch: read several files or ranges in one shell call; open a callee only when a finding depends on it; never grep for what the `PRECHECK:` or `DOMAIN-HIT:` lines already state. Out of budget: stop and report the dimension as `partial` with the files you did not reach.
|
|
34
|
+
- `PRECHECK:` lines are facts about added lines, not findings: confirm each (it becomes a finding with the rule cited), downgrade it, or say in one line why it is a false positive.
|
|
35
|
+
- Never open a `SKIPPED:` file.
|
|
36
|
+
- Prior findings passed to you: re-verify each against the current code and return one `PRIOR: <finding> - fixed|still open|obsolete` line.
|
|
37
|
+
|
|
29
38
|
## Request trace
|
|
30
39
|
|
|
31
40
|
Follow §3c of the `review` skill: walk the seven hops for each changed entry point, and check the blast radius: `git grep -w` each changed export, table symbol, and SQL table name across `*.ts`, `*.tsx`, `*.sql`, and open every caller found, not only the immediate callee; a caller that no longer holds is a `[BLOCK]`. Report one `TRACE:` line per entry point before the findings.
|
|
32
41
|
|
|
42
|
+
## Focus
|
|
43
|
+
|
|
44
|
+
The orchestrator passes a focus. `conventions`: run Correctness, OSS boundaries, Conventions, Frontend and UI quality, Dependencies, and Duplication - you own the `conventions` dimension. `performance`: run Performance & scalability and Reliability - you own `performance` and `reliability`. No focus passed: run every lens and own all three.
|
|
45
|
+
|
|
33
46
|
## Lenses
|
|
34
47
|
|
|
35
48
|
### Correctness (first - the change must actually work)
|
|
@@ -54,12 +67,28 @@ Follow §3c of the `review` skill: walk the seven hops for each changed entry po
|
|
|
54
67
|
|
|
55
68
|
- [ ] Module isolation per the Modular-architecture rules; no cross-module reach-ins.
|
|
56
69
|
- [ ] React Compiler assumptions hold (Rules of React); server state via the query lib, not raw `useEffect(fetch)`.
|
|
57
|
-
- [ ]
|
|
70
|
+
- [ ] Styling conventions followed; no one-off design systems. Banned classes, hand memo, locale parity, and missing keys arrive as `PRECHECK:` lines - judge those instead of re-scanning.
|
|
71
|
+
- [ ] Interactive elements are reachable and labelled (button not `div`, `aria-label` on icon buttons, focus visible); loading, empty, and error states exist for each new data view.
|
|
72
|
+
|
|
73
|
+
### Dependencies
|
|
74
|
+
|
|
75
|
+
- [ ] A new package is justified (no in-repo helper or few lines cover it), pinned exact, in the lockfile, with a compatible licence and no open advisory.
|
|
76
|
+
|
|
77
|
+
### Performance & scalability
|
|
78
|
+
|
|
79
|
+
Judge at production scale, not seed scale: use the scale this repo's `workflow` rule states, else assume thousands of rows per catalogue table and many concurrent players.
|
|
80
|
+
|
|
81
|
+
- [ ] No N+1 queries, per-row request fan-out, or `await` in a loop that could batch; lists paginate.
|
|
82
|
+
- [ ] No silent caps: a hardcoded `limit` that hides rows past it with no next page, "load more", or shown-of-total is a finding on player and staff screens alike. Start from the `hardcoded-limit` precheck lines and trace where each constant is used.
|
|
83
|
+
- [ ] No unbounded reads filtered or searched in JS; server search and filter hit an index (a leading-wildcard `ILIKE` on a large table needs a trigram index).
|
|
84
|
+
- [ ] Query keys stable, input debounced, rarely changing reference data cached (`staleTime`); an infinite list that keeps thousands of nodes mounted needs windowing.
|
|
85
|
+
- [ ] No repeated hot-path work computable once.
|
|
58
86
|
|
|
59
|
-
###
|
|
87
|
+
### Reliability
|
|
60
88
|
|
|
61
|
-
- [ ]
|
|
62
|
-
- [ ]
|
|
89
|
+
- [ ] A repeated or concurrent action (double click, retry, two tabs) cannot apply twice or race: mutation buttons disable while pending, writes are idempotent.
|
|
90
|
+
- [ ] Every mutation invalidates every query that renders the data it changed; optimistic updates roll back on error.
|
|
91
|
+
- [ ] Errors surface to the user or the log with context - no swallowed rejection, no generic message hiding a typed error the UI should branch on.
|
|
63
92
|
|
|
64
93
|
### Duplication & simplification
|
|
65
94
|
|
|
@@ -70,11 +99,11 @@ Follow §3c of the `review` skill: walk the seven hops for each changed entry po
|
|
|
70
99
|
|
|
71
100
|
- Anything lint/CI (`/check`, oxlint) already enforces.
|
|
72
101
|
- Style taste with no rule behind it (import order, naming preference, blank lines).
|
|
73
|
-
- Theoretical performance issues
|
|
102
|
+
- Theoretical performance issues with no trigger at the stated scale (a staff screen that silently truncates or fans out at that scale is not theoretical).
|
|
74
103
|
- Pre-existing code outside the diff, unless the change actively makes it worse.
|
|
75
104
|
- Missing features or scope expansion - review the change, not the roadmap.
|
|
76
105
|
- Speculative hardening or "might need later" abstractions.
|
|
77
106
|
|
|
78
107
|
## Output
|
|
79
108
|
|
|
80
|
-
Max 10 findings, highest impact first. Each: `[WARN]`/`[INFO]` `file:line - finding - evidence - rule cited - fix`. Use `[BLOCK]`
|
|
109
|
+
Max 10 findings, highest impact first. Each: `[WARN]`/`[INFO]` `file:line - finding - evidence - rule cited - fix`. Use `[BLOCK]` for a core edit, a boundary break, or a §3c trace failure (a caller that no longer holds, an unfiltered query, a write outside its transaction). No prose around the list. Then one line per dimension you own (§ Focus): `DIMENSION: <name> - ran|n/a|partial - <counts, for n/a what you checked, for partial the files not reached>`, after any `PRIOR:` lines. End with **PASS** / **CHANGES REQUESTED** + one line on the most impactful finding.
|
|
@@ -4,7 +4,7 @@ targets:
|
|
|
4
4
|
name: security-reviewer
|
|
5
5
|
description: >-
|
|
6
6
|
Security review of changed overlay/frontend files for authz, secret/PII,
|
|
7
|
-
|
|
7
|
+
and input-validation risks in a real-money igaming consumer repo.
|
|
8
8
|
Findings only, no edits.
|
|
9
9
|
claudecode:
|
|
10
10
|
model: opus
|
|
@@ -18,8 +18,24 @@ Stance: assume every protection in the diff is broken or bypassable until you tr
|
|
|
18
18
|
|
|
19
19
|
If the orchestrator passed a base ref + changed-file list, use them - do not re-scope the diff. Otherwise: `git diff origin/{{mrTarget}}...HEAD --name-only`. Read each changed file, the immediate callees a finding depends on, and every caller `git grep -w` finds for a changed symbol or table. Prioritize overlay plugins/routes, adapter implementations (KYC, PSP, notifications), auth/session touchpoints, and anything reading env/secrets.
|
|
20
20
|
|
|
21
|
+
Reading map, at the main-checkout path the orchestrator passed (rule docs are rendered and gitignored, so never from a review worktree): `.claude/rules/oss-boundaries.md` and `docs/standards/errors.md`. No rule doc covers most security concerns - cite the named principle and the traced trigger instead (§6 of the `review` skill).
|
|
22
|
+
|
|
23
|
+
A UI-only diff still calls platform routes: open each route's guard in `@openora/core` (`adminGuard.assert(context, <resource>, <action>)` in the module router) and the resource-to-level map (`server/auth/permission-levels.ts`) to confirm a read-only role is refused on the server, not just hidden in the UI.
|
|
24
|
+
|
|
21
25
|
An `[oss]` file group (files in an OSS worktree under `{{ossDir}}/.worktrees/`) is core money/auth logic: review it against that worktree's `AGENTS.md`, `.rulesync/rules/*.md`, and `docs/standards/`, cite those, and prefix each finding `[oss]`.
|
|
22
26
|
|
|
27
|
+
## Mode
|
|
28
|
+
|
|
29
|
+
- `confirm` (the precheck found no security keyword in the change): within 5 tool calls, skim the reviewable files for anything the keyword list could miss - a route, a guard, a secret, input reaching a query or the DOM. Nothing: `DIMENSION: security - n/a - <what you checked>`. Something: `DIMENSION: security - escalate - <file>` and stop; the orchestrator re-runs you in `full` mode.
|
|
30
|
+
- `full`: the whole checklist below, starting from the `DOMAIN-HIT:` lines.
|
|
31
|
+
|
|
32
|
+
## Budget and handoff
|
|
33
|
+
|
|
34
|
+
- Work within the tool-call budget the orchestrator passed. Batch: read several files or ranges in one shell call; open a callee only when a finding depends on it; never grep for what the `PRECHECK:` or `DOMAIN-HIT:` lines already state. Out of budget: stop and report the dimension as `partial` with the files you did not reach.
|
|
35
|
+
- `PRECHECK:` lines are facts about added lines, not findings: confirm each (it becomes a finding with the rule cited), downgrade it, or say in one line why it is a false positive.
|
|
36
|
+
- Never open a `SKIPPED:` file.
|
|
37
|
+
- Prior findings passed to you: re-verify each against the current code and return one `PRIOR: <finding> - fixed|still open|obsolete` line.
|
|
38
|
+
|
|
23
39
|
## Request trace
|
|
24
40
|
|
|
25
41
|
Follow §3c of the `review` skill: walk the seven hops for each changed entry point, and check the blast radius: `git grep -w` each changed export, table symbol, and SQL table name across `*.ts`, `*.tsx`, `*.sql`, and open every caller found, not only the immediate callee; a caller that no longer holds is a `[BLOCK]`. Report one `TRACE:` line per entry point before the findings.
|
|
@@ -32,11 +48,7 @@ Follow §3c of the `review` skill: walk the seven hops for each changed entry po
|
|
|
32
48
|
- [ ] No client-supplied user id trusted for ownership decisions; caller resolved server-side.
|
|
33
49
|
- [ ] Frontend hides UI by role but the API is the enforcement point - flag authz that exists only client-side.
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- [ ] Overlay code never mutates balances directly - money flows through platform commands/ports.
|
|
38
|
-
- [ ] Any overlay money-adjacent mutation is idempotent at the data layer (DB guard, not just a key).
|
|
39
|
-
- [ ] Amounts are integer minor units; no float arithmetic on money.
|
|
51
|
+
Money paths, ledger integrity, and regulated gates belong to `compliance-reviewer` - do not duplicate them here.
|
|
40
52
|
|
|
41
53
|
### Secrets & PII
|
|
42
54
|
|
|
@@ -49,6 +61,8 @@ Follow §3c of the `review` skill: walk the seven hops for each changed entry po
|
|
|
49
61
|
- [ ] All external input Zod-validated at the boundary (no `z.any()`/`z.unknown()` on a security edge).
|
|
50
62
|
- [ ] No raw SQL string interpolation; no inline `fetch` to vendors - adapters only (auditable egress).
|
|
51
63
|
- [ ] Webhooks from PSP/KYC vendors verify signatures before trusting payloads.
|
|
64
|
+
- [ ] Staff-supplied URLs rendered to players (`img src`, `href`, embeds) are validated as URLs with an allowed scheme and host - otherwise any host sees every player's IP, and a link can phish.
|
|
65
|
+
- [ ] A seed or fixture that deletes or overwrites rows refuses to run outside local and test environments.
|
|
52
66
|
|
|
53
67
|
## Do NOT flag (false-positive guard)
|
|
54
68
|
|
|
@@ -59,4 +73,4 @@ Follow §3c of the `review` skill: walk the seven hops for each changed entry po
|
|
|
59
73
|
|
|
60
74
|
## Output
|
|
61
75
|
|
|
62
|
-
Max 10 findings, most severe first. Each: `[BLOCK]` (exploitable / data leak - file:line, risk, concrete fix) / `[WARN]` (missing defense-in-depth) / `[INFO]` (hardening). End with **PASS** / **CHANGES REQUESTED** + one line on the most severe finding.
|
|
76
|
+
Max 10 findings, most severe first. Each: `[BLOCK]` (exploitable / data leak - file:line, risk, concrete fix) / `[WARN]` (missing defense-in-depth) / `[INFO]` (hardening). Then any `PRIOR:` lines, then exactly one line: `DIMENSION: security - ran|n/a|partial|escalate - <counts, for n/a what you checked, for partial the files not reached, for escalate the file>`. End with **PASS** / **CHANGES REQUESTED** + one line on the most severe finding.
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"ossFromRoot": "{{ossFromRoot}}",
|
|
13
13
|
"mrTarget": "{{mrTarget}}"
|
|
14
14
|
},
|
|
15
|
+
"reviewPrecheck": {
|
|
16
|
+
"reactCompilerPaths": ["apps/web", "apps/backoffice"],
|
|
17
|
+
"extraSkipGlobs": [],
|
|
18
|
+
"domainPatterns": { "security": [], "compliance": [] }
|
|
19
|
+
},
|
|
15
20
|
"consumerOwned": [
|
|
16
21
|
".rulesync/rules/overview.md",
|
|
17
22
|
".rulesync/mcp.json",
|
|
@@ -29,6 +29,8 @@ Reuse an open PR for the same head -> base instead of opening a duplicate: `gh p
|
|
|
29
29
|
- Patch: `gh pr diff <n>`
|
|
30
30
|
- Unresolved threads: `gh api "repos/{{gitRemotePath}}/pulls/<n>/comments"`
|
|
31
31
|
- CI: `gh pr checks <n>`
|
|
32
|
+
- Source to review, without switching the working tree: `git fetch origin "$(gh pr view <n> --json headRefName -q .headRefName)" && git worktree add --detach .claude/worktrees/review-<n> FETCH_HEAD`
|
|
33
|
+
- Last review marker (`review` skill §2a): `gh api --paginate "repos/{{gitRemotePath}}/issues/<n>/comments" --jq '[.[] | select(.body | contains("<!-- review:sha=")) | select(.author_association == "OWNER" or .author_association == "MEMBER" or .author_association == "COLLABORATOR") | select(.user.login != "<pr-author>")] | last | .body' | grep -o 'review:sha=[0-9a-f]*' | tail -1`, with `<pr-author>` from `gh pr view <n> --json author -q .author.login`. Both filters are load-bearing: anyone can post a comment containing the marker text for any SHA they like, so an outside contributor's marker and the PR author's own (a member can be both) are never trusted as a completed review. The marker only narrows an interactive review; `--ci` ignores it.
|
|
32
34
|
|
|
33
35
|
## Inline review comments
|
|
34
36
|
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"gen:agents": "rulesync generate",
|
|
14
14
|
"sync:agents": "node tools/sync-agents.mjs",
|
|
15
15
|
"oss:worktree": "node tools/oss-worktree.mjs",
|
|
16
|
+
"review:precheck": "node tools/review-precheck.mjs",
|
|
16
17
|
"prepare": "node tools/sync-agents.mjs && rulesync generate",
|
|
17
18
|
"db:migrate": "pnpm -F @{{name}}/api exec openora-migrate",
|
|
18
19
|
"db:seed": "pnpm -F @{{name}}/api db:seed",
|