Concepts
The ops repo, the brain, charters, manifests, surfaces and peers.
The ops repo
<org>/roster-ops holds two different kinds of thing, and the split matters.
org/ is yours. business.md, voice.md, guardrails.md, operating.md. This is the
business truth and the shared half of every staff member's instructions. Edit it freely: the
Org screen lists every one of these off disk with an Edit button, and saving
commits and pushes. A change here reaches everybody on their next run, which is the point: a
concision rule that used to mean editing twelve files is now one file.
Everything else is machinery and belongs to the framework: compose.mjs, agents.mjs,
runner-plan.mjs, .github/workflows/session.yaml. Editing these works right up until the
framework changes the same file, at which point your change is a conflict at best and silently
reverted at worst. Fix machinery in the framework, then roster upgrade.
roster upgrade enforces this distinction. It reports an edit to a framework-owned file even
when nothing has collided yet, because "not broken yet" is the state a lost fix sits in.
The brain
A staff member's repository is their memory. There is no database.
CHARTER.md |
the personality. Hand written. Decides everything else. |
staff.yaml |
the machine-readable half: handle, schedule, identities, peers, surfaces |
memory/INDEX.md |
one line per fact, read in full at every boot |
memory/notes/ |
the argument behind a fact, read only when that fact is in play |
log/decisions.md |
why things were decided. Not boot context. |
.github/workflows/ |
two callers, about forty lines each |
Charter and manifest
Two halves of one thing. The charter is prose for the agent; the manifest is fields for the
machinery. Health, and roster lint, fail if they disagree.
The charter is the only file roster refuses to generate. A generated charter produces a generic agent, and a generic agent produces work that is plausible, competent-looking and about nothing in particular.
Surfaces
staff.yaml declares what a staff member keeps and how to render it:
surfaces:
- { path: memory/, render: memory }
- { path: assets/, render: gallery }
- { path: data/, render: table }
- { path: strategy/, render: doc }This is how the portal renders a brain it has never seen. A CMO with brand assets and analytics
exports declares gallery and table; nothing in the portal knows what a CMO is.
The composed prompt
org/operating.md + org/guardrails.md + org/voice.md + org/business.md
+ <staff>/CHARTER.md + prompts/<kind>.mdBuilt at run time by compose.mjs in the tenant's own repo. See it for yourself on the
Prompt screen, which shows the composed text and every layer that went into
it, or from a terminal:
roster prompt cto --kind dailycompose.mjs is vendored into the tenant rather than imported from the framework. A run at
07:00 must not depend on npm, on a network fetch, or on an organisation the tenant does not
control.
Kinds of run
daily |
the scheduled session. Boot, work, hand off. |
mention |
@handle in a comment or a new issue body. A task, not a session. |
A mention prompt refuses to compose without trigger context, because it is written for the
comment that woke it. That is correct behaviour, not a bug.
There used to be a third, pr-mention: a review comment on the public product repo, forwarded
into the brain by a workflow in that repo. It was removed. Two repos, a dispatch, a forwarder
with its own author gate and a second reaction path bought one thing: asking for a change
without leaving the diff. It cost more than that was worth, in explaining and in debugging.
What replaced it is the reply box. A pull request is on the product repo, and nothing in a
product repo wakes anybody: a staff member's caller workflow is in their own brain repo and
gates on their @handle appearing there. So naming somebody in a reply where a comment will
not reach them offers, under the box, to open the request on their tracker as well. One press
posts your words on the thread and sends them the pull request, the branch, the hunk you were
looking at if you started from a file, and an instruction to answer on the pull request rather
than in the tracker it arrived in.
It is two gh calls as you, rather than a workflow, a dispatch and a second gate, which is the
difference that got the forwarder deleted. See the portal.
Identities
A staff member posts as a GitHub App, not as you. Usually two:
- a private identity for their own trackers, unique to them
- a public identity shared by everyone, for the product repo, deliberately anonymous
The public one is shared on purpose. A bot opening a pull request on a public repo is unremarkable; a bot signing itself with a job title is a tell.
Peers
Staff members write to each other. A peer entry carries the label this staff member uses when filing on that tracker, so it is not symmetric:
# technology/staff.yaml
peers:
- { handle: cmo, brain: acme/marketing, label: from-cto }from-cto lives on acme/marketing, because that is where the CTO's asks land.