---
"@remnic/core": minor
---
Add the offline slice of the privacy-safe action-to-outcome trajectory evaluator (issue #2345): new `eval-trajectory`, `eval-trajectory-contracts`, and `eval-trajectory-store` modules (one subsystem split for the #1995 new-file ratchet cap, re-exported from `eval-trajectory.ts`) that join sanitized action rows to delayed outcome rows within one namespace and a half-open time window, and emit a redacted, byte-deterministic shadow artifact (digests, enums, numbers, counts only) into the existing eval store under `trajectory/<day>/<reportId>.json`.
The slice covers schema-v1 input/report contracts, deterministic join precedence (actionId > trajectoryId > memory scope > session scope), per-reason rejection counting, metric scoring (taskOutcome, contextTokenCost, trustViolation, staleMemoryHarm, weighted actionConditionedUtility with missingDimensions), a fail-closed redaction scan, a content-hash-checked reader with expiry, a pure `UnifiedMemoryPromotionReport` derivation with fixed fail-safe thresholds for #2348, and a pure `MemoryOutcomeObservation` view so counter-only outcome rows stay `missing_observation` instead of being guessed. Reads no live stores, writes no memories, changes no policy, ranking, or counters.

Skipped in this slice (deliberate, per the issue's delivery order): eval-queue wiring and live `EvalTrajectoryReader` projections land with #2348's shadow mode; `evals.ts`, `types.ts`, and `storage.ts` are untouched because they sit at their ratchet ceilings — the module is re-exported from the package root instead.
