[ENG-3643] Report where the app is published, on the push that carries the credential - #177
Draft
mariojgt wants to merge 1 commit into
Draft
[ENG-3643] Report where the app is published, on the push that carries the credential#177mariojgt wants to merge 1 commit into
mariojgt wants to merge 1 commit into
Conversation
…ntial A site provisioned by a scan from someone's laptop has no address, so Patchstack stores a placeholder. That address is not decoration: it is what Patchstack fetches to check the published page still carries what was scanned, and it is what the dashboard shows. Until now the only thing that ever filled it in was the disclosure widget's beacon, which runs in a page any visitor can load and carries no credential — so a site's address was writable by anyone who could read its UUID from the page source. Patchstack has stopped accepting it from there, which leaves this: the manifest push, which authenticates as the site. So `scan` now sends `url` when it can know one. `url` in `.patchstackrc.json` (or `PATCHSTACK_SITE_URL`) wins, since a person naming their own site outranks any inference. Otherwise it reads the single variable a host publishes to name its own PRODUCTION url — and only that one. Preview and branch deployments are excluded on purpose: the address is adopted once and then belongs to the site, so a per-deployment URL would freeze the site at whatever preview got there first. Cloudflare Pages publishes no way to tell a production deployment from a branch one, so it is left to configure `url` explicitly rather than guessed at. Hosts that cannot be a published site — localhost, a private network, the placeholder suffix itself — are dropped, and the field is omitted rather than guessed when nothing qualifies. The CLI prints the address it reported, because this is the one value in the payload someone might disagree with. The shipped docs had to change with it: they said `scan` sends no environment variable value at all, and that is no longer true. They now name the four variables that are read and say the field is otherwise absent. AGENT-INSTALL.md is a gated artifact — `node field-test/run.mjs --persona hostile --rounds 3` should run against a published build before this ships. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Introduces site URL reporting with clear logic and robust edge-case tests. ��� Quality: 94% Elite · 📦 Size: Large — consider splitting if possible 🛡️ Standards: no pre-flight fit check ran for this change — wire 📈 This month: Your 81st PR — above team average · Averaging Excellent |
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.
Companion to patchstack/saas#1357, which stops the widget beacon from writing a site's identity.
Why this repo has to change
Patchstack provisions a site from the first manifest. A manifest posted from someone's laptop carries no address, so the site is created with a placeholder host. That address is not decoration — it is what Patchstack fetches to check the published page still carries what was scanned, and it is what the dashboard shows.
Until now the only thing that ever replaced it was the disclosure widget's beacon: a request with no credential, naming the site with a UUID printed in the page it runs in. So a site's address was writable by anyone who could load the site. Patchstack has stopped accepting it from there. This is what replaces it — the manifest push, which authenticates as the site.
What it does
scansendsurlwhen it can know one:urlin.patchstackrc.json, orPATCHSTACK_SITE_URLVERCEL_PROJECT_PRODUCTION_URLVERCEL_ENV=productionURLNETLIFY=trueandCONTEXT=productionRENDER_EXTERNAL_URLRENDER=true, not a PR previewRAILWAY_PUBLIC_DOMAINRAILWAY_ENVIRONMENT_NAME=productionPreview and branch deployments are excluded on purpose. The address is adopted once and then belongs to the site, so a per-deployment URL would freeze the site at whatever preview got there first — which is also why
VERCEL_URLis deliberately not read. Cloudflare Pages publishes no way to tell a production deployment from a branch one, so it configuresurlexplicitly rather than being guessed at.Hosts that could not be a published site —
localhost, a private network, the placeholder suffix itself — are dropped, and the field is omitted rather than guessed when nothing qualifies. The server only ever applies it over a placeholder; it never re-points a site whose address is real.The CLI prints the address it reported. It is the one value in the payload someone might disagree with, and a site pointing at the wrong place is otherwise a silent wrong answer in their dashboard.
The docs had to change with it
They said
scansends no environment variable value at all. That is no longer true, and an inaccuracy here is read by installing agents as misrepresentation.README.mdandAGENT-INSTALL.mdnow name the four variables that are read, say the field is otherwise absent, and say what the server does with it.AGENT-INSTALL.mdis a gated artifact.node field-test/run.mjs --persona hostile --rounds 3should run against a published build before this ships — the fixture installs the published package, so it cannot exercise this change end-to-end until then.Tests
New
tests/site-url.test.ts(16) covers normalisation and every detector, including the negatives that matter: a Vercel preview, a Netlify deploy-preview, a Render PR build, a bareURLwith no Netlify marker beside it, and Cloudflare Pages.tests/config.test.tscovers precedence, andtests/client.test.tsasserts the field is sent when known and absent — not null — when not.1595 pass. One suite fails to collect locally because
fastifyis not installed; it fails identically onmain.Ref ENG-3643
🤖 Generated with Claude Code