The amendment lands, with the definition it needed and the test it claimed
`design-activity-pull` passed its review on 2026-09-05, and both binding files said §2.2's verb changes on approval and not before. It has. §2.2's first never-do and AGENTS.md's first of the four things now read *never stores*, with the permitted rendering stated positively and every limit travelling with it. **"Retains" means holds without a bound — and a bound is a written number, with a reason, sized to the render rather than to retention.** Three drafts of this gloss were wrong in three different ways. The first said "at rest, and only at rest", which would have left §0 permitting an in-process title index for everyone held to restart. The second fixed that and left "without a bound" satisfied by any finite number — a thirty-day maximum over ten thousand people is bounded, and is the same index. So the gloss now names all three bounds rather than one: an age, a maximum number of person entries, and a maximum bytes per person. The entry count is what actually caps the cross-person set; the age alone does not. And at rest is defined as the case where the bound is not the home's own to enforce, which covers swap and core dumps in the same clause. **The amendment also claimed a test that did not exist.** Its whole purchase was that "never stores" has a grep behind it where "never renders" had none — but §12 gate 1's corpus was addresses only, and gate 9 and §3.4 named addresses, team names and queue payloads. The clause was resting on a test that never looked for what it forbids. Gates 1 and 9, §3.4's rule, §3.2's at-rest inventory and AGENTS.md's Data bullet all grow titles, URLs and actor strings. **And it un-anchored the support console**, which is the part worth reading twice: "never learns" forbade an operator reading your content and "never retains" does not, since a console that displays without keeping passes both it and the falsifiable form. Three references pointed at §0 — §2.2's fourth bullet, §14's last row, AGENTS.md's fourth thing — and now point at §2.2's first bullet, each saying why. Both files carry the reading note that "transiently and per request" does not exclude a bounded cross-render cache, since AGENTS.md read alone would otherwise forbid what the spec approves. §2's opening paragraph is qualified: the boundary rule now has something to bite on, ruling 11 survives on the leak profile and the re-check, and carlos/pegamento #1 should see the new phrasing. §9's pepper-rotation sentence is rewritten — an earlier insertion left it claiming every call in the table is instance→home, which is false of four of them. Three follow-ups recorded against the merged design: it still cites §0 for the operator view, its Scope line still says the home learns none of it, and no gate there exercises eviction on the entry-count or bytes-per-person bounds — gate 20 tests the age bound only. Reviewed by Fable 5.1 across three passes; the third approved.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2 files changed,
+200
−50
AGENTS.md+39 −7docs/superpowers/specs/2026-08-30-home-design.md+161 −43
CI passed — run details
diff --git a/AGENTS.md b/AGENTS.md| index dddc792..228e9bf 100644 |
| --- a/AGENTS.md |
| +++ b/AGENTS.md |
| @@ -18,7 +18,15 @@ alternative beside each. |
| > **The home is glue: thin, blind, replaceable. It knows that you exist and |
| > where your teams are. It never stores a readable address, and it never |
| -> learns what is in anything.** |
| +> retains what is in anything.** |
| + |
| +**"Retains", amended from "learns" on 2026-09-05** — spec ruling 18 and |
| +`design-activity-pull`, approved that day. The falsifiable form is unchanged. |
| +**It means holds without a bound**: the home does see titles and does keep |
| +them in RAM across requests, bounded by a TTL and a hard maximum; at rest is |
| +the unbounded case, and that is what it never does. "Blind" above is Factor |
| +XI's category label, not a claim it never sees one. Spec §0 carries the full |
| +gloss. |
| The falsifiable form: **publish this database in full and the worst anyone |
| learns is how many people exist, what their teams are called, and that some |
| @@ -38,7 +46,8 @@ directory upsert **plus rekey** leaves no readable address anywhere, **WAL |
| included**; and **no-content-in-logs** (gate 9). **Gates 1 and 2 need a |
| database and the skeleton has none. Gate 9 needs no database** — it scans |
| strings, and `cmd/home/main.go` already emits log lines — **so it is not |
| -sequenced behind one**. §13 step 1 lists all three beside the skeleton. A guard written after the code it guards is a guard written to |
| +sequenced behind one**. §13 step 1 lists all three beside the skeleton. A |
| +guard written after the code it guards is a guard written to |
| pass. (Stated as the rule rather than as a status: which gates exist today |
| is a question for `git log`, and a status line in a binding file is a |
| sentence that goes stale without anyone noticing.) |
| @@ -50,9 +59,27 @@ sentence that goes stale without anyone noticing.) |
| Each of these is something somebody will propose, in good faith, as an |
| improvement. |
| -1. **Never render content from an instance.** No document previews, no sheet |
| - thumbnails, no cell values. The directory shows what you have access to, |
| - never what is in it. |
| +1. **Never *store* content from an instance.** No previews at rest, no sheet |
| + thumbnails, no cell values, no titles in a database, a log, an error |
| + string, a metric label or an on-disk cache. It **may render**, transiently |
| + and per request, **and only to that person**, what an instance hands it |
| + for the person it hands it for — and nothing wider: no search over pulled |
| + content, no cross-person aggregation, no analytics, no operator view, and |
| + no retry queue holding a response body. |
| + |
| + **"Per request" does not forbid the cache the spec approves.** |
| + `design-activity-pull`'s §7 keeps pulled titles in RAM across requests, |
| + bounded by a refresh TTL and a hard maximum. Read alone, "transiently and |
| + per request" would rule that out, so read it with spec §0's gloss: |
| + **retains means holds without a bound**, at rest is the unbounded case, |
| + and the RAM hold is permitted because it is bounded and tested. |
| + |
| + **Amended 2026-09-05** from *never render*, on spec ruling 18. "Renders" |
| + was doing custody's work: the clause exists to stop the home becoming a |
| + place documents live, and storage is what makes it that. It also gained a |
| + test — spec §12's gates 1 and 9 grew a corpus of known titles, URLs and |
| + actor strings that day, so *never stores* has a grep behind it where |
| + *never renders* had none. |
| 2. **Never hold an authorization model.** The home knows you can reach a |
| team in an app. What you may *do* there is the instance's business, |
| decided from its own grants. |
| @@ -61,7 +88,11 @@ improvement. |
| two apart deliberately: "a row implying an org membership someone does |
| not have is a lie the directory tells on the org's behalf". |
| 4. **Never become a support console.** Reading someone's data to help them |
| - is precisely what the one rule forbids. |
| + is precisely what **rule 1 above** forbids — "only to that person", "no |
| + operator view". It used to be the one rule; since the 2026-09-05 |
| + amendment "never retains" no longer reaches a console that displays |
| + without keeping, so the anchor moved and a reference left pointing at |
| + the one rule would rest on nothing. |
| **And it stays small.** Every proposed feature is weighed against "does this |
| belong in an instance instead?" The answer is usually yes. This service has |
| @@ -185,7 +216,8 @@ quietly ignored). |
| instance makes one compromise an offline dictionary attack against the |
| whole suite directory. |
| - Migrations are additive-only. |
| -- **No address, team name, or queue payload in any log line, error string, |
| +- **No address, team name, queue payload, or pulled content — a title, a |
| + URL, an actor (added 2026-09-05 with §2.2's amendment) — in any log line, error string, |
| job status message or metric label.** Platform-held logs are storage we |
| cannot grep. |
diff --git a/docs/superpowers/specs/2026-08-30-home-design.md b/docs/superpowers/specs/2026-08-30-home-design.md| index 42c35d3..cec6520 100644 |
| --- a/docs/superpowers/specs/2026-08-30-home-design.md |
| +++ b/docs/superpowers/specs/2026-08-30-home-design.md |
| @@ -7,7 +7,10 @@ session with Docs (`oficina/docs`) as a declared consumer. |
| review dispatched to **Fable** (16 confirmed, 6 suspected — verdict "not |
| ready", now addressed). The 2026-09-05 revision was reviewed by **Fable**, |
| which returned 11 findings — three false claims in this file among them — |
| -all applied. **Ruling 22 reviewed by Fable across four passes |
| +all applied. **The 2026-09-05 §0/§2.2 amendment reviewed by Fable 5.1** — three passes — |
| +the first CHANGES NEEDED with three blocking, the second with five, the |
| +third approving. **Ruling 22 |
| +reviewed by Fable across four passes |
| (2026-09-05) — three returning CHANGES NEEDED, the fourth approving; the |
| `?team=` decision took a second opinion from GPT-6 Astra via Codex.** |
| Source claims re-verified by this session before acting. |
| @@ -21,7 +24,58 @@ documents. |
| > **The home is glue: thin, blind, replaceable. It knows that you exist and |
| > where your teams are. It never stores a readable address, and it never |
| -> learns what is in anything.** |
| +> retains what is in anything.** |
| + |
| +**"Retains", amended from "learns" on 2026-09-05** (ruling 18, |
| +`design-activity-pull`, approved that day). The falsifiable form below is |
| +**unchanged** — nothing new goes at rest. |
| + |
| +**"Retains" means holds without a bound.** That definition is doing real |
| +work and a first draft of this gloss got it wrong three times over, so it is |
| +stated once, plainly: |
| + |
| +- The home **does** learn what is in things. It handles titles on every |
| + front-door render, and `design-activity-pull`'s §7 keeps them in memory |
| + across requests, for every person who rendered inside the window. A rule |
| + claiming the home never learns them would be false the first time the |
| + feature ran. |
| +- What it never does is hold them **unbounded**. **A bound is a written |
| + number, with a reason, sized to the render and not to retention** — and |
| + there are three of them, not one: an **age** (`design-activity-pull` §7's |
| + refresh TTL and hard maximum), a **maximum number of person entries**, and |
| + a **maximum bytes per person** (that design's §2.1, evicting oldest |
| + first). The entry count is the one that caps the cross-person set §2 |
| + worries about; the age alone does not. Said this precisely because "without |
| + a bound" is otherwise satisfied by any finite number, and a thirty-day |
| + maximum over ten thousand people is exactly the in-process title index this |
| + gloss exists to forbid. At rest is the case **where the bound is not the |
| + home's own to enforce** — a file outlives the process, and Litestream ships it — which is why |
| + the falsifiable form below is the test that matters and is unchanged. **Two |
| + platform facts sit behind that line and are not yet established** — whether |
| + swap is configured and whether core dumps are off (§15). A swapped or |
| + dumped page of titles is at rest, so the boundary is only as good as those |
| + answers. The |
| + RAM hold is the bounded case: §7's refresh TTL and hard maximum are the |
| + bound, and `design-activity-pull`'s gate 20 tests it by advancing past the |
| + maximum |
| + through a *failed* pull, which is the path where a bound is easiest to |
| + lose. |
| +- So the rule **does** reach the cache, and reaches it by requiring the |
| + bound. An earlier draft said "at rest, and only at rest", which would have |
| + left §0 permitting an in-process title index for everyone, held until |
| + restart, with nothing in the one rule to say no. |
| + |
| +**"Stores" was proposed in review and rejected — RULED 2026-09-05 by Paul.** |
| +The case for it was good: §3.2 and §3.4 delimit it, §2.2 now uses it, and it would |
| +have made the sentence parallel. **"Retains" is kept because it says the |
| +right thing about time.** "Stores" reads as a place — *put somewhere* — and |
| +the risk here is duration. That choice is what makes the definition above |
| +"without a bound" rather than "at rest": the word was kept precisely so the |
| +rule would reach a title held in RAM across requests, and a definition that |
| +excluded the RAM hold would have thrown away the reason for keeping it. |
| + |
| +**"Blind" in the rule above is Factor XI's category label**, not a claim that |
| +the home never sees a title. It sees them; it keeps none. |
| The falsifiable form — the family's own *publish the database and see*: |
| @@ -62,7 +116,7 @@ blind, replaceable*. |
| | 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 | |
| | 17 | **The springboard is one page: an app grid, with the team switcher as a dropdown in the header. Which apps exist comes from a registry, not from your grants. A team is a suite-wide entity that instances belong to** — §11, §10 | A team-switcher screen as a first level; deriving tiles from grants alone, which hides an app you have no team in and leaves nowhere to press New; grouping by hostname label alone, with no row that exists before the first instance and outlives any one of them | Paul, 2026-09-05 | |
| -| 18 | **Activity is approved in principle, pulled at render, sequenced last, and scoped PER TEAM, following `?team=`** — the front door shows a real feed with titles, the home holds none of it at rest, and its slot is a step 10 after step 4 — `design-activity-pull` | Push into the home; a contentless heat map; a cross-team merged list (which `design-activity-pull` specifies and argues for, so that design must be revised); refusing the feature | Paul, 2026-09-05 | |
| +| 18 | **Activity is approved in principle, pulled at render, sequenced last, and scoped PER TEAM, following `?team=`** — the front door shows a real feed with titles, the home holds none of it at rest, and its slot is a step 10 after step 4 — `design-activity-pull` | Push into the home; a contentless heat map; a cross-team merged list (which `design-activity-pull` specified and argued for until its ruling 6 revised it, 2026-09-05); refusing the feature | Paul, 2026-09-05 | |
| | 19 | **A team name is reserved suite-wide. Both paths end in the drain — an existing instance settles the label question for the operator, it does not bypass them. The home answers only facts about its own records, never "may this person"** — §7 | Per-app first-come, which lets a stranger squat `acme.sheets` behind your `acme.docs` on a domain that reads as one suite | Paul, 2026-09-05 | |
| | 20 | **Write the attribute spelling — `rst-btn`, not `class="rst-btn"`. The seven unpaired utilities keep `class`** — §11 | The class vocabulary, which this section ruled on 2026-08-30 and whose every stated reason has since died; "follow whatever the pin's partials use", which changes this app's markup on a dependency bump | Paul, 2026-09-05 | |
| | 21 | **§11's zero-JS rule gains one named carve-out: passkey enrolment and ceremony screens may load script. Everything else stays scriptless** — §11 | Passkeys leaving slice one; a blanket exemption; a progressive-enhancement version, since the ceremony itself cannot happen without script either way | Paul, 2026-09-05 | |
| @@ -75,7 +129,14 @@ blind, replaceable*. |
| One shared instance, not one per account — **and this is not a divergence** |
| (ruling 11; proposed as doctrine at `carlos/pegamento` #1). |
| -**The instance boundary rule governs content, and the home holds none.** |
| +**The instance boundary rule governs content, and the home holds none at |
| +rest.** **Re-examined 2026-09-05**, because the amendment gave the boundary |
| +rule something to bite on: the activity cache is a cross-person set of recent |
| +titles in the one process that also mints sessions. Ruling 11 still holds — |
| +the safety property was never process isolation but the leak profile and the |
| +re-check — and the cache is bounded, per-person-keyed and never at rest. But |
| +it is no longer true that there is *nothing* for the rule to bite on, and |
| +`carlos/pegamento` #1 should see this rather than the original phrasing. |
| Rastrillo's *"a CARLOS app serves one team… isolation by process and file"* |
| and Pegamento §1's four boundaries are all boundaries *around content*. A |
| registry has nothing for the rule to bite on. Factor XI says it outright, |
| @@ -89,8 +150,8 @@ the federation story §3 refuses. |
| **Blast radius is bounded by what a service holds, not by how many processes |
| it runs in.** This draft originally reached for process isolation as the |
| -safety property; for a service holding no content the safety properties are |
| -the leak profile (§3) and the authorization re-check (§6). |
| +safety property; for a service holding no content **at rest** the safety |
| +properties are the leak profile (§3) and the authorization re-check (§6). |
| **What sharing costs**, with the first two structural rather than |
| aspirational: |
| @@ -99,8 +160,14 @@ aspirational: |
| and **every instance re-checks authorization on every request** (§6), so a |
| compromised directory grants nothing. A compromised home costs the graph |
| and a convenience outage. It does not cost a document. |
| -- **It holds no content.** The worst case is §3's leak list, never anyone's |
| - work. |
| +- **It holds no content *at rest*.** The worst case in a published database |
| + is §3's leak list, never anyone's work. **Since the 2026-09-05 amendment a |
| + live compromise is larger**: the activity cache holds recent titles in RAM |
| + for every person who rendered inside its TTL, and minting-for-anyone — which |
| + was always true — now also buys any person's recent titles through call |
| + 7. `design-activity-pull` §5.1 argues that is inside the |
| + hole §3.1's live-host model already concedes — it is, and it is bigger than |
| + it was, so it is said here rather than left to the other document. |
| - **Losing it costs a convenience, not access** — for the directory. Sign-in |
| is the exception and §5 says so rather than pretending otherwise; §2.1 |
| lists what shrinks it. |
| @@ -127,21 +194,41 @@ changing the architecture: |
| Each is something somebody will propose in good faith. |
| -- **Never renders content from an instance.** No previews, no thumbnails, no |
| - cell values. **Under amendment** (ruling 18): `design-activity-pull` |
| - changes this clause's verb to *never **stores***, on the argument that |
| - "renders" was doing custody's work — a title that exists for the length of |
| - one response, or of that design's RAM cache TTL, addressed to the person |
| - entitled to it, does not make the home a place documents live. The verb changes when that design passes |
| - its own review, not before, and it licenses nothing else: no search over |
| - pulled content, no cross-person aggregation, no on-disk cache, no operator |
| - view. Until then this clause stands as written. |
| +- **Never *stores* content from an instance.** No previews at rest, no |
| + thumbnails, no cell values, no titles in a database, a log, an error |
| + string, a metric label or an on-disk cache. It **may render**, transiently |
| + and per request, **and only to that person**, what an instance hands it for |
| + the person it hands it for. **"Per request" does not exclude |
| + `design-activity-pull` §7's cache**, which holds pulled titles in RAM |
| + across renders: §0's gloss defines *retains* as holds without a bound, |
| + and that cache is bounded and tested. Read the two together. |
| + |
| + **Amended 2026-09-05** from *never renders*, on ruling 18 and |
| + `design-activity-pull`, which passed its review that day (four Fable |
| + passes, the fourth approving). "Renders" was doing custody's work: the |
| + clause was written to stop the home *becoming a place documents live*, and |
| + storage is what makes it that. A title that exists for the length of one |
| + response, or that design's RAM cache TTL, addressed to the one person |
| + entitled to it, does not. |
| + |
| + **It licenses nothing else**, recorded so it is not read wider than it is: |
| + no search over pulled content, no cross-person aggregation, no analytics, |
| + no operator view, no on-disk cache, no retry queue holding a response body. |
| + And note what the amendment bought in exchange: "never stores" has a grep |
| + behind it, where "never renders" had no test at all — which is a fair sign |
| + it was a statement of intent rather than a mechanism. |
| - **Never holds an authorization model.** It knows you can reach a team in |
| an app; what you may *do* is the instance's business (§5.5). Ruling 15 |
| exists because the per-team 2FA floor would have breached this. |
| - **Never federates.** Data does not cross an instance boundary. |
| - **Never becomes a support console.** Reading someone's data to help them |
| - is what §0 forbids. |
| + is what **§2.2's first bullet** forbids — "only to that person", "no |
| + operator view". **It used to be §0**, and the 2026-09-05 amendment is why |
| + it no longer can be: "never *learns*" forbade an operator reading content, |
| + and "never *retains*" does not — a console that displays without keeping |
| + passes §0 and the falsifiable form both. The prohibition did not weaken, |
| + but its anchor moved, and a reference left pointing at §0 would be a |
| + prohibition resting on nothing. |
| ### 2.3 A recorded divergence: the directory is location plus graph |
| @@ -206,6 +293,10 @@ journal's new addresses; **sign-in link state** (§5.1). |
| minutes, and §5.2's show-codes-once page depends on it. |
| - Each person's theme. |
| +**Never at rest at all: pulled content** — titles, URLs, actors. Held in |
| +RAM only, bounded per `design-activity-pull` §7 and §2.1, since §2.2's |
| +2026-09-05 amendment. |
| + |
| **Never at rest readable: an email address.** Sealed and short-lived in link |
| state and the journal; hashed in the index; transient in RAM elsewhere. |
| @@ -228,7 +319,8 @@ counted as a fix: coarsening protects a deliberate publication and nothing |
| else.** §3.1's leak models ship the raw database file, whose session rows |
| carry exact timestamps (§3.2), so the timestamp-correlation fingerprint is |
| **unmitigated in a leak**. There is no export verb in this design that |
| -coarsens; if one is ever wanted, that is where the rule would attach. Sealing team display names |
| +coarsens; if one is ever wanted, that is where the rule would attach. |
| +Sealing team display names |
| buys little while hostnames are plaintext; it is kept because it is free, |
| and it is not counted as protection. |
| @@ -239,8 +331,12 @@ rekey and welcome mail. One error string — *"failed to hash |
| alice@example.com"* — ships an address to platform-held `carlos logs`, |
| storage we cannot grep. |
| -**Rule: no address, team name, or queue payload in any log line, error |
| -string, job status message or metric label.** Errors carry person refs and |
| +**Rule: no address, team name, queue payload, or pulled content — a title, |
| +a URL, an actor — in any log line, error string, job status message or |
| +metric label.** (Pulled content added 2026-09-05 with §2.2's amendment: a |
| +log line is at rest, so *never stores* reaches it, and a failed pull is |
| +exactly where a title would otherwise land in an error string.) Errors |
| +carry person refs and |
| codes. Test-enforced (§12 gate 9). Outbound mail necessarily carries |
| addresses through platform SMTP; that is inherent and disclosed. Log lines |
| are not. |
| @@ -533,8 +629,11 @@ sign-in. |
| **Pepper rotation uses an epoch, not a sweep.** The first draft called for a |
| "re-announce sweep" as an operator verb — which has no channel to reach |
| -instances, since every call is instance→home and instances hibernate; a |
| -fleet-wide poke would contradict the platform's zero-infrastructure-access |
| +instances: **no call in this table runs home→instance**, and instances |
| +hibernate. (The one call that does run home→instance is call 7, |
| +`design-activity-pull` §4 — approved, not built, and a per-render pull |
| +rather than a channel anything could be pushed down.) A fleet-wide poke |
| +would in any case contradict the platform's zero-infrastructure-access |
| contract. Instead: **every call-2 and call-5 response carries a pepper |
| epoch**, and an instance whose stored epoch differs re-enumerates its grants |
| on next wake. Rotation becomes a lag rather than an incident. |
| @@ -786,7 +885,8 @@ ceremony. |
| - `sessions` — per origin, keyed on person ref. |
| - `directory` — person ref, app, team sqid, host, kind, updated_at. |
| - `teams` — **the suite-wide team** (ruling 17): team **id** (the integer the |
| - sqid encodes — ruling 22's `/` entry picks the oldest team (§11) and needs it, and a sqid sorts |
| + sqid encodes — ruling 22's `/` entry picks the oldest team (§11) and |
| + needs it, and a sqid sorts |
| by string not by age), team sqid, **label** (the |
| `<team>` DNS segment, and the reservation of ruling 19), sealed display |
| name. One row per team, not per instance. **The home owns the display |
| @@ -846,7 +946,8 @@ before the skeleton existed, not by a later bump. |
| **Write the attribute spelling: `rst-btn`, not `class="rst-btn"`** (ruling |
| 20, 2026-09-05). This section ruled the class vocabulary on 2026-08-30 and |
| every reason it gave has since died, so the ruling went back to Paul rather |
| -than being propped up with a third. Two reasons died. "The attribute grammar is unreleased" died at |
| +than being propped up with a third. Two reasons died. "The attribute |
| +grammar is unreleased" died at |
| v0.21.0. "The partials we render alongside write classes" died at **v0.22.0, |
| the current pin**, where the shipped partials flipped to the attribute |
| spelling — rastrillo's design-system §6-v3 stage 2 — and the class spelling |
| @@ -1004,7 +1105,8 @@ runtime edit nobody reviewed. It holds, per app: slug, display name, |
| `provisionable`, `integrated`, and — **for `integrated: false` entries |
| only** — a foreign host. An integrated app needs no hostname field at all: |
| ruling 16 fixes its shape as `<team>.<app>.oficina.works`, and a free |
| -per-app pattern is an invitation to drift from it. The directory renders your teams' instances |
| +per-app pattern is an invitation to drift from it. The directory renders |
| +your teams' instances |
| under each entry; an entry you have no instance in still renders, showing |
| the New button, which is the affordance a grants-only list cannot have. The |
| registry is not invented for this screen — §4's `<team>.<app>.oficina.works` |
| @@ -1016,8 +1118,9 @@ separate products in separate repositories with their own auth. They render |
| as plain outbound links, never as team-scoped tiles, until each verifies |
| assertions per §5.3 (§14). |
| -No activity feed **yet** — ruling 18 approves one, pulled at render, blocked |
| -on `design-activity-pull`'s outstanding review and sequenced as §13 step 10. |
| +No activity feed **yet** — ruling 18 approves one, pulled at render, per |
| +team; `design-activity-pull` passed its review on 2026-09-05 and it is |
| +sequenced as §13 step 10, blocked on steps 3 and 4. |
| No template gallery, no upsell chrome, no waffle. |
| --- |
| @@ -1025,7 +1128,11 @@ No template gallery, no upsell chrome, no waffle. |
| ## 12. Testing gates |
| 1. **Plaintext grep** — raw SQLite file and WAL plus this app's store |
| - objects, against a seeded corpus of known addresses. |
| + objects, against a seeded corpus of known addresses **and, since the |
| + 2026-09-05 amendment, known titles, URLs and actor strings**. The verb is |
| + now *never stores*, so what the grep looks for has to grow with it or the |
| + clause has no test behind it. `design-activity-pull`'s gate 11 is the |
| + driven version, through the failure paths. |
| 2. **No-address-at-rest** — the schema has no address column, and a full |
| sign-in plus directory upsert plus rekey leaves no readable address |
| anywhere, WAL included. |
| @@ -1049,7 +1156,8 @@ No template gallery, no upsell chrome, no waffle. |
| 8. **Restore drill** — a real restore from replication, before launch, |
| against a written RTO. |
| 9. **No-content-in-logs** — scan log lines, error strings and metric labels |
| - for addresses, team names and queue payloads (§3.4). |
| + for addresses, team names, queue payloads **and pulled content — titles, |
| + URLs, actors** (§3.4). |
| 10. **No-store** — drive every route on both origins and assert each |
| authenticated response carries `Cache-Control: no-store`, the |
| personalised `/` redirect included (ruling 22). It exists for the edge-cache |
| @@ -1076,15 +1184,13 @@ record**, including which model reviewed it. |
| 9. Restore drill and the RTO |
| 10. **Activity on the front door** (ruling 18, `design-activity-pull`). |
| **Per team, following `?team=` — RULED 2026-09-05 by Paul.** |
| - `design-activity-pull` as written specifies a *cross-team* merged list |
| - and argues for it explicitly, so **that design must be revised to |
| - match**; it is recorded here rather than left to whoever reads the two |
| - documents next. Per-team also shrinks the fan-out §6 there worries |
| + `design-activity-pull` was revised to match on 2026-09-05 (its ruling 6) |
| + and approved. Per-team also shrinks the fan-out §6 there worries |
| about, from every instance a person can reach to the apps in one team. |
| **This is not a merge-logic tweak.** Per-team retires that design's |
| headline argument — that only the home can answer "my things" rather |
| - than "this team's things" — so its §2.1 needs re-justifying and its |
| - §5.4 reopening revisiting, not just its query changing. |
| + than "this team's things" — so its §2.1 was re-justified and its §5.4 |
| + reopening revisited, not just its query changed — done 2026-09-05. |
| Blocked on steps 3 and 4, and deliberately last. It has no claim on |
| anything earlier and must not acquire one: the identity layer is the |
| suite's critical path and this is a front-door nicety. |
| @@ -1109,7 +1215,7 @@ ships**, because call 2's person ref is what their grant rows key on. |
| | Any preference beyond theme | It passes §5.4 | |
| | Billing, plans, quotas | Somebody has to pay | |
| | **Mail and Files behind suite SSO** | Keymail or Slopbox verifies assertions per §5.3 in its own repository. Until then they are `integrated: false` registry entries rendered as outbound links (§11, ruling 17) | |
| -| A support console | Never, under §0 | |
| +| A support console | Never, under **§2.2's first bullet** — "only to that person", "no operator view". Anchored there rather than §0 since the 2026-09-05 amendment; see §2.2. | |
| --- |
| @@ -1123,12 +1229,24 @@ ships**, because call 2's person ref is what their grant rows key on. |
| - **`carlos/platform` #4** — the machine credential. |
| - **`carlos/pegamento` #1** — the shared-instance ruling, and whether §9 |
| protects the credential or the knowledge. |
| -- **`design-activity-pull`'s own review pass.** Ruling 18 approves the |
| - shape; the design carrying it is explicitly unapproved — its §12 says the |
| - review AGENTS.md requires has not run. §2.2's verb does not change until |
| - it does. Also open there: the per-instance deadline, the fan-out budget, |
| - the RAM cache TTL and the body cap are all named as decisions and none is |
| - chosen. |
| +- ~~`design-activity-pull`'s own review pass.~~ **Run 2026-09-05: four |
| + passes by Fable, the fourth approving.** What remains open there is design, |
| + not review: the per-instance deadline, the fan-out budget's number, the |
| + body cap, the refresh TTL, the hard maximum cache age, the cache bounds, |
| + the minimum pull interval, whether the two origins are one process, and |
| + whether swap and core dumps are off, whether `actor` is worth having, |
| + and |
| + the front door's layout. |
| +- **`design-activity-pull` §11's last row cites "(§2.2, §0)"** for "an |
| + operator view of anyone's feed". After the 2026-09-05 amendment §0 no |
| + longer forbids that — §2.2's first bullet does. **And its Scope line says |
| + "without the home learning or holding any of it"**, which §0's gloss now |
| + says outright is false: the home does learn, and holds bounded in RAM. |
| + (Its §5.4 is safe — "learns nothing *durable*".) Two one-word fixes in |
| + that file, recorded here so they are not lost. **Third: no gate there |
| + (11-20) exercises eviction on the entry-count or bytes-per-person bounds** |
| + — gate 20 tests the age bound only, and the entry count is the one that |
| + caps the cross-person set. |
| - ~~Class or attribute spelling — §11 needs a re-ruling~~ — **closed by |
| ruling 20**, 2026-09-05: the app writes attributes, and the seven |
| unpaired utilities keep `class`. |