oficina / suite Public

Clone
git clone https://amadan.net/oficina/suite

Plain git — no account needed to clone.

Download

Download this file

🤖 suite

The Oficina suite's shared repository: the sharing doctrine that binds every app, and the contract module they implement against.

The suite is a consolidation. Home, Docs, Sheets, memoria and calendar each keep their own repository, and mail and files arrive later as wrappers around keymail and slopbox. What they share lives here so no app owns the rule that binds the others.

What is here

  • docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md: the doctrine. The team is the boundary. Inside it the apps are one thing; across it, sharing is membership and nothing moves. Read §1 first.
  • The contract module, amadan.net/oficina/suite: types, golden fixtures and a thin client for the calls apps make to each other. It has no dependencies, so the pin chain from an app is one deep.
  • fixtures/: the golden set. custody.json is one case per rung of the sharing ladder; hostile_hosts.json is the list of hostnames a sibling client must refuse. Both are shared so every app runs the same gate rather than inventing its own.
  • conformance/: the harness an app points at its own server half.

How an app uses it

An app spec cites the doctrine and lists the rulings it consumes. It never restates one.

In code, an app will import the module, mount the three sibling routes on a handler, and run the harness against that handler in CI. Not yet — see Status: the import path does not resolve, so the module has no consumers and cannot get one. The shape it will take:

func TestSuiteConformance(t *testing.T) {
    conformance.Run(t, myapp.SuiteRoutes())
}

For the calls it makes, it takes a client that cannot leave its own team:

c := suite.NewSiblingClient("acme", nil)  // refuses another team's label,
                                          // and never follows a redirect

What is built, and what is not

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 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 that serves one, and the fixtures get corrected by the second, which is the point of §10. Nor call 7, call 8, the roster or anything needing an assertion; those are §12 steps 4 and 5 and they wait on the home's identity layer.

Status

The doctrine is the status. Read its own status block rather than this one — it is at docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md and it says which revision it is, who has reviewed it, and what is deliberately unanswered.

This section used to repeat all of that and went stale within a day: it still said revision 4 and three review passes when the doctrine was at 7, which is precisely the drift §2 diagnoses and §10 exists to stop, committed by this repository's own README about its own document. So it stopped repeating it.

What belongs here, because it is about the repository rather than the doctrine: the contract module cannot currently be imported.