refactor(planning): consolidate plan observations in one module

Move time-off periods, work sequences, public-holiday weeks, balance
observations, the placement list and both tie keys into
plan-observations.ts. The code moves without behavior changes; all seven
benchmark scenarios produce byte-identical outcomes, explanations and final
states, and the frozen-engine check passes. Benchmark timings stay within
noise.

Refs #282

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nessarandClaude Opus 5.5 committed 2026-10-16 23:47:34 +02:00
1 parent 24c35542a8
commit 87d72064be
3 files changed
+384 -281

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
# Issue #279: incremental exact scoring
Step-by-step record for [issue #279](https://gitea.nessar.fr/nessar/vac-optimizer/issues/279).
Each step keeps planning outcomes, stable explanations and final states identical
to develop after PR #278 (`a871f8f`). The
[frozen-engine differential check](README.md#frozen-engine-differential-check)
guards every step.
All measurements use Node 24.18.0, Bun 1.3.14 and Vitest 5.0.3 on the development
laptop, with no other test, build or profiling workload running alongside the
protocol. Only same-session before/after pairs are comparable.
```sh
NODE_OPTIONS=--max-old-space-size=2048 timeout 300s bunx vitest run src/app/benchmark/leave-planner-benchmark.spec.ts --maxWorkers=1
```
The per-scenario figures below are the means of the two measured calculations.
## Baseline profile
A CPU profile of the bundled core over all seven scenarios, with
`calculationDate: '2024-01-01'`, put 50.5 of 67.0 loaded-year seconds in
candidate evaluation (`evaluateRuleCandidate`). Of those, 41.3 seconds went to
active-objective evaluation: 15.6 seconds in time-off-period observations,
11.5 seconds in building observations and 7.6 seconds in sorting placement dates
for the placement tie key and the observation cache key. The asynchronous
adapter's 1 ms timer yields cost about 7% on typed obligations.
## #282: consolidate plan observations
Time-off periods, work sequences, public-holiday weeks, balance observations,
the placement list and both tie keys now live in
`src/app/services/plan-observations.ts`. The code moved without behavior
changes. All seven scenarios produce byte-identical outcomes, explanations and
final states compared with `a871f8f`.
| Measurement | Before | After |
| ------------------- | --------: | --------: |
| Vitest duration | 262.000 s | 262.030 s |
| Loaded year | 66.010 s | 66.497 s |
| Typed obligations | 4.887 s | 4.964 s |
| Two years | 2.914 s | 2.977 s |
| Three years | 10.203 s | 10.049 s |
| Representative year | 0.557 s | 0.569 s |
The differences are within run-to-run noise. The functional suite passes
666 tests across 34 files, including the frozen-engine check.