Skip to main content

SPEC-120 v0.1 — Built-in System Agents

Status: draft (Donna authoring; Texi schema verdict + Candi governance verdict already converged; routing to both for ratification pass) Author: Donna, engineering Created: 2026-05-15 Owner: Donna (engineering implementation + PO ratification); Texi architecture schema; Candi governance + onboarding-loop coupling Related: ADR #48 v0.2 (Persona / Identity / Specialization Field Model — active), SPEC-070 (per-persona daemon model), SPEC-094 (local auto-memory deprecation), SPEC-114 (Sage + Clara customer-care personas — receives a narrow lifecycle=system amendment), SPEC-118 (prism_persona_ratify — DOES NOT apply to system agents per §Ratification Model), SPEC-119 (Hazel — first system agent already shipping under this lifecycle).

Origin

Frank operator directive 2026-05-15 + Cherry’s start-all.ps1 / SPEC-111 rewrite signal edbf048c: while applying home_machine bindings, Cherry surfaced the architectural question of whether Clara, Sage, and Hazel should be “built-in” to the Prism platform rather than project-scoped personas. Architecture verdict from Texi (5a0f3c5d) + governance verdict from Candi (eb33b418) converged independently on a new SPEC codifying a lifecycle classification field plus install-time template ratification + scaffold materialization.

Purpose

Define the lifecycle classification for persona contracts and codify the built-in system agent model — a class of personas that:
  • ship as canonical contracts at $PRISM_ROOT/templates/personas/<name>.json with the Prism install
  • are pre-ratified at install time, not per-project (no SPEC-118 ratification needed)
  • materialize into every newly scaffolded project via scaffold_service with implicit_bootstrap=false
  • are never implicit_bootstrap=trueprism_start refuses implicit creation when a canonical lifecycle=system contract exists for the identity
  • carry no authority by virtue of lifecycle=system — runtime authority still derives from authority_scope, backend-authorized verbs, bindings, and governance gates
v0.1 system agent roster: Clara (incident triage, SPEC-114), Sage (customer-care intake, SPEC-114), Hazel (tenant-admin onboarding concierge, SPEC-119). The lifecycle vocabulary is extensible; future system agents register here and follow the same install/template/scaffold/daemon semantics.

Anchors

  • ADR #48 v0.2 field model: lifecycle is a new top-level persona contract field, distinct from identity / surface / specialization / assignment / style. Per Texi binding condition, lifecycle MUST NOT live inside identity_binding; that block stays the registry identity/alias/dedupe/launch_mode/implicit_bootstrap surface.
  • SPEC-070 daemon model: system agents follow the same per-persona daemon pattern. Each gets its own daemon/supervision unit; system agents are not backend services and do not share a machine bus.
  • SPEC-094 local auto-memory deprecation: system agents route all persistent reads/writes through Prism verbs.
  • SPEC-114 Sage + Clara contracts: gets a narrow lifecycle=system amendment per this SPEC.
  • SPEC-118 prism_persona_ratify: explicitly does NOT apply to lifecycle=system agents. Their ratification is install-time / template-recorded; the per-project ratify verb is for tenant-local personas that began as implicit_bootstrap=true or were authored after install.
  • SPEC-119 Hazel: AC-2 already mandates Hazel scaffold-pre-seed; this SPEC codifies the lifecycle vocabulary that AC-2 manifests.

Non-Goals

lifecycle=system does NOT:
  • grant any authority by itself — authority remains in authority_scope + backend-authorized verbs + bindings + governance gates
  • imply auto-launch — auto-launch requires the triple lifecycle=system + launch_mode (operational policy) + host/install profile or launch overlay
  • imply elevated/superuser/tenant-cross privileges
  • promote lifecycle=system agents to backend services or machine-bus singletons — they remain personas with per-instance daemons per SPEC-070
  • block tenant overlay of enablement/bindings/home machine — only canonical contract fields (authority_scope, may_execute, etc.) are Prism-owned-immutable
  • allow Hazel or any other system agent to author NEW system/standing agents — tenant-local archetype composition stays scoped to draft/triggered per §Tenant Customization Boundary

