From 4dd04999876a7932393004018fcf11bd8e13d420 Mon Sep 17 00:00:00 2001 From: m-cahill Date: Fri, 13 Mar 2026 15:17:06 -0700 Subject: [PATCH] M13: txt2img path through runner (#31) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * M13: txt2img path through runner — contract test and verification - Add test_txt2img_runner_contract.py verifying txt2img invokes ProcessingRunner - No routing changes: process_images already delegates to runner (M10) - Update M13_plan, M13_toolcalls, M13_run1 - Scope: UI txt2img only; API/img2img in M14/M15 Made-with: Cursor * docs(M13): add CI run1 results — smoke tests pass Made-with: Cursor --- docs/milestones/M13/M13_plan.md | 150 +++++++++++++++++++ docs/milestones/M13/M13_run1.md | 104 +++++++++++++ docs/milestones/M13/M13_toolcalls.md | 12 ++ test/quality/test_txt2img_runner_contract.py | 55 +++++++ 4 files changed, 321 insertions(+) create mode 100644 docs/milestones/M13/M13_plan.md create mode 100644 docs/milestones/M13/M13_run1.md create mode 100644 docs/milestones/M13/M13_toolcalls.md create mode 100644 test/quality/test_txt2img_runner_contract.py diff --git a/docs/milestones/M13/M13_plan.md b/docs/milestones/M13/M13_plan.md new file mode 100644 index 000000000..308b9fa59 --- /dev/null +++ b/docs/milestones/M13/M13_plan.md @@ -0,0 +1,150 @@ +# M13 — txt2img Execution via Runner + +Phase: Phase III — Runner & Service Boundary +Status: Planned + +--- + +# 1. Intent / Target + +Route the **txt2img execution path** through `ProcessingRunner` explicitly. + +Right now the runner exists but is still only used by the internal `process_images` wrapper. M13 makes the runner the **true execution surface** for txt2img while preserving behavior. + +### Architectural impact + +Before: + +``` +UI/API + │ +process_images + │ +runner +``` + +After: + +``` +UI/API + │ +Runner + │ +Pipeline +``` + +This begins the **UI/runtime separation** that Serena is aiming for. + +--- + +# 2. Scope Boundaries + +## In scope + +• Route txt2img path via runner +• Preserve existing request objects +• No UI or API behavior changes + +## Out of scope + +• API runner +• queue runner +• cancellation +• progress reporting + +--- + +# 3. Invariants + +| Surface | Requirement | Verification | +|---------------|---------------|--------------| +| CLI behavior | unchanged | smoke tests | +| API responses | unchanged | smoke tests | +| Output images | identical | quality tests| +| Extensions | unaffected | extension tests | + +--- + +# 4. Verification Plan + +CI must remain green. + +Expected checks: + +| Check | Expected | +|-------|----------| +| Linter | pass | +| Smoke Tests | pass | +| Quality Tests | pass (post-merge) | +| Coverage | ≥ 40% | + +--- + +# 5. Implementation Steps + +1. **Verify routing** — txt2img path calls `process_images` only; no direct `process_images_inner` in `modules/txt2img.py`. ✓ +2. **Confirm delegation** — `process_images` delegates to `ProcessingRunner().run(ProcessingRequest(p))` inside profiler block. ✓ +3. **Add contract test** — `test/quality/test_txt2img_runner_contract.py` verifies txt2img path invokes runner. ✓ +4. **No routing changes required** — Runner already sits behind `process_images` (M10–M12). Verification milestone. + +Key principle: txt2img call path must flow through `ProcessingRunner.run()` while preserving identical behavior. + +--- + +# 6. Risk & Rollback Plan + +Risk level: **Low** (routing verification milestone; runner already used by process_images) + +Rollback: revert txt2img routing commit; restore direct process_images path. + +--- + +# 7. Deliverables + +Code: + +``` +modules/runtime/runner.py +modules/processing.py +``` + +Tests: + +``` +test/quality/test_processing_runner.py +test/quality/test_txt2img_runner_contract.py # M13 contract test +``` + +Docs: + +``` +docs/milestones/M13/M13_plan.md +docs/milestones/M13/M13_toolcalls.md +docs/milestones/M13/M13_run1.md +docs/milestones/M13/M13_summary.md +docs/milestones/M13/M13_audit.md +``` + +Ledger: + +``` +docs/serena.md +``` + +Tag: + +``` +v0.0.13-m13 +``` + +--- + +# 8. Exit Criteria + +M13 closes when: + +• PR CI passes +• post-merge Quality Tests pass +• txt2img routed through runner merged +• ledger updated +• tag created diff --git a/docs/milestones/M13/M13_run1.md b/docs/milestones/M13/M13_run1.md new file mode 100644 index 000000000..4a6ec6c5e --- /dev/null +++ b/docs/milestones/M13/M13_run1.md @@ -0,0 +1,104 @@ +# M13 Run 1 — CI Analysis + +**Milestone:** M13 — txt2img execution via runner +**Branch:** m13-txt2img-runner +**PR:** [#31](https://github.com/m-cahill/serena/pull/31) +**Baseline:** v0.0.12-m12 (46cf6d1c) + +--- + +## 0. Workflow Run — Actual Results + +| Item | Value | +|------|-------| +| **Workflow** | Smoke Tests | +| **Run ID** | [23038170275](https://github.com/m-cahill/serena/actions/runs/23038170275) | +| **Trigger** | pull_request (#31) | +| **Branch** | m13-txt2img-runner | +| **Commit** | 142f0bbe | +| **Status** | ✓ completed | +| **Conclusion** | ✓ success | +| **Duration** | 2m 45s | + +### Job: smoke tests + +| Step | Result | +|------|--------| +| Verify repository | ✓ | +| Verify base branch | ✓ | +| Checkout Code | ✓ | +| Set up Python 3.10 | ✓ | +| Cache models | ✓ | +| Install test dependencies | ✓ | +| Install runtime dependencies | ✓ | +| Create stub repositories | ✓ | +| Setup environment | ✓ | +| Smoke startup | ✓ | +| Start test server | ✓ | +| **Run smoke tests** | ✓ | +| Kill test server | ✓ | +| Upload main app output | ✓ | + +**Annotation:** Node.js 20 actions deprecation warning (informational; not merge-blocking). + +--- + +## 1. Implementation Summary + +M13 was a **verification milestone**. No routing changes were required because: + +- `process_images` already delegates to `ProcessingRunner().run(ProcessingRequest(p))` (M10) +- `modules/txt2img.py` calls `process_images(p)` only (lines 83, 109) — no direct `process_images_inner` calls +- txt2img → process_images → runner → process_images_inner flow was already in place + +### Changes Made + +| File | Change | +|------|--------| +| `test/quality/test_txt2img_runner_contract.py` | New contract test verifying txt2img path invokes runner | +| `docs/milestones/M13/M13_plan.md` | Updated implementation steps, risk level, deliverables | +| `docs/milestones/M13/M13_toolcalls.md` | Tool call log | + +### Code Diff Size + +~50 lines (new test file + doc updates). No changes to `modules/txt2img.py`, `modules/processing.py`, or `modules/runtime/runner.py`. + +--- + +## 2. CI Results + +| Workflow | Trigger | Expected | Actual | +|----------|---------|----------|--------| +| Smoke Tests | PR | ✓ pass | ✓ pass (2m 45s) | +| Quality Tests | Push to main | ✓ pass | Pending (post-merge) | +| Coverage | Push to main | ≥ 40% | Pending (post-merge) | + +--- + +## 3. Refactor Target + +- **Surface:** txt2img UI path → process_images → ProcessingRunner +- **Posture:** Behavior-preserving +- **Verification:** Contract test locks in runner invocation + +--- + +## 4. Architectural Sign + +That routing required no changes is a **positive signal**: the runner seam introduced in M10–M12 is correctly positioned. All consumers (txt2img, img2img, API) that call `process_images` already flow through the runner. + +--- + +## 5. Conclusion + +**Run 1 status: ✓ GREEN.** Smoke tests passed. PR #31 is ready for merge (with permission). + +--- + +## 6. Next Steps + +1. ~~Await PR smoke CI pass~~ ✓ Done +2. Merge PR (with permission) +3. Verify quality tests pass on main (post-merge) +4. Update ledger, create tag v0.0.13-m13 +5. Proceed to M14 (API integration) diff --git a/docs/milestones/M13/M13_toolcalls.md b/docs/milestones/M13/M13_toolcalls.md new file mode 100644 index 000000000..1bcddd868 --- /dev/null +++ b/docs/milestones/M13/M13_toolcalls.md @@ -0,0 +1,12 @@ +# M13 Toolcalls — txt2img Execution via Runner + +Implementation toolcalls for Cursor execution. + +| Timestamp | Tool | Purpose | Files/Target | Status | +|-----------|------|---------|--------------|--------| +| 2026-03-12 | read | Verify baseline tag, branch creation | git, conftest | Done | +| 2026-03-12 | read | Verify txt2img routing, process_images delegation | txt2img.py, processing.py | Done | +| 2026-03-12 | write | Add contract test | test/quality/test_txt2img_runner_contract.py | Done | +| 2026-03-12 | search_replace | Update M13_plan implementation steps, risk, deliverables | docs/milestones/M13/M13_plan.md | Done | +| 2026-03-12 | write | M13_run1 CI analysis | docs/milestones/M13/M13_run1.md | Done | +| 2026-03-12 | run | Push branch, create PR | git push, gh pr | Done (PR link below) | diff --git a/test/quality/test_txt2img_runner_contract.py b/test/quality/test_txt2img_runner_contract.py new file mode 100644 index 000000000..fdc6b4da3 --- /dev/null +++ b/test/quality/test_txt2img_runner_contract.py @@ -0,0 +1,55 @@ +"""M13 contract test: txt2img path uses ProcessingRunner. + +Verifies that the txt2img execution path flows through process_images → runner, +not direct process_images_inner calls. +""" +from modules.runtime.runner import ProcessingRunner + + +def test_txt2img_path_uses_runner(monkeypatch, initialize): + """txt2img path invokes ProcessingRunner when process_images is called.""" + from modules.processing import ( + StableDiffusionProcessingTxt2Img, + process_images, + Processed, + ) + + calls = [] + + class TestRunner(ProcessingRunner): + def execute(self, state): + calls.append("runner_execute") + return super().execute(state) + + monkeypatch.setattr( + "modules.runtime.runner.ProcessingRunner", + TestRunner, + ) + + # Minimal processing object matching txt2img path + p = StableDiffusionProcessingTxt2Img( + sd_model=None, + prompt="test", + override_settings={}, + steps=1, + width=64, + height=64, + extra_generation_params={}, + ) + p.scripts = None + p.comments = [] + + # Mock process_images_inner to avoid full pipeline (model, device, etc.) + def fake_inner(proc): + return Processed(proc, [], seed=-1, info="", comments="") + + import modules.processing as proc_mod + monkeypatch.setattr(proc_mod, "process_images_inner", fake_inner) + + # Mock model reload to avoid loading weights + import modules.sd_models as sd_models_mod + monkeypatch.setattr(sd_models_mod, "reload_model_weights", lambda: None) + + process_images(p) + + assert "runner_execute" in calls