Adds phase-gating validation to DecisionService.record_decision()
that enforces the specification constraint: certain decision types
are only valid during specific plan phases.
Phase assignment changes:
- resource_selection added to EXECUTE_TYPES (was Strategize-only,
now Strategize-or-Execute per ADR-007 and ADR-033).
- subplan_spawn / subplan_parallel_spawn remain in both phase sets;
code comment documents divergence from ADRs per M4 subplan model.
- is_any_phase_type property updated to check both sets dynamically.
- Module docstring table updated to match actual assignments.
Service changes:
- DecisionPhaseViolationError raised before persistence.
- PHASE_ALLOWED_TYPES typed as Mapping (was dict).
- _resolve_plan_phase: invalid plan_phase string now raises
ValidationError (was uncaught ValueError).
- _resolve_plan_phase: database errors caught and logged, falling
through to skip gating (preserves opt-in contract).
- TOCTOU and uncached-DB-lookup documented with code comments.
Test additions:
- DB-resolved phase for Execute plan (was only Strategize).
- DB lookup when plan not found → gating skipped.
- PlanPhase enum passed directly to plan_phase parameter.
- Inline imports moved to module top-level per CONTRIBUTING.md.
- tempfile.mktemp() replaced with mkstemp().
- UnitOfWork engine.dispose() added to test cleanup.
- Robot tests now assert stderr is empty.
- Flaky concurrency test timing increased.
ISSUES CLOSED: #931