Before you start
Use a feature branch with a GitHuborigin. Push-back uses your local Git credentials; the control plane never receives permission to push. The branch must be a real refs/heads/... branch, and push-back refuses the repository’s default branch.
For reliable Check Run reporting, configure a GitHub App with checks: write. Creating a pull request also needs pull_requests: write. Configure PRELOOP_PUBLIC_URL with an address that GitHub viewers can reach if Check Runs should link back to the run page. A local-only URL leaves the check summary without a public details link.
Choose a command
--create-pr implies --push. A plain preloop run does not request push-back, although workflow loading and job actions can still use GitHub or other network services.
Submit and publish
1
Submit from the feature branch
Run the workflow from the checkout that owns the branch:The CLI prints a run ID. A clean checkout records the current commit. A dirty checkout is snapshotted at submission, so CI tests the uncommitted tree as well. The dirty-tree snapshot does not change your index or working tree.
2
Let the run reach a terminal result
The run executes without a webhook trigger. Follow it with Detached submission returns after acceptance. It does not perform the local Git push after the run finishes; publish later from the submitting checkout with
preloop status RUN_ID or inspect output with preloop logs RUN_ID --job JOB_ID.For a non-interactive submit, use --detach and save the printed run ID:preloop push RUN_ID.3
Publish the tested tree
When the run is terminal, the CLI pushes the exact tested commit to The local Git operation is a branch creation, an already-equal update, or a fast-forward. A diverged remote branch is refused rather than force-pushed. The server then verifies the pushed commit’s tree, reuses the branch’s pull request, creates one when requested, and reports any missing Check Runs.
origin and calls the control plane’s publish endpoint:Dirty working trees
For a dirty--push run, a successful result lets the CLI materialize a commit whose tree exactly matches the snapshot tested by CI. The commit is parented on the submitted base commit and uses your local Git identity. If the working tree changed after submission, materialization stops and the CLI asks for a new submission. A failed dirty-tree run is not materialized or pushed.
On a terminal, a dirty push without --create-pr can ask whether to open a PR. The explicit --create-pr flag takes precedence. Otherwise the head commit’s message labels are honored: [no-pr] suppresses creation, while [pr] or [draft] requests creation; a non-interactive explicit --push pushes without opening a new PR unless a label requests one.
Clean-tree push-back can publish red Check Runs after a failed run. This records the tested result without pretending that the run passed. Dirty-tree push-back only materializes after success.
Run IDs and retries
The submit output,preloop status, and error messages expose the run ID. Use the explicit ID when replaying a publish:
Ctrl-C stops the wait; running preloop push RUN_ID later resumes the same idempotent operation. The server does not retry its own GitHub reads: a transport or 5xx failure is returned as a gateway error and the push-back is recorded as blocked with the upstream message, while other failures are returned as client errors.
Checks on the pull request
Check Runs move throughqueued, in_progress, and completed with the job conclusion. Push-back creates missing checks against the effective published commit, including the materialized commit for a dirty-tree run. The push webhook echo for that same published commit is recognized, so the workflow is not run a second time merely because push-back published it.
The control plane verifies the tested tree before publishing checks. If the GitHub branch points at a different tree, the publish is blocked. The server also refuses the default branch as a push-back target; keep the default branch on the normal webhook flow.
Troubleshooting
Verify the branch and PR after a successful publish:
