Decide the means the core speaks HTTP with: the protocol crate, not a client (#292) - #296
Merged
Merged
Conversation
… client (#292) Record 0292 decides that the core writes and reads HTTP/1.1 through `ureq-proto`, taken with `default-features = false` and the `client` feature alone, driven over a socket the core opens and the TLS stream 0243 decided. The manifest carries the entry with the clause of 0103 that admits it and the condition that retires it, the lockfile carries the seven packages it resolves to, and the index in `docs/decisions/README.md` names the record. What goes wrong without it: the socket #27 writes is written against the first package that compiles, and the first package that compiles for HTTP in this ecosystem is a client. A client holds 0027's bounds as its own settings on a clock 0102's injected source cannot reach, adds a proxy read from the environment to the destinations 0069 fixed, and drops a cancelled body instead of reading it to 0027's bound. None of those reversals reddens a gate here, because the invariants register reads `src/` and judges no dependency, so the record is the only place the reversal is refused. I re-took every count in the record with `--locked` in the scratch crates the readings came from and they reproduce to the package, and I re-ran every source reading against the vendored and registry sources at the versions named. Build, test, lint, format, invariants, decision-records, statements, doc-paths, fixture-scrub, dependencies and all seven target triples pass on this tree; the thread-detector leg cannot link on this machine and is the runner's verdict alone. Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
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.
The issue this belongs to
Closes #292
What changed
The core's HTTP means is decided and recorded.
docs/decisions/0292-the-means-the-core-speaks-http-with.mddecides that the core writes and reads HTTP/1.1 throughureq-proto, taken withdefault-features = falseand theclientfeature alone, driven over a socket the core opens and the TLS stream 0243 already decided. It is admitted under 0103's clause for a dependency a landed record already requires, the records being 0011, which measures that the standard library reaches TCP and stops, and 0027, which requires a transport.The manifest carries the entry with the clause that admits it and the condition that retires it written beside it, as 0103 requires. The lockfile carries the seven packages the entry resolves to. The index in
docs/decisions/README.mdnames the record.The record takes a protocol rather than a client, and it says why as records rather than as taste: every bound, every connection and every destination that 0027, 0069 and 0102 decide is a value
src/server/transport.rsalready holds, and a client would hold them instead, on a clock 0102's injected source cannot reach, with a proxy read from the environment that 0069's set does not admit, and with a cancelled body dropped rather than read to 0027's bound.What failure it prevents
The one 0103 was written against, one layer up. The socket #27 writes would otherwise be written against the first package that compiles, and the first package that compiles for HTTP in this ecosystem is a client that arrives holding opinions about timeouts, pools, redirects and proxies which four landed records here have already decided differently. None of those reversals reddens a gate: the invariants register reads
src/and judges no dependency, so a tree that moved its bounds into a client keeps a greeninvariantsleg while 0102's promise stops being provable. The record is the only place that reversal is refused, which is why it is written before the code.Evidence
The tree every reading is against:
The record's counts were first taken on 2026-09-03 in scratch crates outside this tree. I re-took every one of them today with
--lockedin those same crates, with the toolchainrust-toolchain.tomlpins (cargo 1.98.0 (797e8a9bc 2026-08-05)), and every number reproduces to the package. The scratch crate declaringureq-proto = "0.6"and nothing else, and the one declaring it withdefault-features = falseandfeatures = ["client"], resolve to the same seven packages on all seven triples:The licence of every package the entry brings, read rather than assumed:
The four behaviours 0103 refuses, re-read over the vendored sources of all seven packages:
The readings the record makes of the client shape were re-run against the registry sources at the versions the record names (
ureq-3.4.0,reqwest-0.13.4,isahc-2.0.1,attohttpc-0.31.0,minreq-3.0.0,hyper-1.11.1): thepub(crate) struct CurrentTimeattimings.rs:177withInstant::nowas its default at 215-218,proxy: Proxy::try_from_env()atconfig.rs:872, noimpl Dropanywhere inureq/src, the eleven methods ofpool.rs, the thread inreqwest's blocking client at 1414 and inisahc's agent at 144, noplatform.verifierstring inattohttpc, andminreq'sstatic CONFIGand itsrustls-platform-verifierat0.6.2. Every line number in the record is the one the source prints today.The gate's legs, run on this tree, which is byte for byte the commit pushed (nothing was unstaged when they ran):
The means
Markdown for the record, because a decision record is what
docs/decisions/0001-decision-records.mdfixes as the shape, and a manifest entry with its lockfile for the dependency, because that is the one place 0103 says an admitted dependency and its clause live. Nothing else is available for either, and no language, runtime or tool arrives with this change that the tree did not already carry: the seven packages are pure Rust, one of them runsrustc --versionat build time and none compiles C.What this does not cover
The thread-detector leg. It runs the suite for
x86_64-unknown-linux-gnuunder-Zsanitizer=threadand there is nocclinker for that target on this machine, so the local run refused withlinker cc not foundbefore a single test was collected. That verdict is the runner's alone and is not claimed here. The coverage leg is the same: not measured locally, the runner's number is the one to read.The transport itself. Nothing here opens a socket, and the record says so of itself. #27 is where the read-write loop over
rustls::StreamOwned<ClientConnection, TcpStream>is written, and this record is what that socket is written against. #27's own text names #292 as what it waits on and does not yet name the record by number; that line belongs on #27 and is not written from here.The entry 0243 needs.
rustlsandrustls-platform-verifierare not added by this change, and #291 still stands in front of them, because every graph that includes them carries a C build the target leg cannot compile today. The entry landed here is pure Rust and does not reach that question, which the targets leg above shows: all seven triples compile with it.Nothing runs on any triple but this machine's. The seven-triple result is a compile and never a run, which the targets leg prints beside its own verdict.
Nothing here reads the clause line beside the manifest entry. 0103 says of itself that nothing in this repository does, and the dependencies leg prints the same bound, so whether the clause written there is the right clause is a reading for whoever reviews this and for nobody else.
Who has read it
Nobody besides me has read this change. There is no second reader on this board tonight, and the evidence above stands in place of one: every count in the record was re-taken with
--lockedand reproduces, every source reading was re-run at the version named, and every gate leg that can run on this machine has run on this tree.The pull request this replaces
#295 carried this same commit without the
Signed-off-bytrailer theDCO sign-offcheck requires, and adding the trailer rewrites the commit. A pushed branch is never rewritten here, so the corrected commit arrives under a new branch name and #295 is closed with this reason written into its body. The tree content is identical: the diff of the two heads is empty.