Files
vac-optimizer/docs/planning-duration.md
T
nessar d9d9befa12
CI / policy (push) Successful in 7s
CI / validate (push) Successful in 1m15s
CI / test (push) Successful in 3m18s
CI / benchmark (push) Failing after 5m53s
CI / build (push) Successful in 1m23s
CI / security (push) Successful in 7m6s
CI / policy (pull_request) Successful in 7s
CI / validate (pull_request) Successful in 1m9s
CI / build (pull_request) Successful in 43s
CI / test (pull_request) Successful in 3m19s
CI / images (push) Successful in 3m7s
CI / required (push) Successful in 2s
CI / benchmark (pull_request) Failing after 5m28s
CI / security (pull_request) Successful in 6m37s
CI / images (pull_request) Successful in 3m18s
CI / required (pull_request) Successful in 1s
refactor(planning): remove the original decision trace
2026-10-15 20:42:33 +02:00

6.0 KiB
Raw Blame History

Indicative wait before Calculate

The small range beside Calculate describes the configuration currently in the form. Editing dates, balances or rules updates it without requesting a plan or changing the previously displayed calendar. It is an approximation, with no accuracy guarantee or automatic stopping deadline.

Initial estimate

PlanningDurationService shares the date-only request with CalendarYear so the estimate and calculation use the same horizon, balances and rules. Invalid horizon dates hide the estimate and retain the existing disabled Calculate control. Other malformed inputs keep a rough fallback estimate; the planner still performs its own validation.

The initial model is a deliberately rough engineering prior grounded in the browser reference measurements: the 2026-10-03 annual 30-day scenario returned its outcome in about 0.6 seconds, and the 2026-10-05 two- and three-year calendar runs with 30 days per year took 5.08 and 10.86 seconds. These are throttled desktop measurements, not phone measurements or a validated prediction model. The annual outcome timing does not include final calendar rendering. The new rendered-calendar measurements below supplement those references.

For a half-open horizon of D calendar days, the model uses:

initial_ms = 300 + 600 × (D / 365.25)^1.2 × (max(1, P) / 30)^1.5 × R

P approximates placement load. Each non-negative finite balance contributes at most five sevenths of its calendar-day overlap with the horizon, availability and inclusive expiry. An at-risk balance has weight 1; a deferred balance has weight 0.25 to account for possible supporting placements. Already expired and not-yet-available balances contribute nothing. Each enabled IF_THEN rule adds its non-negative earned quantity times D / 365.25 as a rough allowance.

R starts at 1. Each enabled rule adds max(1, placeDays / 3) times 0.5 for an obligation or 0.15 for a preference. TIME_WINDOW rules wholly outside the horizon contribute nothing. These weights approximate extra search, rather than solving constraints or counting holiday occurrences in the form. Typed obligations, date distribution, interacting rules, earned entitlements, device load and browser differences can all change the actual wait substantially.

The powers and weights are implementation choices, not complexity guarantees or fitted accuracy claims. With 30 available days per year, the model's search term grows as the number of years to the power 2.7, rather than assuming a linear increase. Horizons beyond the references are unvalidated extrapolation. The estimate performs one pass over balances and rules and runs no planner.

Local refinement and precision

After each successfully rendered Plan, the service retains the ratio of its observed elapsed time to the initial model for that calculation's immutable submitted snapshot. The median of the most recent eight ratios scales the initial estimate for the current form. A changed form therefore does not relabel the completed measurement as a calculation of the new configuration. The median limits the effect of isolated unusually slow runs; it cannot remove systematic model error or predict arbitrary obligation searches.

Only eight numeric ratios are retained in memory for the current application session. Reloading restores the initial estimate. Nothing is persisted or sent to a remote service, so there is no saved-measurement restoration dependency. Storage failure does not affect this service.

The displayed lower bound is half the estimated duration, rounded down; the upper bound is three times that duration, rounded up. Values are whole seconds, or whole minutes when the lower bound is at least one minute. The minimum displayed value is 1 and the upper bound is at least one unit higher. Internal duration rounding to whole milliseconds prevents floating-point noise at unit boundaries. Very fast runs can finish before the displayed lower bound. The range is explicitly indicative, not a confidence interval or a promise.

What is timed

Manual requests capture performance.now() inside UserInputService.requestComputation, before updating the calculation trigger. The existing initial calculation falls back to the start of startCalculation. The endpoint is Angular's afterNextRender callback after the complete plan has been projected into the calendar, its months and placements have been rendered, and the loading overlay has been removed. This measures request scheduling, calendar preparation, worker startup, search, outcome transport, projection and Angular rendering. It is a DOM readiness endpoint, rather than a claim to measure a physical screen's paint.

Neither core planningWorkMs nor artifact timings supply the calibration measurement. The callback does not wait for the explanation promise; later delivery, navigation and explanation errors never add a second measurement. Cancellation (including a retained incumbent), incomplete outcomes, invalid inputs, conflicts and calculation errors do not calibrate successful-plan waiting time. Superseded calculations and callbacks for destroyed calendars are ignored. Zero, negative and non-finite elapsed values are discarded.

Exceeding the range has no side effects. The estimate supplies no deadline, timer, date adjustment or new calculation. Cancel remains explicit.

Verification

Controlled-clock tests at the existing calendar and input seams cover initial estimation, unsubmitted edits, minute formatting, local refinement, request scheduling, a twenty-second calculation exceeding its initial range, an explanation that arrives after calendar readiness, cancellation with and without an incumbent, incomplete/error outcomes and superseded calculations. No timing assertion depends on CI hardware speed. Existing settings, planner and worker tests cover saved horizons, long calculations and interrupted-plan explanations.

Rendered annual, two-year and three-year references, with the actual displayed range and historical artifact-delivery wait, are recorded in the benchmark report.