Seven flows, from the system map down to the finest mechanism. Each one answers a single question, and answers it by drawing — not by naming.
Level 0 · the whole system
The system has two halves that barely speak to each other: one publishes and the other serves. They meet in exactly one place — and that is what makes the design safe.
src/app.ts imports GitPublisher and does not import runDeploy.
The panel publishes through git; it has no route to S3.Level 1 · human actor
The actor the system exists for. They are not developers, and the path has to fit on one screen without a single word of infrastructure.
Level 1 · the panel
No longer a mockup. The panel runs on the reference server, reachable only from the office address range, and since 07 Sep it reads real traffic from the router's own log rather than counting what is in git.
| On the screen | Why it is there |
|---|---|
| State of both trees before anything is touched | the operator sees what is live before deciding to change it |
| Money weights must total exactly 100 | prevents the blank money page — enforced by the validator, not by a warning |
The clid, readable and stable | it will live in reports and tickets for years |
| Exactly what gets written into the campaign | no gap between what the panel shows and what the cloaker receives |
| Requests, bytes, errors and silent sites, last 24 h | read from the router's access log, on the same machine |
| Three distinct silences, never one zero | could not read · the log does not name this site · measured, and it is zero |
| A state, never a greyed-out button | the panel does not control DNS or TLS. Showing reality is honest; offering a button that does nothing is not |
manifest.json, which asks the operator to become a developer. The panel says so on its own screen
rather than hiding it.Level 1 · human actor
The most important architecture decision in this project was not made for elegance. It was made because the alternative loses content in silence.
| Pipeline | Repository | Gate | How it reaches the machine |
|---|---|---|---|
deploy-s3.yml | lander-content | manifest validation, in the panel | OIDC → S3. Sole writer. |
deploy-refserver.yml | lander-deploy-platform | typecheck && test && build — the deploy job will not start if any fail | OIDC → IAM role → SSM SendCommand. No SSH key in GitHub, no port 22 open. |
Level 1 · external actor
The path where the revenue lives. Every arrow here has an invariant tied to it, and every invariant exists because the alternative breaks without warning.
Level 2 · the files
Four files explain the entire system: two of ours, on the server, identical for every domain — and two of theirs, in S3, which are pure HTML.
A site has N campaigns — one per traffic slice (geo, source, ad account).
.php — meaning the file someone uploads is executable. In this design the
snippet lives in index.php, which is ours and version-controlled. The pages they upload are static
HTML. Nothing an operator sends can execute. The guardrail has already proved itself in
production: it rejected 537 files carrying the executable bit during the migration — SVG flags
and the Push Notification Tool had arrived with +x set.<?php
ob_start(); // the snippet emits output
// before our headers
require __DIR__.'/lib.php';
$m = manifest(host());
$c = $m['campaigns'][slug()]
?? $m['campaigns'][$m['default_campaign']];
// the PATH identifies the campaign
$_GET['clid'] = $c['clid'];
include APPLOC.'go.php'; // only computes
// $isItSafe and returns
if ($isItSafe) { noIpFraud(); }
// ALLOWED -> money.php and ENDS
// BLOCKED -> falls through ↓
header('Content-Type: text/html');
s3_stream($c['safe']['key']);
It is also the safe path. BLOCKED does not halt — execution continues and the safe page is served by this very file.
<?php
// go.php calls: money.php
// ?c=echowave-mic&page=chest
$m = manifest(host());
$c = $m['campaigns'][$_GET['c'] ?? ''] ?? null;
$e = $c['money'][$_GET['page'] ?? ''] ?? null;
// dictionary lookup, never
// path concatenation
if (!$e) {
alert('money_page_missing', host());
http_response_code(404); exit;
}
header('Content-Type: text/html');
s3_stream($e['key']); // same response
Fails loud. A missing money page is a bug — it must not turn into silence.
<!doctype html> <html lang="en"> <head> <base href="/_s/echowave-mic/"> <!-- injected by the pipeline at deploy --> <meta charset="utf-8"> <title>EchoWave USB Premium Microphone</title> <link rel="stylesheet" href="css/style.css"> </head> <body> … store, review, static content … <!-- ZERO PHP · ZERO snippet --> </body></html>
This is what an ad reviewer sees. It has to be a real site.
<!doctype html> <html lang="pt-BR"> <head> <base href="/_m/chest/"> <!-- disjoint prefix, so assets never collide --> <meta charset="utf-8"> <title>Bet7K — Baú da Sorte</title> <link rel="stylesheet" href="css/style.css"> </head> <body> … offer, CTA, pixel … <!-- ZERO PHP · ZERO snippet --> </body></html>
Served at the same URL as the safe page, with 200, no redirect.
<base href> is what makes assets work without editing the pages.
Both trees can carry css/style.css under the same name; the prefix injected at deploy sends each one
to look in its own space, and the asset handler does not need to know which branch the visitor received.
It also has a cost, and it was paid: the injected base turned every link into
/host/host/…, which is why acceptance check 8 now requires a 301 on duplicated URLs.Level 2 · mechanism
A machine actor. It runs identically for both doors — that is what guarantees the operator and the developer get the same validation and the same gate.
| Field | Written by | Rule |
|---|---|---|
schema | the panel | constant 1. No default — reserved for a future breaking change |
host | the panel, authored | declaration of where the site goes. Beats the folder name when the two differ |
type | the panel | cloaked or direct. Absent or unrecognised serves nothing — never inferred from an empty campaign set |
files[] | the Action | derived from the repository tree. Never hand-written |
campaigns{} | the panel only | {} is valid — a freshly created site has none yet |
default_campaign | the panel | where a bare-root request falls. Required once a cloaked site has a campaign; must be absent on a direct site |
host is authored rather than derived.
Two folders declaring the same host fail the deploy — uniqueness used to be guaranteed by the file
system and a JSON field does not guarantee it. A host that does not look like a hostname is refused.
And every divergence between folder name and declared host is printed, so it never happens quietly.
Renaming the host of a live site leaves the old prefix in S3, still served to anyone pointing that
domain at us. There is no automatic withdrawal for that case — it is a human decision, written here instead of
discovered later.Level 2 · mechanism
The finest mechanism in the system, and the only one where a mistake raises no error. Read in the vendor's code, not in their documentation.
clid can be ours — and that is what makes the query cheap.
The product's loop only draws at random when the name arrives empty or already exists; a brand-new name passes
straight through. With an identifier derived from the site and the slice, "does it already exist?"
becomes a keyed query against the local database — no network, no catalogue, no third party on the critical path.active=0 at the origin and
active=1 in the cloaker. It was not a bug — it was a manual edit made to run a test. The mechanism
that surfaced it is conferir-campanha.py, which compares field by field.conferir-campanha.py before any redeploy of a cloaked site: it prints exactly
what would be overwritten.Level 2 · what goes wrong
All of these leave the site answering 200, with monitoring green. This is the list of
what the panel and the gates exist to make audible — and, unlike in August, every line now has a mechanism
against it.
| # | Silent failure | What the visitor gets | What now catches it |
|---|---|---|---|
| 1 | Tracking subdomain stops answering | a perfect page with a dead CTA | gate 5 — track. and journey. must resolve and answer |
| 2 | Money page missing from the campaign | a blank or default page on paid traffic | money.php returns 404 and alarms; weights must total 100 |
| 3 | Cache leaks which side was served | the decision is readable from the header alone | gate 7 — cloaked sites must answer no-store |
| 4 | The cloaker sees the CDN's address, not the visitor's | every decision made on the wrong input | gate 9 — measured through the /_ipprobe probe, never inferred |
| 5 | Content deployed but the domain still points at the old box | the old site, indefinitely | still open the Action does not check this. It caused a real question from an operator on 01 Sep |
| 6 | An object exists in the bucket that was never meant to be reachable | an internal file served publicly | gates 3b and 3c — the manifest and every other object must 404 |
| 7 | A manual edit in the vendor panel is silently overwritten | the campaign reverts mid-flight | still open conferir-campanha.py shows it, but only if someone runs it |
Run by testar-site.py before and after every origin switch. A site is approved only
when all nine pass.
| # | Check | What it prevents |
|---|---|---|
| 1 | The domain answers, and we record who served it | without this, nothing below means anything |
| 2 | Every manifest file byte-identical to the repository | discounting only the <base href> the pipeline injects |
| 3 | Prefixed paths: assets 200 with the right type, documents 404 | serving HTML where an image was requested |
| 3b | manifest.json returns 404 | the manifest must never be public |
| 3c | Every other object in the bucket returns 404 | serving a file that exists but was never meant to be reachable |
| 4 | Valid TLS for the domain, and who issued it | — |
| 5 | track. and journey. resolve and answer | a 200 page with a dead CTA — traffic paid for, revenue zero |
| 6 | Outbound /click links resolve — without issuing a GET | requesting them would register a false click in RedTrack |
| 7 | Cache headers do not leak the cloaker decision | the served side was readable from the header alone |
| 8 | Duplicated URLs redirect with a 301 | the injected base turned every link into /host/host/… |
| 9 | The cloaker sees the visitor's address | measured through /_ipprobe, never inferred from the page |
1.1.1.1, never the operating system cache — otherwise it tests the old origin
after a switch and reports success. Unknown and not-applicable never count as a pass.
Origin is read from an explicit header, not inferred from an artefact on the page: the previous version inferred
it from the <base href> and broke on the day we started removing it.