oficina / memoria Public

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
Paul Campbell pushed by paul@keymail.dev 87f2f544cbe6d42cb11314784a8d5dfe461b8243 parent 617eb2a
2 files changed, +55 −13
  • QUESTIONS-FOR-PAUL.md +33 −6
  • README.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