The person contract
Roster package contract
The binary embeds one ordered roster:core source set as the default. A caller
may select one external package with the same contract:
roster "core" {
role "platform" {
purpose "Build and land the foundational software the estate is built on."
model-tier "frontier" "commodity" "oss"
skill "role-platform"
method "eval-fixture-suite"
personality "tenacious" "grounded"
identity name="opal platform" pronouns="she"
agent "claude" tier="frontier"
agent "codex" tier="frontier"
}
personality "tenacious" skill="personality-tenacious" color="#8f8c47" motif="rope-fiber"
}
A package splits the manifest, roles, personalities, invariant, and definitions
into the external layout. The loader validates it before
it becomes a source. A role names its display name, purpose, role skill,
methods, ordered personality meld, and seats. Its optional
model-tier list restricts composition, while omission supports all three
tiers. Core roles declare the list explicitly. Core uses exactly two per
role, covers every canonical personality, caps usage at three roles, and
requires legible, distinct derived colors. External packages retain any
nonempty ordered meld. A role skill needs valid
frontmatter, three paragraphs, and at most 400 body words after its leading
title. Invalid sources fail loading. The default has seven roles and ten
personalities. Its explicit role-by-tier matrix groups
complex, foundational, and high-security roles without changing their
authority. A personality entry is a catalog binding from its canonical name to
a stable skill id (personality-<name>). Every role reference needs one or the
loader rejects it. The same selected person source supplies one complete
SKILL.md tree for every binding plus the personality invariant. A missing,
empty, extra, or mismatched definition fails source validation. Roster output
therefore carries every selected definition without a capability provider. The
identity primitives define renderer semantics.
Favorite colors
Every selected personality declares one hex color in its person source, which
owns the exact palette. Bundles tell the agent every active personality's
name, skill, and color plus the melded favorite. The parse gate requires OKLab
lightness 0.60-0.80 and chroma of at least 0.05. Each role derives its favorite
as the OKLab centroid of every component, restores chroma to their minimum, and
clamps it into the legible band - the perceptual middle, never gray.
Agent seats
A Core role declares one identity with a name and pronoun pair. Every agent
node is a harness routing selector for that identity. Optional channel and
tier properties describe routing, and a tier must be canonical and supported
by the role. Launch consumers keep permissions, models, and reasoning effort on
their side. Nothing here grants authority. Every Core Roster role carries
harness seats. Seat keys remain stable join points while the role-owned name
and pronouns remain identical across them. Selecting another seat changes
routing metadata only. External packages authored before role-level identity
may keep name and pronouns on every seat. A role must use one form
consistently. Mixing role-level identity with per-seat identity fails
validation. Seats are personality-neutral. A compose request selects a role,
which activates its role skill, methods, and ordered personality set. See
role-skill delivery. A private overlay may add scoped
instructions or selection rules. It may not redefine selected roles,
personalities, definitions, or role personality sets. Naming the seat is the
one exception: seat identity. An external package replaces
the embedded default as one unit, and AOS owns no copy of either package.
Complete person snapshot
Normal bare acompose convergence and the hidden roster compatibility command
write person.json into the roster artifact directory. The default location is
~/.agent-compose/sources/personality/person.json.
Contract
The JSON format marker is agent-compose.person-snapshot.v3, with numeric
schema version 3. The artifact exports:
- the person name, selected
person:<name>source provenance, and role order - every role's purpose, role-skill id, logical source, digest and body projection, role-method ids, supported model tiers, ordered meld, color, role-stable identity, and seats
- every personality's skill binding, color, emblem, motif, geometry, body, and sound mark, and every role's stance
- the fixed renderer expression vocabulary
Roles and personalities are keyed by their stable slugs. role_order is the
canonical presentation order. Consumers should use the explicit order rather
than relying on JSON object order. Schema v3 carries optional role
compatibility fields. Model-tier compatibility is additive within v3, and
consumers must ignore optional fields they do not interpret. Consumers pinned
to v2 must upgrade before treating the format marker as compatible.
Convergence
The snapshot is generated from the loaded person model in the same owned,
transactional roster projection as the human-readable files. A failed
projection restores the prior owned artifact. A second convergence leaves
identical bytes unchanged. The compose terminal transcript and compact
identity card render the selected-role slice from this same model. Core
surfaces include the canonical role identity once, harness routing selectors,
personality primitives, and the expression vocabulary. The generated file
remains outside repositories.
Consumers can read it but do not edit it or treat it as a second policy source.
Authority boundary
The artifact describes public identity, orientation, and compatibility only. It contains no model choice, reasoning effort, permission, credential, endpoint, routing decision, or runtime authority. Launch consumers and deployment-specific systems keep those fields.