carlos / platform Public

spec: step 3 built on analytics-step3; the eleven step 3 rulings in §8

Status line names the branch and its plan; §8 lists the rulings made
on Paul's behalf while building the browser door, each cheap to
overturn; the pinfra collision grep for /__carlos/ is recorded as run.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 057ec98d196135a6e5c65c328bc2b79bcf5897ef parent d9a5bc0
1 file changed, +42 −2
  • docs/superpowers/specs/2026-09-07-errors-and-analytics-design.md +42 −2

CI passed — run details

diff --git a/docs/superpowers/specs/2026-09-07-errors-and-analytics-design.md b/docs/superpowers/specs/2026-09-07-errors-and-analytics-design.md
index 30d307ecf..c1c0ec571 100644
--- a/docs/superpowers/specs/2026-09-07-errors-and-analytics-design.md
+++ b/docs/superpowers/specs/2026-09-07-errors-and-analytics-design.md
@@ -4,8 +4,12 @@
**Status:** approved (Paul, 2026-09-07: "go ahead with that and plan, build
review cycle overnight"). Rollout step 1 (§7) is merged (forge main 1a99060; plan
`docs/superpowers/plans/2026-09-07-errors-step1-log-and-edge.md`). Step 2 is
-implemented on branch `analytics-step2` (plan
-`docs/superpowers/plans/2026-09-07-analytics-step2-edge-counting.md`). Every
+merged (forge main 40c6ab7; plan
+`docs/superpowers/plans/2026-09-07-analytics-step2-edge-counting.md`). Step 3
+(the browser door and `carlos.js`) is built on branch `analytics-step3` (plan
+`docs/superpowers/plans/2026-09-07-analytics-step3-browser-door.md`; its
+planning rulings and the whole-branch review's rulings are listed at the end
+of §8). Every
choice below is marked **(decision)** and can be overturned cheaply; the
four in §8 are Paul's **(ruling)**s of 2026-09-07 and are marked where
they land. Drafted by Claude Fable,
@@ -775,6 +779,42 @@ Four questions were open in the draft; Paul answered all four.
The `platform-infrastructure` collision check for `/__carlos/` is still
worth one grep before step 3 ships; the double underscore makes a hit
unlikely enough that it is a checklist line, not an open question.
+(Run 2026-09-07 while building step 3: no hit.)
+
+**Step 3 rulings (Claude, 2026-09-07, made on Paul's behalf while building
+`analytics-step3`; each is cheap to overturn):**
+
+1. Both switches travel as one `telemetry.Switches{Count, Door}` map from
+ the host pass into the edge.
+2. A refused beacon is counted in `dropped` whenever the door is open,
+ regardless of the `count` switch (the tab shows `dropped` regardless;
+ the fleet default is count off / door on, so without this every
+ refusal on a default app is invisible; a drop-only day file carries no
+ visitor data). `door: off` records nothing: the owner shut it.
+3. Drops that happen before the body is read (origin, size) are charged
+ to the hostname's root app.
+4. The per-visitor rate key is `fnv64(clientIP ‖ UA)` in edge memory,
+ unsalted, never stored.
+5. The loader `/__carlos/carlos.js` is a two-line script that appends the
+ hashed asset; errors thrown before the asset runs are missed.
+6. `validPathPrefix` refuses `__carlos` and `lookupUpstreamPath` ignores
+ such a key defensively; the intercept matches the cleaned first
+ segment too, so `/./__carlos/x` is never proxied.
+7. Coverage lines: the Analytics tab shows `edge` always and adds
+ `browser` once the range has a named event or a browser drop; the
+ Errors tab shows `log, edge` always and adds `browser`/`server` once a
+ record with that source is in the window.
+8. The reserved path sits before the observer wrap and so before the
+ password gate: the snippet and both beacons are reachable on a gated
+ host; the Origin rule, caps and buckets are the defence there. Pinned
+ by a test.
+9. The door is checked before the body is read: a door-off hostname
+ answers 202 and reads nothing.
+10. The Origin rule accepts the port the edge listens on (`-https`),
+ and `http` origins only under `--dev`.
+11. The coalescing budget (§3.2's 1,000 per app-hour) is per (app,
+ source) with one `_overflow` row per source, so a browser flood
+ cannot blind edge errors.
## 9. Review round 1