Per IMPLEMENTATION-ORDER.md 1.2: quest_instances gains a NOT NULL
window column (CHECK-constrained to the const window spellings) and
the table-level UNIQUE constraint widens to the full fan-out tuple.
- schema.py: instance table body extracted to QUEST_INSTANCES_TABLE_SQL
shared with the rebuild migration; uniqueness docstring rewritten for
the widened key.
- migrations.py: migration 5 rebuilds a pre-window quest_instances via
the canonical procedure; migrated rows are pinned to the documented
default 'morning' window (pre-window rows were whole-day obligations;
future dates are regenerated with real windows by materialization),
preserving ids so completion_events keep pointing at the same
instances; PRAGMA foreign_key_check verified inside the transaction.
- dao_instances.py: upsert takes required keyword window and is
idempotent on the widened tuple; the immutable-once-completed check
and the read-back get() are keyed on the full tuple; window spelling
validated via dao_rules._validate_window.
- tests: schema shape (window column, widened autoindex columns),
twice-daily and shared-assignee fan-out cases at both the DDL and DAO
layers (incl. idempotent re-runs), cross-child same-key allowance,
window CHECK/NOT NULL constraints, v2 seed frozen to the true
version-2 shapes and its migration assertions widened.