Repository navigation
refactor: extract the pull request host boundary (A7 step 1) - #676
Merged
Merged
Conversation
services::forge holds the Forge trait, a neutral ForgeError, capabilities and the host-neutral types the runtime needs; GitHub implements it in services::github::forge, its code moved rather than rewritten. The runtime no longer imports GitHub types or matches GitHub errors. Linking instructions, tool descriptions, the URL hint and merge/close detection are parameterised by the host's terms. Diff pages are opaque cursors, and reviewers and labels carry opaque ids.
Reply, resolve, reactions, the request-changes verdict, draft, reopen, revert, auto-merge and update-branch are offered only where the host has them; what the account may do still decides the rest.
…g capability Forge::terms takes the pull request's key; the linking block, the tool descriptions and merge/close detection read every host's terms from core, so nothing in the runtime holds one host's words. Capability flags nothing reads are dropped, and so are the fingerprint and media flags: a host without them answers through the trait's default and its own media read. Native stack writes have trait defaults that refuse.
Tryanks
marked this pull request as ready for review
October 9, 2026 09:16
# Conflicts: # crates/protocol/src/lib.rs
Tryanks
enabled auto-merge (squash)
October 9, 2026 09:19
# Conflicts: # crates/protocol/src/lib.rs
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Step 1 of #643 (A7 of #535): the host trait extracted from the finished GitHub code as a pure refactor. No second host.
Part of #643
Evidence
GitHubApi,GitHubError,PullRequests,PullRequestReads,repository,stack_actions,pull_request_watchand matchedGitHubErrorvariants in pull_requests.rs, pull_request_watch.rs, pull_request_stacks.rs (host study §7.1).After:
grep -rn "services::github\|GitHubApi\|GitHubError" crates/runtime/src crates/ui/src crates/core/srcoutside test files: no matches.HOSTS = [GITHUB], the linking block is byte-identical to origin/main'sLINKING_INSTRUCTIONS, and the MCP description still reads "without asking GitHub." (checked with a throwaway comparison against origin/main, not committed).strip_linking_instructionsnow strips any<pull_request_linking>…</pull_request_linking>block, not only the current text, so older persisted turns get the instructions label too.cargo fmt --all --check: cleancargo clippy --workspace --all-targets --locked -- -D warnings: cleancargo nextest run --workspace --locked --no-fail-fast:1089 tests run: 1089 passed, 13 skipped. An earlier fail-fast run had one failure intcode-traverse::transport an_invitation_that_finds_no_path_pairs_at_a_typed_address, which passed alone and in the full rerun. That test uses a fake host and depends only on protocol and client, none of which this change touches.cargo machete: no unused dependenciesTests touched, none of them with a changed assertion or expected value:
merge_or_close_detection_matches_words_in_the_raw_commandmoved from runtime to core with the same cases, wheremerges_or_closesnow lives (step 3: moved to the owning boundary).pull_requests_tests.rsandpull_request_watch_tests.rs: setup only. The fixture GitHubApi is wrapped inGitHub::new, and the swapped summary service became a swapped forge. The instructions expected by one test arelinking_instructions(). Intests.rs,state.githubbecamestate.forgebuilt withforge::connect.pull_request_reads.rs: the twoPullRequestReviewerliterals gainid(GitHub's id is the login).detail.rspaging test: the page number became the opaque cursor"2", and the conversation literal carriescapabilities.github_errors_keep_their_meaning_across_the_boundary, a neutral error round trip covering the rate-limit retry time and a disabled host.Merge Danger
Door: two-way
Blast Radius: pull-requests
Wire changes, noted above PROTOCOL_VERSION:
Files{cursor}andnext_cursorreplace page numbers, reviewers and labels carry ids, and the conversation and action state carry capabilities. A client and host from different commits on main disagree on these shapes, which is allowed between releases. The release feed now has its own anonymous GitHub transport. Only the release check used the anonymous ledger scope, so the release check sees no difference. pull-request-mcp now depends on tcode-core for the hosts' terms.