Control plane for AI code review · review-only pilot

Put a gate between your pull requests and the AI that reviews them.

Galactic Outpost is the admission, idempotency, and authority boundary between GitHub pull requests and sandboxed AI review. It admits the event, mints the identity, caps the spend, brokers a single-use read lease, and validates every byte of returned evidence before a human sees a finding. There is no checkout on the runner, no GitHub write API, and no token downstream.

REVIEW-ONLY PILOT · 158 LOCAL TESTS PASS · NOTHING HAS RUN LIVE

  • Server-owned allow-lists
  • Deterministic task identity
  • Durable intent in SQLite
  • Single-use read leases
  • Split control & broker listeners
  • Inference must report LiteLLM
  • Fail-closed validation
The problem

Where AI review bots go wrong.

The model is rarely the dangerous part of an AI reviewer. The checkout, the write token, and the rendering that teams bolt on around it are.

FAULT 01

The checked-out payload

A pull_request_target workflow that checks out PR content hands the author’s code your OIDC token and your runner. The exploit is a one-line workflow edit away.

FAULT 02

The double review

Webhook redelivery, a reopened PR, an Actions rerun — naive bots dispatch again each time. You pay twice and race yourself.

FAULT 03

The helpful write token

A bot that comments needs a write scope. A write scope in a prompt-injectable system is a lateral-movement kit with a friendly avatar.

FAULT 04

The trusting render

Model output pasted into comments, checks, or ::workflow-commands is attacker-reachable markup executed with your bot’s authority.

Outpost’s answer is a perimeter rather than a prompt. The runner never checks out PR content, nothing holds a GitHub write scope, and no reusable token exists to steal, because none of that was ever installed.

The boundary

Two small objects carry the boundary.

Everything Outpost enforces hangs off two small, verifiable objects: a task identity that makes retries converge, and a read lease that makes access expire.

Primitive A — the task identity

Retries converge on one task

Identity is derived from the event, not generated at dispatch:

external_task_id  github:{repository_id}:pr:{number}:{head_sha}
attempt          1
idempotency key   {external_task_id}:1
workflow ID       sc:{opaque deterministic sha256}

Duplicate delivery and Actions reruns reuse the same dispatch. A different head SHA is deliberately a different task.

Primitive B — the read lease

A ticket, not a credential

The sandbox’s only path to repository content — and it barely qualifies as access:

  • single-use, expires in fifteen minutes or less
  • bound to the task, attempt, idempotency key — and, once started, the actual run and workflow IDs
  • authorization to request access, not a credential itself
  • never reaches the Actions runner
  • redeemed against a StarColony attestation, which Outpost checks by online introspection; StarColony has not shipped that endpoint yet
  • in the public pilot, redeems to an anonymous HTTPS clone descriptor — no GitHub token exists to steal

Intent persists to SQLite before the network call. While dispatch_pending, the workflow re-POSTs the identity-equivalent event; after the 180-second dispatch claim expires, the durable intent is reclaimed and the identical key reissued. Ambiguity reconciles by reissuing the identical key, never by minting a new task. The same key with different material input gets a 409 conflict.

The courier

The runner is a courier.

pull_request_target is dangerous when the job checks out pull-request content. Outpost keeps the workflow file on the protected default branch and gives the job no way to touch PR content.

A contract test rejects forbidden primitives in the template itself, and the threat model states the residual: this path is safe only while it never checks out or executes PR content. A test fails if the template ever gains such a step. There is no hosted CI, so the local suite is that gate.

Dispatch pipeline

Kill any process and the pipeline converges.

Every stage is derived from durable state, so duplicate deliveries, reruns, and crashed processes land on the same execution. The status vocabulary is five words.

  1. PR event, trusted base. opened / synchronize / reopened fires the trusted-base workflow; the runner parses $GITHUB_EVENT_PATH only.

  2. Tailnet identity, metadata in. SHA-pinned Tailscale action, workload identity federation, one POST of normalized PR metadata. GITHUB_TOKEN has no repository API scope.

  3. Admit, quota, persist. Repository ID and owner/name allow-list, approved base ref, approved head-ref prefix, head repo = base repo; atomic active + rolling-hour quotas; immutable intent to SQLite; lease issued.

  4. Idempotent dispatch. One POST with the deterministic key; the first sc: workflow ID and first non-null run ID are bound, and drift is rejected forever after.

  5. Attested sandbox review, on the StarColony side and not yet built. The design has the sandbox prove run, workflow, and attempt identity, redeem the lease, review base_sha..head_sha read-only with default-deny egress, and route inference through LiteLLM on a run-scoped key.

  6. Validate everything, fail closed. Every evidence artifact fetched by content digest; size, digest, and media type verified; every repository-task-result/v2 invariant enforced.

  7. A job summary, and only a job summary. Escaped, bounded findings to GITHUB_STEP_SUMMARY; the job fails on error / critical. No comments, no checks, no statuses.

The gates

Five server-side checks.

None of these is enforced by a prompt. Each is a server-side check with a test in the local suite.

  • Gate 01
    Admission

    Repository content never supplies policy.

    • numeric repo ID + owner/name
    • base ref · head-ref prefix
    • server-owned config
    Mechanism: ALLOW-LISTED
  • Gate 02
    Identity

    Retries converge; they don’t multiply.

    • deterministic external_task_id
    • attempt 1
    • one Temporal execution
    Mechanism: DETERMINISTIC
  • Gate 03
    Quota

    Spend is capped before the task exists.

    • active-task cap
    • rolling one-hour cap
    • atomic check · duplicates don’t consume
    Mechanism: ATOMIC
  • Gate 04
    Lease

    Access is a ticket, not a credential.

    • single-use · ≤15 min
    • attested redemption · introspection pending
    • issuance cross-check
    Mechanism: SINGLE-USE
  • Gate 05
    Validation

    Absence is never success.

    • digest-fetched evidence
    • workspace_changes.count = 0
    • gateway = litellm · verified cleanup
    Mechanism: FAIL-CLOSED

