The generated HTML and Cobertura reports no longer show unmeasured
branch and function coverage as 100%. Poll and waitFor deadlines use
performance.now so frozen dates cannot make them loop forever, the
malformed-configuration test covers undefined again next to the empty
array, compose health checks honor PORT, and the migration spec lists
only what is still open.
Refs #291, #292, #293
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cancelled stage takes about a millisecond, so under load the worker
could finish it before the cancel message arrived and report it as
completed. The real-worker harness now holds the worker after reporting
that stage until the cancel is delivered, keeping every assertion.
Refs #291
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pin Bun 1.4.3 with packageManager, and force every bun run script onto
the Bun runtime through bunfig so ng, ESLint and Prettier never fall
back to an installed Node. Type checking uses bun check for the
application and test projects, next to the Angular build.
CI jobs install the pinned release from a checksum-verified download
instead of npm and run project steps in a shell without Node on PATH,
which stays available only for the checkout and upload actions. The
image test's fake docker runs on Bun.
Refs #290, #293
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Angular's server build needs Node loader hooks that Bun does not apply,
and every route is client-rendered, so Angular now builds a client-only
bundle and a small Bun.serve server delivers it: hashed assets with the
one-year cache, index.html revalidated, extension-less routes falling
back to index.html, missing assets 404, traversal and malformed paths
rejected, and other methods 405. Express, @angular/ssr and the unused
hydration provider are removed. Both Docker stages use the pinned
oven/bun:1.4.3-alpine image without Node, and the health checks use
Bun's fetch.
Refs #292
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace Vitest with bun test across the whole suite. A preload compiles
components through Angular's JIT transform with inlined templates, sets
up jsdom, TestBed and zoneless change detection, and a small shim covers
the Vitest APIs bun:test lacks. Files run isolated, real-worker specs
spawn the running Bun, and line coverage from lcov is converted to the
existing HTML and Cobertura reports. The CI benchmark replaces its heap
cap with a container memory limit. Vitest, Jest, Nx and their Vite
configuration are removed.
Refs #291
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stable Bun 1.4.3 runs installs, the development server, standalone type
checks, the native test runner and a Bun.serve static server. Native
lint/fmt are canary-only, and Angular's server build needs Node loader
hooks Bun does not apply, so the spec now keeps ESLint/Prettier until a
stable release, builds Angular client-only behind a Bun static server,
converts line coverage from lcov, and replaces the heap cap with a
container memory limit.
Refs #289
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Record the proposed decision to run project-owned JavaScript under Bun
with its native test runner, linter, formatter, type checker and HTTP
server, keeping Angular's standard build pipeline, plus the development
spec for the migration tickets.
Refs #289
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No caller read CalendarProjection.horizon, and with fixed months it no
longer described the listed months.
Refs #276
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Declaring a date at the edge of the planning period widened the
projection and inserted a disabled month above the grid. Declaration
entry now lists only the planning period's months, while selections
keep the connected-period widening.
Refs #276
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-mounting the calendar no longer records a duration sample or
announces the previous result, explanation or rejected explanation.
Starting a calculation during a cancellation announces loading and
keeps focus where it is. Only rejected explanation deliveries are
announced, as before. Replacement tests now replace a real plan.
Refs #275, #274
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
release() already clears the worker handlers, so the released checks
inside them could never run. The lifetime test now states what it
checks: no handler is left for late messages.
Refs #277
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CalendarService.project returns the covered months together with the
projected selections, so month enumeration and selected-day rendering
share one projection horizon. SelectedDates is built once from the
complete range list and groups connected periods internally, exposing
read-only selection, boundary and day-type queries.
In declaration entry, months reached by adjacent declared or
non-working days are now shown, matching the projected selections.
Refs #276
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PlanningCalculationService now builds the submitted request, owns the
pending and accepted calculation state, and delivers explanations for
the accepted calculation only. The duration estimator reads the same
request. The calendar and leave-balance summary consume the accepted
outcome instead of coordinating writable state on the input service.
Refs #275
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Planning, counterfactual analysis and checkpoint explanation now share
one internal worker-job owner for creation, handler cleanup,
termination and supersession, and one request/response message
contract between the coordinator and the worker. Job-specific progress,
checkpoint recovery and completion rules stay explicit.
Refs #277
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The summary and details already read the displayed plan's remaining
balances, so the writable mirror, its legacy conversion and the VacDay
classification/reason fields it alone populated are removed.
Refs #274
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Print the calibration and a Markdown table with one aligned row per
scenario as soon as it finishes: both planning times, mean, budget, ratio,
multiplier, outcome, placements, determinism and budget status. Write
directly to stdout so Vitest adds no per-line headers. The complete TSV
report still follows the table.
Refs #281, #285
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first PR run landed on srvhome, about 1.9 times slower than
nessar-desktop. The fixed 300-second timeout killed its protocol during the
loaded year, although every completed scenario was within its relative
budget. Raise the CI timeout to 600 seconds and the test timeout to 570
seconds so they only guard against hangs, and record the first CI-runner
ratios.
Refs #285
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The exact optimizations bring the loaded year from 66.0 s to 44.1 s, but the
target of 10 s for the loaded year and 3 s for the other scenarios is not
reached for the loaded year, typed obligations and three years. Record the
gap and the remaining profile, keep the relative-gate multipliers and the
300-second hang guard unchanged, and note that ADR 0003's five-second target
should be revisited together with a decision on search changes.
Refs #286
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Before the protocol, time the frozen engine on the two-year scenario, best
of three, and fail any scenario whose mean planning time exceeds its
multiplier times that calibration. Multipliers come from development-machine
ratios with about 1.5x headroom until #286 tightens them. The 300-second
timeout stays only as a hang guard. The benchmark keeps running on push and
pull_request events because the push run gates image publication.
This replaces the absolute 300-second acceptance protocol named in #78.
Refs #285
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Finalizing a candidate never moves or retypes a placement, so preference
results and calendar optimizations already have their final values before
it, and leave-balance optimizations do too when nothing can be earned.
Reject a candidate before finalizing when the first differing such
objective of the protected prefix is worse than the baseline. Leave-placement
objectives and earning contexts stop the walk.
The frozen-engine check now also compares cancelled asynchronous runs,
including checkpoints and retained incumbents. The loaded year drops from
48.5 s to 44.3 s; outcomes, explanations and final states are unchanged.
Refs #284
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cache an immutable occupancy per placements map and derive a candidate's
time-off period groups, holiday-week completeness and placement tie key
from its parent when one date is added or removed. The from-scratch
computation stays as the test oracle and an opt-in shadow mode. A
fast-check property test compares both after every operation.
The loaded year drops from 66.5 s to 48.5 s and the protocol from 262.0 s
to 193.7 s. Outcomes, explanations and final states stay identical.
Refs #283
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Print the report header before the measured runs and each scenario's rows
as soon as its repetitions complete, so a timed-out job still shows the
finished scenarios. The final report, scenarios, warm-ups, repetitions,
assertions, heap limit and timeout are unchanged.
Refs #281
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bundle the planning core at a871f8f (develop after PR #278) as a frozen
fixture and compare it with the current engine on 5,000 seeded random
requests. Outcomes, stable explanations, explanation errors and final-state
snapshots must be strictly deep-equal. Requests cover obligations,
preferences, IF_THEN and TIME_WINDOW rules, earned entitlements, composed
optimization rules, declared days, year boundaries and public holidays.
Refs #280
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reduce objective evaluation and calendar allocation work while preserving planner outcomes and deterministic explanations. Restore required benchmark gating and record the unchanged protocol, differential checks, and browser evidence for #78.
Run the unchanged benchmark as a separate advisory job while #78 is open.
Keep functional coverage and other checks required, and retain the 2 GB heap
and 300-second protocol limit. Record #78's obligation to restore the gate.
Refs: #75, #78
Evaluate explicit, ordered optimization configurations through one shared
planner model. Add six editable presets, durable one-time legacy migration,
and consistent completed and cancelled plan provenance.
Include functional regressions and the agreed trace-removal and benchmark
follow-up specs. Performance acceptance remains in #78 under unchanged gates.
Refs: #70, #71, #72, #73, #74, #75, #76, #77, #78
- Added informational styling to warning cards in user input component.
- Improved remaining days details and history display with new computed properties.
- Updated user input service to manage planning outcomes and traces more effectively.
- Enhanced leave planner service to classify remaining balances with detailed reasons.
- Expanded translation service to support new balance reasoning and suggestions.
- Updated translations for multiple languages to reflect new features and terminology.
- Introduced calculationDate in various service interfaces and snapshots to track the date of planning calculations.
- Added futureEntitlement and includedEntitlement fields to the translation service and respective language files for better user feedback.
- Updated leave-planner.worker to handle calculationDate and declaredDays in requests.
- Enhanced tests to ensure proper handling of calculation dates and artifact retention during planning processes.
- Improved snapshot and explanation outputs to include calculation date for clarity in planning results.
- Implemented PlanningDurationService to provide an indicative wait time before calculation based on user input and calendar settings.
- Introduced duration estimation logic that considers horizon dates, balances, and rules without triggering a calculation.
- Enhanced user input component to display estimated duration using the new service.
- Updated translation files to include new duration estimate strings in multiple languages.
- Added tests for PlanningDurationService to ensure accurate duration estimation and calibration.
- Refactored leave planner service to remove hardcoded deadlines and improve worker responsiveness.
- Refactor leave-planner.worker.ts to support cancellation of ongoing calculations.
- Introduce `calculatePlanningAsyncInternal` for asynchronous planning calculations.
- Add cancellation handling in the worker message event.
- Update planning-date.ts with new utility functions for date manipulation.
- Extend translation-service.ts and translation files (en.json, de.json, es.json, fr.json) to include new strings related to planning horizon and cancellation.
- Create documentation for the cancellation feature in planner-cancellation.md.
- Add unit tests for cancellation functionality in leave-planner-cancellation.spec.ts and leave-planner.worker.spec.ts.
#57#58