Tilt Up
Principles (Always Active)
These apply whenever working with Tiltfiles, Tilt errors, or dev environment bootstrap:
Fix the Tiltfile, Not the Symptoms
- Fix the source config directly - Tiltfile, Dockerfile, k8s manifest, or helm values
- Never add shell workarounds - no wrapper scripts, no
|| true, no try/except pass
- Never hard-code ports, paths, hostnames, image tags, or container names that should be dynamic
- Never add fallbacks that mask the real error - if a resource fails, the failure must be visible
- Never add sleep/retry loops for flaky dependencies - fix dependency ordering via
resource_deps() or k8s_resource(deps=)
- Never add polling for readiness that Tilt already handles - use
k8s_resource(readiness_probe=) or probe configs
Express Dependencies Declaratively
- Port conflicts: fix the port allocation source, don't pick a different port
- Resource ordering: use
resource_deps(), not sequential startup scripts
- Env vars: use
silo.toml or gen-env output, not inline defaults
- Image availability: use
image_deps or deps, not sleep-until-ready
Tilt Live-Reloads
After editing a Tiltfile, Tilt picks up changes automatically. Never restart tilt up for:
- Tiltfile edits
- Source code changes
- Kubernetes manifest updates
Restart only for: Tilt version upgrades, port/host config changes, crashes, cluster context switches.
Workflow (When Explicitly Starting Tilt)
Step 1: Assess Current State
Check if tilt is already running:
PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" || basename "$PWD")
zmx list --short 2>/dev/null | grep -q "^${PROJECT}-tilt$"
If running, check health via tilt get uiresources -o json and skip to Step 3.
Check for required env files (.localnet.env, .env.local, silo.toml):
- If
silo.toml exists, use silo up path
- If gen-env script exists, run it first
- If neither, check project README for bootstrap instructions
Check for k3d cluster or Docker prerequisites.
Step 2: Start Tilt in zmx
Follow the zmx skill patterns:
PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" || basename "$PWD")
SESSION="${PROJECT}-tilt"
if zmx list --short 2>/dev/null | grep -q "^${SESSION}$"; then
echo "Tilt session already exists: $SESSION"
else
zmx run "$SESSION" 'tilt up'
echo "Started tilt in zmx session: $SESSION"
fi
For silo projects: silo up instead of tilt up.
Step 3: Monitor Bootstrap
Poll for convergence:
- Wait 10s for initial resource registration
- Poll every 15s, up to 20 iterations. Include docker-compose container health
(
composeResourceInfo.healthStatus) — an Up (unhealthy) compose container
keeps runtimeStatus=ok and is otherwise invisible, so bootstrap can look
"done" while canton/splice/postgres are silently failing their HEALTHCHECK:tilt get uiresources -o json | jq -r '.items[] | select(.status.runtimeStatus == "error" or .status.updateStatus == "error" or .status.updateStatus == "pending" or .status.composeResourceInfo.healthStatus == "unhealthy") | "\(.metadata.name): runtime=\(.status.runtimeStatus) update=\(.status.updateStatus) compose=\(.status.composeResourceInfo.healthStatus // "-")"'
- Track resources:
pending -> in_progress -> ok
- Success: all resources reach
runtime=ok, update=ok (or not_applicable)
AND no docker-compose resource is composeResourceInfo.healthStatus == "unhealthy"
- If resources stabilize in
error, OR a compose resource stays unhealthy,
proceed to Step 4. For an unhealthy compose probe, read the real cause with
docker inspect <compose-project>-<svc> --format '{{json .State.Health}}' —
often the mounted healthcheck script calls a CLI the image lacks (the service
is up; fix the probe script, don't disable the check)
Step 4: Diagnose and Fix Errors
For each resource in error state:
- Read logs:
tilt logs <resource> --since 2m
- Read the Tiltfile and relevant k8s manifests
- Identify root cause in the config (not the running process)
- Apply fix following the Principles above
- Tilt live-reloads - re-poll status to verify
After 3 fix iterations on the same resource without progress:
- Report the error with full logs
- Identify whether it's a Tiltfile bug, upstream dependency, or infrastructure problem
- Do not silently skip or disable the resource
Step 5: Report
## Tilt Status: <healthy|degraded|errored>
**Resources**: X/Y ok
**Session**: zmx $SESSION
### Errors (if any)
- <resource>: <root cause> — <what was fixed or what remains>
1---2name: tiltup3description: Use when starting tilt, debugging Tiltfile errors, or bootstrapping a dev environment. Starts Tilt in zmx, monitors bootstrap to healthy state, fixes Tiltfile bugs without hard-coding or fallbacks.4---5
6# Tilt Up
7
8## Principles (Always Active)
9
10These apply whenever working with Tiltfiles, Tilt errors, or dev environment bootstrap:
11
12### Fix the Tiltfile, Not the Symptoms
13
14- **Fix the source config directly** - Tiltfile, Dockerfile, k8s manifest, or helm values
15- **Never add shell workarounds** - no wrapper scripts, no `|| true`, no `try/except pass`
16- **Never hard-code** ports, paths, hostnames, image tags, or container names that should be dynamic
17- **Never add fallbacks** that mask the real error - if a resource fails, the failure must be visible
18- **Never add sleep/retry loops** for flaky dependencies - fix dependency ordering via `resource_deps()` or `k8s_resource(deps=)`
19- **Never add polling** for readiness that Tilt already handles - use `k8s_resource(readiness_probe=)` or probe configs
20
21### Express Dependencies Declaratively
22
23- Port conflicts: fix the port allocation source, don't pick a different port
24- Resource ordering: use `resource_deps()`, not sequential startup scripts
25- Env vars: use `silo.toml` or gen-env output, not inline defaults
26- Image availability: use `image_deps` or `deps`, not sleep-until-ready
27
28### Tilt Live-Reloads
29
30After editing a Tiltfile, Tilt picks up changes automatically. **Never restart `tilt up`** for:
31- Tiltfile edits
32- Source code changes
33- Kubernetes manifest updates
34
35Restart only for: Tilt version upgrades, port/host config changes, crashes, cluster context switches.
36
37## Workflow (When Explicitly Starting Tilt)
38
39### Step 1: Assess Current State
40
411. Check if tilt is already running:
42 ```bash
43 PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" || basename "$PWD")
44 zmx list --short 2>/dev/null | grep -q "^${PROJECT}-tilt$"
45 ```
46 If running, check health via `tilt get uiresources -o json` and skip to Step 3.
47
482. Check for required env files (`.localnet.env`, `.env.local`, `silo.toml`):
49 - If `silo.toml` exists, use `silo up` path
50 - If gen-env script exists, run it first
51 - If neither, check project README for bootstrap instructions
52
533. Check for k3d cluster or Docker prerequisites.
54
55### Step 2: Start Tilt in zmx
56
57Follow the `zmx` skill patterns:
58```bash
59PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" || basename "$PWD")
60SESSION="${PROJECT}-tilt"
61
62if zmx list --short 2>/dev/null | grep -q "^${SESSION}$"; then
63 echo "Tilt session already exists: $SESSION"
64else
65 zmx run "$SESSION" 'tilt up'
66 echo "Started tilt in zmx session: $SESSION"
67fi
68```
69
70For silo projects: `silo up` instead of `tilt up`.
71
72### Step 3: Monitor Bootstrap
73
74Poll for convergence:
751. Wait 10s for initial resource registration
762. Poll every 15s, up to 20 iterations. Include docker-compose container health
77 (`composeResourceInfo.healthStatus`) — an `Up (unhealthy)` compose container
78 keeps `runtimeStatus=ok` and is otherwise invisible, so bootstrap can look
79 "done" while canton/splice/postgres are silently failing their HEALTHCHECK:
80 ```bash
81 tilt get uiresources -o json | jq -r '.items[] | select(.status.runtimeStatus == "error" or .status.updateStatus == "error" or .status.updateStatus == "pending" or .status.composeResourceInfo.healthStatus == "unhealthy") | "\(.metadata.name): runtime=\(.status.runtimeStatus) update=\(.status.updateStatus) compose=\(.status.composeResourceInfo.healthStatus // "-")"'
82 ```
833. Track resources: `pending` -> `in_progress` -> `ok`
844. Success: all resources reach `runtime=ok, update=ok` (or `not_applicable`)
85 AND no docker-compose resource is `composeResourceInfo.healthStatus == "unhealthy"`
865. If resources stabilize in `error`, OR a compose resource stays `unhealthy`,
87 proceed to Step 4. For an unhealthy compose probe, read the real cause with
88 `docker inspect <compose-project>-<svc> --format '{{json .State.Health}}'` —
89 often the mounted healthcheck script calls a CLI the image lacks (the service
90 is up; fix the probe script, don't disable the check)
91
92### Step 4: Diagnose and Fix Errors
93
94For each resource in error state:
951. Read logs: `tilt logs <resource> --since 2m`
962. Read the Tiltfile and relevant k8s manifests
973. Identify root cause in the config (not the running process)
984. Apply fix following the Principles above
995. Tilt live-reloads - re-poll status to verify
100
101After 3 fix iterations on the same resource without progress:
102- Report the error with full logs
103- Identify whether it's a Tiltfile bug, upstream dependency, or infrastructure problem
104- Do not silently skip or disable the resource
105
106### Step 5: Report
107
108```
109## Tilt Status: <healthy|degraded|errored>
110
111**Resources**: X/Y ok
112**Session**: zmx $SESSION
113
114### Errors (if any)
115- <resource>: <root cause> — <what was fixed or what remains>
116```