oficina / suite Public

Revision 7: S6 moves to where it is needed, and gains the reason it exists

Two sessions converged on S6 within the hour and between them corrected both
halves of revision 6.

The memoria session had the piece neither of the others did: S6 does not
block slice 1. Slice 1 is S1, S2, S3 and memoria §4.1, all of which the
module already has. The numeric and aggregate class of memoria §8.2's router
is slice 2, and that is the one query class S6 answers. Revision 6 put S6's
step before slice 1, implying a dependency that does not exist and reading as
though slice 1 were blocked. It is now step 4, after slice 1 and before slice
2, and the step says out loud that slice 1 does not need it.

The activity-pull session corrected itself on the other half. It had offered
two ways out and called dropping S6 the cheaper and more honest one; against
memoria decision 10 that is not deferring a feature, it is removing the only
route by which a query class can answer without breaking a settled §1
decision. Still an option, but Paul's product call rather than a sequencing
tidy-up, and it had been framed as the latter.

So decision 10's reasoning is now in §6, where the S6 row said what the call
takes and never why. "memoria never does arithmetic. A number comes from a
cell, or from Sheets' engine via S6" — Paul's, reached by two models
independently — forbids a model averaging numeric strings it retrieved: a
failure that stacks incomplete recall on wrong operand selection and
arithmetic outside the engine that owns it, and cites its sources correctly
while being wrong. That is why the call takes an enumerated function and
never expression text, since expression text lets a consumer grow into a
formula author one release at a time.

Written down because a reader tidying an enumerated function into a general
one would have been removing a ruling without knowing there was one. Same
failure as an unscheduled call reading as finished, one level down: a shape
with no recorded reason is a shape somebody will improve.

Revision 7 per gate 9 — §6 and §12 are normative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev ba8270e7ad1ced0a230f6d3ffcdd49a7d629632b parent 7876689
2 files changed, +45 −15
  • README.md +2 −1
  • docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md +43 −14
diff --git a/README.md b/README.md
index 5d084f7..9082fdb 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,8 @@ c := suite.NewSiblingClient("acme", nil) // refuses another team's label,
Built: S1 the change feed, S2 authorization with its total decoder, S3
content, the typed asker subject, the team-bound client, and gates 1 to 4.
That is the doctrine's §12 step 2, and it does not wait on the home. S6 is
-step 3, with Sheets serving and memoria calling; it is specified and has no
+step 4,
+after memoria's slice 1 and before its slice 2; it is specified and has no
fixture yet.
Not built, deliberately: the server half — that arrives with the first app
diff --git a/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md b/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md
index 9bcad6a..ac34d76 100644
--- a/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md
+++ b/docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md
@@ -3,7 +3,14 @@
How the apps of the suite share identity, membership and content with
each other, and where the line is that nothing crosses.
-**Status:** design, **revision 6**, 2026-09-05.
+**Status:** design, **revision 7**, 2026-09-05.
+
+**Revision 7 moves S6 to where it is actually needed and records why it has
+the shape it has.** Revision 6 gave it a step before memoria slice 1, which
+was earlier than the dependency requires and implied slice 1 was blocked on
+it. The memoria session supplied the piece neither of the other two had:
+slice 1 is S1, S2, S3 and §4.1 and needs no S6 at all; the numeric and
+aggregate class in its §8.2 router is slice 2, and that is where S6 bites.
**Revision 6 schedules S6, which had a number and no builder.** It is in §6's
contract table and A.4 tells memoria to cite it, and no step of §12 ever
@@ -672,11 +679,29 @@ spec, which owns them, and are cited here for completeness of direction.
was no roster of record; call 8 is that record. A lone instance never
needed it. memoria decision 11 is superseded (Appendix A.4).
-**S6 is a call, and until step 3 it is a specification without a fixture.**
+**S6's shape is a settled decision of Paul's, not an API style.** memoria
+decision 10 — *"memoria never does arithmetic. A number comes from a cell,
+or from Sheets' engine via S6"* — was reached by two models independently
+and forbids one specific failure: a model averaging numeric strings it
+retrieved.
+That failure stacks incomplete recall on wrong operand selection and
+arithmetic done outside the engine that owns it, and it **cites its sources
+correctly while being wrong**, which is the hardest failure in this product
+to catch. So S6 takes an enumerated function — `SUM`, `AVERAGE`, `MIN`,
+`MAX`, `COUNT` — over cell refs, and never expression text, because a call
+that accepted expression text would let a consumer grow into a formula
+author one release at a time.
+
+Recorded here because §6's row said what S6 takes and not why, and a reader
+tidying an enumerated function into a general one would have been removing a
+ruling without knowing there was one. *(memoria decision 10, Paul; surfaced
+by the memoria session, 2026-09-05.)*
+
+**S6 is a call, and until its step it is a specification without a fixture.**
Ruling 7 says fixtures are the interface, so a call with no fixture has no
-interface — it has a description. §12 step 3 builds it, beside memoria
-slice 1, because Sheets is its only server and memoria its only caller,
-and neither is useful to it alone. Until then a consumer cites S6's
+interface — it has a description. §12 step 4 builds it, after memoria slice
+1 and before slice 2, because Sheets is its only server and memoria its only
+caller and neither is useful to it alone. Until then a consumer cites S6's
specification here and not a golden fixture, and A.4 says so rather than
implying one exists.
@@ -1142,15 +1167,19 @@ that cannot be written as stated is a spec bug.
2. **The contract module**, types and fixtures only: S1, S2, S3, the
hostile-hostname fixture, gates 1 to 4. No server half yet. Docs moves
its module path.
-3. **S6, with the same pair.** Sheets serves it, memoria calls it, and it
- ships with slice 1 rather than after it: an enumerated aggregate over
- cell refs, capped at 64, never expression text, with the typed asker and
- the custody intersection S2 carries. It is listed separately from the
- line below because revision 5 left it in the contract table and in A.4
- with no step at all, and a call that is numbered but unscheduled is
- indistinguishable from one that is finished.
-4. **memoria slice 1 against the module**, with Sheets and Docs serving
+3. **memoria slice 1 against the module**, with Sheets and Docs serving
S1 to S3. The second adoption corrects the fixtures.
+4. **S6, before memoria's slice 2 and not before its slice 1.** Sheets
+ serves it, memoria calls it, and nobody else does either: an enumerated
+ aggregate over cell refs, capped at 64, never expression text, carrying
+ the typed asker and the custody intersection S2 carries.
+
+ **Slice 1 does not need it** — that is S1, S2, S3 and memoria §4.1, all
+ of which the module already has. Slice 2 is memoria's model layer, and
+ the numeric and aggregate class of its §8.2 router is the one query class
+ S6 answers. Revision 6 put this step before slice 1, which implied a
+ dependency that does not exist; revision 5 gave it no step at all, which
+ let a numbered call read as a finished one.
5. **The home's identity layer** (home §13 step 4) and, on top of it,
call 8 and the roster (§5). Gates 5 and 8.
6. **Call 7**, the activity pull, once the home can mint assertions
@@ -1434,7 +1463,7 @@ own uploads. *(GPT-6 review, finding 3.)*
§11: memoria's person-ref and home dependency on slice 1 survives A.4 as
written. Slice 1 runs in lone shape against sibling tokens (suite §3, §12
-step 4), so the dependency is on the typed asker subject, not on the
+step 3), so the dependency is on the typed asker subject, not on the
home. Correct it, or slice 1 stays blocked on something that is not
actually in its way.