---
title: Move the sanctuary and poaching windows onto the constitutional Offseason
type: task
status: planned
description: >-
  The sanctuary/poaching schedule and the poach-release cap penalty anchor on
  current_season.offseason (the previous Super Bowl) instead of the constitutional championship
  resolution, which over-reaches by up to eleven months. Blocked on a per-season championship
  anchor.
base_uri: user:task/league/move-sanctuary-poaching-onto-constitutional-offseason.md
created_at: '2026-09-12T14:16:54.566Z'
entity_id: 728ab66d-cade-43ee-a9f1-51728a37181a
owner_identity_uri: █████████████████████████
priority: Medium
public_read: true
relations:
  - blocked_by [[user:task/league/move-regular-season-boundary-onto-season-row.md]]
  - relates [[████████████████████████████-██████-████████-██████████]]
  - relates [[user:guideline/nfl/league/season-member-naming.md]]
tags:
  - user:tag/league-xo-football.md
  - user:tag/software-task.md
updated_at: '2026-09-12T14:17:01.533Z'
visibility_analyzed_at: '2026-11-05T23:49:44.605Z'
---

Both `libs-shared/get-sanctuary-poaching-periods.mjs` and `libs-server/process-release.mjs` read `current_season.offseason`, which is the PREVIOUS season's Super Bowl date. The constitution (definitions, "Offseason") runs the period from the resolution of the LEAGUE CHAMPIONSHIP. This step was carved out of [[████████████████████████████-██████-████████-██████████]] when that task landed its vocabulary work, because it is the one step in that plan with an external data blocker and it must not hold the rest.

**OPERATOR RULING 2026-09-11: use the constitutional definition; the loosening is the correct posture.** Confirmed. The work proceeds on that basis; only the data anchor is missing.

## Scope, measured 2026-09-11

`current_season.offseason` has exactly three readers: the two files above and `scripts/current-season-info.mjs` (display only). The enforcement module `libs-shared/is-santuary-period.mjs` — note the misspelling in the filename — does NOT read it: its extension-deadline branch is a bare `now.isBefore(league.extension_deadline_at)` with no start anchor at all. So poaching LEGALITY does not move; what moves is the rendered schedule window and the poach-release cap penalty at `process-release.mjs:214`.

## The real defect is an eleven-month over-reach, not a six-week shift

An earlier draft said the change makes releases stricter by roughly six weeks. That is wrong and was corrected by injecting clocks. `offseason` is a FIXED constant — 2026-02-09 for the whole 2026 season — and the check runs whenever `!is_regular_season`:

- July 2026, mid-offseason: the window is `[2026-02-09, now]`, which IS the current offseason. Correct.
- January and February 2027, after the championship and before the Super Bowl: `is_regular_season` is already false (week 18 through 24) but the anchor still reads 2026-02-09, so the window covers **the entire 2026 season plus the offseason before it**. Any player poached at any point in the preceding eleven months blocks a release.

So adopting the constitutional start is predominantly a LOOSENING — it cuts that eleven-month window down to the weeks since the championship — and is mildly stricter only in the ordinary offseason, where the championship sits about five weeks before the Super Bowl.

The surrounding guard already uses the constitutional boundary: `process-release.mjs` gates the whole check on `!current_season.is_regular_season`, and `is_regular_season` ends at `final_week` (the championship). One function already gates on the championship while comparing against a Super Bowl eleven months gone. That internal contradiction is the cleanest framing for the spec.

## Why this is blocked

"The most recent championship resolution" cannot be computed from what exists today. `season-dates.mjs` holds exactly ONE season, so during the ordinary offseason the relevant championship belongs to the PREVIOUS season and its week anchor is not in the constants at all. The `seasons` table carries `championship_round` and `wildcard_round` as week NUMBERS and a `season_started_at`, but no championship resolution timestamp and no per-season week anchor. That gap is exactly what [[user:task/league/move-regular-season-boundary-onto-season-row.md]] exists to close, so this work follows it rather than inventing a parallel source.

## Plan

- [ ] **Move the sanctuary and poaching windows onto the constitutional Offseason**
  - Files: `libs-shared/get-sanctuary-poaching-periods.mjs`, `libs-server/process-release.mjs`
  - Changes: read the per-season championship anchor landed by the boundary task rather than the `offseason` date field.
  - Verify: a spec asserting the cap-penalty boundary moves to the championship, with a control at a clock between the championship and the Super Bowl where the old and new rules must DIFFER — that window is where the eleven-month over-reach lives, so a spec that does not probe it cannot see the fix. Plus a spec pinning that the schedule module and `is-santuary-period.mjs` agree, since the former's own comment claims "every boundary mirrors `is-santuary-period.mjs` exactly" and that claim is false today for this start.
  - **A league notice applies if this lands in-season**, since release eligibility changes for real managers.

## Vocabulary note

The season vocabulary consolidation has landed, so write against the current member names: `nfl_season_week`, `fantasy_season_week`, `nfl_last_kicked_off_season_year`. The raw week counter is a private field on `Season` and cannot be read. `local/no-season-member-reconstruction` forbids deriving a retrospective season from the clock — see [[user:guideline/nfl/league/season-member-naming.md]].
