KB-6BAA
Orchestrator O1 · 02 Module Placement Decision
4 min read Revision 1
dot-iu-cutterv0.6orchestrator-o1-authoringmodule-placementg1-passdieu442026-05-20
Orchestrator O1 · 02 Module Placement Decision
doc 2 of 6 · 2026-05-20 · G1 gate
phase : G1 — module placement outcome : G1 PASS — `cutter_agent/orchestrator/` (new subpackage) production_mutation : NONE
1. Options surveyed
| Option | Verdict | Rationale |
|---|---|---|
A. New subpackage cutter_agent/orchestrator/ |
ADOPTED | Cleanly separable from v0.5-ratified modules at top level; no risk of accidental edit to ratified files; explicit import boundary (from cutter_agent.orchestrator import …). |
B. Mix into top-level cutter_agent/ |
REJECTED | Pollutes ratified surface; future hardcode-cleanliness audits would need to re-scan all files. |
C. Top-level iu_orchestrator/ sibling package |
REJECTED | Splits a single codebase into two packages, complicates imports + tests + future deploy. |
D. cutter_agent/v0_6_orchestrator/ |
REJECTED | Version-name in path locks the package to v0.6; future v0.7+ renames create churn. |
2. Boundary asserted
ratified_v0_5_surface : cutter_agent/*.py at top level (UNCHANGED by O1)
new_o1_surface : cutter_agent/orchestrator/*.py
+ cutter_agent/orchestrator/phases/*.py
+ tests/test_orchestrator_o1_*.py
The O1 macro touches zero files outside the new surface (verified post-commit by git show 35ca9e1 --stat).
3. Module layout (final)
cutter_agent/orchestrator/
├── __init__.py # package banner: __execution_enabled__ = False
├── enums.py # state machine, gates, phases, batch states
├── errors.py # 17-entry STOP-route exception hierarchy
├── run_context.py # RunContext + PhaseRecord + ApprovalRecord
├── policy.py # no-user-artifact, discover-first, no-PIN-leak hooks
├── gates.py # gate-kind classifier + invariant registry + evaluator
├── state_store.py # fcntl-locked JSON sidecar
├── approval.py # sovereign approval doc validator
├── kb_reporter.py # Protocol + DryRunReporter (writes to disk)
├── discover.py # Discoverer Protocol + InMemoryDiscoverer
├── runner.py # OrchestratorRunner (state-machine driver)
├── batch.py # queue loader + BatchRunner skeleton
└── phases/
├── __init__.py # PHASE_REGISTRY
├── source_pin.py # FUNCTIONAL (read-only)
├── mark.py # SKELETON (StopNotImplemented)
├── cutplan.py # SKELETON
├── backup.py # SKELETON
├── grant_probe.py # SKELETON
├── cut_leg_a.py # SKELETON + ProductionExecutionNotAuthorized guard
├── structural_verify.py # SKELETON
├── leg_b_record.py # SKELETON + Production…guard
├── write_verify.py # SKELETON + Production…guard
├── lifecycle_enact.py # SKELETON + Production…guard
└── closeout.py # SKELETON
tests/
├── test_orchestrator_o1_state_machine.py
├── test_orchestrator_o1_run_context.py
├── test_orchestrator_o1_runner.py
└── test_orchestrator_o1_approval_and_batch.py
4. No-duplicate / no-clutter
- Each module owns a single responsibility (design doc 06 §2).
cli.pyextensions deliberately not added in O1 (deferred to O2 to keep the public CLI behaviour identical until the runner is wired to real DB). Tests reachOrchestratorRunnerdirectly.- No
__pycache__checked in;.gitignorealready excludes.
5. Verdict
g1_outcome : PASS
chosen : cutter_agent/orchestrator/ (subpackage)
ratified_modules_touched: 0
new_files : 24 (.py) + 4 (tests)
clutter_check : no duplicate / no shadow modules