Give planning calculations one state owner #275

Closed
opened 2026-10-15 21:52:15 +02:00 by nessar · 0 comments
Owner

What to build

A calculation service owns the submitted planning request, pending calculation, and accepted calculation state. The calendar and leave-balance summary consume the same accepted outcome and immutable snapshot. Users can edit inputs, calculate, cancel, read explanations, and compare placement dates with the existing behavior, while components no longer coordinate shared writable calculation state.

Acceptance criteria

  • Give the calculation service ownership of request construction from the selected planning horizon, leave balances, declared non-working days, and ordered rules. Supply the duration estimator from that same request; calculating must not depend on request construction inside the estimator.
  • Expose start/cancel operations and read-only pending and accepted calculation state. Keep the underlying planning calculation context and its independent outcome, explanation, and explanation-error delivery contracts. Migrate both calendar and summary consumers together, removing their displaced writable state and trigger bookkeeping.
  • Preserve the initial calculation behavior and explicit Calculate action. Editing inputs alone does not recalculate or replace the displayed plan. A preceding result and its horizon remain visible until the submitted replacement outcome is accepted.
  • Accept each outcome with its own immutable submitted snapshot, horizon, declared days, and rule identities. Ignore outcomes, progress, and explanations belonging to replaced calculations. A completed outcome becomes usable before its explanation, and an explanation failure cannot discard it.
  • Preserve cancellation before and after a valid incumbent, cancelling feedback, and best-valid-partial-plan recovery without reporting a false obligation conflict. Invalid input, actual planning conflicts, worker unavailability, and planner errors retain their distinct supported outcomes.
  • Keep displayed-placement counterfactual date analysis tied to the accepted calculation and final state. Changing selection, closing the comparison, or replacing the calculation ignores obsolete results; comparison failures remain local and retryable. Hypothetical analysis never mutates the displayed plan.
  • Keep dialog control, focus, live announcements, rendering, and calendar-ready duration measurement at the component boundary. Calibrate successful calculations against their submitted snapshot after rendering; replaced or cancelled calculations do not become successful duration samples.
  • Move lifecycle checks to the calculation service where appropriate and retain component checks for actual rendering, keyboard access, focus, and announcements. Cover replacement during calculation and explanation delivery, rejection, cancellation, and edits made after submission. Preserve saved input and rule-migration behavior.
  • Replace the affected contracts and all callers in one cohesive change, with no temporary parallel calculation owner or compatibility adapter. Preserve the current planning algorithm, preference order, deterministic results, and technical planning-work budget semantics.

Integration

Complete the change on the shared feature/planning-architecture branch after ticket #274. Tickets #276 and #277 are independent and are not blockers for this ticket's implementation. After all four tickets are integrated, run the required correctness and coverage suites, static and formatting checks, production build, real-worker checks, and browser QA for calculation, cancellation, declaration entry, explanation, comparison, and summary agreement, including keyboard interaction and a narrow viewport. Verify deterministic fixture and benchmark-caller assertions without weakening them. Rebase the working branch onto the latest origin/develop and rerun required PR checks before integration. Record the combined result; the shared branch is ready only after this gate passes. Existing trace-removal verification remains in #77, and full benchmark performance acceptance and optimization remain in #78; this architecture work does not change CI or benchmark policy.

Blocked by

  • #274 — Remove the unused remaining-balance mirror. The replacement proceeds from the canonical displayed-plan representation established by that prefactor.
## What to build A calculation service owns the submitted planning request, pending calculation, and accepted calculation state. The calendar and leave-balance summary consume the same accepted outcome and immutable snapshot. Users can edit inputs, calculate, cancel, read explanations, and compare placement dates with the existing behavior, while components no longer coordinate shared writable calculation state. ## Acceptance criteria - [ ] Give the calculation service ownership of request construction from the selected planning horizon, leave balances, declared non-working days, and ordered rules. Supply the duration estimator from that same request; calculating must not depend on request construction inside the estimator. - [ ] Expose start/cancel operations and read-only pending and accepted calculation state. Keep the underlying planning calculation context and its independent outcome, explanation, and explanation-error delivery contracts. Migrate both calendar and summary consumers together, removing their displaced writable state and trigger bookkeeping. - [ ] Preserve the initial calculation behavior and explicit Calculate action. Editing inputs alone does not recalculate or replace the displayed plan. A preceding result and its horizon remain visible until the submitted replacement outcome is accepted. - [ ] Accept each outcome with its own immutable submitted snapshot, horizon, declared days, and rule identities. Ignore outcomes, progress, and explanations belonging to replaced calculations. A completed outcome becomes usable before its explanation, and an explanation failure cannot discard it. - [ ] Preserve cancellation before and after a valid incumbent, cancelling feedback, and best-valid-partial-plan recovery without reporting a false obligation conflict. Invalid input, actual planning conflicts, worker unavailability, and planner errors retain their distinct supported outcomes. - [ ] Keep displayed-placement counterfactual date analysis tied to the accepted calculation and final state. Changing selection, closing the comparison, or replacing the calculation ignores obsolete results; comparison failures remain local and retryable. Hypothetical analysis never mutates the displayed plan. - [ ] Keep dialog control, focus, live announcements, rendering, and calendar-ready duration measurement at the component boundary. Calibrate successful calculations against their submitted snapshot after rendering; replaced or cancelled calculations do not become successful duration samples. - [ ] Move lifecycle checks to the calculation service where appropriate and retain component checks for actual rendering, keyboard access, focus, and announcements. Cover replacement during calculation and explanation delivery, rejection, cancellation, and edits made after submission. Preserve saved input and rule-migration behavior. - [ ] Replace the affected contracts and all callers in one cohesive change, with no temporary parallel calculation owner or compatibility adapter. Preserve the current planning algorithm, preference order, deterministic results, and technical planning-work budget semantics. ## Integration Complete the change on the shared `feature/planning-architecture` branch after ticket [#274](https://gitea.nessar.fr/nessar/vac-optimizer/issues/274). Tickets [#276](https://gitea.nessar.fr/nessar/vac-optimizer/issues/276) and [#277](https://gitea.nessar.fr/nessar/vac-optimizer/issues/277) are independent and are not blockers for this ticket's implementation. After all four tickets are integrated, run the required correctness and coverage suites, static and formatting checks, production build, real-worker checks, and browser QA for calculation, cancellation, declaration entry, explanation, comparison, and summary agreement, including keyboard interaction and a narrow viewport. Verify deterministic fixture and benchmark-caller assertions without weakening them. Rebase the working branch onto the latest `origin/develop` and rerun required PR checks before integration. Record the combined result; the shared branch is ready only after this gate passes. Existing trace-removal verification remains in [#77](https://gitea.nessar.fr/nessar/vac-optimizer/issues/77), and full benchmark performance acceptance and optimization remain in [#78](https://gitea.nessar.fr/nessar/vac-optimizer/issues/78); this architecture work does not change CI or benchmark policy. ## Blocked by - [#274](https://gitea.nessar.fr/nessar/vac-optimizer/issues/274) — Remove the unused remaining-balance mirror. The replacement proceeds from the canonical displayed-plan representation established by that prefactor.
nessar added the ready-for-agent label 2026-10-15 21:52:15 +02:00
nessar added a new dependency 2026-10-15 21:52:16 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: nessar/vac-optimizer#275