# AEG-V15-034 — Catch-up policy

## Scope

- **WBS ID:** `AEG-V15-034`; **Slice:** VS-18 / Scheduler
- **Requirement / API / DB / Job / UI / Test:** `REQ-V15-SCH-02` / `V15-SCH-API` / `MIG-0020` / `J31~J40` / `Cross` / `T-V15-SCH-02`
- **Dependency / Gate:** `AEG-V15-033` (completed, commit `6a86997`) / `G3`
- **Acceptance:** `LATEST_ONLY`, `SKIP_MISSED`, and `ALL_WITH_LIMIT` bound recovery work so outage recovery does not create a job storm.

## Source / Assumption / Unknown / Decision Required

- **Source:** `contracts/schedules/model-operations.v3.json`; `DEC-071` (scheduledFor anchor); `DEC-072` (default LATEST_ONLY, no unbounded replay); `ScheduleOccurrencePlanner`; `ModelOperationsDispatcherJob`; schedule repository contract.
- **Assumption:** `ALL_WITH_LIMIT` means dispatch at most the configured `maxCatchUp` most-recent missed anchored occurrences in one dispatcher pass. `LATEST_ONLY` dispatches only the most-recent due occurrence. `SKIP_MISSED` advances without dispatching missed occurrences.
- **Unknown:** there is no approval to enable any schedule. This slice must remain test-only with scheduler defaults unchanged.
- **Decision Required:** `DEC-083` (enqueue/mark atomicity) remains unresolved. The implementation retains the existing lease/release boundary and does not claim a transactional outbox solution.

## Actual evidence

- `dotnet test tests/KArtSell.ModelOperations.UnitTests/KArtSell.ModelOperations.UnitTests.csproj -c Release --filter FullyQualifiedName~ScheduleOccurrencePlannerTests --logger "trx;LogFileName=ScheduleOccurrencePlannerTests_20260809.trx" --results-directory evidence/AEG-V15-034`
- Result: passed `4/4`; artifact: `evidence/AEG-V15-034/ScheduleOccurrencePlannerTests_20260809.trx`; SHA-256: `DC28BE4F2FCF511D5859B9FC3A0ADDF8CE3A566262C9848F05B06D825EA944AD`.
- The targeted build compiled the modified dispatcher and Dapper schedule repository. No database integration test, schedule activation, market-calendar claim, or transactional enqueue/mark claim is made.