Decision

Add a top-level lifecycle field to the persona contract schema (.agent/schemas/persona.schema.json). Values (Candi-locked enum):
  • system — built-in: ships with Prism install, scaffold-pre-seeded into every project, install-time/template ratification, explicit from birth (no implicit_bootstrap=true).
  • project_standing — long-running project persona, per-persona daemon under SPEC-070, may be authored post-install. Project-scoped.
  • project_triggered — event/cron-driven persona, runs on schedule or signal (e.g. SPEC-109 Researcher). Project-scoped.
  • interactive — operator-launched session, no daemon, lives for the conversation.
Default value: project_standing — preserves existing persona-contract semantics on rollout. Existing contracts that omit lifecycle resolve to project_standing. Migration is additive. lifecycle is contract provenance/classification, NOT operational launch policy. identity_binding.launch_mode stays the operational launch policy. Specs MUST state lifecycle != launch_mode to prevent the confusion.

Naming convention (locked by Candi governance call, signal eb33b418 + Cherry packaging 64a4b652)

Texi flagged a naming ambiguity: standing / triggered overlap with potential launch_mode values. Candi’s governance pick eliminates the overlap with sharp scope-explicit naming: Locked enum: system | project_standing | project_triggered | interactive (default project_standing). The project_ prefix on project_standing / project_triggered makes it unambiguous that the agent is project-scoped (vs system which is install-shipped + scaffold-materialized into projects). The lifecycle != launch_mode spec assertion still holds: lifecycle is contract provenance/classification; identity_binding.launch_mode is operational launch policy.

Definitions

Canonical contract: A persona contract committed at $PRISM_ROOT/templates/personas/<name>.json (alongside templates/CLAUDE.md / templates/AGENTS.md / templates/prism-*.md). System agents have canonical contracts; tenant-local agents do not. Template ratification: The install-time ratification path for lifecycle=system agents. The canonical contract is reviewed + ratified at SPEC ratification time (this SPEC + each system agent’s introducing SPEC); the install ships pre-ratified content. No per-project SPEC-118 prism_persona_ratify invocation is needed for system agents. Scaffold materialization: The Phase-0 mechanism scaffold_service uses to drop a copy of each canonical contract into a newly scaffolded project at .agent/personas/<name>.json with implicit_bootstrap=false. The copy is a materialization, not a fork — drift between the materialized copy and the canonical template is a repair condition flagged at prism_start time. Tenant overlay rights: The set of fields a tenant/project may modify on a materialized system agent without violating the canonical-Prism-property invariant. Per Candi: bindings.identity_binding.launch_mode, bindings.home_machine, enablement flags, tenant-local extension agents (not system agents themselves). Fields explicitly NOT overlay-eligible: authority_scope, may_execute, capabilities, canonical_role, specialization.

Ratification Model

