The Harbourmaster review pipeline
Harbourmaster separates trusted context and publication verification from the OpenCode review runtime. OpenCode decides what the review says and submits it. The TypeScript runner controls what data and tools agents can access and proves that publication happened on the intended pull request head.
flowchart TD
PR["GitHub pull request"] --> Context["Load PR context through Octokit"]
Context --> Filter["Filter diff and classify risk"]
Filter --> Stage["Stage isolated patch files"]
Stage --> Workspace["Write review index and context files"]
Workspace --> Coordinator["Start OpenCode coordinator"]
subgraph OpenCode["OpenCode review runtime"]
Coordinator --> Specialists["Run selected specialists in parallel"]
Specialists --> Verify["Aggregate adversarial verification"]
Verify --> Edit["Edit one coherent review"]
Edit --> Publish["Call trusted publication plugin (up to three attempts)"]
end
Publish --> Publication["Verify receipt and marked review on exact head SHA"]
Coordinator -.-> Logs["Stream raw stdout and stderr"]
Context -.-> Telemetry["Emit redacted logfmt telemetry"]
Publication -.-> TelemetryGitHub context enters through a trusted boundary
Harbourmaster obtains pull request metadata, changed files, and bounded existing discussion through Octokit. It also loads review threads through GitHub GraphQL before specialists start. The coordinator receives those threads as untrusted quoted facts, including resolved state, outdated flags, and developer replies.
The runner then verifies the expected head SHA, skips drafts and forks, filters noisy files, classifies risk, and selects specialists. Exact bounds, filters, and specialist rules are in the review behavior reference.
The runner stages one patch file per reviewable changed file in an ephemeral
directory. Before OpenCode starts, it writes review-index.json,
shared-pr-context.txt, and review-discussion.txt. File roles and tool limits
are in the configuration reference. OpenCode
starts in this directory with the trusted bundled configuration.
Specialists inspect scoped evidence
Selected specialists run as independent sibling sessions. They can use read-only
file tools against the review files, patches/, and any staged root reference
paths. They cannot use a shell, browse the network, create nested agents, or
access GitHub.
The code-quality reviewer also receives read-only access to the canonical checkout so it can trace callers, contracts, and tests beyond the diff. Other specialists and the verifier inspect only the staged material. Findings must concern behavior introduced by the pull request and refer to changed lines. Checkout content remains untrusted review context.
A trusted hook canonicalizes paths for read, glob, grep, and list before
those tools access files. It rejects paths that escape the allowed directory,
including symlink escapes.
After specialists finish, the verifier tests their claims against the staged material and the evidence they provide. The editor then removes duplicates, calibrates severity, and prepares one coherent review. The editor supplies one disposition for every active Harbourmaster finding.
Only the editor can publish
In comment mode, the editor invokes the preloaded spawn_reviewers tool exactly
once, then uses publish_review after verification. The GitHub token is passed
only to this editor process. Specialists and the verifier receive neither the
tool nor the token.
The plugin owns the trusted repository, pull request, head SHA, publication marker, and changed-file allowlist. A failed publication attempt returns its tool error to the editor, which may correct the input and retry up to two more times. The first successful result is cached and ends publication retries.
The editor always submits one COMMENT review, including when no validated
issues remain. Silent and check-only modes do not publish. Blocking mode retains
fail-closed runtime behavior but publishes the same advisory review event.
Lifecycle replies use GitHub's REST review-comment reply endpoint and run concurrently. On later runs, the trusted GraphQL loader accepts a completion marker only from an expected Harbourmaster bot identity.
The runner verifies instead of republishing
Before OpenCode starts, the runner snapshots existing pull request review IDs and creates a unique marker containing the run ID and exact head SHA. After OpenCode exits, the runner queries GitHub and accepts success only when it finds a new submitted review on the exact head that contains that marker.
Harbourmaster does not parse OpenCode output as a control message. The publication plugin writes a private receipt, and the runner cross-checks its review ID and head SHA against the marked review returned by GitHub. OpenCode standard output and standard error are streamed unchanged to the GitHub Actions log.
Failures remain observable
Harbourmaster classifies configuration, GitHub, OpenCode, model, diff, policy,
and internal failures. Retryable operations use bounded attempts and configured
fallback models. In non-blocking modes, selected OpenCode startup failures can
produce a degraded outcome. strict_runtime turns a run with no real model
execution into a failure, and blocking mode fails closed when the runtime cannot
complete.
Every stage emits redacted logfmt telemetry. The specialist plugin writes a versioned execution receipt outside the agent-readable diff directory. The telemetry plugin writes private snapshots of observed session events. Process attempts never substitute for model calls. The runner removes receipt files after each attempt.