mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2026-03-23 06:40:23 -07:00
Merge pull request #30 from m-cahill/m11-runner-lifecycle
M11: Runner lifecycle surface
This commit is contained in:
commit
08ac1c0e24
5 changed files with 245 additions and 32 deletions
|
|
@ -1,45 +1,48 @@
|
||||||
# M11 — Runner Lifecycle Surface
|
# M11 — Runner Lifecycle Surface
|
||||||
|
|
||||||
Phase: **Phase III — Runner & Service Boundary**
|
Phase: **Phase III — Runner & Service Boundary**
|
||||||
Status: Planned
|
Status: In Progress
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 1. Intent / Target
|
# 1. Intent / Target
|
||||||
|
|
||||||
Introduce lifecycle structure on ProcessingRunner:
|
Introduce a **lifecycle structure** for the ProcessingRunner.
|
||||||
|
|
||||||
|
The runner currently exposes a single method: `ProcessingRunner.run(request)`.
|
||||||
|
|
||||||
|
This milestone refactors the internal implementation into three lifecycle stages:
|
||||||
|
|
||||||
```
|
```
|
||||||
runner.prepare()
|
prepare → execute → finalize
|
||||||
runner.execute()
|
|
||||||
runner.finalize()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This enables:
|
This creates a **stable execution surface** that later milestones can instrument
|
||||||
* cancellation
|
(progress tracking, cancellation, API runners, queue workers).
|
||||||
* instrumentation
|
|
||||||
* progress reporting
|
|
||||||
* distributed execution (later milestones)
|
|
||||||
|
|
||||||
Behavior-preserving. No runtime changes yet.
|
Behavior must remain identical.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 2. Scope Boundaries
|
# 2. Scope Boundaries
|
||||||
|
|
||||||
### In scope
|
## In scope
|
||||||
|
|
||||||
* Add prepare / execute / finalize structure to ProcessingRunner
|
* Add lifecycle methods to ProcessingRunner
|
||||||
* Route existing run() logic through execute()
|
* Refactor run() to delegate to lifecycle stages
|
||||||
* Maintain identical behavior
|
* Add minimal lifecycle contract test
|
||||||
* Add minimal contract tests
|
* Preserve all current execution behavior
|
||||||
|
|
||||||
### Out of scope
|
## Out of scope
|
||||||
|
|
||||||
* No cancellation implementation yet
|
* No API changes
|
||||||
* No async
|
* No CLI changes
|
||||||
* No instrumentation hooks (M12)
|
* No runtime behavior changes
|
||||||
* No txt2img path through runner (M13)
|
* No async / threading
|
||||||
|
* No cancellation yet
|
||||||
|
* No instrumentation yet
|
||||||
|
|
||||||
|
Those come in later Phase III milestones.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -47,17 +50,125 @@ Behavior-preserving. No runtime changes yet.
|
||||||
|
|
||||||
| Surface | Invariant | Verification |
|
| Surface | Invariant | Verification |
|
||||||
|---------|-----------|--------------|
|
|---------|-----------|--------------|
|
||||||
| CLI behavior | Identical | smoke tests |
|
| CLI behavior | identical outputs | smoke tests |
|
||||||
| API responses | Unchanged | tests |
|
| API responses | unchanged schemas | smoke tests |
|
||||||
| Processing results | Byte-identical | quality tests |
|
| Processing results | identical images / metadata | golden outputs |
|
||||||
| CI coverage | ≥ 40% | CI gate |
|
| Runtime context | still created inside process_images_inner | code review |
|
||||||
|
| Coverage | ≥ 40% | CI gate |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 4. Deliverables
|
# 4. Verification Plan
|
||||||
|
|
||||||
|
CI must remain green.
|
||||||
|
|
||||||
|
Expected CI checks:
|
||||||
|
|
||||||
|
| Check | Expected |
|
||||||
|
|-------|----------|
|
||||||
|
| Linter | pass |
|
||||||
|
| Smoke Tests | pass |
|
||||||
|
| Quality Tests | pass (post-merge) |
|
||||||
|
| Coverage | ≥ 40% |
|
||||||
|
|
||||||
|
Manual verification: `pytest`
|
||||||
|
|
||||||
|
Runner contract tests must pass.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 5. Implementation Steps
|
||||||
|
|
||||||
|
## Step 1 — Extend ProcessingRunner
|
||||||
|
|
||||||
|
File: `modules/runtime/runner.py`
|
||||||
|
|
||||||
|
Refactor runner:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class ProcessingRunner:
|
||||||
|
|
||||||
|
def run(self, request):
|
||||||
|
state = self.prepare(request)
|
||||||
|
result = self.execute(state)
|
||||||
|
return self.finalize(state, result)
|
||||||
|
|
||||||
|
def prepare(self, request):
|
||||||
|
return request
|
||||||
|
|
||||||
|
def execute(self, state):
|
||||||
|
from modules.processing import process_images_inner
|
||||||
|
return process_images_inner(state.processing)
|
||||||
|
|
||||||
|
def finalize(self, state, result):
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
|
Important: prepare/execute/finalize must remain **pass-through behavior**.
|
||||||
|
|
||||||
|
## Step 2 — Preserve delegation
|
||||||
|
|
||||||
|
Call graph must remain:
|
||||||
|
|
||||||
|
```
|
||||||
|
process_images(p)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
ProcessingRunner.run(request)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
prepare
|
||||||
|
│
|
||||||
|
execute
|
||||||
|
│
|
||||||
|
finalize
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
process_images_inner(p)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3 — Update contract tests
|
||||||
|
|
||||||
|
Add lifecycle verification.
|
||||||
|
|
||||||
|
File: `test/quality/test_processing_runner.py`
|
||||||
|
|
||||||
|
Add test verifying lifecycle order. Keep existing `test_processing_runner_delegates`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 6. Risk & Rollback Plan
|
||||||
|
|
||||||
|
Risk level: **Low**
|
||||||
|
|
||||||
|
Changes are mechanical and internal.
|
||||||
|
|
||||||
|
Rollback: revert runner lifecycle commit, restore single run(), re-run CI.
|
||||||
|
|
||||||
|
No runtime data or external API surfaces change.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 7. Deliverables
|
||||||
|
|
||||||
|
Code: `modules/runtime/runner.py` lifecycle implementation
|
||||||
|
|
||||||
|
Tests: updated `test_processing_runner.py`
|
||||||
|
|
||||||
Code: `modules/runtime/runner.py` (lifecycle methods)
|
|
||||||
Tests: `test/quality/test_processing_runner.py` (lifecycle contract)
|
|
||||||
Docs: M11_plan.md, M11_toolcalls.md, M11_run1.md, M11_summary.md, M11_audit.md
|
Docs: M11_plan.md, M11_toolcalls.md, M11_run1.md, M11_summary.md, M11_audit.md
|
||||||
Ledger: Update `docs/serena.md`
|
|
||||||
|
Ledger update: `docs/serena.md`
|
||||||
|
|
||||||
Tag: `v0.0.11-m11`
|
Tag: `v0.0.11-m11`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 8. Exit Criteria
|
||||||
|
|
||||||
|
M11 closes when:
|
||||||
|
|
||||||
|
* PR CI passes
|
||||||
|
* post-merge Quality Tests pass
|
||||||
|
* lifecycle runner merged
|
||||||
|
* ledger updated
|
||||||
|
* tag created
|
||||||
|
|
|
||||||
56
docs/milestones/M11/M11_run1.md
Normal file
56
docs/milestones/M11/M11_run1.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# M11 CI Run 1 — Runner Lifecycle Surface
|
||||||
|
|
||||||
|
**Date:** 2026-03-12
|
||||||
|
**Branch:** m11-runner-lifecycle
|
||||||
|
**PR:** [#30](https://github.com/m-cahill/serena/pull/30)
|
||||||
|
**Trigger:** push, pull_request
|
||||||
|
**Commit:** fb705fe6 (M11 impl), ce2659f1 (trigger CI)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Workflow Identity
|
||||||
|
|
||||||
|
| Workflow | Run ID | Trigger | Branch | Status |
|
||||||
|
|----------|--------|---------|--------|--------|
|
||||||
|
| Linter | 22989791480, 22989833120 | push | m11-runner-lifecycle | ✓ success |
|
||||||
|
| Smoke Tests | — | pull_request | m11-runner-lifecycle | not triggered |
|
||||||
|
|
||||||
|
**Quality Tests:** Post-merge only (runs on push to main).
|
||||||
|
|
||||||
|
**Note:** Smoke Tests did not run for this PR (may be branch-protection or workflow config). Linter (ruff + eslint) passed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Workflow Inventory
|
||||||
|
|
||||||
|
### Linter (22989833120)
|
||||||
|
|
||||||
|
| Job | Required? | Purpose | Pass/Fail | Notes |
|
||||||
|
|-----|-----------|---------|-----------|-------|
|
||||||
|
| ruff | Yes | Python lint | ✓ | 7s |
|
||||||
|
| eslint | Yes | JS lint | ✓ | 13s |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Refactor Signal Integrity
|
||||||
|
|
||||||
|
### A) Tests
|
||||||
|
|
||||||
|
- **Tier:** Smoke (not run for this PR), Quality (post-merge)
|
||||||
|
- **Coverage of refactor target:** `test_runner_lifecycle_order` verifies prepare → execute → finalize order. `test_processing_runner_delegates` verifies run still delegates to process_images_inner.
|
||||||
|
- **Expected:** Both pass. No behavior change.
|
||||||
|
|
||||||
|
### B) Change Inventory
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|------|--------|
|
||||||
|
| modules/runtime/runner.py | Lifecycle: prepare, execute, finalize; run() delegates |
|
||||||
|
| test/quality/test_processing_runner.py | Add test_runner_lifecycle_order |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Verdict
|
||||||
|
|
||||||
|
**Verdict:** Linter passed. Smoke Tests did not run for this PR (may require manual trigger or merge). Implementation is mechanical and behavior-preserving; Quality Tests will run post-merge.
|
||||||
|
|
||||||
|
**Recommended:** Merge PR; verify Quality Tests pass post-merge. If Smoke Tests are required for merge, consider re-running workflows or checking branch protection.
|
||||||
|
|
@ -4,3 +4,10 @@ Implementation toolcalls for Cursor execution.
|
||||||
|
|
||||||
| Timestamp | Tool | Purpose | Files/Target | Status |
|
| Timestamp | Tool | Purpose | Files/Target | Status |
|
||||||
|-----------|------|---------|--------------|--------|
|
|-----------|------|---------|--------------|--------|
|
||||||
|
| 2026-03-11 | run | Create branch m11-runner-lifecycle | git | done |
|
||||||
|
| 2026-03-11 | search_replace | Implement lifecycle in runner.py | modules/runtime/runner.py | done |
|
||||||
|
| 2026-03-11 | search_replace | Add test_runner_lifecycle_order | test/quality/test_processing_runner.py | done |
|
||||||
|
| 2026-03-11 | search_replace | Update M11_plan.md with full details | docs/milestones/M11/M11_plan.md | done |
|
||||||
|
| 2026-03-11 | run | Commit and push M11 implementation | git | done |
|
||||||
|
| 2026-03-11 | run | Create PR #30 | gh pr create | done |
|
||||||
|
| 2026-03-12 | search_replace | Update M11_run1.md with CI results | docs/milestones/M11/M11_run1.md | done |
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""ProcessingRunner — unified execution entrypoint for Serena pipeline.
|
"""ProcessingRunner — unified execution entrypoint for Serena pipeline.
|
||||||
|
|
||||||
M10: Thin adapter around process_images_inner. No behavior changes.
|
M10: Thin adapter around process_images_inner. No behavior changes.
|
||||||
|
M11: Lifecycle surface (prepare → execute → finalize). Pass-through behavior.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,9 +15,24 @@ class ProcessingRequest:
|
||||||
class ProcessingRunner:
|
class ProcessingRunner:
|
||||||
"""
|
"""
|
||||||
Unified execution entrypoint for Serena processing pipeline.
|
Unified execution entrypoint for Serena processing pipeline.
|
||||||
|
M11: Exposes lifecycle stages for future instrumentation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def run(self, request):
|
def run(self, request):
|
||||||
"""Execute processing pipeline."""
|
"""Execute processing pipeline via lifecycle stages."""
|
||||||
|
state = self.prepare(request)
|
||||||
|
result = self.execute(state)
|
||||||
|
return self.finalize(state, result)
|
||||||
|
|
||||||
|
def prepare(self, request):
|
||||||
|
"""Lifecycle stage 1: prepare request. Pass-through in M11."""
|
||||||
|
return request
|
||||||
|
|
||||||
|
def execute(self, state):
|
||||||
|
"""Lifecycle stage 2: run processing. Delegates to process_images_inner."""
|
||||||
from modules.processing import process_images_inner
|
from modules.processing import process_images_inner
|
||||||
return process_images_inner(request.processing)
|
return process_images_inner(state.processing)
|
||||||
|
|
||||||
|
def finalize(self, state, result):
|
||||||
|
"""Lifecycle stage 3: finalize. Pass-through in M11."""
|
||||||
|
return result
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,30 @@
|
||||||
"""Contract tests for ProcessingRunner (M10 runner skeleton)."""
|
"""Contract tests for ProcessingRunner (M10 runner skeleton, M11 lifecycle)."""
|
||||||
from modules.runtime.runner import ProcessingRunner, ProcessingRequest
|
from modules.runtime.runner import ProcessingRunner, ProcessingRequest
|
||||||
|
|
||||||
|
|
||||||
|
def test_runner_lifecycle_order(monkeypatch, initialize):
|
||||||
|
"""ProcessingRunner invokes prepare → execute → finalize in order."""
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
class TestRunner(ProcessingRunner):
|
||||||
|
def prepare(self, request):
|
||||||
|
calls.append("prepare")
|
||||||
|
return request
|
||||||
|
|
||||||
|
def execute(self, state):
|
||||||
|
calls.append("execute")
|
||||||
|
return "result"
|
||||||
|
|
||||||
|
def finalize(self, state, result):
|
||||||
|
calls.append("finalize")
|
||||||
|
return result
|
||||||
|
|
||||||
|
runner = TestRunner()
|
||||||
|
runner.run(ProcessingRequest(processing="dummy"))
|
||||||
|
|
||||||
|
assert calls == ["prepare", "execute", "finalize"]
|
||||||
|
|
||||||
|
|
||||||
def test_processing_runner_delegates(monkeypatch, initialize):
|
def test_processing_runner_delegates(monkeypatch, initialize):
|
||||||
"""ProcessingRunner.run delegates to process_images_inner."""
|
"""ProcessingRunner.run delegates to process_images_inner."""
|
||||||
import modules.processing
|
import modules.processing
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue