-`lib/jsonExtract.js` — tolerant JSON extractor (fences, prose, `<think>` blocks, trailing commas) + one retry on parse failure.
-`lib/verdict.js` — **service-side verdict derivation is authoritative**: `fail` iff a finding has severity ∈ {critical, high} AND confidence = confirmed in axes correctness/security (untagged confirmed criticals also block, conservatively).
-`lib/trailers.js` — `Co-Authored-By` trailer parser for agent attribution.
-`lib/digest.js` — nightly per-agent digests (score trend, recurring finding categories, last N reviews).
Dependencies: **none**. Node ≥ 22.13 (uses `node:sqlite`, global `fetch`).
## Review posture (approved)
**BLOCK on confirmed-critical, with human override.**
- Commit status context: `granthi-review`. verdict pass → `success`; warn → `success` with warning description; fail → `failure`.
- Branch protection on pilot repos requires the `granthi-review` context but does **not** apply to admins — an admin merge is the override. The blocking comment says so explicitly.
- **Fail-open with visibility**: if the router/LLM is down or output is unparseable after retry, the service posts status `warning` with "review unavailable" — it never blocks silently and never fakes a pass.
- Bare pushes (no PR): commit status + ledger + dashboard only. Gitea 1.27 has no commit-comment API endpoint, so no comment is posted for pushes.
## Config
`~/.granthi-review/config.json` (chmod 600):
```json
{
"port":5498,
"forgeBaseUrl":"http://localhost:3030",
"botToken":"<shre-reviewer API token: write:repository,write:issue>",
"webhookSecret":"<shared HMAC secret>",
"routerUrl":"http://localhost:5497",
"model":"anthropic/claude-sonnet-4-6",
"tenantId":"nirlab",
"publicBaseUrl":"http://localhost:5498"
}
```
Bot identity: Gitea user `shre-reviewer` (created via `gitea admin user create`).
## Deploy (Mac dev tier)
-`launchd/ai.granthi.review.plist` → `~/Library/LaunchAgents/`, KeepAlive service on :5498.
- Webhooks: Gitea **system webhook** (admin → hooks) pointed at `http://host.docker.internal:5498/webhook` (the gitea container reaches the host that way), events push + pull_request, secret = `webhookSecret`. Fallback: per-repo hooks on pilot repos.
- Pilot gating: `nirpa/gitea-distro` main branch protection lists `granthi-review` in `status_check_contexts` (alongside the CI build context); `enable_approvals_whitelist`/admin-bypass left so admins can merge over a block.
## Adding the Reviews tab later (Granthi overlay)
The dashboard page `GET /review/{owner}/{repo}` is designed to be iframed or
linked as a repo tab. In the gitea-distro overlay, add an extra-tabs template