sync.listHosts and sync.listReposByCollection return 502 UpstreamFailure against the dev oracle because no relay is running. A schema check cannot distinguish "PDS broke the contract" from "dev environment has no relay", so the generator skips both with the reason documented.
These belong in an integration mode that stands up (or points at) a real relay. Design question: reuse @atproto/dev-env (TestNetwork / relay fixtures) or target a live relay? Note the full TestNetwork harness requires Postgres + Redis; TestPds-style minimal fixtures may not cover relay behavior.
Done when: both endpoints have checks that produce a real verdict in integration mode and a documented skip otherwise.
Done. Neither TestNetwork nor a live relay, as it turns out.
The reference PDS has no route for either endpoint -- they fall through to the pipethrough catchall, which 401s the unauthenticated caller and then proxies to whatever appview is configured. The 502 was just the oracle having no appview at all. So the thing a PDS actually owns here is the auth gate plus faithful proxying, and a tiny stub XRPC server playing the role of appview exercises that whole path with no Postgres or Redis in sight.
What landed:
StubUpstreaminsrc/oracle.ts, plusgetOracleWithStubUpstream()which boots the TestPds with its bskyAppView pointed at the stub. e2e uses this by default now.src/checks/integration.ts:sync.listHosts.integrationandsync.listReposByCollection.integration. They assert the 401 unauthenticated gate against any target, and the proxied happy path plus lexicon output shape when an upstream exists.PDSUITE_STUB_UPSTREAM_URL, documented indocs/integration-mode.md.The three paths, verified:
pnpm e2e(lifecycle): both checks PASS with real 200 verdicts through the stub. 56 pass overall, exit 0.mode-lifecycle-not-enabled, documented.endpoint-not-implemented:-- tranquil 501s both unless you send an atproto-proxy header, which is their documented architectural rule, so the runner's absence-as-skip behavior is doing exactly what it should.Generator skip reasons now point at the integration checks instead of a shrug. Closing.