Skip to content

Reviewer: port the hardened harness from bookplayer-android (247 tests, trust split) - #1611

Merged
GianniCarlo merged 1 commit into
developfrom
reviewer/port-hardened-harness
Oct 6, 2026
Merged

GianniCarlo merged 1 commit into
developfrom
reviewer/port-hardened-harness

Conversation

@GianniCarlo

Copy link
Copy Markdown
Collaborator

What

A copy, not a merge. The reviewer harness is repository-agnostic, so this PR replaces the first-generation .github/claude/reviewer/ (two files from July, no tests) with bookplayer-android's develop copy (7f1996c0), and claude-review.yml with its workflow. It's the same port as bookplayer-api#40 and bookplayer-support-pipeline#16.

before (develop) after
Harness review.mjs + github.mjs, 462 lines, no tests 9 modules by seam, 247 tests incl. the conservation fuzzer
Agent permissions bypassPermissions, the agent holds GH_TOKEN canUseTool grammar gate + PreToolUse hook, reads confined to the checkout + diff file, write tokens withheld, redaction on every post and log line
Model pinned claude-opus-4-8, SDK latest, no lockfile, 50 turns newest Opus resolved at runtime (runner-up retry), SDK pinned 0.3.280 with lockfile, effort: high, 12-min deadline
Closing a thread resolved when no longer reported closed only by a verification pass (fixed / not applicable / accepted by a maintainer / duplicate); hidden state record
Workflow pull_request, PR-head harness, repo-level secrets pull_request_target, harness + guide from develop, PR tree as data, secrets in the reviewer environment, fork/draft/Dependabot skipped, harness-tests job without secrets

The per-repository files

  • repo.mjs (new):
    • Secret file Debug.xcconfig. Debug.template.xcconfig stays readable. Release.xcconfig is deliberately not listed: it is tracked with replace.me placeholders despite its .gitignore entry, so it stays reviewable.
    • Secret shapes:
      • the Sentry DSN with or without https://. The xcconfig stores it without the scheme and AppDelegate prepends it, so android's scheme-required pattern would miss this repository's form.
      • RevenueCat/store keys (appl_…).
  • review-guide.md: the rubric is kept, with four edits:
    • The diff instructions (gh pr diff, "Diff against origin/develop") now point at the diff file the harness writes. The agent no longer has gh or a base ref.
    • The iOS focus list the old prompt carried moves into "How to review": [weak self], stored cancellables, @MainActor/DB threading, AVAudioSession, the BookPlayerKit boundary. The shared prompt names no repository.
    • The Release.xcconfig wording now matches reality.
    • "Reporting findings" describes how threads close now.
  • Workflow and README: these differ from android only in the branch list ([develop]) and the env-policy and local-run lines.

Trust split: done, and what happens on merge

  • The reviewer environment exists on this repo with deployment-branch policy develop. It holds ANTHROPIC_API_KEY and REVIEW_RESOLVE_TOKEN, piped from SSM; the key is stored under /anthropic/github-reviewer-bookplayer-ios.
  • No reviewer runs on this PR. Each side's workflow file lacks the other trigger: develop's file has no pull_request_target, and this branch's has no pull_request. The new workflow's first live run is the first PR after the merge.
  • Release PRs into main stay unreviewed, as today. Adding main would make the first release PR fail its review check until main carries this harness.
  • After the first green run, delete the repository-level ANTHROPIC_API_KEY and REVIEW_RESOLVE_TOKEN.
  • Fork PRs (More accurate VBR durations #1573, Allow web URL imports via the share extension #1516) are skipped by design: under pull_request_target they would receive the secrets.
  • Existing first-generation threads use the same fingerprint marker, so the new harness adopts them. External resource support for media-server items (Jellyfin / AudiobookShelf) #1586's one open thread will be verified on its next push. Its 317 resolved threads carry no marker, so they read as maintainer-resolved and stay closed.

Verification

  • npm ci --ignore-scripts && node smoke.mjs && node --test test/ on Node 20: the SDK loads, the native CLI runs, 247/247 tests pass.
  • The 18 shared files are byte-identical to the android, api and support-pipeline copies.
  • Mutation check on repo.mjs: each of 6 deliberate breaks turns the suite red. The breaks were the scheme-required android DSN pattern, a non-global regex, a keeps line that matches a DSN, dropping appl, raising the key length past the example, and an empty secret-file list.
  • Checked against a real local Debug.xcconfig, without printing values: the DSN and RevenueCat key are redacted, and the file is refused by Bash and Read.

🤖 Generated with Claude Code

…s, trust split)

Replaces the first-generation reviewer (review.mjs + github.mjs from July: no
sandbox, bypassPermissions, model pinned to claude-opus-4-8, SDK "latest", no
lockfile, no tests) with bookplayer-android's develop copy (7f1996c0). The 18
shared files are byte-identical to the android, api and support-pipeline
copies; the per-repository files are repo.mjs, review-guide.md, the README's
local-run example and the workflow's branch list.

Workflow: pull_request_target on develop only; the harness and guide run from
the base branch, the PR tree is checked out beside them as data, and the
secrets live in the `reviewer` environment (deployment-branch policy develop).
Fork, draft and Dependabot PRs are skipped. Release PRs into main stay
unreviewed, as before.

repo.mjs: Debug.xcconfig is a secret file (the template stays readable;
Release.xcconfig is tracked with placeholders and stays reviewable). Shapes:
the Sentry DSN with or without its scheme, because the xcconfig stores it
without https:// and AppDelegate prepends it, and the RevenueCat/store keys.

review-guide.md: the agent no longer has gh or an origin/develop ref, so the
diff instructions point at the file the harness writes; the iOS focus list
the old prompt carried (weak self, stored cancellables, @mainactor and DB
threading, AVAudioSession lifecycle, the BookPlayerKit boundary) moves into
"How to review", since the shared prompt names no repository; the
Release.xcconfig wording matches what the file is; "Reporting findings"
describes the verification pass that now closes threads.
@GianniCarlo
GianniCarlo merged commit 84dcf11 into develop Oct 6, 2026
1 check passed
@GianniCarlo
GianniCarlo deleted the reviewer/port-hardened-harness branch October 6, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant