-- v13.0 continuous model feedback loop. All schedules are inserted disabled and are evidence/proposal only. create table if not exists evaluation.prediction_freeze ( prediction_freeze_id uuid primary key, portfolio_scope text not null, market_session date not null, as_of timestamptz not null, dataset_id text not null, model_version text not null, config_version text not null, code_sha text not null, contract_version text not null, content_hash text not null unique, frozen_at timestamptz not null default now(), unique (portfolio_scope, market_session, model_version, content_hash) ); create table if not exists evaluation.evaluation_window_maturity ( maturity_id uuid primary key, decision_id uuid not null, window_sessions integer not null check (window_sessions in (1,5,20,63,126,252)), due_session date not null, maturity_revision integer not null check (maturity_revision > 0), status text not null check (status in ('PENDING','MATURED','HELD_DATA','EVALUATED','SUPERSEDED')), dataset_id text not null, supersedes_maturity_id uuid null references evaluation.evaluation_window_maturity(maturity_id), content_hash text not null unique, created_at timestamptz not null default now(), check (supersedes_maturity_id is null or supersedes_maturity_id <> maturity_id), unique (decision_id, window_sessions, dataset_id, maturity_revision) ); create table if not exists governance.model_improvement_hypothesis ( hypothesis_id uuid primary key, model_version text not null, hypothesis_version integer not null check (hypothesis_version > 0), problem_statement text not null, evidence_json jsonb not null, proposed_change text not null, expected_effect text not null, falsification_test text not null, non_goals text not null, status text not null check (status in ('DRAFT','REVIEW_REQUIRED','APPROVED_FOR_EXPERIMENT','REJECTED','SUPERSEDED','EXPIRED')), maker_id text not null, checker_id text null, supersedes_hypothesis_id uuid null references governance.model_improvement_hypothesis(hypothesis_id), expires_at timestamptz not null, content_hash text not null unique, created_at timestamptz not null default now(), decided_at timestamptz null, check (supersedes_hypothesis_id is null or supersedes_hypothesis_id <> hypothesis_id), check (status not in ('APPROVED_FOR_EXPERIMENT','REJECTED') or (checker_id is not null and checker_id <> maker_id and decided_at is not null)), unique (model_version, hypothesis_version) ); drop trigger if exists prediction_freeze_append_only on evaluation.prediction_freeze; create trigger prediction_freeze_append_only before update or delete on evaluation.prediction_freeze for each row execute function building_blocks.prevent_append_only_change(); drop trigger if exists evaluation_window_maturity_append_only on evaluation.evaluation_window_maturity; create trigger evaluation_window_maturity_append_only before update or delete on evaluation.evaluation_window_maturity for each row execute function building_blocks.prevent_append_only_change(); drop trigger if exists model_improvement_hypothesis_append_only on governance.model_improvement_hypothesis; create trigger model_improvement_hypothesis_append_only before update or delete on governance.model_improvement_hypothesis for each row execute function building_blocks.prevent_append_only_change(); insert into evaluation.model_operation_schedule (schedule_id, operation_code, operation_name, scope_key, cadence, automation_mode, queue_name, schedule_version, enabled, next_due_at, max_lag, primary_owner, secondary_owner, calendar_id, due_policy, dependency_json, catch_up_policy, max_catch_up) values ('e4100000-0000-4000-8000-000000000031','J31','PredictionFreezeRun','GLOBAL','DAILY','EVALUATION_ONLY','q-evaluation',2,false,now()+interval '1 day',interval '1 day','Quant/Data','QA/Risk','APPROVED_MARKET_CALENDAR','TRADING_SESSION','["PIT_CONTEXT_APPROVED","MODEL_CONTEXT_APPROVED"]','LATEST_ONLY',1), ('e4100000-0000-4000-8000-000000000032','J32','OutcomeMaturitySweep','GLOBAL','DAILY','EVALUATION_ONLY','q-evaluation',2,false,now()+interval '1 day',interval '1 day','Quant/Ops','Data/QA','APPROVED_MARKET_CALENDAR','TRADING_SESSION','["TOTAL_RETURN_COMPLETE","CALENDAR_APPROVED"]','BOUNDED',7), ('e4100000-0000-4000-8000-000000000033','J33','SellReentryAttributionReview','GLOBAL','WEEKLY','EVALUATION_ONLY','q-evaluation',2,false,now()+interval '7 days',interval '7 days','Quant/Risk','Advisor/QA','GLOBAL_UTC','FIXED_CADENCE','["OUTCOME_MATURED","METRIC_CONTRACT_APPROVED"]','LATEST_ONLY',1), ('e4100000-0000-4000-8000-000000000034','J34','CalibrationRegimeReview','GLOBAL','WEEKLY','EVALUATION_ONLY','q-evaluation',2,false,now()+interval '7 days',interval '7 days','Quant/Risk','Data/IndependentValidation','GLOBAL_UTC','FIXED_CADENCE','["COHORT_VERSION_APPROVED","REGIME_DEFINITION_APPROVED"]','LATEST_ONLY',1), ('e4100000-0000-4000-8000-000000000035','J35','ImprovementHypothesisBuild','GLOBAL','MONTHLY','PROPOSAL_ONLY','q-research',2,false,now()+interval '30 days',interval '30 days','Quant Lead','Risk/Architect','GLOBAL_UTC','FIXED_CADENCE','["SCORECARD_COMPLETE","ATTRIBUTION_COMPLETE","DEBT_REGISTER_CURRENT"]','LATEST_ONLY',1), ('e4100000-0000-4000-8000-000000000036','J36','ChallengerExperimentPlan','GLOBAL','MONTHLY','PROPOSAL_ONLY','q-research',2,false,now()+interval '30 days',interval '30 days','Quant Lead','IndependentValidation/QA','GLOBAL_UTC','FIXED_CADENCE','["HYPOTHESIS_APPROVED_FOR_EXPERIMENT","EXPERIMENT_REGISTRY_READY"]','LATEST_ONLY',1), ('e4100000-0000-4000-8000-000000000037','J37','IndependentValidationPack','GLOBAL','QUARTERLY','PROPOSAL_ONLY','q-control',2,false,now()+interval '90 days',interval '90 days','IndependentValidation','Risk/Compliance','GLOBAL_UTC','FIXED_CADENCE','["OOS_COMPLETE","PBO_DSR_COMPLETE","REPRODUCIBILITY_COMPLETE"]','LATEST_ONLY',1), ('e4100000-0000-4000-8000-000000000038','J38','ModelPolicyDebtReview','GLOBAL','MONTHLY','PROPOSAL_ONLY','q-control',2,false,now()+interval '30 days',interval '30 days','Risk/Architect','Quant/PM','GLOBAL_UTC','FIXED_CADENCE','["DEBT_REGISTER_CURRENT","INCIDENT_REVIEW_COMPLETE"]','LATEST_ONLY',1) on conflict (operation_code, scope_key, schedule_version) do nothing;