For operators. This playbook takes a blank-but-stable self-hosted Temper
install — database up, schema migrated, a compatible binary, MCP configured
against your IdP — and turns it into a usable org with people in it.By the end you will have: a first system admin, instance settings recorded,
an everyone-team every member auto-joins, an org-identity cognitive map born
and reconciled and bound to that team, and team contexts resources can be
written into. Every step after the first is an idempotent temper command,
so re-running the sequence converges rather than duplicating.Prerequisites#
An embed-capable temper binary. cogmap create and cogmap
reconcile embed the charter client-side (ONNX). The default install
bundles it; a non-embed build returns a clear requires the 'embed'
feature error rather than running.
Authentication. The operator running the commands must be logged in
(temper auth login, or TEMPER_TOKEN exported) as the profile promoted
in the root step below. A profile auto-provisions on its first
authenticated request, so sign in once before the root step to
materialize it.
For the root step only: psql and the database connection string
(admin role).
For the trust model that gates every command below, see
trust boundary. For the team and role model
that membership and roles follow, see
teams and roles.Why a blank install isn't yet a usable org#
Resource writes into a team context already work — a team member can
temper resource create --context +team/ctx today. The chain breaks above
the write path: on a fresh install no team exists, no team-owned context can
be created, no org-identity cognitive map has been born, nothing is bound to
a team, and gating/admin configuration is SQL-only. This playbook closes
that gap.What you end up with#
| Outcome | Produced by |
|---|
| A first system admin | the SQL root step (irreducible) |
| Instance settings (name, gating, mode) | temper admin settings |
| An everyone-team every member auto-joins | temper team create … --auto-join-role watcher |
| An org-identity cognitive map, born + populated | temper cogmap create then temper cogmap reconcile |
| The map reaching the org's shared corpus | temper cogmap bind |
The sequence#
SAML instances. On an instance that fronts a SAML IdP, some SAML steps
run before this sequence and one runs after it: provision the IdP and
apply its row before anyone can authenticate; the first admin signs in via
SAML to JIT-provision their profile (the precondition of step 0 below);
run this playbook; then map SAML groups to the teams this playbook creates.
For the full SAML sequence, see the
enterprise install.
0. The irreducible SQL root step#
There is nothing to authenticate an admin-gated command against until the
first admin exists — so the first admin and the initial gating configuration
are set directly in the database. This is the one step that is not a
surfaced temper command.Find the first admin's profile id (the operator must have signed in once
already so the profile row exists):Then admit the profile and promote it. These are two separate things, and
each reads exactly one table:Admission — may this principal use the instance at all?
has_system_access reads kb_principal_standing and nothing else. Without
an approved row there, every gated request is a 403 SYSTEM_ACCESS_REQUIRED.
Governance — may this principal change the rules?
is_system_admin reads kb_principal_governance and nothing else.
Neither reads team membership. Owning the gating team does not make anyone an
admin, and being an admin does not admit you.Snapshot prod before a hand-run data change. On Neon, create a
copy-on-write backup branch first.
1. Instance settings#
Now an admin exists; everything below is a surfaced, admin-gated command run
as that admin. Record the human-facing instance name (and confirm
gating/mode):To promote a second admin so you are not a bus factor of one:2. Create the everyone-team#
A flat, parentless audience team every member auto-joins. It is
deliberately not the team DAG root — grants on a root would inherit
down into every sub-team and over-share. --auto-join-role is admin-gated
and makes enrollment idempotent and complete across open / invite_only:Every existing profile with system access is backfilled into the team on
enable, and every future profile auto-joins — this is the org-wide audience
pool that org cogmaps are bound to.3. Birth the org-identity cognitive map#
Genesis births a new map with its telos charter from a genesis manifest.
Save the following as org-identity.yaml and replace the prose with your
org's identity:The output reports the realized identity:{ "cogmap_id": "019f…", "telos_resource_id": "019f…", "created": true }
Capture cogmap_id — the next two steps need it. Genesis is idempotent at
a given id: pin cogmap_id in the manifest (or pass --id) and a re-run
is a no-op (created: false). Without a pinned id the CLI mints a fresh one
each run.Authority. cogmap create is open to any authenticated profile with
approved principal standing; the creator is granted read+write+grant on
the new map. A caller-supplied id is honored only for a system admin.
4. Deliver the map's landmark content#
Genesis births the map and its charter; reconcile delivers the landmark
content. Save the following as org-identity-landmarks.yaml and replace the
example landmarks with your org's:Then deliver the landmarks:Reconcile is idempotent — a re-run against unchanged content reports
{ created: 0, updated: 0, folded: 0, unchanged: N, charter: "unchanged" }.5. Bind the map to the everyone-team#
Binding widens the map's reach to the team's shared resources (an unbound map
reaches nothing through the team — empty join, default-closed):Authority. cogmap bind takes a system admin, or a team
owner/maintainer who administers the map (on a non-gating team). The
gating team itself can never be a bind target.
The org is now usable: members auto-join the everyone-team, the org-identity
map is born + populated + reaching the org's shared corpus, and resources
written into a team context (temper context create <ctx> --owner +everyone,
then temper resource create --context +everyone/<ctx>) land in a place the
map can see.Running it as the applier#
The applier script system-bootstrap.sh automates steps 1–5 (and optionally
step 0) from a declarative profile. Save the following as
install-profile.yaml, filling in your first admin's profile id:It needs yq to read the profile and temper on PATH (authenticated).
Because every step is idempotent, re-applying the profile converges rather
than duplicating — pin the org-identity cogmap_id in the profile to keep
genesis a no-op on re-runs. There is no state backend; plan/diff
(Terraform-like) semantics are deferred.The SAML half of an install (provision the IdP, apply its row, map groups) is
a separate applier, saml-setup.sh — kept out of system-bootstrap.sh
so the script stays auth-agnostic and usable for Auth0/Okta-OAuth installs.
See the enterprise install for the full SAML
sequence.Validation#
After the sequence completes, verify the org is usable end to end. Create a
context owned by the everyone-team and write a resource into it:Then confirm the resource is reachable through the bound org-identity map:The map's foundations should include the team context's resources. If the
resource is not visible, check that:has_system_access and is_system_admin both returned true for the
admin (step 0 — they are independent; one without the other is a silent
half-state).
The everyone-team was created with --auto-join-role watcher (step 2).
The cogmap was bound to +everyone (step 5).
Further reading#
The trust model that gates every command in this playbook:
trust boundary. Modified at 2026-08-20 02:05:41