feat(change): require host[:port] authority in change URIs#329
Merged
Conversation
JamyDev
reviewed
Jul 10, 2026
17dbcc1 to
d4c28d4
Compare
24c270f to
fad6b9e
Compare
behinddwalls
added a commit
that referenced
this pull request
Jul 10, 2026
## Summary
### Why?
Change URIs are the system-wide identity of a code change — stored as a
primary-key column, correlated by strict string equality, and shared
across SubmitQueue, Stovepipe, and Runway via the `api/base/change`
contract. Today only `git://` URIs name the provider instance; GitHub
and Phabricator URIs carry no host, so the same URI can name two
different changes on two provider instances, and the host lives
out-of-band in queue config — coupling change identity to queue
topology.
### What?
Adds `doc/rfc/change-uri.md`, a spec for change URIs: every URI is
`scheme://{host[:port]}/{path}` where the scheme names the provider
model, the mandatory authority names the instance, and the path pins the
change to an exact code state. Defines the per-provider formats (GitHub
PR, Phabricator Diff, git ref/commit), canonical-form rules (validated,
never normalized: lowercase host, verbatim optional port, full 40-hex
SHAs, byte-for-byte round-trip), and rejected alternatives (out-of-band
host, per-flavor `ghe`/`ghes` schemes, web URLs as identity).
Also links the RFC from `doc/rfc/index.md` under Shared, and drops a
pre-existing duplicated "Build Runner" entry from the index.
## Test Plan
## Issues
## Stack
1. @ #328
1. #329
JamyDev
approved these changes
Jul 10, 2026
## Summary
### Why?
The Change URIs RFC (doc/rfc/change-uri.md, previous PR in this stack) makes every change URI carry the provider instance's `host[:port]` as its RFC 3986 authority, so a URI is globally unambiguous on its own: GitHub and Phabricator URIs previously carried no host (the same URI could name two different changes on two provider instances), and the `ghe`/`ghes` schemes stood in for an instance discriminator without actually being one.
### What?
- `platform/base/change/github`: parser rewritten on `net/url`; format is now `github://{host[:port]}/{org}/{repo}/pull/{pr}/{sha}`; single `github` scheme — `ghe`/`ghes` are rejected; parsed form gains a `Host` field.
- `platform/base/change/phabricator`: same treatment; format is now `phab://{host[:port]}/D{revision}/{diff}`; the host moves in-band from queue config into the URI authority.
- `platform/base/change/git`: unchanged format (it already carried the authority); gains only the new lowercase-host validation.
- `platform/base/change/changeutil`: new `IsLowercaseASCII` predicate — canonical form is validated, never normalized (uppercase hosts are rejected, not folded), matching the existing full-40-hex SHA rule.
- Contract docs updated in `api/base/change` proto (comment-only, regenerated via `make proto`), `platform/base/change`, and entity comments; all test fixtures across gateway, orchestrator, extensions, runway, integration, and e2e suites moved to authority-bearing URIs (`github.example.com` / `phab.example.com`).
No wire change: `Change.uris` stays a repeated string; only the accepted grammar of its contents changes. Pre-production, so this is a hard cutover with no dual-format window (per the RFC's rejected alternatives).
## Test Plan
✅ `make test` (65/65), ✅ `make build`, ✅ `make proto` / `make fmt` / `make gazelle` idempotent. Parser suites cover the new grammar: host and host:port round-trips, nested orgs, and rejections for missing host, uppercase host, host-less legacy URIs, and `ghe://`/`ghes://` schemes.
3771850 to
42c89c8
Compare
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
Why?
The Change URIs RFC (doc/rfc/change-uri.md, previous PR in this stack) makes every change URI carry the provider instance's
host[:port]as its RFC 3986 authority, so a URI is globally unambiguous on its own: GitHub and Phabricator URIs previously carried no host (the same URI could name two different changes on two provider instances), and theghe/ghesschemes stood in for an instance discriminator without actually being one.What?
platform/base/change/github: parser rewritten onnet/url; format is nowgithub://{host[:port]}/{org}/{repo}/pull/{pr}/{sha}; singlegithubscheme —ghe/ghesare rejected; parsed form gains aHostfield.platform/base/change/phabricator: same treatment; format is nowphab://{host[:port]}/D{revision}/{diff}; the host moves in-band from queue config into the URI authority.platform/base/change/git: unchanged format (it already carried the authority); gains only the new lowercase-host validation.platform/base/change/changeutil: newIsLowercaseASCIIpredicate — canonical form is validated, never normalized (uppercase hosts are rejected, not folded), matching the existing full-40-hex SHA rule.api/base/changeproto (comment-only, regenerated viamake proto),platform/base/change, and entity comments; all test fixtures across gateway, orchestrator, extensions, runway, integration, and e2e suites moved to authority-bearing URIs (github.example.com/phab.example.com).No wire change:
Change.urisstays a repeated string; only the accepted grammar of its contents changes. Pre-production, so this is a hard cutover with no dual-format window (per the RFC's rejected alternatives).Test Plan
✅
make test(65/65), ✅make build, ✅make proto/make fmt/make gazelleidempotent. Parser suites cover the new grammar: host and host:port round-trips, nested orgs, and rejections for missing host, uppercase host, host-less legacy URIs, andghe:///ghes://schemes.Stack