Run these in order. If any step fails, read the matching “If this fails” block before proceeding. Stop and report if a blocker is reached.
bun src/cli.ts --env sandbox-use2 health
Expected output shape:
# Kompo server is healthy
...
# KCP Discovery Chain
- knowledge.yaml: OK (kcp_version: ..., units: 0, updated: ...)
The deployed knowledge.yaml is a known 0-unit redirect-stub gap (and may be
reported as DEGRADED once the pending client fix merges); this does not fail
this step. The real 14-unit manifest arrives via --manifest in step 2.
If this fails: The sandbox API is unreachable. Check your network, wait a few minutes, retry. If persistent, stop and report: the API is down.
bun src/cli.ts --env sandbox-use2 auth/status
Expected output shape (unauthenticated):
# Auth Status (sandbox-use2)
- source: none (no user auth file)
- auth file: ~/.kompo/auth-sandbox-use2.json — not found
- Run kli auth/url + auth/complete to log in.
If it says authenticated with a future expiry, skip to step 2.
To log in (human must do this once):
bun src/cli.ts --env sandbox-use2 auth/url
Open the printed URL in a browser, log in. The browser lands on a broken localhost page — this is normal. Copy the FULL address-bar URL and run:
bun src/cli.ts --env sandbox-use2 auth/complete "<pasted-url>"
If your platform operator has pre-provisioned ~/.kompo/auth-<env>.json,
auth/status will already report authenticated — skip the login.
If this fails:
?code=...&state=....After login, verify:
bun src/cli.ts --env sandbox-use2 auth/status
Expected: authenticated as <email> with a future expiry. Proceed to step 2.
bun src/cli.ts --env sandbox-use2 init --manifest <path-to-project-root>/knowledge.yaml
Expected output shape:
✅ AGENTS.md written to .../AGENTS.md
→ Bootstrap summary:
Environment: sandbox-use2
Tools operations: 24
Knowledge units: 14
Auth: ✅ authenticated as ...
The exact tools count may grow as the deployed manifest adds tools.
If this fails:
The scenario expects two audio files in scenarios/first-video/media/.
Check which files you have:
ls -la scenarios/first-video/media/
For each track defined in fixtures.json, find the matching file by the
filePatterns glob. Upload each:
bun src/cli.ts --env sandbox-use2 upload-analyze scenarios/first-video/media/<filename>
Expected output shape:
# upload-analyze
- fileId: <id>
- analysisStatus (response): queued
- analysisJob.jobId: <job-id>
- result: PASS
Capture each fileId — you will need them for the komposition.
If this fails:
scenarios/first-video/media/.bun src/cli.ts --env sandbox-use2 job-status/<jobId>.The rails runner fetches each track’s analysis endpoint directly and polls until
the flat response has analyzedAt and a finite bpm (up to about 60 attempts,
5 seconds apart). An LLM should use the same GET with its bearer token, or
report BLOCKED if it cannot make an authenticated request:
curl -H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
"${API_URL}/api/multimedia/<fileId>/analysis"
The response fields are bpm, confidence, method, beat1Ms (the advisory
start-time), downbeats (the beat grid), beats, and analyzedAt (completion
marker). There is no musicDNA wrapper, analysis job, or status field in this
response. Check that bpm matches the expected value from fixtures.json
(within tolerance; accept 0.5x or 2x octave multiples), and that the grid is
present. The rails runner also records BPM implied by the beats array as
secondary evidence.
Use fixtures.json to know the expected values. The rails runner reads the
analysis response and performs the BPM/start-time/grid checks; record a BLOCKED
result instead of inventing a client command if those fields are not exposed.
Key verification points:
bpmTolerance of expectedBpm (or 0.5x/2x if acceptBpmOctaves: true)beat1Ms: advisory, WARN onlydownbeats: beat gridanalyzedAt: completion markerIf this fails:
Write a komposition markdown file in beats-based format (V1/V2). Use the measured BPM from step 4 and the fileIds from step 3.
The order is defined in fixtures.json: beatsPerTrackSegment beats from
each track, sequenced in tracks order. All tracks in a multi-track komposition share one global BPM for beat-to-time conversion; do not mix tracks of very different tempo without accounting for this.
Minimal komposition structure:
# First Video — E2E Scenario
## Metadata
- BPM: <measured-bpm>
## Tracks
### Audio
- [<fileId1>](source-audio) "track-1-name"
- Start: 0 beats
- End: <beatsPerTrackSegment> beats
- [<fileId2>](source-audio) "track-2-name"
- Start: <beatsPerTrackSegment> beats
- End: <2*beatsPerTrackSegment> beats
### Visuals
If `fixtures.json` contains `visualFallback`, use its pre-uploaded file as a
source-video background:
```markdown
- [<visualFallback.fileId>](source-video) "Background"
- Start: 0 beats
- End: <total-beats> beats
Without visualFallback, use the Remotion visual:
- [remotion:KompoTitle](source-generated) "First Video Title"
- Start: 0 beats
- End: <total-beats> beats
- Props: {"title": "E2E First Video", "accentColor": "#6366f1"}
The fallback is a pre-uploaded solid background used while the Remotion render
is unavailable; removing it from fixtures.json restores the Remotion path.
Save it to a temp file (e.g., first-video.kompo.md) and load it:
bun src/cli.ts --env sandbox-use2 workstate/load-file first-video.kompo.md
Expected output shape:
# Muse Workstate
- **Environment:** sandbox-use2
...
## Current Object
- **Type:** komposition
- **Title:** First Video — E2E Scenario
- **ID:** `<komposition-id>`
Capture the komposition ID.
If this fails:
bun src/cli.ts --env sandbox-use2 workstate/render-qc
This command submits a video_build job, polls until terminal (SUCCEEDED or FAILED), resolves the production, and prints the stream URL.
If production/stream resolution is empty, the job’s own output_files[].download_url is a valid fallback for verification; report this as a possible server-side production-registration gap, not a build failure.
Expected output shape:
# Muse Renderability Lock
- Komposition: First Video — E2E Scenario (<id>)
- Job: <job-id>
- Status: PENDING
- Poll: kli --env sandbox-use2 job-status/<job-id>
# Muse Fresh Build QC
- Komposition: First Video — E2E Scenario (<id>)
- Job: <job-id>
- Job status: SUCCEEDED
- Production: <production-id>
- Stream URL: [present]
The command may take 2-10 minutes depending on render queue depth.
If this fails:
bun src/cli.ts --env sandbox-use2 jobs/<jobId> for
error details. Common causes: missing file references, invalid komposition
format, server-side render pipeline error.Download the video and run verification:
bun scenarios/first-video/verify.ts <downloaded-video.mp4> \
--expect-duration <computed-seconds> \
--tolerance 0.5 \
--resolution 1920x1080
Expected output shape:
# Video Verification
File: <path> (<size> bytes)
Streams detected: 2
video (h264): 1920x1080
audio (aac): ...
## Checks
✅ Duration: expected 14.22s ±0.5s, got 14.25s (diff 0.03s)
✅ Video stream: expected present, got present
✅ Audio stream: expected present, got present
✅ Resolution: expected 1920x1080, got 1920x1080
✅ Bitrate: expected >0, got 1234567 bps
Overall: PASS
Output resolution is a fixed platform default (1920x1080), not client-specifiable.
The expected duration is computed from the komposition using its single global
BPM: total_beats × 60 / global_bpm. Do NOT hardcode a number — compute it.
If this fails:
brew install ffmpegAll of these must be true:
docs/kcp/ or src/commands/.