Record oficina.works as the primary domain
Supersedes the provisional platform-default hosts (<app>.<sqid>.oncarlos.com under Carloku account sqid bds) with the suite's own domain: id.oficina.works credential origin / RP oficina.works directory, at the apex <team>.<app>.oficina.works one team, one instance, one hostname The team slot is new: the provisional shape had nowhere to put the per-team hostname that home spec S7 reserves at enqueue. The RP rename drill (LegacyRPID + a window sized by the guest tail) did not have to run. No app in the suite has a passkey.Config yet -- sign-in is magic-link throughout -- so no credential was ever scoped to an oncarlos.com host. Moving now was free; moving after passkeys ship is not. The full-host RP ID constraint survives the move, with a new reason: oficina.works as an RP ID would be valid at every host in the zone, including the directory and each team instance, collapsing the split origins that home ruling 2 exists to create. Specs only. No code, no behaviour change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJ4p3qTNQqScxS6Z6wp8Pw
1 file changed,
+37
−13
docs/superpowers/specs/2026-08-30-home-design.md+37 −13
CI passed — run details
Intent
Attributed to this commit: 175 g CO₂e (15712881 tokens). This is an attribution, not a measurement — usage counted from this commit's own marker forward to the next one on domain/oficina-works, never backward from it. A turn that produced more than one commit books all of its tokens to the last one, and a concurrent session on this branch can add to the same figure. Some of it was priced using the shared default rate, because no model-specific factor row exists yet for at least one model involved. The Carbon view has the repo total, which is never derived from this attribution.
diff --git a/docs/superpowers/specs/2026-08-30-home-design.md b/docs/superpowers/specs/2026-08-30-home-design.md| index aa0f313..444fbd9 100644 |
| --- a/docs/superpowers/specs/2026-08-30-home-design.md |
| +++ b/docs/superpowers/specs/2026-08-30-home-design.md |
| @@ -52,9 +52,10 @@ blind, replaceable*. |
| | 10 | **Theme is per person, suite-level, resolved before first paint** | Per document; per team; follow-OS only | Paul, 2026-08-30 | |
| | 11 | **One shared instance — and this is not a divergence** — §2 | Instance-per-person; calling it a divergence | This session, 2026-08-30 | |
| | 12 | **Sealed at rest, DEK from platform secrets** | Plaintext (a plaintext column is a plaintext bucket leak) | This session, 2026-08-30 | |
| -| 13 | **Provisional origins are `oncarlos.com` hosts under account `bds`; the RP ID is always the full host** | `carloku.com` (console brand); a suffix RP ID | Corrected 2026-08-30 | |
| +| 13 | ~~Provisional origins are `oncarlos.com` hosts under account `bds`~~ — superseded by 16. The half that survives: **the RP ID is always the full host** | `carloku.com` (console brand); a suffix RP ID | Corrected 2026-08-30 | |
| | 14 | **Hand-roll sign-in: subject is an opaque person ref, link state is sealed** — §5.1 | `rastrillo/auth` as shipped (stores readable addresses); blocking on upstream | Paul, 2026-08-30 | |
| | 15 | **Passkey 2FA is optional per person. Owner-enforceable per-team is NOT in slice one** — §14 | Promising a per-team floor neither spec can build | Paul, 2026-08-30 | |
| +| 16 | **`oficina.works` is the primary domain — RP `id.oficina.works`, directory at the apex, instances at `<team>.<app>.oficina.works`** — §4 | Staying on `oncarlos.com` until passkeys forced the move; keeping the `bds` slot | Paul, 2026-09-03 | |
| --- |
| @@ -231,16 +232,31 @@ The directory obtains its session by exchanging an assertion, the same |
| mechanism instances use (§5.3), so there is one assertion path rather than |
| two. An XSS on the directory cannot reach the RP. |
| -**Provisional hostnames (ruling 13).** Account `oficina`, sqid **`bds`**. |
| -Default addresses are `<app>.<sqid>.<apps-domain>` and the hosted |
| -apps-domain is **`oncarlos.com`** — *not* `carloku.com`, which is the |
| -console brand and appears nowhere in `platform.md`. |
| - |
| -**Never widen the RP ID to a registrable suffix.** WebAuthn permits an RP ID |
| -that is a suffix of the origin's hostname, so `oncarlos.com` would be |
| -*accepted* — and it is shared by every Carloku tenant, which would scope our |
| -credentials across other people's apps. **The RP ID is the full host**, |
| -asserted by a test. |
| +**The hostnames (ruling 16, 2026-09-03).** The suite's primary domain is |
| +**`oficina.works`**, registered and ours. It replaces the provisional |
| +platform-default addresses `<app>.<sqid>.oncarlos.com`, where `bds` was a |
| +Carloku *account* sqid — a hosting artifact that earns nothing on a domain |
| +we own. |
| + |
| +- **`id.oficina.works`** — the credential origin. This is the RP. |
| +- **`oficina.works`** — the directory, at the apex. A different hostname |
| + from the RP, which is what this section requires. |
| +- **`<team>.<app>.oficina.works`** — one team, one instance, one hostname: |
| + `acme.docs.oficina.works`, `acme.sheets.oficina.works`. This is the team |
| + slot the provisional shape never had, and §7's "team name and hostname |
| + reserved at enqueue" needs somewhere to reserve them. |
| + |
| +Hosting stays on Carloku; `oficina.works` is a custom domain in front of it, |
| +with a wildcard certificate per app zone (`*.docs.oficina.works`). |
| + |
| +**Never widen the RP ID to a registrable suffix** — and note that the reason |
| +changed with the domain rather than disappearing. WebAuthn permits an RP ID |
| +that is a suffix of the origin's hostname, so `oficina.works` would be |
| +*accepted* for `id.oficina.works`. On `oncarlos.com` the objection was other |
| +Carloku tenants. On a zone we own it is that `oficina.works` as an RP ID is |
| +valid at *every* host in the zone — the directory and each team instance |
| +included — which collapses the split this very section exists to make |
| +(ruling 2). **The RP ID is the full host**, asserted by a test. |
| --- |
| @@ -410,9 +426,17 @@ Absent from the first draft, and the abuse suite did not test it. |
| works inside the attacker's account. |
| - Both are in gate 3. |
| -### 5.7 The RP rename drill |
| +### 5.7 The RP rename drill — not needed for the `oficina.works` move |
| + |
| +**Ruling 16 moved the domain before this service enrolled its first |
| +credential**, which is the whole reason the move cost nothing. At the time |
| +of the move `home` held no `passkey.Config` at all — sign-in across the |
| +suite was magic-link only — so no credential had ever been scoped to an |
| +`oncarlos.com` host and there was nothing to strand. The drill below is |
| +therefore documented rather than scheduled. |
| -Provisional hostnames schedule this rather than avoid it. **The mechanism |
| +Every *later* hostname move pays the full price described here, which is the |
| +argument for having taken this one early. **The mechanism |
| exists:** `passkey.Config.LegacyRPID` is *"a relying party this instance |
| used to be, accepted for assertions (never registration) so a hostname move |
| doesn't strand enrolled keys"* — verified at source. Set it, run the window, |