# 🤖 suite

The shared repository of the Oficina suite. See `README.md` for what it
holds. This file is binding. Where it disagrees with a general skill, this
file wins.

---

## The one rule

> **Cite, never restate.**

This repository exists because five app specs each restated one contract
in their own words and the copies drifted. A rule that lives here is
stated here once. An app spec names the ruling number and the commit it
read; it does not paraphrase. A paraphrase in an app spec is a bug in that
spec, fixed by replacing it with a citation.

The same rule binds this repository in the other direction: the home's
calls 1 to 6 belong to the home spec and are cited here, not restated.

---

## Authorship

- Every ruling carries who made it and when. "This session" is a valid
  author and is marked as such so a reader can tell a ruling from a
  proposal.
- A design here is not approved until a review pass by the
  highest-capability model available, recorded by name in the status
  block. The author of a draft cannot be its reviewer.
- Rejected alternatives are recorded beside the ruling that rejected
  them, so nobody proposes them again in good faith without seeing why.

## The contract module

- Additive only. A removed field is a new major version.
- No rastrillo dependency. The module is types, fixtures and a thin
  client, so the pin chain from an app is one deep.
- Fixtures are the interface. A fixture is added with the first client
  that needs it and corrected by the second implementation, never
  designed from two specs at once.
- Every constant carries its reason in a comment: a cap, a deadline, a
  TTL.

## Discussions

Cross-repository requests go through `amadan discuss` on the repository
whose text must change. A request asks for a boundary to be recorded, not
for a ruling to be reversed, and says which of the two it is.

## The checkout on disk can lie

`amadan branch merge` lands a branch on the **remote**. It does not touch
any working checkout, including this repository's own. So a session that
merges its work and then walks away leaves the repository on disk showing
the state before the merge — and the next reader, human or session, sees
that state with nothing on screen saying it is behind.

**Two rules follow.**

**Fetch before you read a spec you did not just write**, in this repository
or a sibling. A grep of a stale checkout is not evidence, and it is
confident in exactly the same way a fresh one is.

**Fast-forward the shared checkout after you merge.** Your worktree is not
where anybody else looks.

This is written down because it happened, at length, on 2026-09-05. Every
merge of the doctrine and the contract module went to the remote through
`amadan branch merge`, and the shared checkout sat on the initial commit
with an empty `docs/superpowers/specs/` for the whole session. A peer
session on `oficina/home` spent an entire coordination pass reading a
*worktree* rather than a commit, and only knew to flag it because three
commits it was given for one revision failed to line up. Had they lined up,
it would have cited a working tree and neither of us would have known.

The failure to guard against is not that empty directory — that one is
loud. It is the quiet version: a session reading a file that is merely a
few commits behind, citing it with a commit hash that resolves, and being
wrong about the text. Suite gate 9 checks that a citation's revision
belongs to its commit; nothing checks that the reader read the commit.

## Work in a worktree, and catch main up first

Take a worktree for the work. Do not work in the shared checkout.

    git -C <repo> fetch origin
    git -C <repo> worktree add ../<repo>-<task> -b <branch> origin/main

Both halves matter, for different reasons.

**The worktree**, because several sessions share this machine and some
share this repository, and a checkout has one HEAD, one index and one
working tree between all of them. A branch switch under somebody else's
uncommitted work destroys it with nothing on screen to say so, and two
sessions editing the same paths disagree quietly instead of conflicting
loudly. A worktree gives the work its own HEAD and its own files, and
costs a directory.

**From `origin/main`, after a fetch** — not from whatever the checkout
happens to be sitting on. A branch cut from a stale main is a merge
conflict scheduled for later, against files somebody else has renamed in
the meantime. A branch cut from another task's branch is worse: it
carries that task's commits into yours, where they are reviewed as
though you wrote them, and the two can only be separated by hand.

Remove it when the work has landed — `git worktree remove` — so that
`git worktree list` keeps saying something true.

Written down because of 2026-09-17, in `meet`. The shared checkout was
sitting on one task's branch while holding a *different* task's feature
uncommitted on disk — some four hundred lines, a new migration among
them — put there by a session nobody else knew was working in that tree.
Two other sessions were meanwhile coordinating over the same checkout by
asking each other not to touch it, which is the arrangement a worktree
makes unnecessary. Nothing was lost. Nothing about the arrangement would
have said so if it had been, and by then the same feature existed twice,
once on each side of a rename, because the two sessions had branched
from different starting points.
