6.0 KiB
M05 Plan — Override Isolation / Temporary Opts Seam
Project: Serena
Phase: Phase II — Runtime Seam Preparation
Milestone: M05
Title: Override Isolation / Temporary Opts Seam
Branch: m05-override-isolation
Posture: Behavior-Preserving Refactor
Target: Introduce an isolated mechanism for temporary option overrides during generation.
1. Intent / Target
Introduce a temporary options override seam that prevents direct mutation of shared.opts during generation runs.
Currently, process_images() temporarily mutates global options when applying override_settings, then restores them afterward.
This milestone introduces a context-managed override mechanism that:
- isolates temporary option changes
- preserves runtime behavior
- prepares the runtime pipeline for future opts snapshot injection
This is the first runtime seam milestone in Phase II.
2. Problem Being Solved
The current implementation inside modules/processing.py roughly resembles:
for k, v in p.override_settings.items():
opts.set(k, v)
process_images_inner(p)
restore_settings()
Issues:
- mutates global state
- creates potential nondeterminism
- makes testing harder
- couples generation pipeline to
shared.opts
This milestone does not change behavior, but introduces a structured override mechanism.
3. Scope Boundaries
In scope
- Introduce a temporary options context manager
- Replace inline override logic in
process_images() - Ensure restoration logic is deterministic
- Preserve identical runtime semantics
Explicitly out of scope
- Changing how
optsvalues are accessed elsewhere - Introducing
opts_snapshot(M07) - Changing processing pipeline structure
- Any modification to API/UI behavior
- Performance changes
4. Invariants (Must Not Change)
The following runtime surfaces must remain identical:
| Surface | Verification |
|---|---|
| Image outputs | Smoke tests |
| API response schemas | API tests |
| CLI behavior | Smoke tests |
| Extension behavior | Extension loading smoke |
| Generation semantics | txt2img / img2img smoke tests |
These invariants are part of the Serena invariant registry.
5. Verification Plan
CI gates expected to remain green
- Smoke tests
- Quality tests
- Coverage ≥ 40%
- verify_pinned_deps
- pip-audit (informational)
Evidence artifacts
CI should still produce:
coverage.xml
ci_environment.txt
as introduced in M04.
Behavioral verification
- Compare outputs from smoke generation tests
- Ensure override settings behave identically
6. Implementation Steps
Step 1 — Add temporary override context manager
Create helper:
modules/runtime_utils.py
(or similar location appropriate to project structure)
Add:
from contextlib import contextmanager
from modules import shared
@contextmanager
def temporary_opts(overrides: dict):
if not overrides:
yield
return
original = {}
try:
for key, value in overrides.items():
if hasattr(shared.opts, key):
original[key] = getattr(shared.opts, key)
shared.opts.set(key, value)
yield
finally:
for key, value in original.items():
shared.opts.set(key, value)
Purpose:
- isolate override logic
- centralize restore semantics
- enable later replacement with snapshot model
Step 2 — Replace override block in process_images()
Locate override logic inside:
modules/processing.py
Replace pattern similar to:
for k, v in p.override_settings.items():
opts.set(k, v)
process_images_inner(p)
restore_settings()
with:
with temporary_opts(p.override_settings):
process_images_inner(p)
Step 3 — Remove redundant restore logic
Remove manual restore code now handled by context manager.
Ensure behavior remains identical.
Step 4 — Minimal unit test
Add small test under:
test/quality/test_opts_override.py
Example:
def test_temporary_opts_restores_value():
from modules import shared
from modules.runtime_utils import temporary_opts
original = shared.opts.some_option
with temporary_opts({"some_option": "test_value"}):
assert shared.opts.some_option == "test_value"
assert shared.opts.some_option == original
Purpose:
- verify restoration behavior
- protect seam for future milestones
Step 5 — Ensure no behavior drift
Run:
pytest
Verify:
- generation tests unchanged
- API tests unchanged
- coverage still ≥ 40%
7. Risk & Rollback Plan
Risk
Low.
Changes are isolated to override application.
Potential issue
If extensions rely on exact ordering of override logic.
Rollback
Revert the commit introducing:
temporary_opts
and restore original override block.
Because the change is localized, rollback is trivial.
8. Deliverables
Code
New helper:
modules/runtime_utils.py
Modified:
modules/processing.py
New test:
test/quality/test_opts_override.py
Documentation
Update milestone artifacts:
docs/milestones/M05/M05_summary.md
docs/milestones/M05/M05_audit.md
Update ledger:
docs/serena.md
9. Acceptance Criteria
M05 is complete when:
- CI passes
- Coverage ≥ 40%
- Override logic replaced with context manager
- Runtime behavior unchanged
- Milestone documentation completed
- Audit score remains 5.0
10. Expected Architectural Impact
Before:
process_images
└─ mutate shared.opts
After:
process_images
└─ temporary_opts
└─ process_images_inner
This creates the first runtime seam required for Phase II.
11. Next Milestone
M06 — Prompt / Seed Preparation Extraction
Goal:
Extract prompt + seed preparation logic from process_images_inner().