docs: the origin is oficina.works, and what the old hostname still does
The certificate for memoria.oficina.works issued at 07:47Z. MEMORIA_ORIGIN now points there and the instance has been restarted onto it. That was the whole switch: no hostname is compiled into this binary, so there was nothing to rebuild — only README.md differed from the live 71bebef. Two things the README now states because they were checked rather than assumed: - memoria.bds.oncarlos.com still answers, and sign-in there still starts. A first draft of this paragraph said the old host was refused. It is not. csrf.SameOrigin reads Sec-Fetch-Site before it compares origins, so a browser sitting on the old hostname sends same-origin and passes; what gets a 403 is a scripted post carrying a stale Origin header, which is what my curl probe was. The mailed link, whose base is MEMORIA_ORIGIN, is what actually funnels people onto one host. - QUESTIONS-FOR-PAUL §3 still said it had never run anywhere but localhost. New §7 flags that the deployed hostname carries no <team> label, which home ruling 16 and spec §6.3 both specify and which §6.3's barrier 2 is defined to compare. All four live siblings are <app>.oficina.works with no label and no wildcard cert, so this matches them rather than inventing a team name alone. The spec is deliberately untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJRwhRTr2kBeBjQNuH4HWm
2 files changed,
+55
−13
QUESTIONS-FOR-PAUL.md+33 −6README.md+22 −7
diff --git a/QUESTIONS-FOR-PAUL.md b/QUESTIONS-FOR-PAUL.md| index d6f569a..64646a8 100644 |
| --- a/QUESTIONS-FOR-PAUL.md |
| +++ b/QUESTIONS-FOR-PAUL.md |
| @@ -82,14 +82,15 @@ the source, never to cache its authorization. Tell me if you would rather |
| trade differently, because the alternative is a short-TTL cache and that |
| is a stated leak window rather than a correctness fix. |
| -## 3. Deploy it, or leave it local? |
| +## 3. Deploy it, or leave it local? — ANSWERED: it is deployed |
| -It has never run anywhere but localhost. Deploying creates a new app on |
| -your `bds` CARLOS account, which is outward-facing provisioning I did not |
| -want to do unattended. One command when you want it, in the README. |
| +Live at **https://memoria.oficina.works**, account `bds`, channel `edge`. |
| +The origin moved off `memoria.bds.oncarlos.com` on 2026-09-04 once the |
| +certificate issued; see the README's "Live" section for what that entailed |
| +and what the old hostname still does. |
| -Local is genuinely usable — keymail accepts the loopback `client_id`, which |
| -I verified. |
| +Local is still genuinely usable — keymail accepts the loopback |
| +`client_id`, which I verified. |
| ## 4. Your rastrillo CLI is about six releases stale, and it affects every app |
| @@ -139,3 +140,29 @@ you'd prefer, or whether it belongs upstream in rastrillo. |
| asked. Codex's own banner says `gpt-5.6-sol`. I recorded the discrepancy |
| in the spec's review table rather than picking one, since §Review requires |
| attributing a review to a model and the two sources disagree. |
| + |
| +## 7. The deployed hostname has no `<team>` label, and the spec says it should |
| + |
| +home ruling 16 and this project's own spec (§6.3, and line 4) put an |
| +instance at **`<team>.<app>.oficina.works`**. In §6.3 that label is not |
| +decoration: barrier 2 is *"memoria's client refuses any host whose |
| +`<team>` label differs from its own"*, test-enforced against a fixture of |
| +hostile hostnames. A hostname with no team label gives that guard nothing |
| +to compare. |
| + |
| +What is deployed, across the whole suite, is `<app>.oficina.works` — no |
| +team label, no wildcard certificate: `docs.oficina.works`, |
| +`sheets.oficina.works`, `calendar.oficina.works`, and now |
| +`memoria.oficina.works`. I matched the four live siblings rather than |
| +invent a team label on my own, because slice 0 has no siblings for barrier |
| +2 to defend against and consistency with what is already running seemed |
| +the safer default. |
| + |
| +It stops being free at slice 3, when the connector client wants a label to |
| +compare. Roughly the options: re-host every app under a team label before |
| +then — a second origin change each, and every one is a sign-in cutover — |
| +or amend ruling 16 to make the team label a slice-3 addition and say what |
| +barrier 2 compares until it exists. |
| + |
| +**I did not touch the spec.** Ruling 16 is settled and AGENTS.md forbids |
| +relitigating one in a drive-by. This is the flag, not the change. |
diff --git a/README.md b/README.md| index 129b2ca..9780666 100644 |
| --- a/README.md |
| +++ b/README.md |
| @@ -29,7 +29,7 @@ once, at indexing time — not just the passages behind an answer. See |
| ## Live |
| -**https://memoria.bds.oncarlos.com** — account `bds`, channel `edge`, |
| +**https://memoria.oficina.works** — account `bds`, channel `edge`, |
| serving `71bebef`. Sign in with `paul@keymail.dev`, `paul@rslw.com` or |
| `paul@tito.io`; real email goes out through the platform's SES, so no |
| sign-in link is ever written to a log. |
| @@ -38,12 +38,27 @@ It starts **empty**. Paste or upload on the front page to fill it — the |
| seed tool needs filesystem access to the database, so it only works |
| against a local instance. |
| -`memoria.oficina.works` is attached to the same route but was still |
| -`pending-dns` with no certificate when this was written, so the origin |
| -stays on `oncarlos.com`. Switching it later means changing |
| -`MEMORIA_ORIGIN` and restarting: that value is the CSRF yardstick, the |
| -cookie scope, and keymail's `client_id`, so it must match the host the |
| -browser is actually on. |
| +The origin moved here from `memoria.bds.oncarlos.com` on 2026-09-04, once |
| +the certificate issued — the move `docs`, `sheets` and `calendar` had |
| +already made, along with `id.oficina.works` and the apex. It was |
| +`MEMORIA_ORIGIN` and a restart and nothing else: no hostname is compiled |
| +into this binary. |
| + |
| +`memoria.bds.oncarlos.com` still answers. It is the platform route the |
| +custom hostname sits in front of, not a second deployment. Signing in |
| +there still *starts* — but it does not leave you signed in there, because |
| +`MEMORIA_ORIGIN` is the base of every emailed link, so the link lands you |
| +on `oficina.works` and the session cookie is set for that host. Use the |
| +canonical name. |
| + |
| +That value is also the CSRF yardstick and the OAuth `client_id` keymail |
| +validates redirects against, so it must match the host the browser is |
| +actually on. Be precise about how much the CSRF half is doing, though: |
| +`csrf.SameOrigin` reads `Sec-Fetch-Site` **before** it compares origins, |
| +so a browser sitting on the old hostname sends `same-origin` and passes. |
| +What refuses is a scripted post carrying a stale `Origin` header. The |
| +mailed link, not the CSRF check, is what actually funnels people onto one |
| +host. |
| **The DEK is the whole corpus.** It lives in `carlos secrets` for this |
| app, and a copy is at `memoriadrive/DEK-production.txt`. Lose both and the |