diff --git a/.claude/skills/pr-review/SKILL.md b/.claude/skills/pr-review/SKILL.md index b374cfd6..839471ec 100644 --- a/.claude/skills/pr-review/SKILL.md +++ b/.claude/skills/pr-review/SKILL.md @@ -163,13 +163,41 @@ orbit-api. A paired diff can be **both**. That classification gates which rubric ```json {"reviewerKind":"independent","verdict":"BLOCKING","rounds":1, "reviewedHeadOid":"","baseSha":"", - "rubricBaseOid":"","rubricArtifactPath":"", + "rubricRepositoryKey":"","rubricCommitOid":"", + "rubricBlobOid":"", + "rubricArtifactPath":"", "artifactPath":"", "frozenFindingIds":["F1"], "findings":[{"id":"F1","severity":"High","file":"apps/web/hooks/use-streak.ts","line":42, "claim":"one sentence: what is wrong and what goes wrong if it ships","blocking":true}]} ``` +### Rubric provenance: which rubric you read, and where it came from + +The four rubric fields are not bookkeeping. `record-readiness.mjs` proves them with git and refuses +the receipt when they do not hold, so a review bound to the wrong or a stale rubric cannot reach +READY. Fill them from the snapshot you were given: + +| Field | What it must be | +|---|---| +| `rubricRepositoryKey` | the repository the snapshot was materialized FROM | +| `rubricCommitOid` | the commit it was materialized from, full 40 characters | +| `rubricBlobOid` | `git rev-parse :.claude/skills/pr-review/rubric.md` | +| `rubricArtifactPath` | the absolute path of the materialized snapshot you actually read | + +Two bindings, decided by the repository under review, not by you: + +- **The repository carries the rubric at the pull request's base** (orbit-ui-mobile, orbit-api). + `rubricRepositoryKey` is that repository and `rubricCommitOid` is the pull request's own base SHA. +- **The repository carries no rubric** (orbit-landing-page has no `.claude` tree at any commit). + `rubricRepositoryKey` is `ui` and `rubricCommitOid` is orbit-ui-mobile's current `origin/main`. + Binding a landing review to its own base was impossible, and it is why four landing pull requests + reported `REVIEW_STALE` on 2026-08-08 while being complete on every other dimension. + +The snapshot is compared against the committed blob byte for byte, with line endings normalized. A +hand-edited snapshot fails, a wrong blob fails, and a stale rubric fails. Do not invent these +values: if you were not given a snapshot and its provenance, say so and stop. + `severity` is descriptive and comes from the rubric's ladder. A candidate below the target repository floor never enters this array. `blocking` is the decision for a surviving candidate: a High that does not break behaviour, security, or data integrity is `"blocking": false` and