# SPRINT v0.1.34 - NEXT FOR OPENCODE
## Stop Mixing Sessions, Stop Validating Running Jobs, Recover Runtime Truth Before Musical Iteration

**Owner:** OpenCode  
**Reviewer:** Codex  
**Fecha:** 2026-04-03  
**Report reviewed:** `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\docs\SPRINT_v0.1.33_VALIDATION_REPORT.md`

---

## 1. Executive Review

The main problem was not only that the set looked bad.

The main problem was that OpenCode validated and reported **mixed runtime truths**:

- one job was still running
- the manifest came from an older completed run
- the older completed run had actually ended with an internal error

That means the report was not a reliable description of one single generation.

This sprint is about restoring truth discipline before more musical iteration.

---

## 2. Runtime Truth Verified By Codex

Codex verified these facts from disk:

- `generation_manifests.json` latest persisted session is:
  - `689f4f6b2361`
- `generation_jobs.json` shows:
  - report job `f7bd2d0a95e8` was still `running`
  - stage was only `generating_config`
  - it had not completed when OpenCode validated

Codex also verified this:

- `ba1111cd6a59` stored `session_id = 689f4f6b2361`
- that job was marked `completed`
- but its `result_text` contains a real traceback:
  - `KeyError: 'C:\\ProgramData\\Ableton\\Live 12 Suite\\Resources\\MIDI Remote Scripts\\libreria\\reggaeton\\kick\\kick nes 2.wav'`
- so that completed state was false-positive job bookkeeping

Therefore the v0.1.33 report mixed at least two incompatible truths:

1. live/validation state from the still-running async job `f7bd2d0a95e8`
2. manifest state from previous stored session `689f4f6b2361`

That invalidates the report as senior evidence.

---

## 3. Code Review Findings

### P0. Async jobs could be marked completed even when generation returned an error string

In:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\server.py`

`_run_generation_job(...)` treated any returned text from `generate_track(...)` or `generate_song(...)` as success.

That allowed this broken state:

- job status = `completed`
- result text = `Error generando track: ...`

This was a real reporting bug, not user confusion.

### P0. `get_generation_manifest()` returned stale latest manifest while a newer async job was still running

In:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\server.py`

OpenCode called `get_generation_manifest()` without explicit `session_id`.

While a newer job was still running, that returned the previous stored manifest instead of the current job truth.

This is exactly how the report ended up mixing:

- `job_id = f7bd2d0a95e8`
- `session_id = 689f4f6b2361`

### P0. Cross-generation memory could crash at generation end

In:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\sample_selector.py`

`_update_cross_generation_memory(...)` compacted `defaultdict` state into plain dicts, then later did `+=` on unseen keys.

That is the real cause of the stored traceback in the completed job.

### P1. QA bus counting depended on `list_buses`, but the active runtime does not expose that command

In:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\server.py`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\abletonmcp_init.py`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\abletonmcp_runtime.py`

The runtime path used by validation did not implement `list_buses`.

So `diagnose_generated_set()` and parts of `validate_set()` could claim:

- `bus_count = 0`

even when the generation manifest had real buses.

### P1. QA over-penalized source MIDI tracks that were already replaced by audio

In:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\server.py`

`_validate_empty_clips(...)` treated empty source tracks as failures even when matching `AUDIO ...` replacement tracks existed.

That was inflating false negatives in audio-first or recovery-fallback runs.

---

## 4. Fixes Already Applied By Codex

These fixes are already on disk. Do not revert them.

### 4.1 Async job error detection

Codex added result-text failure detection in:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\server.py`

Now a job that returns:

- `Error generando track: ...`

is marked `failed`, not `completed`.

### 4.2 Stale manifest guard

Codex hardened:

- `get_generation_manifest(...)`

Now if there is an active `queued` or `running` generation and no explicit `session_id` was given, the tool returns an error instead of silently handing back a stale old manifest.

### 4.3 Cross-generation memory fix

Codex fixed:

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\sample_selector.py`

So cross-generation memory stays safe when new sample families or new paths appear after compaction.

### 4.4 Bus fallback for QA

Codex added server-side fallback bus inference from live track names.

This means validation/diagnosis no longer depends entirely on `list_buses`.

### 4.5 Audio replacement awareness in empty-clip QA

Codex changed QA so empty source MIDI tracks are not treated as hard failures when matching audio replacement tracks are already present.

---

## 5. Validation Performed By Codex

Codex verified:

- `python -m py_compile` passed for:
  - `server.py`
  - `sample_selector.py`
  - `tests\test_sample_selector.py`
  - `tests\test_piano_forward.py`
- tests passed:
  - `tests\test_sample_selector.py`
  - `tests\test_piano_forward.py`

Codex also added regression coverage for:

- cross-generation memory after compaction
- bus inference fallback when runtime has no `list_buses`
- async manifest guard while a job is still running
- result-text error detection for generation jobs

No new song was generated in this review turn.

---

## 6. What OpenCode Must Do Next

### P0. Never validate a running async job

If `get_generation_job_status(...)` returns:

- `queued`
- `running`

then:

- do not call `validate_set`
- do not call `diagnose_generated_set`
- do not call `get_generation_manifest("")`
- do not write a validation report yet

Wait until the job is:

- `completed`
- or `failed`

### P0. A report must describe one single run, not mixed state

The next report is invalid unless all of these match:

- `job_id`
- `session_id`
- validation target
- manifest target

If OpenCode uses:

- `job_id = X`

then the report must validate the completed session that belongs to `X`.

No mixing:

- running live state from one job
- manifest from another older job

### P0. If async generation fails, report failure honestly

If job status is `failed`, OpenCode must:

- stop claiming generation success
- include the actual `error`
- include `result_text`
- include `session_id` only if one was partially stored
- explain whether the set in Live is partial, stale, or broken

### P0. Use explicit `session_id` for manifest retrieval after async work

After a job completes:

1. call `get_generation_job_status(job_id)`
2. extract its final `session_id`
3. call `get_generation_manifest(session_id)`

Do not call:

- `get_generation_manifest("")`

after async generation unless there are no active jobs and you intentionally want the latest stored manifest.

### P1. Keep no-piano policy active

Still required:

- no piano audio loops
- no `HARMONY_PIANO_MIDI`
- no piano timbre as harmonic spine

Harmonic support must use non-piano families.

### P1. Only iterate musically after truth is clean

The user complaint about “porqueria” is valid.

But OpenCode must not jump back into musical tweaking until the next report proves:

- one job
- one session
- one manifest
- one validation target

Otherwise musical conclusions are unreliable.

---

## 7. Required Evidence For The Next Report

The next report is invalid unless it includes:

1. exact `job_id`
2. exact final job `status`
3. exact final `session_id`
4. explicit proof that validation ran after completion
5. manifest fetched with explicit `session_id`
6. clear statement whether the run is:
   - usable
   - partial
   - failed
7. if failed, the real error text

If the job is still running, the correct report is not a validation report.

It is only a progress note.

---

## 8. Immediate Product Direction After Truth Recovery

Once the job/session/report mismatch is closed, the next real musical targets remain:

- stop 4-second loop feeling
- stop empty holes after one good block
- improve continuity in Arrangement
- improve real section-to-section development
- keep user library central
- keep vocals manual-only

But do not tackle those while the reporting layer is still lying.

Runtime truth first.
