Skip to content

feat(rpf): let the runtime run declared configured gates - #25

Merged
jiunbae merged 1 commit into
mainfrom
feat/rpf-declared-gates
Oct 1, 2026
Merged

jiunbae merged 1 commit into
mainfrom
feat/rpf-declared-gates

Conversation

@jiunbae

@jiunbae jiunbae commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Problem

The rpf runtime hard-coded every RPF_CONFIGURED_GATE as not-run-unavailable, and convergence requires UNAVAILABLE_CHECKS=none. A repository that declared a gate could never reach converged, even when the controller had run the gate. Real runs show this: gates ran, and status stayed blocked or limit-reached.

Change

  • run_configured_gate() runs one exact, non-prohibited declared gate:
    • It runs without a shell, inline code (-c/-e), or env-dump executables.
    • It runs in a worktree whose tracked files are the committed GATE_HEAD_SHA. That commit must carry the approved fence bytes, and the fence base must be one of its ancestors.
    • Its environment has only PATH, HOME, TMPDIR, USER, LOGNAME and DEVELOPER_DIR, plus a fixed locale and CI=1.
    • A timeout kills the gate's whole process session, and the gate is recorded as failed.
    • The run is rejected if the gate changes tracked files or moves HEAD.
    • The output tail is kept only when it contains no restricted content.
  • The result is a process-sealed GateReceipt. capture_authority(gate_receipts=...) accepts passed/failed only with the exact receipt for that gate, command and fence. The receipt is threaded through publish, create_if_absent and captured_authority_valid.
  • Docs: SKILL.md (phase 0, PHASE 4, convergence), runtime-contract.md and concurrency.md.
  • Leftover wording: "This repository has no external provider trust root" now reads "The bundled RPF runtime has no …".

Tests

python3 -m unittest discover -s tests in agents/rpf: 81 pass (74 existing + 7 new). The new tests cover:

  • the pass and fail paths
  • a timeout
  • a passed row without a receipt, a mismatched classification, and a forged receipt
  • an undeclared gate, a prohibited gate, env, bash -c and python3 -c
  • a stale HEAD and a tracked-file change
  • leftover untracked build output, which is allowed
  • a gate that mutates the snapshot
  • environment secrets being dropped

🤖 Generated with Claude Code

The bundled runtime classified every RPF_CONFIGURED_GATE as
not-run-unavailable, while convergence requires UNAVAILABLE_CHECKS=none.
Any repository that declared a gate could therefore never converge, even
when the controller ran the gate with host tools.

run_configured_gate() now runs one exact, non-prohibited declared gate
without a shell, in a worktree whose tracked files are the committed
GATE_HEAD_SHA carrying the approved fence bytes, with a toolchain-only
environment. It returns a process-sealed GateReceipt. capture_authority()
accepts a passed/failed gate row only with the matching receipt; every
other gate stays not-run-unavailable or not-run-prohibited.

Also fixes the leftover "This repository has no external provider trust
root" wording to name the bundled RPF runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jiunbae
jiunbae merged commit d131d86 into main Oct 1, 2026
2 checks passed
@jiunbae
jiunbae deleted the feat/rpf-declared-gates branch October 1, 2026 13:05
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