docs: Codex round 1 fixes for slice 6 (S6-1..S6-13)
Applies Codex round 1's thirteen findings against README.md, AGENTS.md, PRODUCT.md and the spec, plus a review-record update. S6-1: README's Deploying section enumerates every deploy setting, which five refuse startup on and which two default instead (MEET_ZONE to UTC, CARLOS_RELAY to no relay). S6-2: README and AGENTS.md state the `carlos apps build-probe` prerequisite the deploy-wait guarantee depends on, and the X-Carlos-Version fallback when it is absent. S6-3: README, PRODUCT.md and spec §9 name the chat panel and the live admission controls as script-gated alongside browser media participation; §15.18 notes the widening. S6-4: README and PRODUCT.md say `CGO_ENABLED=0 make ci` and name all three CGO_ENABLED=1 exceptions (make race, native-test's meetcore sub-step, the native Apple bindings), matching AGENTS.md. S6-5: README says the platform supplies CARLOS_SMTP_FROM too, which MEET_SMTP_FROM optionally overrides. S6-6: spec §0.2's rows 3, 6, 9 and 15 and the two paragraphs below the table cite section/ruling only now, dropping the doctrine restatements; PRODUCT.md's actor sentence likewise; ruling 16's provenance kept. S6-7: spec §8.4 gains a 2026-09-14 amendment recording the shipped native milestone and its browser-approval handoff; PRODUCT.md's two native-client citations point at it. S6-8: README's relay paragraph quotes join.html's same-network floor sentence verbatim. S6-9: PRODUCT.md says "five destructive confirmation pairs"; spec §9 says "every confirm page (five)". S6-10: README distinguishes a legacy meeting's first Share (mints a new recoverable invitation) from every retrieval after. S6-11: README and PRODUCT.md describe the agent rate limit as one request a second sustained with a burst of 60, not a flat 60/minute. S6-12: README's canary `instances create` carries --app/--account and states the environment bundle must already exist. S6-13: README and PRODUCT.md link to spec §15.18 as the disposition of record; the platform-124, no-Estilo-tag and credits-branch-canary claims are attributed to dated records rather than presented as independently verified. Also adds the Codex round 1 disposition block to docs/superpowers/reviews/2026-09-14-slice-6-record.md, replacing CODEX_ROUNDS_PLACEHOLDER (a fresh placeholder follows for later rounds), and resolves that file's now-stale carried item on §9's confirm-page count.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CzvnuKhLzudvq7jZ7SvVt2
5 files changed,
+371
−106
AGENTS.md+10 −5PRODUCT.md+52 −36README.md+77 −44docs/superpowers/reviews/2026-09-14-slice-6-record.md+188 −0docs/superpowers/specs/2026-09-07-meet-design.md+44 −21
CI passed — run details
diff --git a/AGENTS.md b/AGENTS.md| index 2617dbb..b7ab6b0 100644 |
| --- a/AGENTS.md |
| +++ b/AGENTS.md |
| @@ -85,11 +85,16 @@ by the framework, outside app middleware. |
| `make release VERSION=<sha>` builds and stamps the artifact; `carlos |
| deploy --app meet --account oficina --channel edge --version <sha> |
| ---target linux-arm64 releases/meet-linux-arm64` ships, promotes and |
| -waits until `/api/version` serves it. A migration applied under an |
| -earlier filename fails at boot; otherwise migrations never re-run. |
| -Every deploy, and every relay config change, restarts the instance and |
| -drops live calls — no drain exists. The wait can time out before |
| +--target linux-arm64 releases/meet-linux-arm64` ships and promotes it, |
| +waiting until `/api/version` serves it — but only once `carlos apps |
| +build-probe --app meet --account oficina /api/version` has been run |
| +for the app (set on the flagship app since 2026-09-09); a new app or |
| +account needs that first, or the wait watches `X-Carlos-Version` |
| +instead, which can report the version adopted before the process has |
| +actually changed. A migration applied under an earlier filename fails |
| +at boot; otherwise migrations never re-run. Every deploy, and every |
| +relay config change, restarts the instance and drops live calls — no |
| +drain exists. The wait can time out before |
| hand-over — check `/api/version` before retrying. See the README's |
| Deploying section for the canary recipe. |
diff --git a/PRODUCT.md b/PRODUCT.md| index 10dfc17..fffc52e 100644 |
| --- a/PRODUCT.md |
| +++ b/PRODUCT.md |
| @@ -17,7 +17,7 @@ |
| ## Platform |
| Web, plus native Mac and iPhone/iPad clients over the same server |
| -contracts (spec §8.4, `native/README.md`). |
| +contracts (spec §8.4's 2026-09-14 amendment, `native/README.md`). |
| ## Users |
| @@ -75,17 +75,22 @@ a captured-logger test, not merely asserted (§0.1). |
| - **Routes today** (`internal/meet/app.go`): `GET /`, `POST /meetings`; |
| `GET /j/{token}` (outside the session group); the holding screen and |
| room; signalling (`stream`, `signal`, `ice`); `POST /m/{sqid}/share` |
| - (2026-09-12); four confirm/POST pairs; Settings and agent tokens; |
| - sign-in including optional Home routes; native handoff endpoints; a |
| - bearer-only `/api/v1/*` group (`api.go`) outside CSRF and the session |
| - group. `GET /healthz`/`GET /api/version` answer from rastrillo itself, |
| - outside app middleware. |
| -- **Scriptless, with one named exception: browser media participation.** |
| - Every other screen — the list, creating a meeting, a link shown once, |
| - every confirm page, sign-in, `/welcome`, the agent token page, the |
| - Share page and the Home account-link screens (§7.1.1), and the |
| + (2026-09-12); five destructive confirmation pairs (remove, takeover, |
| + replace invitation, end meeting, revoke agent); Settings and agent |
| + tokens; sign-in including optional Home routes; native handoff |
| + endpoints; a bearer-only `/api/v1/*` group (`api.go`) outside CSRF and |
| + the session group. `GET /healthz`/`GET /api/version` answer from |
| + rastrillo itself, outside app middleware. |
| +- **Scriptless, with browser media participation as the exception, and |
| + two script-only parts inside a live room.** Reaching a camera and |
| + another browser needs script; so, once a call exists, do the chat |
| + panel (`partials/chat.html` renders it `hidden` until script un-hides |
| + it) and the admission queue's Admit controls (`room.js`). Every other |
| + screen — the list, creating a meeting, a link shown once, every |
| + confirm page, sign-in, `/welcome`, the agent token page, the Share |
| + page and the Home account-link screens (§7.1.1), and the |
| server-rendered parts of the holding screen and room — works with |
| - scripts off (§9; `AGENTS.md`'s UX line carries the same exception; |
| + scripts off (§9; `AGENTS.md`'s UX line carries the media exception; |
| full list below). |
| - **Nothing stored beyond a meeting's bones.** Rooms, peers, admission, |
| chat and presence live in an in-process hub and die with the process |
| @@ -122,10 +127,13 @@ deliberately not here" below for the full, cited list. |
| 15-second hub tick (§2.3, §2.4). A shipped migration is never edited. |
| The agent API's rate limit keys on the resolved agent, not the client |
| address, deliberately (§15.17; see below). |
| -- **`make race`** for any change to `internal/meet/hub` or the stream — |
| - the one place `CGO_ENABLED=1` is allowed, for a test binary only. |
| - **`make browser`** needs UDP, which the Claude Code bash sandbox |
| - blocks (`AGENTS.md`). |
| +- **`CGO_ENABLED=0 make ci` is the server's cgo-free gate; three things |
| + run under `CGO_ENABLED=1`, none of them shipped.** `make race`, for |
| + any change to `internal/meet/hub` or the stream; `make native-test`'s |
| + own `meetcore` race sub-step; and the native Apple bindings |
| + (`native/go.mod`), the one place real cgo bridges Go to Objective-C |
| + (`AGENTS.md`). **`make browser`** needs UDP, which the Claude Code |
| + bash sandbox blocks (`AGENTS.md`). |
| ## Brand Commitments |
| @@ -135,10 +143,10 @@ deliberately not here" below for the full, cited list. |
| suite doctrine, consuming a decision made there rather than restating |
| it (preamble, §0.2). |
| - **The theme is Estilo's**, adopted at whatever Estilo holds when each |
| - slice lands. No tag exists (`git ls-remote --tags` on `oficina/estilo` |
| - was empty on 2026-09-14); consumed at a pseudo-version, already |
| - adopted by the Home integration on main. **[inferred — confirm]** the |
| - exact commit at any later date. |
| + slice lands. As recorded on 2026-09-14 (`git ls-remote --tags` |
| + against `oficina/estilo`, empty at that check), no tag exists; |
| + consumed at a pseudo-version, already adopted by the Home integration |
| + on main. **[inferred — confirm]** the exact commit at any later date. |
| - **The chat panel is Meet's contribution to Estilo** — "one |
| self-contained template partial and one script file so a second app |
| can adopt it," the suite's first chat, built to be taken (§6). |
| @@ -162,7 +170,10 @@ deliberately not here" below for the full, cited list. |
| testimonials, benchmarks, pricing, usage numbers, launch date, press, |
| or a production promotion from this slice — edge |
| (`meet.oficina.works`) is promoted by hand by Paul, separately from |
| - documentation (slice 6 plan, "What slice 6 was"). |
| + documentation (slice 6 plan, "What slice 6 was"). The acknowledgements |
| + page and the Estilo theme pin are the other two slice-6 items with a |
| + disposition rather than a delivery; spec §15.18 is the record for all |
| + three. |
| ## Product Principles |
| @@ -185,7 +196,7 @@ deliberately not here" below for the full, cited list. |
| Signalling, `/ice` and the meeting API are contracts a native client |
| could speak (ruling 15, §8.4); the native apps are that ruling paying |
| off. |
| -5. **Every write names its real actor**, `person:<id>` or `agent:<id>` |
| +5. **Actors are `person:<id>` or `agent:<id>`, never fabricated** |
| (§7.2, doctrine ruling 9). |
| ## Accessibility & Inclusion |
| @@ -197,11 +208,12 @@ text label and not colour alone, and empty states that say what the |
| screen is for. |
| **The scriptless floor is the accessibility constraint this app adds |
| -beyond that shared list**, and it is exact: reaching a camera and |
| -another browser needs script; nothing else does. With scripts off the |
| -holding screen's join button becomes one paragraph saying a call needs |
| -JavaScript and everything else on the page works without it (§3.3); the |
| -room does the same (§3.4). |
| +beyond that shared list.** Reaching a camera and another browser needs |
| +script, and so, once a call exists, do the room's chat panel and its |
| +admission-queue Admit controls; nothing else does. With scripts off |
| +the holding screen's join button becomes one paragraph saying a call |
| +needs JavaScript and everything else on the page works without it |
| +(§3.3); the room does the same (§3.4). |
| No target locale count or WCAG conformance level is stated in the Meet |
| spec or `AGENTS.md`. **[inferred — confirm]**: Docs states "WCAG 2.2 AA, |
| @@ -210,11 +222,13 @@ and this file does not assume it does. |
| ## What is deliberately not here |
| -- **Scriptless media** — the one named exception to the scriptless |
| - floor: reaching a camera and another browser needs script; every other |
| - screen, including the server-rendered parts of the holding screen and |
| - the room, works with scripts off (spec §9; `AGENTS.md`'s |
| - UX-conventions line carries the same exception in the same words). |
| +- **Scriptless media, chat and admission** — the exceptions to the |
| + scriptless floor: reaching a camera and another browser needs script, |
| + and so, once a call exists, do the room's chat panel and its |
| + admission-queue Admit controls; every other screen, including the |
| + server-rendered parts of the holding screen and the room, works with |
| + scripts off (spec §9; `AGENTS.md`'s UX-conventions line carries the |
| + media exception in the same words). |
| - **No STUN or TURN server of Meet's own.** ICE servers come from the |
| platform relay, present or not at all — never a server Meet names |
| itself (suite ruling 6, §5.2, §5.5). |
| @@ -223,10 +237,11 @@ and this file does not assume it does. |
| platform SFU that decrypts to forward ships, in its own spec revision, |
| not a quiet cap change (§5.7, §0.3, §11 "rooms above four"). |
| - **No client-address limiter on the drive surface.** The agent API's |
| - per-agent rate limit (60/min) keys on the resolved agent, not the |
| - client address: behind the platform's relay socket every request can |
| - share one address, and an address-keyed limiter would let one flood |
| - take out every real agent at once (§15.17). |
| + per-agent rate limit (one request a second sustained, burst 60) keys |
| + on the resolved agent, not the client address: behind the platform's |
| + relay socket every request can share one address, and an |
| + address-keyed limiter would let one flood take out every real agent |
| + at once (§15.17). |
| - **No passkeys ruling of its own.** Unlike Docs §8.1, the spec states |
| no instance-local-passkey decision. **[inferred — confirm]**. |
| - **Chat is never stored.** A `chat` message fans out to admitted peers |
| @@ -239,7 +254,8 @@ and this file does not assume it does. |
| - **No native client sign-in method of its own** — a native client |
| authenticates through the same Home/local sign-in the browser uses, |
| handed off through a five-minute, one-use authorization; no separate |
| - bearer or token scheme for native apps (§8.4, `native/README.md`). |
| + bearer or token scheme for native apps (§8.4's 2026-09-14 amendment, |
| + `native/README.md`). |
| **No attendance claim, ever**: §0.3 says Meet does not record who was |
| in a call or for how long; an earlier revision implied one and the |
| spec dropped the implication rather than building the model. |
diff --git a/README.md b/README.md| index c8101f5..53753fb 100644 |
| --- a/README.md |
| +++ b/README.md |
| @@ -8,16 +8,20 @@ beside the call and a screen to share. An agent can also create, |
| list, relink and end meetings over an API. Every screen works with |
| JavaScript disabled except browser media participation — the camera |
| preview and join button on the holding screen, and the call itself in |
| -the room — and both pages still render their title, start time, |
| -standing, floor notice, the paragraph that says what needs script, and |
| -a member's navigation with scripts off (spec §9). |
| +the room — and, once a call exists, the room's two other script-only |
| +parts: the chat panel and the live admission queue with its Admit |
| +controls. Both pages still render their title, start time, standing, |
| +floor notice, the paragraph that says what needs script, and a |
| +member's navigation with scripts off (spec §9). |
| ICE servers come from the CARLOS platform relay, delivered as |
| `CARLOS_RELAY` and minted fresh for each call at `GET /m/{sqid}/ice`; |
| Meet names no STUN or TURN server of its own (suite ruling 6). With no |
| relay configured, calls are direct only: two browsers connect when ICE |
| -can find a working path straight between them, and the holding screen |
| -says so. Enabling or changing the relay restarts the instance. When |
| +can find a working path straight between them, which the holding |
| +screen states plainly above the join button: "This team's Meet has no |
| +relay yet. Calls usually connect only between people on the same |
| +network." Enabling or changing the relay restarts the instance. When |
| the relay is in the path it forwards DTLS-SRTP packets encrypted |
| between the browsers, so it carries bytes it cannot read; Meet's own |
| process never receives a media packet at all. With the relay on, a |
| @@ -53,9 +57,12 @@ member lets them in; removing a participant and ending a meeting each |
| go through their own confirm page — there is no in-room control that |
| skips one (spec §3.5). A member can retrieve the current invitation |
| again from the holding screen or the room with Share (`POST |
| -/m/{sqid}/share`); replacing a link revokes every live one. Chat is |
| -fanned out live to admitted peers and never stored (spec §6). Screen |
| -share adds a second tile per sharer |
| +/m/{sqid}/share`). On a meeting whose only link predates the |
| +2026-09-12 sharing update, the first Share mints a new recoverable |
| +invitation alongside the old, still-valid one rather than opening it; |
| +every Share after that retrieves the same recoverable one. Replacing a |
| +link revokes every live one. Chat is fanned out live to admitted peers |
| +and never stored (spec §6). Screen share adds a second tile per sharer |
| (spec §5.4). The room lives in one process's memory, so every deploy |
| drops every live call (spec §15.11). |
| @@ -69,8 +76,8 @@ link, end it, and read one meeting's detail. It cannot join a call |
| (spec §8). An agent's reach is re-derived from its operator's current |
| standing on every request, so an operator who leaves the team takes |
| their agent's reach with them at once, with no separate revocation |
| -step. A limit of 60 requests a minute applies per agent (spec §8, |
| -§15.17). |
| +step. Requests are limited per agent to one a second sustained, with a |
| +burst of 60 (spec §8, §15.17). |
| ## Native apps |
| @@ -81,17 +88,21 @@ the Mac app with `make native-mac`. See `native/README.md` and |
| ## Building and gates |
| -`make ci` (vet, gofmt, tests, migration check) is the one gate a |
| -runner and a push share, and it stays `CGO_ENABLED=0` throughout. |
| -`make race` is the one exception, building a test binary under |
| -`CGO_ENABLED=1` for any change to `internal/meet/hub` or the |
| -signalling stream. `make browser` drives a real call across two real |
| +`CGO_ENABLED=0 make ci` (vet, gofmt, tests, migration check) is the |
| +one gate a runner and a push share; `ci` itself does not set the |
| +variable, so the runner and every push must. Three things ship or run |
| +under `CGO_ENABLED=1`, each isolated from the server: `make race` |
| +builds a server test binary, never a release, for any change to |
| +`internal/meet/hub` or the signalling stream; `make native-test`'s own |
| +`meetcore` race sub-step does the same for the shared Go core; and the |
| +native Mac and iPhone/iPad bindings under `native/` bridge Go to |
| +Objective-C with real cgo, isolated in `native/go.mod` and built with |
| +`make native-mac`. `make browser` drives a real call across two real |
| Chromium contexts, 31 scenarios in about nine minutes; it needs the |
| Claude Code bash sandbox off, because the sandbox blocks UDP and every |
| -call then fails with `frames` stuck at 0. `make native-test` covers |
| -the shared Go core and the gomobile bridge. `make release |
| -VERSION=<sha>` stamps that version into `/api/version`, so a deploy |
| -can be checked against what it is meant to be running. |
| +call then fails with `frames` stuck at 0. `make release VERSION=<sha>` |
| +stamps that version into `/api/version`, so a deploy can be checked |
| +against what it is meant to be running. |
| ## Deploying |
| @@ -101,36 +112,56 @@ with the version `/api/version` will report (`strings -a |
| releases/meet-linux-arm64 | grep -cx <sha>` confirms the stamp) — then |
| deploy it: `carlos deploy --app meet --account oficina --channel edge |
| --version <sha> --target linux-arm64 releases/meet-linux-arm64`, |
| -checked against the build probe on `/api/version`. `--account` is a |
| +which waits until `/api/version` reports it — but only once a build |
| +probe is configured for the app: `carlos apps build-probe --app meet |
| +--account oficina /api/version`, set on the flagship app since |
| +2026-09-09. A new app or account needs that command run once before |
| +the wait means anything; without it `carlos deploy` watches |
| +`X-Carlos-Version` instead, which can report the new version adopted |
| +before the running process has actually changed. `--account` is a |
| global flag; `carlos ship` uploads only, while `carlos deploy` is ship, |
| -promote and wait until the URL serves the version (its own help text). |
| -Building for your own architecture and shipping that uploads fine and |
| -fails to exec on the instance. |
| - |
| -Secrets — `MEET_INSTANCE_KEY`, `MEET_DEK` (32 base64 bytes) and |
| -`MEET_SMTP_PASS` — go through `carlos secrets`; the rest go through |
| -`carlos env`. Mail reads `MEET_SMTP_*` with `CARLOS_SMTP_*` as a |
| -per-variable fallback, so `carlos email enable` covers everything but |
| -`MEET_SMTP_FROM`. `carlos relay enable --app meet` turns on the |
| -platform relay. Every deploy, and every relay change, restarts the |
| -instance and drops every live call — no drain exists, so deploy |
| -outside meeting hours. Migrations apply once each at boot |
| -(`msg=migrate` in the log) and are never re-run; a database that |
| -already applied a migration file under an earlier name fails at boot |
| -rather than silently diverging. The deploy wait can time out before |
| -the hand-over while the instance then serves the new version a minute |
| -later — check `/api/version` before retrying. |
| +promote and wait (its own help text). Building for your own |
| +architecture and shipping that uploads fine and fails to exec on the |
| +instance. |
| + |
| +These are the settings a deploy needs (`config.go`, `standing.go`). |
| +Five refuse startup when empty outside `-env development`: |
| +`MEET_ORIGIN` (the external origin, scheme included); |
| +`MEET_INSTANCE_KEY`; `MEET_DEK` (base64 of exactly 32 decoded bytes, |
| +not 32 base64 characters); `MEET_ALLOWED_ADDRESSES` (comma-separated, |
| +non-empty — this is the team); and mail, `MEET_SMTP_*` or the |
| +platform's `CARLOS_SMTP_*`. Two are optional, each with its own |
| +default rather than a refusal: `MEET_ZONE` (an IANA zone, defaulting |
| +to UTC when unset) and `CARLOS_RELAY` (empty means no relay, §5.5 — |
| +only a *malformed* value refuses startup), delivered by `carlos relay |
| +enable --app meet` rather than set by hand. Secrets — |
| +`MEET_INSTANCE_KEY`, `MEET_DEK` and `MEET_SMTP_PASS` — go through |
| +`carlos secrets`; the rest go through `carlos env`. Mail reads |
| +`MEET_SMTP_*` with `CARLOS_SMTP_*` as a per-variable fallback; the |
| +platform supplies a sender too |
| +(`CARLOS_SMTP_FROM`), which `MEET_SMTP_FROM` can optionally override, |
| +so `carlos email enable` alone is enough to send mail. `carlos relay |
| +enable --app meet` turns on the platform relay. Every deploy, and |
| +every relay change, restarts the instance and drops every live call — |
| +no drain exists, so deploy outside meeting hours. Migrations apply |
| +once each at boot (`msg=migrate` in the log) and are never re-run; a |
| +database that already applied a migration file under an earlier name |
| +fails at boot rather than silently diverging. The deploy wait can time |
| +out before the hand-over while the instance then serves the new |
| +version a minute later — check `/api/version` before retrying. |
| Canary a build on its own host: `carlos canary --app meet --name |
| slice2` composed `slice2.meet.bds.oncarlos.com`, and the console |
| refused it ("invalid host, an instance host is one DNS label followed |
| -by .bds.oncarlos.com" — 2026-09-10, filed as platform discussion #124, |
| -still open). The recipe actually used: `carlos instances create --host |
| +by .bds.oncarlos.com") — as recorded on 2026-09-10 in platform |
| +discussion #124, open as of that record. The recipe actually used: |
| +`carlos instances create --app meet --account oficina --host |
| slice2-meet.bds.oncarlos.com --channel canary/slice2 --environment |
| -slice2` — the environment bundle carries `MEET_ORIGIN` for the canary |
| -host; without it sign-in refuses on the canary while GETs look healthy |
| -— then `carlos deploy --account oficina --app meet --channel |
| -canary/slice2 --host slice2-meet.bds.oncarlos.com --version <sha> |
| +slice2`. The `slice2` environment bundle must already exist, created |
| +separately, carrying `MEET_ORIGIN` for the canary host; without it |
| +sign-in refuses on the canary while GETs look healthy. Then `carlos |
| +deploy --account oficina --app meet --channel canary/slice2 --host |
| +slice2-meet.bds.oncarlos.com --version <sha> |
| releases/meet-linux-arm64`. |
| ## Where things are written down |
| @@ -139,4 +170,6 @@ The design lives in `docs/superpowers/specs/2026-09-07-meet-design.md`, |
| the slice plans in `docs/superpowers/plans/`, and each slice's review |
| in `docs/superpowers/reviews/`. `PRODUCT.md` covers what Meet is for |
| and what it deliberately leaves out; `AGENTS.md` covers the |
| -conventions the code is held to. |
| +conventions the code is held to. Spec §15.18 is the disposition of |
| +record for what slice 6 delivered, deferred (the acknowledgements |
| +page) and declined (the Estilo theme pin, the production promotion). |
diff --git a/docs/superpowers/reviews/2026-09-14-slice-6-record.md b/docs/superpowers/reviews/2026-09-14-slice-6-record.md| new file mode 100644 |
| index 0000000..93f82b3 |
| --- /dev/null |
| +++ b/docs/superpowers/reviews/2026-09-14-slice-6-record.md |
| @@ -0,0 +1,188 @@ |
| +# Meet slice 6 — the record |
| + |
| +Branch `slice/6-deploy`, `9225ec2..HEAD` (this commit; started on main |
| +`9225ec2`, tag `v0.1.0`). Spec: `docs/superpowers/specs/2026-09-07-meet-design.md`, |
| +revision 9 (§15.18 carries this slice's dispositions). Plan: |
| +`docs/superpowers/plans/2026-09-14-meet-slice-6-deploy.md`. |
| + |
| +Slice 6 is the programme's closing slice (spec §12 item 6) and is |
| +documentation only: `README.md`, `PRODUCT.md`, a Deploying section in |
| +`AGENTS.md`, the *Consumed suite rulings* commit (`fa875c7`, the hash |
| +suite Appendix A.6 points at) and the spec amendments that commit and |
| +the review made. No file under `internal/`, `cmd/`, `native/`, |
| +`meetcore/` or `protocol/` changed. The ledger is |
| +`.superpowers/sdd/2026-09-14-meet-slice-6-deploy/` (gitignored; this |
| +file is its substance). |
| + |
| +--- |
| + |
| +## 1. Rulings and decisions |
| + |
| +- **The slice was re-scoped against main as it is on 2026-09-14, not |
| + as the programme imagined it on 2026-09-09.** Between slice 5 |
| + (`a283c53`, 2026-09-11) and this slice, other sessions landed Home |
| + sign-in (§7.1.1), the shared Estilo day theme and brand, the |
| + invitation `Share` route (the 2026-09-12 amendment), and the native |
| + Mac, iPhone and iPad apps. The plan's "What slice 6 was, and what it |
| + is now" table is the disposition of each programme item; §12 item 6 |
| + and §15.18 restate it in the spec. |
| +- **The acknowledgements page is not built here.** `oficina/meet` |
| + discussion 10, branch `feat-open-source-credits` (`117b6e4`, |
| + `bbc126e`), carries a shared Estilo credits page with a runtime |
| + dependency inventory and its freshness gate, Fable-approved and |
| + verified live on the overnight canary. Building a second one would |
| + be the duplication the programme forbids. |
| +- **The Estilo theme pin.** The programme's condition was a tagged |
| + release; `git ls-remote --tags` on `oficina/estilo` is empty on |
| + 2026-09-14. The theme is nevertheless adopted on main at an indirect |
| + pseudo-version (`go.mod`), brought in by the Home integration. |
| + Recorded as: condition unmet, adoption done by another route, |
| + nothing changed here. |
| +- **No deploy from this slice.** The change is documentation. Edge |
| + (`meet.oficina.works`) is promoted by hand by Paul (`651cff2` on |
| + 2026-09-12), with discussion 14's web UI work queued behind a live |
| + check. A redeploy would drop live calls for nothing; a queued |
| + promotion is never announced as live (programme §5). The domain was |
| + attached before this slice. |
| +- **Copy review is waived** for this round by Paul's steering on |
| + `oficina/suite` discussion 5. README and PRODUCT.md prose is |
| + catalogued here (§3) rather than reviewed. |
| +- **Writers did not commit.** Three writers worked concurrently in one |
| + worktree on disjoint files; the controller committed each set. The |
| + index is the shared resource, not the files. |
| +- **Every behavioural claim is verified against the code on the |
| + branch and cites its source.** The whole-branch review's finding was |
| + that the writers verified the documents against the code but not the |
| + code's documents against the documents: four spec sentences on main |
| + asserted things about "the README" that the README, once it existed, |
| + did not say (§0.1/§5.6's encryption sentence, §5.5's TCP-443 cause |
| + and "first paragraph", §3.2's residue). All four now hold, and the |
| + fix wave swept every spec sentence naming README, AGENTS.md or |
| + PRODUCT.md (twelve remaining, all true). |
| +- **The two meanings of "floor".** §5.5's floor is "no relay"; §9's is |
| + the scriptless floor. §12 item 6 now says which goes where (the |
| + scriptless sentence in the README's first paragraph, the relay |
| + paragraph carrying §5.5's sentence second); §15.18 notes the two |
| + senses. |
| +- **Platform facts stated from this project's own deploys**, not from |
| + the platform source: `carlos canary` composed a host the console |
| + refused (platform discussion 124, open); the recipe used is |
| + `carlos instances create --host <name>-meet.bds.oncarlos.com |
| + --channel canary/<name> --environment <name>` then `carlos deploy |
| + --channel …`, with the environment bundle mandatory because a canary |
| + without one serves `MEET_ORIGIN` for the main host and refuses |
| + sign-in while GETs look healthy. The release command is `carlos |
| + deploy --app meet --account oficina --channel edge --version <sha> |
| + --target linux-arm64 releases/meet-linux-arm64` after `make release |
| + VERSION=<sha>`; the deploy wait can time out before the hand-over |
| + while the instance serves the new version a minute later. |
| +- **Ruling 16** stays cited as on the doctrine's |
| + `worktree-worktree-token-at-rest` branch, not doctrine main (whose |
| + rulings run 1 to 15 at `1ac4323`, revision 8, confirmed current by |
| + `ls-remote` on 2026-09-14), as amended by the 2026-09-12 sharing |
| + update for invitation tokens; agent credentials remain hash-only and |
| + shown once. |
| + |
| +--- |
| + |
| +## 2. Per-task review dispositions |
| + |
| +Three writing tasks (Sonnet) in parallel, then one whole-branch review |
| +(Opus) and one fix wave, then Codex rounds. |
| + |
| +- **Task 1, README and AGENTS.md** (`93f1c2e`): 106 lines, the two |
| + paragraphs first. Flagged and acted on: spec §11 still listed a |
| + native client as not built (`aa9b227`). Flagged and initially left, |
| + then closed by the review: §5.5's "first paragraph" cross-reference; |
| + `MEET_SMTP_PASS` as a secret. |
| +- **Task 2, PRODUCT.md** (`e684b97`): impeccable product schema 1 in |
| + `oficina/docs`' shape with the unattended-writing disclaimer; "What |
| + is deliberately not here" carries the scriptless exception spec §9 |
| + asked for. |
| +- **Task 3, the consumed-rulings commit** (`fa875c7`): §0.2's 4/12 row |
| + consumes the home's assertions through §7.1.1 with the allowlist as |
| + membership authority; a ruling-16 row as amended; §12 item 6 |
| + annotated; §15.18 added. Revision line left at 9, following what |
| + §15.13 to §15.17 did. |
| +- **Whole-branch review** (`e684b97`): verdict **merge with named |
| + fixes**, W6-1 to W6-15, all applied in `bf3b86b` and `c22cae7` |
| + (reflow), plus the handoff's spec sweep, the two-floors |
| + disambiguation, §15.11's stale "until slice 3, or until a drain |
| + exists" (no drain exists; every deploy drops live calls) and |
| + `token_sealed` added to §2.1's `meeting_links` columns. Roughly |
| + sixty behavioural claims were traced to file and line and found |
| + correct; the fifteen findings were the remainder. |
| + |
| +**Codex round 1** (independent, static, scope `9225ec2..c22cae7`): |
| +verdict **request changes** — thirteen findings, S6-1 through S6-13. |
| +All applied in one commit (`.superpowers/sdd/2026-09-14-meet-slice-6-deploy/fix-wave-report.md`, |
| +round-1 section): |
| + |
| +- **S6-1 — P2, deployment settings undocumented. Fixed:** README's Deploying section enumerates every required setting and which refuse startup outside `-env development`. |
| +- **S6-2 — P2, the deploy-wait guarantee had an unstated prerequisite. Fixed:** README and AGENTS.md now state the `carlos apps build-probe` prerequisite and the `X-Carlos-Version` fallback it stands in for. |
| +- **S6-3 — P2, the scriptless exception was narrower than shipped. Fixed:** README, PRODUCT.md and spec §9 now name the chat panel and the live admission controls as script-gated too, alongside browser media participation; §15.18 notes the widening. |
| +- **S6-4 — P2, the cgo claims didn't match the Makefile. Fixed:** README and PRODUCT.md now say `CGO_ENABLED=0 make ci` and name `make race`, `make native-test`'s `meetcore` sub-step, and the native Apple bindings as the three `CGO_ENABLED=1` cases, none of them shipped. |
| +- **S6-5 — P2, the SMTP fallback description was backwards. Fixed:** README now says the platform supplies `CARLOS_SMTP_FROM` too, which `MEET_SMTP_FROM` optionally overrides. |
| +- **S6-6 — P2, suite restatements remained under §0.2. Fixed:** rows 3, 6, 9 and 15 and the two paragraphs below the table cite section and ruling number only now; PRODUCT.md's actor sentence likewise; ruling 16's off-main provenance kept as before. |
| +- **S6-7 — P2, PRODUCT.md cited a section that denies native clients shipped. Fixed:** spec §8.4 gained a 2026-09-14 amendment recording the shipped milestone (`v0.1.0` at `9225ec2`) and the browser-approval handoff (`86ed9f3`); PRODUCT.md's two native-client citations now point at that amendment. |
| +- **S6-8 — P2, the shipped same-network sentence was missing from the README. Fixed:** the relay paragraph now quotes `join.html`'s floor sentence verbatim. |
| +- **S6-9 — P2, the route inventory undercounted confirmation pairs. Fixed:** PRODUCT.md now says "five destructive confirmation pairs"; spec §9 now says "every confirm page (five)". |
| +- **S6-10 — P3, Share's legacy behavior was omitted. Fixed:** README now distinguishes a legacy meeting's first Share (mints a new recoverable invitation alongside the old one) from every retrieval after. |
| +- **S6-11 — P3, "60 requests a minute" obscured the permitted burst. Fixed:** README and PRODUCT.md now say "one request a second sustained, with a burst of 60". |
| +- **S6-12 — P2, the canary creation command relied on undocumented app/account defaults. Fixed:** README's `instances create` now carries `--app meet --account oficina` and states the named environment bundle must already exist, created separately. |
| +- **S6-13 — P3, disposition coverage and external-state attribution were incomplete. Fixed:** README and PRODUCT.md now link to spec §15.18 as the disposition of record for the three deferred/declined items; the platform-124, no-Estilo-tag and credits-branch-canary claims are now attributed to dated records rather than presented as independently verified current state. |
| + |
| +CODEX_ROUNDS_PLACEHOLDER |
| + |
| +--- |
| + |
| +## 3. Carried items, and where they go |
| + |
| +- **The acknowledgements page.** Discussion 10's branch |
| + `feat-open-source-credits`, not yet on main. **Destination: that |
| + branch's owner**; when it merges, the README's "Where things are |
| + written down" section should gain the credits page's path (one |
| + line). |
| +- **The Estilo theme tag.** No tagged release exists; the pseudo-version |
| + pin stays until one does. **Destination: oficina/estilo.** |
| +- **The production promotion of main's head.** Edge serves `651cff2`; |
| + main is at `9225ec2` plus this slice. `9225ec2` changed native code |
| + only; this slice changes documents only. **Destination: Paul**, who |
| + is promoting by hand while discussion 14's web UI work is queued. |
| +- **Unauthenticated flood control on `/api/v1`** (from slice 5). |
| + **Destination: carlos/platform**, unchanged. |
| +- **Platform discussion 124** (`carlos canary` and the one-label host). |
| + Open. The README carries the recipe that works. **Destination: |
| + carlos/platform.** |
| +- **Spec §9's "four confirm pages" is five** (remove, takeover, |
| + replace-link, end, revoke-agent). **Resolved in Codex round 1 |
| + (S6-9):** §9 now says "every confirm page (five)" and PRODUCT.md |
| + says "five destructive confirmation pairs". |
| +- **Copy catalogue** (copy review waived): the README's and |
| + PRODUCT.md's prose are the new user-facing text this slice adds; |
| + neither is an app string. Nothing in `internal/meet/templates` |
| + changed. |
| +- **The ledger's process note.** A writer's flag should become a task, |
| + not a paragraph: two of the three task reports flagged the right |
| + problems (W6-3, W6-6) in their "not corrected" sections and the |
| + controller took them as recorded rather than as work. |
| + |
| +--- |
| + |
| +## 4. Deploying this slice |
| + |
| +Nothing to deploy. No binary, migration, template, client or |
| +configuration changed. When main is next promoted, the README's |
| +Deploying section is the recipe, and the `carlos deploy` wait note in |
| +§1 applies. |
| + |
| +--- |
| + |
| +## 5. The gates, and how to run them |
| + |
| +| Gate | Command | This slice | |
| +|---|---|---| |
| +| CI | `CGO_ENABLED=0 make ci` | Green on every commit of the branch; remote CI passed on `e684b97` and `c22cae7`. Markdown cannot fail it; it is run so the branch's head is known green. | |
| +| Race | `make race` | Not run: no change under `internal/meet/hub` or the stream. | |
| +| Browser | `make browser` (sandbox off) | Not run: no page, template or client file changed. The last run on a shipping head is slice 5's, 31 of 31 on `4f896c2`. | |
| +| Native | `make native-test` | Not run: nothing under `native/`, `meetcore/` or `protocol/` changed. | |
diff --git a/docs/superpowers/specs/2026-09-07-meet-design.md b/docs/superpowers/specs/2026-09-07-meet-design.md| index 911f834..0523d0e 100644 |
| --- a/docs/superpowers/specs/2026-09-07-meet-design.md |
| +++ b/docs/superpowers/specs/2026-09-07-meet-design.md |
| @@ -89,20 +89,18 @@ This app cites the suite sharing doctrine (`oficina/suite`, |
| | Ruling | Used for | |
| |---|---| |
| | 1, 5 | One instance per team; the first deploy is the **lone shape** (§7.1). | |
| -| 3 | Authorization is asked per request and never cached. Standing (member, guest, neither) is derived at each request and re-derived on every hub tick (§2.3). | |
| +| 3 | §2.3: standing (member, guest, neither) is derived at each request and re-derived on every hub tick. | |
| | 4, 12 | The home now mints assertions; Meet consumes them through `home/connect`'s bridge, resolving to the existing person and re-checking membership on every request, while the allowlist remains the membership authority throughout (§7.1.1). | |
| -| 6 | No product-wide egress. Meet never names a STUN or TURN server of its own; ICE servers come from the platform (§5.2) or there are none (§5.5). | |
| -| 9 | Every write names its real actor: a member, a guest who signed in, or an agent (§8). | |
| -| 15 | Three rungs plus a read-only link. A meeting link is a capability to obtain a **guest grant at sign-in**, the `granted` rung, and never a way into a room without a name (§3). Ruled for Meet on `oficina/suite` discussion 3, Paul, 2026-09-06. | |
| +| 6 | §5.2, §5.5: Meet never names a STUN or TURN server of its own; ICE servers come from the platform, or there are none. | |
| +| 9 | §8: a member, a guest who signed in, or an agent. | |
| +| 15 | §3: a meeting link is a capability to obtain a **guest grant at sign-in**, the `granted` rung, and never a way into a room without a name. Ruled for Meet on `oficina/suite` discussion 3, Paul, 2026-09-06. | |
| | 16 | The token at rest (§3.1), as amended by the 2026-09-12 sharing update at the top of this file: invitation tokens are hash-indexed with a sealed copy so a member can share the current one again; agent credentials stay hash-only and shown once (§15.17). Ruling 16 is on the doctrine's `worktree-worktree-token-at-rest` branch (suite discussion 2), not on main on 2026-09-14; Meet adopts it early so it never has the Docs defect that produced it. | |
| -Doctrine §5.2 is also relied on: a guest grant held by the instance is |
| -authoritative for that grant, which is why §2 stores it and does not |
| -ask anyone. |
| +Doctrine §5.2 is also relied on, for §2: a guest grant is stored, not |
| +asked for. |
| -Also consumed: `oficina/suite` discussion 4 (agents as their own |
| -principal, on behalf of a person, bound to the operator's reach and no |
| -more) for the drive surface (§8); the CARLOS media roadmap |
| +Also consumed: `oficina/suite` discussion 4, for the drive surface |
| +(§8); the CARLOS media roadmap |
| (`carlos/platform`, |
| `docs/superpowers/specs/2026-09-07-media-platform-roadmap-design.md`, |
| merged at 8291cb2) and the stage 4a relay spec |
| @@ -978,6 +976,19 @@ A thin adapter over §8.2, deferred until a consumer asks by name. |
| ### 8.4 Native clients |
| +**2026-09-14 amendment.** The SwiftUI Mac, iPhone and iPad apps this |
| +section specifies shipped on `main` (`native/`, `meetcore/`, |
| +`protocol/`, tag `v0.1.0` at `9225ec2`), closing the authentication gap |
| +the bullets below name with a browser-approval hand-off |
| +(`native/README.md`): a five-minute, one-use authorization bound to a |
| +proof secret held only by the app; approving in the browser creates an |
| +ordinary framework session, no cookie copied and no new bearer type |
| +introduced. The production handoff endpoints were deployed in |
| +`86ed9f3`. This supersedes the closing paragraph's "version one does |
| +not ship a native client" below; the rest of this section, written |
| +before that milestone, otherwise stands as the contract the shipped |
| +apps speak. |
| + |
| Ruling 15: a native app is the next client after the browser, and |
| nothing in Meet's server contracts may assume the browser. Concretely, |
| in version one: |
| @@ -1004,14 +1015,19 @@ until an OpenAPI document earns its place. |
| ## 9. The scriptless floor |
| -The exception is **browser media participation** and nothing wider: |
| -reaching a camera and another browser needs script. Every other screen |
| -works with scripts off, including the meeting list, creating a meeting, |
| -seeing and copying a link, all four confirm pages, sign-in and |
| -continuation, the `/welcome` page, the agent token page, and the server-rendered |
| -parts of the holding screen and the room (§3.3, §3.4): title, start |
| -time, standing, floor sentence, the paragraph that says what needs |
| -script, and navigation to everything that does not. |
| +The exception is **browser media participation**: reaching a camera |
| +and another browser needs script. Inside a room that exists, script |
| +also gates the chat panel (`chat.html`'s whole panel is rendered |
| +`hidden` until script un-hides it, because a Send button with no |
| +script behind it would be a lie, §6, §10) and the admission queue's |
| +Admit controls (`room.js`), since neither can do anything before a |
| +call does. Every other screen works with scripts off, including the |
| +meeting list, creating a meeting, seeing and copying a link, every |
| +confirm page (five), sign-in and continuation, the `/welcome` page, |
| +the agent token page, and the server-rendered parts of the holding |
| +screen and the room (§3.3, §3.4): title, start time, standing, floor |
| +sentence, the paragraph that says what needs script, and navigation to |
| +everything that does not. |
| `AGENTS.md`'s line "screens work with JavaScript disabled" gains, in |
| slice 2, the one exception in those words, so the binding file and the |
| @@ -2160,6 +2176,12 @@ floor" is the no-relay condition, and §9's "The scriptless floor" is |
| the JavaScript exception; item 6's bullet above now names each rather |
| than leaving the bare word to carry both. |
| +§9's exception was also corrected here, on Codex round 1: browser |
| +media participation was never the only script-gated part of a room — |
| +the live admission controls have needed script since slice 2 and the |
| +chat panel since slice 4 — and §9, the README and `PRODUCT.md` now say |
| +so rather than "and nothing wider." |
| + |
| - **Delivered.** `README.md`, with the scriptless floor sentence and |
| the relay paragraph first. `PRODUCT.md`. `AGENTS.md`'s deploy notes. |
| §0.2 above, refreshed against doctrine main `1ac4323`, still |
| @@ -2171,9 +2193,10 @@ than leaving the bare word to carry both. |
| - **Deferred, not duplicated.** The acknowledgements page lives on |
| `oficina/meet` discussion 10, branch `feat-open-source-credits` |
| (`117b6e4`, `bbc126e`): a shared Estilo credits page with a runtime |
| - dependency inventory, Fable-approved, verified live on the overnight |
| - canary, not yet merged to main. Building a second one here would be |
| - the duplication the programme forbids. |
| + dependency inventory. As recorded on that branch's own review, it is |
| + Fable-approved and was verified live on the overnight canary, not |
| + yet merged to main — not independently reverified here. Building a |
| + second one here would be the duplication the programme forbids. |
| - **Declined: the Estilo theme pin.** The programme's condition for |
| pinning was a tagged release; `git ls-remote --tags` against |
| `oficina/estilo` is empty on 2026-09-14, so no tag exists and no pin |