Retries beyond the first attempt are not exposed in the pilot. The requirement for when they are: maxima only decrease, allow-lists only shrink, deny-lists only grow. policy_digest is already immutable per task.

Result validation

One result shape, checked field by field.

Outpost accepts exactly one result shape, repository-task-result/v2, and rejects everything else. Open a row to read the evaluation.

Result Condition Verdict
Structured findings, SHAs match, clean workspace Verdict: ACCEPTED
evidence digest · base/head bound · workspace_changes.count = 0 · teardown.verified = true — rendered to the job summary, escaped and bounded.
workspace_changes.count = 3 Verdict: INVALID
review mode mutated nothing, or it isn’t a review. Any nonzero workspace change count fails the task — there is no threshold to tune.
Patch field present in a review result Verdict: INVALID
patch, change-manifest, and tree-digest fields are forbidden in repository-task-result/v2 — and a zero-byte patch is never reinterpreted as a clean review.
resolution.inference_gateway = "direct" Verdict: INVALID
inference is valid only when reported through LiteLLM; any other gateway invalidates the result outright.
Terminal success, no findings evidence Verdict: FAILED CLOSED
absence is not success; missing evidence or unverified cleanup fails the task.

Model output is untrusted data end to end: schema-validated, byte-bounded, control characters rejected, unnormalized paths rejected, Markdown escaped — never shell source, never a GitHub expression, never a workflow command.

Boundaries

What was never installed.

These are requirements with contract tests, not configuration defaults, except where a row says otherwise.

Never executes PR content on the runner. No checkout, fetch, download, import, build, test, source, or execution of pull-request content — and the contract suite proves the template contains no such step.

Never calls a GitHub write API. No PR reviews, no inline comments, no commit statuses, no check runs. The renderer has no write path to invoke.

Never hands StarColony a GitHub token. No Actions GITHUB_TOKEN, no Tailscale credential, no write token — by requirement, not configuration.

Never lets a patch masquerade as a review. Forbidden fields or a nonzero workspace change count, and Outpost rejects the result as invalid_repository_task_result.

Never treats absence as success. Missing evidence, missing cleanup, or an unknown status all become failed, never an empty “clean” review.

Never puts a reusable credential in the sandbox. No source-control write credential, no raw provider key; the pilot redeems to an anonymous HTTPS clone descriptor.

Never lets repository content steer the system. Policy, prompts, budgets, tool grants, adapter selection, callback URLs, egress rules — none can come from repo content; model output can change none of them.

Never bypasses LiteLLM. A result reporting any other inference gateway is invalid.

Never widens a grant on retry. A requirement not yet exercised, since retries are not exposed in the pilot. policy_digest is immutable per task today.

Never exposes dispatch to the sandbox. Separate control and broker listeners. The broker has no task-start or status route, so a compromised sandbox cannot fabricate events or spend budget. Which routes sandbox egress can reach at all is set on the StarColony side and is a live hold point.

What a prompt-injected model is designed to reach: the repo clone, LiteLLM, one lease-redemption endpoint, and the scoped evidence store. No GitHub API, no public internet, no credentials. That egress rule lives in StarColony and the tailnet, and it has not been exercised live.

Site survey

What is proven, and what is held.

Galactic Outpost is a review-only pilot built contract-first. Present tense on this page describes the contract. Here is what the local suite proves, what has been built since, and what is held.

Proven: what the local suite demonstrates

  • Dependency-free Python reference service with separate control and broker listeners
  • 158 tests run with one command: PYTHONPATH=src python3 -m unittest discover -s tests
  • Idempotent dispatch: duplicates, reruns, and crash recovery converge on one task
  • Forbidden-primitive checks on the workflow template itself
  • Durable intent recovery after ownership-claim expiry
  • Every result-validation invariant, including the fail-closed paths
  • A local dispatch runner that resolves one PR from GitHub, sends metadata only, and prints the summary, so the pilot needs no Actions minutes
  • Local review tooling in dogfood: a non-executing ast-grep evidence collector, a two-of-three reviewer consensus check, an MCP server, and a Claude and Codex plugin

Also true

The review is advisory. It does not approve or merge code; it writes one job summary, and the job’s pass/fail, which your branch protection may or may not enforce, is its only signal.

The pilot is one approved public synthetic repository. No forks, no private repos, no arbitrary branches.

The local suite proves Outpost’s side of the contract. The other side is StarColony’s, and StarColony has not built the repository-task workflow, the evidence API, or attestation introspection yet. Nothing has run live.

Contact

Talk to us before the pilot widens.

Outpost is a reference build and a dogfood tool today, run by one operator against one synthetic repository. If you want AI review on your pull requests with the authority questions settled first, we would like to hear what your repositories look like.

Dispatch manifest · pilot contact
STAGEsynthetic review pilot
SCOPEone approved public repo
SUBSTRATEStarColony on Temporal, workflow not yet built
SURFACEa job summary, or stdout from the local runner
Talk to us

A conversation about your repositories and our hold points. No signup exists yet.