feat(plan): enforce decision type phase-gating at recording time #973

Merged
hurui200320 merged 2 commits from feature/m4-decision-phase-gating into master 2026-03-19 07:53:44 +00:00

2 Commits

Author SHA1 Message Date
hurui200320 a3706a393d Merge branch 'master' into feature/m4-decision-phase-gating
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 30s
CI / security (pull_request) Successful in 51s
CI / typecheck (pull_request) Successful in 1m3s
CI / unit_tests (pull_request) Successful in 3m25s
CI / integration_tests (pull_request) Successful in 3m45s
CI / docker (pull_request) Successful in 55s
CI / e2e_tests (pull_request) Successful in 5m19s
CI / coverage (pull_request) Successful in 7m1s
CI / benchmark-regression (pull_request) Successful in 38m21s
2026-03-19 07:45:35 +00:00
hurui200320 296daebe59 feat(plan): enforce decision type phase-gating at recording time
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 21s
CI / lint (pull_request) Successful in 27s
CI / quality (pull_request) Successful in 33s
CI / typecheck (pull_request) Successful in 47s
CI / security (pull_request) Successful in 53s
CI / unit_tests (pull_request) Successful in 3m13s
CI / integration_tests (pull_request) Successful in 3m50s
CI / docker (pull_request) Successful in 56s
CI / e2e_tests (pull_request) Successful in 5m47s
CI / coverage (pull_request) Successful in 7m12s
CI / benchmark-regression (pull_request) Has been cancelled
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
2026-03-19 06:58:01 +00:00