LifecycleRatification MechanismWhere Recorded
systemInstall-time / template ratification at SPEC ratification timeEach system agent’s introducing SPEC + this SPEC + templates/personas/<name>.json provenance
project_standingPer-project via prism_persona_ratify (SPEC-118) when persona row begins as implicit_bootstrap=true and is reconciled to its committed contractBackend personas table implicit_bootstrap=false flag + binding row + audit event
project_triggeredPer-project ratification at first authoring; no implicit-bootstrap path expectedPersona contract + cron/event registration
interactiveNo ratification needed; ephemeralSession-lived only
prism_persona_ratify (SPEC-118 task #57 implementation) MUST refuse to operate on a lifecycle=system agent. System agents are pre-ratified; calling ratify on them is a category error.

Auto-Launch Policy

lifecycle=system alone does NOT auto-launch. Auto-launch requires the triple:
  1. lifecycle=system (the contract is install-shipped + scaffold-materialized)
  2. bindings.identity_binding.launch_mode set to a value that requests auto-launch (e.g. daemon, auto-on-scaffold)
  3. Host/install profile or launch overlay declares this machine + install is eligible (SPEC-111 home_machine + start-all script home_machine guard)
All three must agree before any launcher (bin/coder.sh, bin/hazel.sh, start-all.sh, start-all.ps1) fires the persona. Operators with -Force / --force-machine overrides can bypass condition 3 for deliberate cross-machine launches; conditions 1 and 2 are not override-able from a launcher (they require contract / binding edit).

Validator Rules

.agent/schemas/persona.schema.json validator MUST enforce, for lifecycle=system:
  1. identity_binding.implicit_bootstrap is false (system agents are born explicit)
  2. Contract provenance points at a canonical template path ($PRISM_ROOT/templates/personas/<name>.json)
  3. When materialized in .agent/personas/, a corresponding bindings.json entry exists for the binding context (scaffold-pre-seed materializes both)
  4. lifecycle=system is NOT inside identity_binding — it is a top-level field
  5. lifecycle=system does not grant any authority — schema does not synthesize authority_scope entries from the lifecycle alone
prism_start runtime enforcement MUST:
  • Refuse implicit-bootstrap creation when the resolving identity matches a canonical lifecycle=system contract. Surface as “scaffold/registry drift — re-scaffold or re-materialize,” NOT as a new implicit persona row.
  • Surface materialization drift (canonical-template hash ≠ materialized-copy hash) as a rules_reminder so operators can re-materialize with prism_sync_bios-equivalent flow (mechanism TBD; tracked in §Open Questions).

Built-in System Agent Roster (v0.1)

Per Frank operator definition (signal 64a4b652 Cherry packaging):
IdentityScopeRoleContract PathIntroduced By
Claratenant-level bindings (cross-project within tenant/org)tenant-based incident manager; runs on server1 / backendtemplates/personas/clara.jsonSPEC-114 (narrow lifecycle=system amendment)
Sagetenant-level bindings (cross-project within tenant/org)global Prism assistance + customer servicetemplates/personas/sage.jsonSPEC-114 (narrow lifecycle=system amendment)
Hazelscaffold-seeded into first-project onboardinggetting-started bootstrap assistant; “agents creating agents”; lifecycle ends after preseedtemplates/personas/hazel.jsonSPEC-119 AC-2 already mandates this materialization
Per Candi guardrail #2, cross-project Clara/Sage need tenant/org-scoped signal/read permissions enumerated explicitly and audited. Their materialized contracts specify the scoping; backend authorization enforces tenant isolation at every verb call.

Tenant-Level Bindings (new file-type concept)

Per Cherry packaging 64a4b652 + Candi governance eb33b418: the v0.1 binding model is .agent/projects/<pid>/bindings.jsonper-PID scope. Clara and Sage operate cross-project within a tenant/org and need a higher-scope binding artifact. New artifact: .agent/tenants/<tenant_id>/bindings.json (or equivalent — exact path TBD in implementation slice). Carries Clara + Sage binding entries with tenant-scoped signal/read permissions enumerated. Hazel is NOT a tenant-level binding because her scope ends after preseed; she materializes per-project at scaffold time and goes idle. Project-local references: Clara + Sage entries appear in per-project .agent/projects/<pid>/bindings.json as discoverability references only — they point at the tenant-level binding for routing. Per-project entries do NOT carry independent authority. Resolution order at prism_start / launcher time:
  1. Read tenant-level bindings for lifecycle=system agents
  2. Read project-level bindings for lifecycle=project_standing / project_triggered / interactive agents
  3. Resolve home_machine overlay per agent (Cherry’s SPEC-111 home_machine mechanism applies uniformly)
  4. Project-level discoverability references for system agents do NOT override the tenant-level binding
Open design questions on the tenant-level bindings file:
  • Exact path: .agent/tenants/<tenant_id>/bindings.json vs backend DB tenant-scoped table vs both with the file as projection
  • Authoring authority: who can edit (Candi? operator? Hazel never)
  • Materialization: scaffold seeds it on first install vs explicit prism_tenant_bindings_init verb
  • These open questions land as Slice 6 implementation work; v0.1 SPEC specifies the concept and the resolution order, exact mechanism land in Slice 6 PR.
Additions to the roster (future system agents) require:
  1. A new SPEC introducing the agent + its canonical contract
  2. Architecture review (Texi) on the contract + scaffold-materialization mechanic
  3. Governance review (Candi) on the authority scope + cross-tenant boundaries
  4. Donna PO ratification
  5. This SPEC’s roster table amended in the new SPEC’s PR

Tenant Customization Boundary

Per Candi governance answer (eb33b418): Tenant/project MAY:
  • bind a system agent to a different home_machine
  • enable/disable a system agent per project via explicit enabled: false in the bindings.json entry (never absence-as-disabled; absence means materialization or registry drift, not intentional suppression). For Sage + Clara: project-level enabled: false may suppress project-local discoverability and auto-launch, but does NOT erase tenant-level inherited help/incident routing unless the tenant-level binding is disabled by authorized operator policy. Sage (Prism help) and Clara (incident triage) remain a Prism project mandate inherited by every project.
  • add tenant-local extension agents (new identities with lifecycle != system)
  • compose tenant-local draft/triggered archetypes (Hazel’s Phase-2 capability per SPEC-119)
Tenant/project MUST NOT:
  • mutate canonical contract fields on a system agent (authority_scope, may_execute, capabilities, canonical_role, specialization)
  • promote a tenant-local agent to lifecycle=system (system-agent promotion is a Candi-reviewed PR adding the agent to templates/personas/ + this SPEC’s roster table)
  • treat materialization drift as intentional customization — the materialized copy is a refresh-from-template artifact, not a fork
Per Candi guardrail #3, Hazel may compose tenant-local draft/triggered archetypes only. Standing/system agent composition requires a ratification path outside Hazel (a separate SPEC, Candi+Texi review, Donna PO ratification).

Implementation Slices

Slice 0 — Schema + validator (Donna):
  • Add lifecycle field to .agent/schemas/persona.schema.json with enum + default
  • Validator rules per §Validator Rules
  • Backward-compat: existing contracts without lifecycle default to project_standing
  • Tests for the validator
Slice 1 — Template + scaffold (Donna + Candi):
  • Move canonical contracts for Clara, Sage, Hazel to $PRISM_ROOT/templates/personas/<name>.json if not already there
  • Update scaffold_service.py to materialize the three canonical contracts into every newly scaffolded project at .agent/personas/<name>.json with implicit_bootstrap=false
  • Update bindings.json scaffold to include the three system agents
  • Smoke: scaffold a fresh project, verify three agents materialized with correct lifecycle=system field
Slice 2 — prism_start enforcement (Donna):
  • prism_start refuses implicit creation when identity matches canonical lifecycle=system contract
  • Materialization-drift detection: surface as rules_reminder if canonical-template hash ≠ materialized-copy hash
  • Tests for the refuse path + drift detection
Slice 3 — SPEC-114 amendment (Donna + Candi):
  • Amend SPEC-114 Sage + Clara contracts to specify lifecycle=system
  • Cross-reference this SPEC
Slice 4 — SPEC-118 amendment (Donna + Texi):
  • Amend SPEC-118 prism_persona_ratify to refuse lifecycle=system identities
  • Task #57 implementation honors this
Slice 5 — Tenant-level bindings (Donna + Candi):
  • Implement the .agent/tenants/<tenant_id>/bindings.json artifact (or backend-DB equivalent) per §Tenant-Level Bindings
  • Clara + Sage binding entries with enumerated cross-project signal/read permissions
  • Resolution order at prism_start and launcher (coder.sh, start-all.{sh,ps1})
  • Project-local discoverability references in .agent/projects/<pid>/bindings.json point at tenant-level entries

Open Questions

  1. Materialization-drift repair mechanism — when a canonical-template hash differs from a project’s materialized copy, do we expose a prism_sync_personas verb, fold into prism_sync_bios, or surface drift as a rules_reminder only? Donna (PO) call.
  2. System-agent template-version tracking — should templates/personas/<name>.json carry a template_version field similar to bios_version so projects can pin / migrate? Texi call; carry into implementation slices if approved.
(Q2 enable/disable mechanism resolved — Candi decision recorded in §Tenant Customization Boundary: use explicit enabled: false, never absence-as-disabled. Q4 naming convention resolved in §Decision above — locked enum system|project_standing|project_triggered|interactive, default project_standing, per Candi governance call signal eb33b418.)

Acceptance Criteria

Slice 0 (schema + validator):
  • AC-1. .agent/schemas/persona.schema.json carries a lifecycle field with enum system|project_standing|project_triggered|interactive, default project_standing (Candi-locked enum per signal eb33b418).
  • AC-2. Validator rejects lifecycle=system with implicit_bootstrap=true.
  • AC-3. Validator rejects lifecycle placed inside identity_binding.
  • AC-4. Existing contracts omitting lifecycle validate (default project_standing).
Slice 1 (template + scaffold):
  • AC-5. Canonical contracts for Clara, Sage, Hazel exist at $PRISM_ROOT/templates/personas/{clara,sage,hazel}.json with lifecycle: "system".
  • AC-6. scaffold_service.py drops materialized copies of the three contracts into .agent/personas/ of every newly scaffolded project, with implicit_bootstrap=false.
  • AC-7. Scaffolded bindings.json includes binding entries for the three system agents.
  • AC-8. Fresh-scaffold smoke: scaffold a project, inspect .agent/personas/, verify three lifecycle=system contracts present with implicit_bootstrap=false.
Slice 2 (prism_start enforcement):
  • AC-9. prism_start resolving an identity matching a canonical lifecycle=system contract refuses to create an implicit_bootstrap=true row.
  • AC-10. Materialization drift (canonical hash ≠ materialized hash) surfaces in rules_reminders at next prism_start.
Slice 3 (SPEC-114 amendment):
  • AC-11. SPEC-114 doc carries the lifecycle=system designation for Sage + Clara.
Slice 4 (SPEC-118 amendment):
  • AC-12. SPEC-118 doc + prism_persona_ratify task #57 implementation refuse to operate on lifecycle=system identities.

Cross-references

  • ADR #48 v0.2 — Persona / Identity / Specialization Field Model (active; lifecycle is the 6th top-level field this SPEC introduces)
  • SPEC-070 — Per-persona daemon model (system agents follow the same pattern)
  • SPEC-094 — Local auto-memory deprecation (applies to system agents like everyone else)
  • SPEC-111 — Agent Roster Seed and Runtime .agent Launch Contract (launcher reads bindings.json which scaffold-materialization populates)
  • SPEC-114 — Sage + Clara Customer Care Personas (gets narrow lifecycle=system amendment)
  • SPEC-118 — prism_persona_ratify (gets narrow amendment refusing lifecycle=system)
  • SPEC-119 — Hazel Tenant Onboarding Concierge (AC-2 mandates Hazel scaffold-pre-seed; this SPEC codifies the lifecycle vocabulary)
  • Cherry start-all.ps1 SPEC-111 rewrite with home_machine guard (signal edbf048c)
  • Texi schema verdict signal 5a0f3c5d
  • Candi governance verdict signal eb33b418

Authority

Donna authored under engineering-outcome-driver authority and holds PO ratification per Frank operator directive. Texi schema verdict already approved the lifecycle field + 5 binding conditions (signal 5a0f3c5d). Candi governance verdict already approved the ratification model + tenant overlay rights + 3 guardrails (signal eb33b418). SPEC-114 + SPEC-118 amendments land in companion PRs after this SPEC ratifies.
Last modified on May 17, 2026