# ADR: Session Tiltfiles own cp9 persona runtime graphs

Status: Accepted

Date: 2026-06-16

Related PRD:
[`20260615-prd-cp9-cloud-dev-integration-substrate.md`](./20260615-prd-cp9-cloud-dev-integration-substrate.md)

## Context

The cloud-hosted cp9 acceptance proof needs a staging-faithful persona graph without making
`cp9.yaml` a second service registry. The previous shape put persona topology in
the session config and had cp9 generate a Tiltfile, which made cp9 responsible
for source/live/stub classification, service dependencies, build definitions,
and proof-specific readiness.

That boundary made each persona change a cp9 generator change, while the real
runtime authoring surface was already Tilt.

## Decision

Persona runtime graphs are owned by user-editable Session Tiltfiles, not by
`cp9.yaml` or generated Tiltfiles.

Each persona may provide a copyable Persona Tiltfile example under
`personas/<persona>/`. A user copies that example before starting a session and
points the Session config at the copied file with an explicit `tilt.file` path.
The Session config keeps only session and substrate inputs such as session name,
host mode, target, Terraform settings, CI mode, Tilt port, and the selected
Tiltfile path.

cp9 writes a read-only Session context containing resolved session and
substrate facts, then runs Tilt with the configured Session Tiltfile, kube
context, namespace, and `CP9_SESSION_CONTEXT`. cp9 lifecycle remains generic:
start Tilt, stop managed tunnels/processes, surface Tilt resource status, run
thin Tilt wrappers for resource commands, and destroy cp9-owned substrate,
host, IAM, secrets, and Terraform resources. Persona-specific readiness,
product proof, and cleanup semantics live in Tilt resources/local_resources
inside the Session Tiltfile. `session_context_write` emits only generic
session/substrate context and directory references; per-service scripts,
manifests, probes, and graph inputs are checked in under the persona or produced
by the Session Tiltfile.

Implementation work for this change is folded into the existing cloud-host
issue train rather than split into a new standalone task. The active cloud-host
proof line is a hard cutover: it requires `tilt.file` and does not carry a
compatibility shim for old `appDelivery` or `services` runtime graph fields.
The first implementation slice targets the Premium cloud-host proof line; other
persona examples migrate after that pattern is proven. The first Premium
Session Tiltfile is a conservative port of the current generated Premium graph
intent, not a from-scratch redesign of the graph.

## Alternatives Considered

### Keep the generated Tiltfile and service graph in cp9.yaml

This preserves a central cp9 schema for persona topology, but it turns cp9 into
a graph generator and makes every persona-specific proof concern a cp9 core
concern.

### Add generic override files on top of generated Tiltfiles

This keeps some central generation while allowing customisation, but it creates
two competing graph surfaces: generated cp9 topology and user-edited overrides.
The result is harder to reason about than making the Session Tiltfile the single
runtime graph source of truth.

## Consequences

Positive:

- Persona authors can express runtime topology directly in Tilt.
- cp9 core owns session and substrate lifecycle rather than persona topology.
- Proof-specific resources can write evidence through the Session context
  without expanding cp9's config schema.
- Parallel sessions are explicit because each Session config chooses its own
  copied Session Tiltfile.

Costs:

- cp9 loses schema-level validation over persona service graphs.
- Persona authors must keep their Tiltfiles disciplined and reviewable.
- Existing generator code and docs need a migration path into the cloud-host
  issue train.
- Existing session configs using cp9-owned service graph fields must be
  migrated instead of silently supported.

Guardrails:

- `tilt.file` is explicit and required; cp9 does not infer the Session Tiltfile
  path.
- Session context contains session/substrate facts only, not persona topology or
  raw secret values.
- `cp9 destroy` remains generic and must not embed product-specific cleanup
  semantics.
- The migrated cloud-host examples must not keep both generated and
  Session-Tiltfile runtime graph paths alive.
- `session_context_write` must not become a renamed service graph generator.
- The conservative Premium port preserves existing Tilt resource names wherever
  possible so day-2 commands, session reports, and proof evidence remain
  comparable across the boundary change.
