# VETS Coin API Guide (Live)

Purpose: living reference for partner/internal API calls.

## Versioning

Current API version: v1 (implicit, URL paths are unversioned)

Versioning policy:
- Breaking changes will be noted in the changelog and ideally rolled out behind a new path prefix (e.g., `/api/v2/...`).
- Non-breaking additions (new fields/endpoints) can ship without version changes.
- Deprecation window: at least 30 days for partner-facing breaking changes, with reminders at 7 days and 1 day prior to cutoff.

Partner migration checklist:
- Confirm new endpoint paths and auth requirements.
- Validate signing format against the new spec.
- Test in staging with a new key and idempotency headers.
- Roll out to production with monitoring and rollback plan.

## Changelog

- 2026-03-08: Expanded admin 403 digest triage and export surfaces (tasks `I-224`, `I-225`, `I-231`, `I-232`, `I-234`, `I-236`, `I-237`, `I-238`, `I-1212`, `I-1213`):
  - endpoints:
    - `GET /admin/ops/403-digest`
    - `GET /admin/ops/403-digest/export.json`
    - `GET /admin/ops/403-digest/export.csv`
    - `GET /admin/ops/403-digest/probe-trend.png`
    - `GET|POST /admin/ops/403-digest/suppressions`
    - `GET /admin/ops/403-digest/suppressions/export.json`
  - behavior:
    - 403 digest now supports probe baseline selector via `baseline_mode=rolling_24h|same_hour_yesterday|same_weekday_hour_4w`.
    - Added recurring fingerprint rollup (`path+ip+ua`) with first/last seen and streak counters.
    - Added top-new-path detection (`top_new_paths`) against prior `new_path_lookback_days` window.
    - Added paired denied-vs-probe hourly overlay (`paired_overlay`) for divergence triage.
    - Added probe-spike persistence signal (`probe_spike_signal`) with configurable `spike_consecutive_hours`.
    - Added suppression rules + allowlist support from `ADMIN_403_DIGEST_SUPPRESSIONS_FILE` with explicit rule expiry tracking and suppressed-hit summaries.
    - Added origin tagging metadata (`probe_origin_tags`) and per-row `origin_tag` / `origin_confidence`.
- 2026-02-27: Added compact tuple-validity/flag-key-count helpers + direct CSV copy alias parity (tasks `I-1132`, `I-1133`, `I-1134`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_tuple_is_valid` (bool contract check; `tuple_len == 3`)
      - `windows_meta_order_bucket_flags_keys_count` (expected `4`)
  - UI:
    - readiness quick-links row now includes `Copy CSV URL (Direct)` alias for direct-link wording parity.
  - payload additions:
    - `windows_meta_order_bucket_tuple_is_valid` (compact mode)
    - `windows_meta_order_bucket_flags_keys_count` (compact mode)
  - tests:
    - expanded authenticated coverage for direct CSV copy alias and new tuple/flag-count metadata across requested/default/custom ordering.
- 2026-02-27: Added compact tuple-length/flag-key-order helpers + baseline direct JSON copy alias parity (tasks `I-1129`, `I-1130`, `I-1131`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_tuple_len` (tuple length contract helper, expected `3`)
      - `windows_meta_order_bucket_flags_keys` (ordered flag keys: `["is_default","is_requested","is_asc","is_custom"]`)
  - UI:
    - readiness quick-links row now includes `Copy JSON URL (Direct)` alias for baseline JSON wording parity.
  - payload additions:
    - `windows_meta_order_bucket_tuple_len` (compact mode)
    - `windows_meta_order_bucket_flags_keys` (compact mode)
  - tests:
    - expanded authenticated coverage for baseline direct JSON copy alias and new tuple/flags metadata across requested/default/custom ordering.
- 2026-02-27: Added compact hex/csv helper fields + compact direct copy alias parity (tasks `I-1126`, `I-1127`, `I-1128`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_flags_code_hex` (hex string form of `windows_meta_order_bucket_flags_code`, e.g. `0x06`)
      - `windows_meta_order_bucket_tuple_csv` (`bucket_code,bucket_short,bucket_label`)
  - UI:
    - readiness quick-links row now includes `Copy JSON Compact URL (Direct)` alias pointing at compact direct URL (`compact=1`).
  - payload additions:
    - `windows_meta_order_bucket_flags_code_hex` (compact mode)
    - `windows_meta_order_bucket_tuple_csv` (compact mode)
  - tests:
    - expanded authenticated coverage for compact direct copy alias and new hex/csv helper fields across requested/default/custom ordering.
- 2026-02-27: Added compact flags bitmask/tuple helpers + compact+meta direct copy alias parity (tasks `I-1123`, `I-1124`, `I-1125`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_flags_code` (bitmask: `1=default,2=requested,4=asc,8=custom`)
      - `windows_meta_order_bucket_tuple` (`[bucket_code,bucket_short,bucket_label]`)
  - UI:
    - readiness quick-links row now includes `Copy JSON Compact+Meta URL (Direct)` alias pointing at explicit `include_windows_meta=1`.
  - payload additions:
    - `windows_meta_order_bucket_flags_code` (compact mode)
    - `windows_meta_order_bucket_tuple` (compact mode)
  - tests:
    - expanded authenticated coverage for compact+meta direct copy alias and bitmask/tuple semantics across requested/default/custom ordering.
- 2026-02-27: Added compact bucket flags/code helpers + normalized compact copy alias parity (tasks `I-1120`, `I-1121`, `I-1122`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_flags` (`is_default`,`is_requested`,`is_asc`,`is_custom`)
      - `windows_meta_order_bucket_code` (`0|1|2` as string)
  - UI:
    - readiness quick-links row now includes `Copy JSON Compact URL (Normalized)` alias pointing to explicit `include_windows_meta=0`.
  - payload additions:
    - `windows_meta_order_bucket_flags` (compact mode)
    - `windows_meta_order_bucket_code` (compact mode)
  - tests:
    - expanded authenticated coverage for normalized compact copy alias and bucket flags/code semantics across requested/default/custom ordering.
- 2026-02-27: Added compact short/default bucket helpers + compact+meta normalized direct-link alias (tasks `I-1117`, `I-1118`, `I-1119`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_short` (`def|req_asc|req_custom`)
      - `windows_meta_order_bucket_is_default`
  - UI:
    - readiness quick-links row now includes direct-link alias `Export JSON Compact+Meta (Normalized)` using explicit `include_windows_meta=1`.
  - payload additions:
    - `windows_meta_order_bucket_short` (compact mode)
    - `windows_meta_order_bucket_is_default` (compact mode)
  - tests:
    - expanded authenticated coverage for compact+meta normalized direct-link alias and short/default bucket semantics across requested/default/custom ordering.
- 2026-02-27: Added compact bucket-label/requested-split helpers + no-meta direct-link alias (tasks `I-1114`, `I-1115`, `I-1116`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket_label` (`Default Asc|Requested Asc|Requested Custom`)
      - `windows_meta_order_bucket_is_requested`
  - UI:
    - readiness quick-links row now includes direct-link alias `Export JSON Compact (No Meta)` using explicit `include_windows_meta=0`.
  - payload additions:
    - `windows_meta_order_bucket_label` (compact mode)
    - `windows_meta_order_bucket_is_requested` (compact mode)
  - tests:
    - expanded authenticated coverage for no-meta direct-link alias and bucket label/requested split semantics across requested/default/custom ordering.
- 2026-02-27: Added compact non-custom/rank helpers + explicit compact+meta normalization copy label (tasks `I-1111`, `I-1112`, `I-1113`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_is_requested_non_custom`
      - `windows_meta_order_bucket_rank` (`0|1|2`)
  - UI:
    - readiness quick-links row now includes `Copy JSON Compact+Meta URL (Normalized)` using explicit `include_windows_meta=1`.
  - payload additions:
    - `windows_meta_order_is_requested_non_custom` (compact mode)
    - `windows_meta_order_bucket_rank` (compact mode)
  - tests:
    - expanded authenticated coverage for compact+meta normalization copy label and requested/default/custom rank semantics.
- 2026-02-27: Added compact order bucket/requested-asc helpers + explicit no-meta compact copy control (tasks `I-1108`, `I-1109`, `I-1110`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_bucket` (`default_asc|requested_asc|requested_custom`)
      - `windows_meta_order_is_requested_asc`
  - UI:
    - readiness quick-links row now includes `Copy JSON Compact URL (No Meta)` using explicit `include_windows_meta=0` for normalized handoff links.
  - payload additions:
    - `windows_meta_order_bucket` (compact mode)
    - `windows_meta_order_is_requested_asc` (compact mode)
  - tests:
    - expanded authenticated coverage for compact no-meta quick-links copy control and requested/default/custom bucket semantics.
- 2026-02-27: Added compact requested/custom/default booleans + digest copy parity (tasks `I-1105`, `I-1106`, `I-1107`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_is_requested_custom`
      - `windows_meta_order_is_default`
  - UI:
    - readiness quick-links row now includes `Copy 403 Digest URL` beside `Open 403 Digest`.
  - payload additions:
    - `windows_meta_order_is_requested_custom` (compact mode)
    - `windows_meta_order_is_default` (compact mode)
  - tests:
    - expanded authenticated coverage for digest quick-links copy parity and requested/default/custom compact-order boolean semantics.
- 2026-02-27: Added quick-links detail CSV copy parity + compact requested/asc booleans (tasks `I-1102`, `I-1103`, `I-1104`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes:
      - `windows_meta_order_is_requested_windows`
      - `windows_meta_order_is_asc`
  - UI:
    - readiness quick-links row now includes `Copy CSV URL` beside `Export CSV (7/14/30)`.
  - payload additions:
    - `windows_meta_order_is_requested_windows` (compact mode)
    - `windows_meta_order_is_asc` (compact mode)
  - tests:
    - expanded authenticated coverage for quick-links-row `Copy CSV URL` parity and requested/custom/default compact-order boolean semantics.
- 2026-02-27: Added incidents wording alias parity + quick-links summary+points copy parity + custom-order bool (tasks `I-1099`, `I-1100`, `I-1101`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes `windows_meta_order_is_custom` as the inverse companion to `windows_meta_order_is_default_asc`.
  - UI:
    - incidents timeline now includes `Copy Incident URL` alias (detail JSON endpoint with non-JSON wording).
    - readiness quick-links row now includes `Copy CSV Summary+Points URL`.
  - payload additions:
    - `windows_meta_order_is_custom` (compact mode)
  - tests:
    - expanded authenticated coverage for incidents alias wording parity, quick-links-row summary+points CSV copy parity, and custom/default ordering booleans.
- 2026-02-27: Added incident/detail alias parity + quick-links summary copy parity + default-order bool (tasks `I-1095`, `I-1096`, `I-1097`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes `windows_meta_order_is_default_asc` (boolean single-check signal for default ascending order behavior).
  - UI:
    - incidents timeline now includes `Copy Incident Detail URL`.
    - readiness quick-links row now includes `Copy CSV Summary URL` parity control.
  - payload additions:
    - `windows_meta_order_is_default_asc` (compact mode)
  - tests:
    - expanded authenticated coverage for incident detail alias control, quick-links-row summary CSV copy parity, and default-vs-custom ordering boolean semantics.
- 2026-02-27: Added detail-copy label parity + compact order-key traceability (tasks `I-1092`, `I-1093`, `I-1094`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact payload now includes `windows_meta_order_keys` (ordered key snapshot used for order evaluation/debug traceability).
  - UI:
    - incidents timeline now includes `Copy Detail JSON URL` alias beside existing detail copy controls.
    - readiness quick-links row now includes `Copy JSON URL` for baseline JSON link/copy parity.
  - payload additions:
    - `windows_meta_order_keys` (compact mode)
  - tests:
    - expanded authenticated coverage for detail-copy alias visibility, quick-links-row baseline JSON copy parity, and order-key metadata in default + custom window scenarios.
- 2026-02-27: Added incident/detail copy wording parity + compact order-source metadata (tasks `I-1089`, `I-1090`, `I-1091`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - compact 403-noise payload now includes `windows_meta_order_source` (`default|requested_windows`) to indicate whether window ordering came from explicit query input.
  - UI:
    - incidents timeline now includes `Copy Incident JSON URL`.
    - readiness quick-links row now includes `Copy JSON Compact URL` alongside existing compact+meta copy control.
  - payload additions:
    - `windows_meta_order_source` (compact mode)
  - tests:
    - expanded authenticated coverage for compact-order source semantics (`default` and `requested_windows`) and new copy controls.
- 2026-02-27: Added quick-links copy parity + compact order metadata semantics (tasks `I-1086`, `I-1087`, `I-1088`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1&include_windows_meta=1`
  - behavior:
    - compact payload now includes `windows_meta_order` (`asc|custom`) so BI jobs can validate window ordering semantics.
  - UI:
    - incidents timeline now includes `Copy Postmortem URL`.
    - readiness quick-links row now includes `Copy JSON Compact+Meta URL` for direct link/copy parity.
  - payload additions:
    - `windows_meta_order` (compact mode)
  - tests:
    - expanded authenticated coverage for quick-links-row compact+meta copy parity, postmortem URL copy control, and custom window-order metadata.
- 2026-02-27: Added copy/export parity controls + compact map-count metadata (tasks `I-1083`, `I-1084`, `I-1085`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1&include_windows_meta=1`
  - behavior:
    - compact metadata payload now includes `windows_meta_map_count` for strict map/list/key parity checks.
  - UI:
    - incidents timeline now includes `Copy Draft JSON URL`.
    - readiness `Admin 403 Noise Trend` copy controls now include `Copy CSV URL` (full detail export URL).
  - payload additions:
    - `windows_meta_map_count` (compact mode with `include_windows_meta=1`)
  - tests:
    - expanded authenticated coverage for `Copy Draft JSON URL`, `Copy CSV URL`, and `windows_meta_map_count`.
- 2026-02-27: Added export/copy parity controls + compact keys-count metadata (tasks `I-1080`, `I-1081`, `I-1082`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1&include_windows_meta=1`
  - behavior:
    - compact metadata payload now includes `windows_meta_keys_count` for strict schema validation checks.
  - UI:
    - incidents timeline now includes `Copy Draft TXT URL`.
    - readiness `Admin 403 Noise Trend` copy controls now include `Copy JSON URL` (baseline full export URL).
  - payload additions:
    - `windows_meta_keys_count` (compact mode with `include_windows_meta=1`)
  - tests:
    - expanded authenticated coverage for `Copy JSON URL`, `Copy Draft TXT URL`, and `windows_meta_keys_count`.
- 2026-02-27: Added compact-link export discoverability + incident minimal URL copy controls (tasks `I-1077`, `I-1078`, `I-1079`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1&include_windows_meta=1`
  - behavior:
    - compact metadata payload now includes `windows_meta_keys` (ordered window key list) in addition to `windows_meta_map`.
  - UI:
    - incidents timeline now includes:
      - `Copy Draft MD Minimal URL`
      - `Copy Draft TXT Minimal URL`
    - readiness `Admin 403 Noise Trend` card now includes direct compact links:
      - `Export JSON Compact (7/14/30)`
      - `Export JSON Compact+Meta (7/14/30)`
  - payload additions:
    - `windows_meta_keys` (compact mode with `include_windows_meta=1`)
  - tests:
    - expanded authenticated coverage for readiness compact links, incident minimal copy controls, and `windows_meta_keys`.
- 2026-02-27: Added readiness/incident handoff copy-link enhancements + compact metadata map (tasks `I-1073`, `I-1074`, `I-1075`, `I-1076`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1&include_windows_meta=1`
  - behavior:
    - compact 403-noise metadata payload now includes `windows_meta_map` keyed by window (`"7"`, `"14"`, `"30"`) for O(1) downstream lookups.
  - UI:
    - readiness `Admin 403 Noise Trend` card now includes one-click copy controls for:
      - `Copy CSV Summary URL`
      - `Copy CSV Summary+Points URL`
      - `Copy JSON Compact URL`
      - `Copy JSON Compact+Meta URL`
    - incidents timeline now includes direct minimal links:
      - `Draft MD Minimal`
      - `Draft TXT Minimal`
  - payload additions:
    - `windows_meta_map` (compact mode with `include_windows_meta=1`)
  - tests:
    - expanded authenticated coverage for readiness copy-control rendering, incidents minimal direct links, and `windows_meta_map`.
- 2026-02-27: Added minimal draft quick actions + compact export windows metadata (tasks `I-1069`, `I-1071`, `I-1072`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1&include_windows_meta=1`
  - behavior:
    - incidents table now includes:
      - `Create Draft Minimal` (markdown minimal template)
      - `Create Draft TXT Minimal` (text minimal template)
    - compact 403-noise export can include window-level metadata records (`windows_meta`) without returning `trends`.
  - payload additions:
    - `windows_meta` (compact mode, optional)
    - `windows_meta_count` (compact mode, optional)
  - tests:
    - added authenticated coverage for compact metadata option and minimal quick-action presence.
- 2026-02-27: Added incident draft template variants + compact 403-noise JSON mode + readiness quick export links (tasks `I-1067`, `I-1068`, `I-1070`):
  - endpoints:
    - `GET /admin/ops/incidents/draft.md?template=v1|minimal`
    - `GET /admin/ops/incidents/draft.txt?template=v1|minimal`
    - `GET /admin/ops/readiness/403-noise/export.json?compact=1`
  - behavior:
    - incident markdown/text drafts now support `template=minimal` for short responder ticket bodies.
    - compact 403-noise JSON mode omits detailed `trends` points and returns window summaries via `summary_by_window`.
  - UI:
    - readiness card now exposes direct links for:
      - `Export CSV Summary (7/14/30)`
      - `Export CSV Summary+Points (7/14/30)`
  - tests:
    - added authenticated coverage for minimal draft templates and compact JSON export behavior.
- 2026-02-27: Added hybrid 403-noise CSV appendix mode + JSON window summary map + incidents `Create Draft TXT` action (tasks `I-1064`, `I-1065`, `I-1066`):
  - endpoints:
    - `GET /admin/ops/readiness/403-noise/export.csv?mode=summary&include_points=1`
  - behavior:
    - summary CSV mode now supports `include_points=1` to append compact per-day point rows after each summary row.
    - 403-noise JSON export now includes top-level `summary_by_window` map keyed by window days (`"7"`, `"14"`, `"30"`).
  - payload additions:
    - `summary_by_window` (JSON export)
  - UI:
    - incidents timeline now includes `Create Draft TXT` quick action (copies draft JSON URL and opens text draft).
  - tests:
    - added authenticated coverage for JSON `summary_by_window` and CSV `mode=summary&include_points=1`.
- 2026-02-27: Added draft text companion + readiness CSV summary mode + suppression-state enum (tasks `I-1060`, `I-1061`, `I-1062`, `I-1063`):
  - endpoints:
    - `GET /admin/ops/incidents/draft.txt`
    - `GET /admin/ops/readiness/403-noise/export.csv?mode=summary`
  - behavior:
    - `draft.txt` is generated from the same incident draft payload as `draft.json` and `draft.md`.
    - readiness CSV export now supports `mode=summary` for one-row-per-window executive reporting.
    - 403-noise anomaly payload now includes `suppression_state` enum (`none|insufficient_baseline`) for downstream BI filtering.
  - payload additions:
    - `anomaly.suppression_state`
  - UI:
    - incidents timeline now includes `Copy Draft MD URL` one-click action beside `Create Draft`.
  - tests:
    - added authenticated coverage for `draft.txt` and `mode=summary` CSV export.
    - added auth-gate smoke coverage for `/admin/ops/incidents/draft.txt`.
- 2026-02-27: Added incident markdown draft export + readiness 403-noise CSV companion and suppression annotation (tasks `I-1056`, `I-1057`, `I-1058`, `I-1059`):
  - endpoints:
    - `GET /admin/ops/incidents/draft.md`
    - `GET /admin/ops/readiness/403-noise/export.csv`
  - behavior:
    - `draft.md` is generated from the same payload as `draft.json`, so human and automation outputs stay aligned.
    - readiness 403-noise exports now include explicit suppression context when anomaly detection is muted due to insufficient baseline points.
  - payload additions:
    - `anomaly.suppressed_due_to_insufficient_baseline`
    - `anomaly.suppression_points_missing`
    - `anomaly.suppression_hint`
  - UI:
    - incidents timeline now includes `Create Draft` quick action (copies draft JSON URL and opens markdown draft).
    - readiness card now includes `Export CSV (7/14/30)` and suppression hint messaging.
  - tests:
    - added authenticated coverage for `draft.md` and `403-noise/export.csv`.
    - added auth-gate smoke coverage for both new endpoints.
- 2026-02-27: Added readiness 403-noise anomaly flag logic (task `I-1052`):
  - behavior:
    - `_collect_admin_403_noise_trend(...)` now emits anomaly metadata comparing latest day noise ratio vs baseline median.
    - anomaly triggers when delta exceeds configurable threshold.
  - payload additions:
    - `anomaly.is_anomalous`
    - `anomaly.reason` (`latest_vs_baseline_median_delta|normal|insufficient_baseline`)
    - `anomaly.delta_threshold_pct`
    - `anomaly.baseline_days`
    - `anomaly.min_points`
    - `anomaly.baseline_points`
    - `anomaly.baseline_median_noise_ratio_pct`
    - `anomaly.delta_vs_baseline_pct`
  - config:
    - `READINESS_ADMIN_403_NOISE_ANOMALY_DELTA_PCT` (default `20`)
    - `READINESS_ADMIN_403_NOISE_ANOMALY_BASELINE_DAYS` (default `7`)
    - `READINESS_ADMIN_403_NOISE_ANOMALY_MIN_POINTS` (default `3`)
  - UI:
    - readiness `Admin 403 Noise Trend` card now shows `Anomaly flag` status + delta/threshold context.
  - tests:
    - added helper anomaly-spike coverage and readiness card assertion.
- 2026-02-27: Added readiness 403-noise trend export endpoint (task `I-1051`):
  - endpoint:
    - `GET /admin/ops/readiness/403-noise/export.json`
  - behavior:
    - exports admin 403 denied/probe trend payloads for dashboard windows (`7`, `14`, `30` days by default).
    - supports `days=<7|14|30>` for single-window export or `windows=7,14,30` for multi-window export.
    - each trend row includes denied/probe totals, overall noise ratio, sparkline, and daily points.
  - UI:
    - readiness `Admin 403 Noise Trend` card now includes `Export JSON (7/14/30)` shortcut.
  - tests:
    - added authenticated export payload coverage.
    - added auth-gate smoke coverage for `/admin/ops/readiness/403-noise/export.json`.
- 2026-02-27: Added automatic incident draft generator endpoint (task `I-933`):
  - endpoint:
    - `GET /admin/ops/incidents/draft.json`
  - behavior:
    - composes a structured incident ticket draft for the selected timeline row (`index`) using:
      - incident window/detail context,
      - preflight guard delta summary (`day_offset` configurable),
      - latest runbook-check status + non-ok checks,
      - top recent error signatures from `event_logs`.
    - returns deterministic `schema_version` (`ops_incident_draft.v1`) with `signals`, `evidence_links`, and `recommended_actions` for automation and manual triage.
  - query controls:
    - incident selection: `hours`, `limit`, `source`, `severity`, `since`, `until`, `index`, `context`
    - signal controls: `preflight_day_offset`, `top_errors_hours`, `top_errors_limit`, `top_errors_top_n`
  - UI:
    - incidents timeline now includes `Draft JSON` quick action per row.
  - tests:
    - added authenticated draft payload coverage.
    - added auth-gate smoke coverage for `/admin/ops/incidents/draft.json`.
- 2026-02-27: Completed preflight guard wave `I-1046`..`I-1050` plus anomaly handoff export `I-1053`:
  - endpoint:
    - `GET /admin/ops/preflight-guards/anomalies.csv`
  - behavior:
    - exports only currently flagged anomaly rows from the 7-day baseline detector (same filters as anomalies JSON).
    - includes anomaly/baseline metadata + per-section changed-field counts for ticket handoff.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonnegative` (bool; numeric parse only).
  - readiness:
    - added helper text for:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonpositive` numeric-only emission context.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonnegative` numeric-only emission + semantics (`true` when sign bucket is `zero|positive`).
    - added preflight guard quick links for `Anomalies JSON` and `Anomalies CSV`.
  - tests:
    - expanded admin delta-summary parity coverage:
      - nonnegative parity (`254=false`, `255=true`, `256=true`) and non-numeric suppression.
    - added authenticated coverage for `/admin/ops/preflight-guards/anomalies.csv`.
    - added auth-gate smoke coverage for anomalies CSV endpoint.
    - added digest stability coverage for explicit-field regressed links when preflight context includes `...sign_bucket_is_nonnegative`.
- 2026-02-24: Added preflight-guard anomalies endpoint with 7-day baseline spike detection (task `I-931`):
  - endpoint:
    - `GET /admin/ops/preflight-guards/anomalies.json`
  - behavior:
    - compares each day’s preflight-guard drift against recent baseline change counts.
    - flags unusual rows using configurable z-score / flat-baseline rules.
    - supports focused anomaly views via `section=`, `fields=`, and `fields_preset=...`.
  - query controls:
    - `days` (default `30`), `baseline_days` (default `7`), `min_baseline_points` (default `3`), `zscore_threshold` (default `2.0`), `min_change_count` (default `2`).
  - tests:
    - added authenticated endpoint coverage for anomaly detection and preset-filter behavior.
    - added auth-gate smoke coverage for anomalies endpoint.
- 2026-02-24: Added readiness `Admin 403 Noise Trend` card with 7-day denied/probe telemetry (task `I-932`):
  - readiness:
    - `/admin/ops/readiness` now shows a dedicated `Admin 403 Noise Trend` card with:
      - 7-day denied vs probe totals.
      - window noise ratio (`probe / (probe + denied)`).
      - 7-day ASCII sparkline for noise ratio trend.
      - latest-day denied/probe snapshot + direct link to `/admin/ops/403-digest`.
  - backend:
    - added daily trend aggregation helper for `admin_403_denied` + `admin_403_probe` and ratio sparkline rendering.
  - tests:
    - added helper coverage for daily ratio math and trend shaping.
    - expanded readiness page assertions for new card content.
- 2026-02-24: Added sign-bucket-is-nonzero emission helper + sign-bucket-is-nonpositive metadata (waves `I-1041`..`I-1045`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonzero` appears only when `include_fields_max` parses as numeric and sign-bucket metadata is available.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonpositive=true` only when sign bucket is `negative` or `zero`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonpositive` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for sign-bucket-is-nonpositive parity (`254=true`, `255=true`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes sign-bucket-is-nonpositive metadata.
- 2026-02-24: Added sign-bucket-is-zero emission-context helper + sign-bucket-is-nonzero metadata (waves `I-1036`..`I-1040`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_zero` appears only when `include_fields_max` parses as numeric and sign-bucket metadata is available.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonzero=true` only when sign bucket is `negative` or `positive`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_nonzero` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for sign-bucket-is-nonzero parity (`254=true`, `255=false`, `256=true`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes sign-bucket-is-nonzero metadata.
- 2026-02-24: Added sign-bucket-is-zero emission helper + sign-bucket-is-zero metadata (waves `I-1031`..`I-1035`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_matches_index` appears only when `include_fields_max` parses as numeric and sign-bucket metadata is available.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_zero=true` only when sign bucket is `zero`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_is_zero` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for sign-bucket-is-zero parity (`254=false`, `255=true`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes sign-bucket-is-zero metadata.
- 2026-02-24: Added sign-bucket-sign emission helper + sign-bucket/index parity metadata (waves `I-1021`..`I-1030`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_matches_sign=true` when sign bucket equals sign metadata.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_matches_index=true` when sign bucket aligns with side index mapping (`-1=negative`, `0=zero`, `1=positive`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_matches_sign` (bool; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket_matches_index` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for sign-bucket/sign parity and sign-bucket/index parity (`254/255/256=true`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes sign-bucket/sign parity and sign-bucket/index parity metadata.
- 2026-02-24: Added side-index-sign-is-nonnegative emission helper + side-index-sign-bucket alias metadata (waves `I-1016`..`I-1020`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonnegative` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket` mirrors sign metadata as canonical `negative|zero|positive` enum alias.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_bucket` (string; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign-bucket parity (`254=negative`, `255=zero`, `256=positive`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign-bucket metadata.
- 2026-02-24: Added side-index-sign-is-nonpositive emission helper + side-index-sign-is-nonnegative metadata (waves `I-1011`..`I-1015`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonpositive` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonnegative=true` when side-index sign is `zero` or `positive`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonnegative` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign-is-nonnegative parity (`254=false`, `255=true`, `256=true`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign-is-nonnegative metadata.
- 2026-02-24: Added side-index-sign-is-positive emission helper + side-index-sign-is-nonzero/nonpositive metadata (waves `I-1001`..`I-1010`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_positive` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonzero=true` only when side-index sign is not `zero`.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonpositive=true` when side-index sign is `negative` or `zero`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonzero` (bool; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_nonpositive` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign-is-nonzero parity (`254=true`, `255=false`, `256=true`) and side-index-sign-is-nonpositive parity (`254=true`, `255=true`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign-is-nonzero and side-index-sign-is-nonpositive metadata.
- 2026-02-24: Added side-index-sign-is-negative emission helper + side-index-sign-is-positive metadata (waves `I-996`..`I-1000`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_negative` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_positive=true` only when side-index sign equals `positive`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_positive` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign-is-positive parity (`254=false`, `255=false`, `256=true`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign-is-positive metadata.
- 2026-02-24: Added side-index-sign/index emission helper + side-index-sign-is-negative metadata (waves `I-991`..`I-995`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_matches_index` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_negative=true` only when side-index sign equals `negative`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_negative` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign-is-negative parity (`254=true`, `255=false`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign-is-negative metadata.
- 2026-02-24: Added side-index-sign-zero emission helper + side-index-sign/index parity metadata (waves `I-986`..`I-990`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_zero` appears only when `include_fields_max` parses as numeric and side-index-sign metadata is available.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_matches_index=true` means side-index sign aligns with side-index mapping (`-1=negative`, `0=zero`, `1=positive`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_matches_index` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign/index parity (`254/255/256=true`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign/index parity metadata.
- 2026-02-23: Added side-label-midpoint emission helper + side-index-sign metadata + side-index-sign-is-zero metadata (waves `I-976`..`I-985`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_label_is_midpoint` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign` maps side index to `negative|zero|positive` for `-1|0|1`.
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_zero=true` only when side-index sign equals `zero`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_sign` (string; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_index_sign_is_zero` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-sign parity (`254=negative`, `255=zero`, `256=positive`) and side-index-sign-is-zero parity (`254=false`, `255=true`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-sign and side-index-sign-is-zero metadata.
- 2026-02-23: Added side-index-midpoint emission helper + side-label-side parity metadata + side-label-midpoint metadata (waves `I-966`..`I-975`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index_is_midpoint` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_label_matches_side=true` means side label aligns with side token mapping (`below=min`, `exact=midpoint`, `above=max`).
      - `include_fields_max_requested_numeric_midpoint_side_label_is_midpoint=true` only when side label equals `exact`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_label_matches_side` (bool; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_label_is_midpoint` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-label-side parity (`254/255/256=true`) and side-label-is-midpoint parity (`254=false`, `255=true`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-label-side parity and side-label-is-midpoint metadata.
- 2026-02-23: Added side-label-index emission helper + side-index-side parity metadata + side-index-midpoint metadata (waves `I-956`..`I-965`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_label_matches_index` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_index_matches_side=true` means side index aligns with side token mapping (`-1=min`, `0=midpoint`, `1=max`).
      - `include_fields_max_requested_numeric_midpoint_side_index_is_midpoint=true` only when side index equals `0`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_index_matches_side` (bool; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_index_is_midpoint` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for side-index-side parity (`254/255/256=true`) and side-index-is-midpoint parity (`254=false`, `255=true`, `256=false`) with non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-index-side parity and side-index-is-midpoint metadata.
- 2026-02-23: Added midpoint-side-label emission helper + side-label-is-exact metadata + side-label-index parity metadata (waves `I-946`..`I-955`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_label` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_label_is_exact` appears only when `include_fields_max` parses as numeric and is true only for `side_label=exact`.
      - `include_fields_max_requested_numeric_midpoint_side_label_matches_index=true` means side label aligns with side index mapping (`-1=below`, `0=exact`, `1=above`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_label_is_exact` (bool; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_label_matches_index` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-side-label-is-exact parity (`254=false`, `255=true`, `256=false`) plus side-label-index-parity checks (`254/255/256=true`) and non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes side-label-is-exact and side-label-index-parity metadata.
- 2026-02-23: Added midpoint-side-is-midpoint emission helper + midpoint-side-label parity coverage + midpoint-side-label digest link guard (wave `I-941`,`I-942`,`I-943`,`I-944`,`I-945`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_is_midpoint` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_label` maps side index `-1/0/1` to `below|exact|above`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_label` (`below|exact|above`; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-side-label parity (`254=below`, `255=exact`, `256=above`) and non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-side-label metadata.
- 2026-02-23: Added midpoint-side-index emission helper + midpoint-side-is-midpoint metadata + midpoint-side-is-midpoint digest link guard (wave `I-926`,`I-927`,`I-928`,`I-929`,`I-930`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_side_index` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side_is_midpoint=true` only at exact midpoint.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side_is_midpoint` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-side-is-midpoint parity (`254=false`, `255=true`, `256=false`) and non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-side-is-midpoint metadata.
- 2026-02-23: Added midpoint-delta-abs emission helper + midpoint-side metadata + midpoint-side-index metadata (waves `I-916`..`I-925`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_delta_abs` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_side` / `_midpoint_side_index` semantics for below/equal/above midpoint triage.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_side` (`min|midpoint|max`; numeric parse only).
      - `include_fields_max_requested_numeric_midpoint_side_index` (`-1|0|1`; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-side and midpoint-side-index parity (`254`, `255`, `256`) and non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-side and midpoint-side-index metadata.
- 2026-02-23: Added midpoint-delta emission helper + midpoint-delta absolute metadata + midpoint-delta-abs digest link guard (wave `I-911`,`I-912`,`I-913`,`I-914`,`I-915`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_delta_signed` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_delta_abs=0` means requested numeric max is exactly at midpoint.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_delta_abs` (absolute value of midpoint signed delta; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-delta absolute parity (`254=1`, `255=0`, `256=1`) and non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-delta absolute metadata.
- 2026-02-23: Added midpoint-reference emission helper + midpoint-delta signed metadata + midpoint-delta digest link guard (wave `I-906`,`I-907`,`I-908`,`I-909`,`I-910`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_reference` appears only when `include_fields_max` parses as numeric.
      - `include_fields_max_requested_numeric_midpoint_delta_signed < 0` trends toward min, `0` is midpoint, and `> 0` trends toward max.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_delta_signed` (`requested_numeric - midpoint_reference`; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-delta signed parity (`254=-1`, `255=0`, `256=+1`) and non-numeric suppression.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-delta metadata.
- 2026-02-23: Added midpoint-reference helpers + midpoint-reference metadata + midpoint-reference digest link guard (wave `I-901`,`I-902`,`I-903`,`I-904`,`I-905`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_midpoint_tie=true` implies `include_fields_max_requested_numeric_nearest_boundary=tie`.
      - `include_fields_max_requested_numeric_midpoint_reference` is derived from current min/max clamp bounds (`10` and `500`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_reference` (int; numeric parse only, current midpoint `255`).
  - tests:
    - expanded admin coverage for midpoint-reference parity, including `254/255/256` nearest-boundary and tie behavior.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-reference metadata.
- 2026-02-23: Added nearest-tie helper notes + midpoint-tie metadata + midpoint-context digest link guard (wave `I-896`,`I-897`,`I-898`,`I-899`,`I-900`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_nearest_boundary=tie` indicates equal distance to min and max boundaries.
      - midpoint tie currently occurs at `include_fields_max=255` for min/max bounds `10` and `500`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_midpoint_tie` (bool; numeric parse only).
  - tests:
    - expanded admin coverage for midpoint-tie parity across representative values (including `255=true` and non-tie values).
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes midpoint-tie metadata.
- 2026-02-23: Added absolute-distance zero helper notes + nearest-boundary metadata + nearest-context digest link guard (wave `I-891`,`I-892`,`I-893`,`I-894`,`I-895`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_distance_abs_to_min=0` means requested max exactly equals min boundary (`10`).
      - `include_fields_max_requested_numeric_distance_abs_to_max=0` means requested max exactly equals max boundary (`500`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_nearest_boundary` (`min|max|tie`; numeric parse only).
  - tests:
    - expanded admin coverage for nearest-boundary parity across representative values (including midpoint `255 -> tie`).
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes nearest-boundary metadata.
- 2026-02-23: Added in-range boundary helper + absolute-distance metadata + distance-metadata digest link guard (wave `I-886`,`I-887`,`I-888`,`I-889`,`I-890`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_distance_direction=in_range` includes exact boundary values (`10`,`500`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_distance_abs_to_min` (absolute distance to min bound `10`; numeric parse only).
      - `include_fields_max_requested_numeric_distance_abs_to_max` (absolute distance to max bound `500`; numeric parse only).
  - tests:
    - expanded admin coverage for absolute-distance parity across boundary, in-range, and off-range numeric requests.
    - added digest coverage ensuring explicit-field regressed links remain stable when preflight context includes distance-direction + absolute-distance metadata.
- 2026-02-23: Added distance-sign helpers + numeric distance-direction metadata + explicit-max digest link stability guard (wave `I-881`,`I-882`,`I-883`,`I-884`,`I-885`):
  - readiness:
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_distance_to_min < 0` means requested numeric max is below min clamp (`10`).
      - `include_fields_max_requested_numeric_distance_to_max < 0` means requested numeric max is above max clamp (`500`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_distance_direction` (`below_min|in_range|above_max`; numeric parse only).
  - tests:
    - expanded admin coverage for distance-direction parity across boundary, in-range, and off-range numeric requests.
    - added digest coverage ensuring explicit-field regressed summary links stay stable when preflight context carries non-default include-fields max metadata.
- 2026-02-23: Added ultra forensic combo preset + boundary-distance metadata + boundary-none helper semantics (wave `I-876`,`I-877`,`I-878`,`I-879`,`I-880`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 65536B+500 URL`
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_at_boundary=none` means numeric requested max was not exactly `10` or `500`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_distance_to_min` (requested numeric minus `10`; numeric parse only).
      - `include_fields_max_requested_numeric_distance_to_max` (`500` minus requested numeric; numeric parse only).
  - tests:
    - added admin coverage for distance-to-boundary parity across boundary, in-range, and off-range numeric requests.
- 2026-02-23: Added max forensic combo + boundary-state metadata + responder sparse-link guard (wave `I-871`,`I-872`,`I-873`,`I-874`,`I-875`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 32768B+500 URL`
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_is_negative=true` indicates malformed low numeric input.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_at_boundary` (`min|max|none`; numeric parse only).
  - tests:
    - added admin coverage for `include_fields_max_requested_numeric_at_boundary` parity across boundary and non-boundary numeric values.
    - added digest coverage for single `responder` section regressions with explicit `fields=` and threshold-suppressed include-fields links.
- 2026-02-23: Added extreme forensic combo preset + negative-numeric metadata + boundary parity/artefact sparse-link guards (wave `I-866`,`I-867`,`I-868`,`I-869`,`I-870`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 16384B+500 URL`
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_clamped_to` is the final applied cap after numeric clamp.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_is_negative` (bool; numeric parse only).
  - tests:
    - added admin coverage for exact-boundary numeric parity (`include_fields_max=10` and `include_fields_max=500`) across requested numeric metadata fields.
    - added digest coverage for single `artifact` section regressions with explicit `fields=` and threshold-suppressed include-fields links.
- 2026-02-23: Added forensic combo preset + requested-max clamped metadata + single-section threshold-suppressed explicit-field guard (wave `I-861`,`I-862`,`I-863`,`I-864`,`I-865`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 8192B+500 URL`
    - helper text now clarifies:
      - `include_fields_max_requested_numeric_in_range=true` means the numeric requested value was already inside `10..500`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_clamped_to` (final effective numeric cap after clamp; numeric parse only).
  - tests:
    - added admin coverage for zero-value clamp parity (`include_fields_max=0`) and new clamped metadata behavior.
    - added digest coverage for stable explicit-field regressed links when only a single section is regressed and include-fields links are threshold-suppressed.
- 2026-02-23: Added deep combo preset + requested-max numeric range metadata + threshold-suppressed explicit-fields order guard (wave `I-856`,`I-857`,`I-858`,`I-859`,`I-860`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 4096B+300 URL`
    - helper text now clarifies:
      - `include_fields_max_requested_numeric` appears only when `include_fields_max` parses as numeric.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric_in_range` (`true` when parsed requested numeric is within `10..500`).
  - tests:
    - added admin coverage for negative numeric input sign preservation (`include_fields_max=-5` keeps `include_fields_max_requested_numeric=-5`).
    - added digest coverage ensuring sparse regressed-section ordering remains stable with explicit `fields=` when include-fields links are threshold-suppressed.
- 2026-02-23: Added expanded combo presets + parsed requested-max numeric metadata + explicit-fields sparse-order guard (wave `I-851`,`I-852`,`I-853`,`I-854`,`I-855`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 1024B+100 URL`
      - `Copy 2048B+300 URL`
    - helper text now clarifies:
      - `include_fields_max_effective_source` is `default` for empty/non-numeric input and `requested` for numeric input.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now conditionally includes:
      - `include_fields_max_requested_numeric` (int; present only when `include_fields_max` parses as numeric).
  - tests:
    - added admin coverage ensuring non-numeric input keeps `include_fields_max_effective_source=default` while preserving string echo.
    - added digest coverage for stable sparse regressed-section ordering when explicit `fields=` filters drive summary links.
- 2026-02-22: Added richer combo presets + max-source metadata + sparse-section order guard (wave `I-846`,`I-847`,`I-848`,`I-849`,`I-850`):
  - readiness:
    - `Preflight Guard Delta` combo copy controls now include:
      - `Copy 2048B+100 URL`
      - `Copy 2048B+200 URL`
    - helper text now clarifies:
      - `include_fields_max_requested` appears only when `include_fields_max` query param is non-empty.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now includes:
      - `include_fields_max_effective_source` (`default|requested`)
  - tests:
    - added admin coverage for trimmed numeric input handling (`" 50 "` => `requested="50"`).
    - added digest coverage for stable regressed-section link ordering with sparse section sets.
- 2026-02-22: Added max-cap diagnostics copy presets + full clamp bounds metadata + threshold-suppressed ordering guard (wave `I-841`,`I-842`,`I-843`,`I-844`,`I-845`):
  - readiness:
    - `Preflight Guard Delta` max-count copy controls now include:
      - `Copy Max200 URL`
      - `Copy Max500 URL`
    - added helper row clarifying invalid max behavior:
      - non-numeric `include_fields_max` falls back to default (`200`) without setting `clamped=true`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now includes:
      - `include_fields_max_changed_fields_min` (`10`)
      - `include_fields_max_changed_fields_max` (`500`)
  - tests:
    - added admin coverage confirming `include_fields_max_requested` is omitted for blank/whitespace query values.
    - added digest coverage for stable regressed-section link ordering when include-fields links are suppressed by threshold.
- 2026-02-22: Added readiness max-default visibility + combo copy presets + summary requested-max echo (wave `I-836`,`I-837`,`I-838`,`I-839`,`I-840`):
  - readiness:
    - `Preflight Guard Delta` now shows `Max-count default` sourced from summary metadata (`200` by default).
    - added combo copy controls:
      - `Copy 512B+25 URL`
      - `Copy 1024B+50 URL`
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now includes:
      - `include_fields_max_requested` (only when `include_fields_max` query param is provided).
  - tests:
    - added digest coverage ensuring regressed section summary links maintain stable section ordering:
      - `responder -> synthetic -> digest -> token -> artifact`
    - added admin coverage confirming `include_fields_max_changed_fields_clamped` stays `false` for in-range requests (`25`,`50`,`100`).
- 2026-02-22: Added preflight max-count copy presets + clamp metadata fields + digest link guard test (wave `I-831`,`I-832`,`I-833`,`I-834`,`I-835`):
  - readiness:
    - `Preflight Guard Delta` now includes max-count copy controls for summary+fields URLs:
      - `Copy Max25 URL`
      - `Copy Max50 URL`
      - `Copy Max100 URL`
    - added helper row documenting max-count clamp policy:
      - `include_fields_max` is clamped to `10..500` (default `200`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now also includes:
      - `include_fields_max_changed_fields_default` (`200`)
      - `include_fields_max_changed_fields_clamped` (`true|false`)
  - digest tests:
    - added coverage ensuring digest-generated preflight summary links do not emit `include_fields_max=` unless explicitly supported/configured in the digest link builder.
- 2026-02-22: Completed preflight readiness/copy wave + include-fields max knob (wave `I-794`,`I-797`,`I-799`,`I-826`,`I-827`,`I-828`,`I-829`,`I-830`):
  - readiness:
    - `Preflight Guard Delta` now includes JSON copy controls next to CSV copies:
      - `Copy Delta JSON URL`
      - `Copy History JSON URL`
    - card now also surfaces explicit JSON export rows:
      - `Delta export JSON URL`
      - `History export JSON URL`
    - shows `Byte-limit clamp max` (`250000`) and concrete regressed section copy buttons (`responder`, `token`).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now supports:
      - `include_fields_max=<int>` (safe clamp: `10..500`, default `200`).
    - existing metadata remains:
      - `include_fields_max_changed_fields`
      - `include_fields_bytes_limit_max`
  - tests:
    - added admin coverage for new JSON copy controls in readiness.
    - added admin coverage for `include_fields_max` clamp behavior (`low`, `high`, `invalid`).
    - added digest coverage for negative threshold clamp (`OPS_DAILY_DIGEST_PREFLIGHT_INCLUDE_FIELDS_MAX_CHANGE_COUNT<0` => `0`).
- 2026-02-22: Added readiness threshold/env visibility + regressed-template copy controls + max-changed-fields metadata (wave `I-821`,`I-822`,`I-823`,`I-824`,`I-825`):
  - readiness:
    - `Preflight Guard Delta` now shows `Digest include-fields threshold` (current env-resolved value).
    - added `Digest regressed-section template copies`:
      - `Copy Regressed Template (fields on)`
      - `Copy Regressed Template (fields off)`
    - added placeholder guidance:
      - replace `SECTION_NAME` with `responder|synthetic|digest|token|artifact`.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now includes:
      - `include_fields_max_changed_fields` (current cap for changed-field list, currently `200`).
  - daily digest test coverage:
    - added clamp behavior test for `OPS_DAILY_DIGEST_PREFLIGHT_INCLUDE_FIELDS_MAX_CHANGE_COUNT=0` (always disable inline `include_fields=1` links).
  - readiness/admin test coverage:
    - added assertions that thresholded digest copy URLs preserve explicit-fields-over-preset precedence.
- 2026-02-22: Added thresholded digest-copy presets + effective byte-limit echo + inline-threshold visibility (wave `I-816`,`I-817`,`I-818`,`I-819`,`I-820`):
  - readiness:
    - `Preflight Guard Delta` now includes thresholded digest summary copy controls:
      - `Copy Digest URL (fields on)`
      - `Copy Digest URL (fields off)`
    - helper examples now explain byte-budget intent for:
      - `512` (tickets), `1024` (chat), `2048` (postmortems)
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now includes:
      - `include_fields_bytes_limit_effective`
    - this echoes post-clamp effective bytes limit (including `0` when unset/disabled).
  - daily digest text:
    - preflight section now includes explicit threshold visibility line:
      - `preflight_guard_include_fields_inline: threshold=<N> change_count=<M> applied=<yes|no>`
  - test coverage:
    - added parity assertion that `include_fields_bytes_limit=0` behaves exactly like unset.
    - added digest assertions for threshold visibility and include-fields on/off behavior.
- 2026-02-22: Added digest include-fields thresholding + byte-budget copy presets + byte-limit applied introspection (wave `I-808`,`I-811`,`I-812`,`I-813`,`I-814`,`I-815`):
  - daily digest text:
    - preflight summary links now include `include_fields=1` only when `change_count` is within a safe threshold.
    - threshold is configurable via:
      - `OPS_DAILY_DIGEST_PREFLIGHT_INCLUDE_FIELDS_MAX_CHANGE_COUNT` (default `25`).
  - readiness:
    - `Preflight Guard Delta` now adds copy presets for byte-budget summary links:
      - `include_fields_bytes_limit=512`
      - `include_fields_bytes_limit=1024`
      - `include_fields_bytes_limit=2048`
    - helper text now explicitly calls out server-side byte-limit clamping.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now includes:
      - `include_fields_bytes_limit_applied` (`true|false`)
    - existing `field_bytes_over_limit` + `include_fields_bytes_limit` semantics remain.
  - test coverage:
    - added digest tests for threshold-on/threshold-off include-fields link behavior.
    - added admin test for high byte-limit case proving `field_bytes_over_limit` stays `False` when limit is sufficient.
- 2026-02-22: Added summary+fields copy control + include-fields byte limit + copy-color help + digest explicit-field normalization tests (wave `I-806`,`I-807`,`I-809`,`I-810`):
  - readiness:
    - `Preflight Guard Delta` now includes:
      - `Summary + fields URL Copy` (`include_fields=1` deep-link copy control).
      - inline helper text documenting copy-status colors (`ok` green, `fail` red).
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now supports:
      - `include_fields_bytes_limit=<int>`
    - when byte-limit mode is used, response includes:
      - `field_bytes_over_limit` (`true|false`)
      - `include_fields_bytes_limit` (echoed when applied)
    - `changed_fields_truncated` now also reflects byte-limit truncation.
  - daily digest tests:
    - added coverage for explicit-field list normalization (trim/dedupe/order-preserve) in preflight summary links.
    - added coverage that explicit-field fallback also works when only `fields_filter` is present.
- 2026-02-22: Added include-fields readiness deep link + digest explicit-fields fallback + copy-status color states + field-bytes metric (wave `I-801`,`I-802`,`I-803`,`I-804`,`I-805`):
  - readiness:
    - `Preflight Guard Delta` now includes a direct `Summary + fields URL` row pointing to:
      - `GET /admin/ops/preflight-guards/delta.summary.json?...&include_fields=1`
    - preflight copy status now uses explicit visual states:
      - success: `admin-copy-state-ok`
      - failure: `admin-copy-state-fail`
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now also includes:
      - `changed_fields_bytes` (UTF-8 byte size of the returned compact `changed_fields` list)
  - daily digest text:
    - preflight summary links now fall back to explicit `fields=` when preflight context indicates resolved explicit fields.
    - invalid `fields_preset` values are ignored in generated summary links.
- 2026-02-22: Added preset-preserving digest links + readiness filter-effect visibility + combined copy-URL encoding coverage (wave `I-788`,`I-789`,`I-795`):
  - readiness:
    - `Preflight Guard Delta` now shows `Filters effective` (`none|preset|explicit_fields`) from summary filter resolution.
    - copy URL controls are now validated for combined `fields` + `fields_preset` query contexts (encoded comma handling).
  - daily digest text:
    - preflight summary links now preserve active `fields_preset` when present in preflight context:
      - `preflight_guard_delta_summary_json`
      - `preflight_guard_delta_summary_regressed_<section>`
- 2026-02-22: Added summary field-list toggle + effective-filter marker + copy-status timeout reset (wave `I-787`,`I-790`,`I-791`):
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json` now includes:
      - `filters_effective` (`none|preset|explicit_fields`) to show how filters were resolved.
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_fields=1` now adds compact changed-field payload:
      - `changed_fields` (sorted, capped at 200)
      - `changed_fields_total`
      - `changed_fields_truncated`
      - `fields_preset_resolved_fields` is still included only when preset-driven filtering is applied.
  - readiness:
    - preflight copy-status labels now auto-clear after a short timeout so the card stays clean after repeated copy actions.
- 2026-02-22: Added preflight regressed-section summary links + preset resolved-fields echo + extra readiness copy controls (wave `I-778`,`I-783`,`I-786`):
  - readiness:
    - `Preflight Guard Delta` now includes quick-copy controls for:
      - `Summary URL`
      - `Delta CSV URL`
      - `History CSV URL`
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json` now includes:
      - `fields_preset_resolved_fields` when `fields_preset` is actively applied.
  - daily digest text:
    - when preflight severity is `regressed`, digest now includes section-filtered summary links:
      - `.../preflight-guards/delta.summary.json?day_offset=1&section=<section>&include_compare_timestamps=1`
- 2026-02-22: Added readiness summary-copy control + preflight preset CSV parity + digest compare-timestamp summary link (wave `I-776`,`I-782`,`I-784`,`I-785`):
  - readiness:
    - `Preflight Guard Delta` card now includes a `Copy Summary URL` control beside the current summary endpoint URL.
    - added helper note clarifying filter precedence: explicit `fields=` overrides `fields_preset`.
  - preflight CSV exports:
    - `GET /admin/ops/preflight-guards/delta.csv` metadata includes:
      - `fields_preset=<value|none>`
    - `GET /admin/ops/preflight-guards/history.csv` metadata includes:
      - `fields_preset=<value|none>`
  - daily digest text:
    - when preflight baseline exists and changes are listed, digest now includes:
      - `preflight_guard_delta_summary_json: /admin/ops/preflight-guards/delta.summary.json?day_offset=1&include_compare_timestamps=1`
- 2026-02-22: Added preflight fields presets + compare timestamps toggle + digest section-count object (wave `I-772`,`I-774`,`I-775`):
  - readiness:
    - `Preflight Guard Delta` selector now supports:
      - `fields_preset=docs_mode|token_secret|synthetic_thresholds`
    - preset selection is threaded through quick export links (`delta.json`, `delta.csv`, `history.csv`, `history.json`, `delta.summary.json`).
  - preflight exports:
    - `GET /admin/ops/preflight-guards/delta.json` now echoes:
      - `fields_preset`
      - `fields_preset_applied`
      - `fields_filter_explicit`
    - `GET /admin/ops/preflight-guards/delta.summary.json` now echoes:
      - `fields_preset`
      - `fields_preset_applied`
    - `GET /admin/ops/preflight-guards/delta.summary.json?include_compare_timestamps=1` now adds:
      - `compare_timestamps.current_generated_at_utc`
      - `compare_timestamps.baseline_generated_at_utc`
    - `GET /admin/ops/preflight-guards/delta.csv` and `GET /admin/ops/preflight-guards/history.csv` now include `fields_preset` metadata comments.
    - `GET /admin/ops/preflight-guards/history.json` now echoes:
      - `fields_preset`
      - `fields_preset_applied`
  - digest artifact:
    - top-level `preflight_section_counts` now mirrors section counts (`all|responder|synthetic|digest|token|artifact`) outside `metrics`.
- 2026-02-22: Added readiness section-count summary drilldowns + compact changed-sections field (wave `I-769`,`I-771`,`I-773`):
  - readiness:
    - `Preflight Guard Delta` section-count row now renders clickable links for:
      - `all`, `responder`, `synthetic`, `digest`, `token`, `artifact`
    - each link opens matching:
      - `GET /admin/ops/preflight-guards/delta.summary.json?...&section=<section>&fields=...`
    - card now shows explicit current-summary URL hint line.
  - delta summary payload:
    - `GET /admin/ops/preflight-guards/delta.summary.json` now includes:
      - `changed_sections` (compact array of section names with non-zero change counts).
- 2026-02-22: Added delta-summary cache validators + normalization coverage + digest section-count line (wave `I-767`,`I-768`,`I-770`):
  - `GET /admin/ops/preflight-guards/delta.summary.json`:
    - now returns cache validators:
      - `ETag`
      - `Last-Modified`
    - supports conditional `304` with:
      - `If-None-Match`
      - `If-Modified-Since`
  - digest text:
    - preflight section now includes section-level changed-field counts:
      - `preflight_guard_section_counts: all=... responder=... synthetic=... digest=... token=... artifact=...`
  - test coverage:
    - added normalization assertions for `delta.summary.json` invalid `section` fallback and malformed `fields` normalization.
- 2026-02-22: Added digest preflight section-count metrics + lightweight delta summary endpoint (wave `I-754`,`I-755`):
  - daily digest metrics:
    - now includes section-level preflight changed-field counters:
      - `preflight_guards_changed_fields_all`
      - `preflight_guards_changed_fields_responder`
      - `preflight_guards_changed_fields_synthetic`
      - `preflight_guards_changed_fields_digest`
      - `preflight_guards_changed_fields_token`
      - `preflight_guards_changed_fields_artifact`
  - new endpoint:
    - `GET /admin/ops/preflight-guards/delta.summary.json?day_offset=1`
      - lightweight drift summary payload for polling:
        - compare metadata (`day_offset`, `compare_day_utc`, `summary_status`, `previous_found`)
        - severity (`delta_severity`, `improved_signals`, `regressed_signals`)
        - compact counts (`change_count`, `changed_fields_by_section_counts`)
      - supports `section=` + `fields=` filters on summary counts.
- 2026-02-22: Added readiness quick section exports + delta CSV section-count metadata + readiness section summary (wave `I-751`,`I-752`,`I-753`):
  - readiness:
    - `Preflight Guard Delta` card now includes quick section export links (`section=...`) for direct delta JSON/CSV triage workflows.
    - card now surfaces section-level change-count summary (`all`, `responder`, `synthetic`, `digest`, `token`, `artifact`) derived from delta section counts.
  - delta CSV metadata:
    - `GET /admin/ops/preflight-guards/delta.csv` now includes:
      - `changed_fields_all`
      - `changed_fields_responder`
      - `changed_fields_synthetic`
      - `changed_fields_digest`
      - `changed_fields_token`
      - `changed_fields_artifact`
- 2026-02-22: Added history `section` filters + readiness exact delta URL hint + digest severity line (wave `I-741`,`I-743`,`I-744`):
  - preflight history exports:
    - `GET /admin/ops/preflight-guards/history.csv` now supports:
      - `section=all|responder|synthetic|digest|token|artifact`
    - `GET /admin/ops/preflight-guards/history.json` now supports:
      - `section=all|responder|synthetic|digest|token|artifact`
      - response now echoes `section_filter`
  - readiness:
    - `Preflight Guard Delta` card now supports `section` + `fields` selectors and surfaces exact current delta CSV URL for copy/paste triage.
  - daily digest:
    - preflight section now includes:
      - `preflight_guard_delta_severity: <stable|improved|regressed> improved=<n> regressed=<n>` when previous-day baseline exists.
- 2026-02-22: Added preflight delta grouped field summary + readiness day-offset passthrough + digest severity metric (wave `I-731`,`I-732`,`I-738`):
  - preflight delta JSON:
    - `GET /admin/ops/preflight-guards/delta.json` now includes grouped change summaries:
      - `changed_fields`
      - `changed_fields_by_section` (`responder|synthetic|digest|token|artifact`)
      - `changed_fields_by_section_counts`
  - readiness:
    - `Preflight Guard Delta` card export links now pass through currently selected `day_offset`, preserving compare-window context across export clicks.
  - daily digest metrics:
    - now includes `preflight_guards_delta_severity` (`stable|improved|regressed`) for parity with readiness badge state.
- 2026-02-22: Added preflight export filters + digest delta CSV link (wave `I-722`,`I-723`,`I-725`):
  - preflight guard export filters:
    - `GET /admin/ops/preflight-guards/delta.csv` now supports:
      - `section=all|responder|synthetic|digest|token|artifact`
      - `fields=<comma-separated field names>`
    - `GET /admin/ops/preflight-guards/delta.json` now supports:
      - `fields=...`
      - `section=...`
    - `GET /admin/ops/preflight-guards/history.csv` now supports:
      - `fields=...`
    - `GET /admin/ops/preflight-guards/history.json` now supports:
      - `fields=...`
  - daily digest:
    - preflight section now includes direct delta CSV link when guard changes are detected:
      - `/admin/ops/preflight-guards/delta.csv?day_offset=1`
- 2026-02-22: Added preflight guard history JSON + readiness delta selector/severity (wave `I-721`,`I-724`,`I-729`):
  - new endpoint:
    - `GET /admin/ops/preflight-guards/history.json?days=30`
      - JSON mirror of history CSV rows for dashboard integrations.
  - preflight delta payloads:
    - `GET /admin/ops/preflight-guards/delta.json` now includes:
      - `delta_severity` (`stable|improved|regressed`)
      - `improved_signals`
      - `regressed_signals`
    - `GET /admin/ops/preflight-guards/delta.csv` metadata now includes same severity/signal counts.
  - readiness:
    - `Preflight Guard Delta` card now supports `day_offset` selection (1..30 days) and renders severity badge with improved/regressed signal counts.
- 2026-02-22: Added preflight guard delta/history exports (wave `I-709`,`I-711`,`I-713`):
  - new endpoints:
    - `GET /admin/ops/preflight-guards/delta.json?day_offset=1`
      - compares current guard snapshot vs prior UTC-day artifact (`day_offset` selectable, `1..30`).
    - `GET /admin/ops/preflight-guards/delta.csv?day_offset=1`
      - ticket-friendly CSV of changed guard fields (`previous -> current`) for selected compare day.
    - `GET /admin/ops/preflight-guards/history.csv?days=30`
      - flattened daily history rows (`snapshot_day_utc,generated_at_utc,field,value,artifact_path`) from retained preflight-guard artifacts.
  - readiness:
    - `Preflight Guard Delta` card now links directly to delta JSON/CSV and history CSV exports.
- 2026-02-22: Added strict synthetic-zero preflight mode + preflight-guard artifact retention/delta view (wave `I-635`,`I-636`,`I-637`):
  - deploy preflight script:
    - added `--strict-synthetic-zero`
    - hard-fails preflight when synthetic zero guard reports `synthetic_export_zero_guard_status=fail`
    - `--json` payload now includes `inputs.strict_synthetic_zero`
  - preflight guard artifact persistence:
    - `/admin/ops/preflight-guards.json` now writes:
      - latest artifact: `PREFLIGHT_GUARDS_ARTIFACT_FILE` (default `/home/vets-coin/logs/preflight_guards_latest.json`)
      - daily artifact: `preflight_guards_YYYYMMDD.json` in the same folder
    - retention pruning controlled by `PREFLIGHT_GUARDS_ARTIFACT_RETENTION_DAYS` (default `30`)
  - readiness:
    - `/admin/ops/readiness` now includes `Preflight Guard Delta` card:
      - compares current guard snapshot vs previous UTC-day artifact
      - surfaces summary (`changed|no_change|baseline_missing`) and field-level guard drift lines.
- 2026-02-21: Added digest preflight-guard mode-change snippet (wave `I-640`):
  - daily ops digest:
    - now captures a `preflight_guards` snapshot inside digest artifacts.
    - compares current guard modes vs previous UTC day artifact.
    - text digest now includes:
      - current key guard states (`responder_docs_link`, synthetic/export retention, token-secret explicit-set)
      - previous-day snapshot availability/timestamp
      - explicit `preflight_guard_change` rows when fields changed.
  - digest metrics now include preflight drift counters/status:
    - `preflight_guards_change_count`
    - `preflight_guards_previous_day_found`
    - `preflight_guards_summary_status`
    - `preflight_guards_delta_severity`
    - `preflight_guards_responder_docs_mode`
    - `preflight_guards_responder_docs_ok`
- 2026-02-21: Added readiness preflight-guard mode chip + deploy preflight JSON mode (wave `I-633`,`I-634`):
  - readiness:
    - `/admin/ops/readiness` `Responder Docs-Link Mode` card now includes a linked mode chip:
      - `preflight-guards mode=<dry-run|enforced>`
      - link target: `GET /admin/ops/preflight-guards.json`
  - deploy preflight script:
    - `bash scripts/deploy_preflight.sh --json`
    - emits machine-readable summary with:
      - `overall_status`
      - `summary` counts (`pass|warn|fail`)
      - `key_guard_states`
      - parsed `checks` and output tail
    - exit code remains aligned with normal preflight result.
- 2026-02-21: Added digest concentration thresholding + preflight guard env visibility/exports (wave `I-628`,`I-631`,`I-632`):
  - daily ops digest:
    - warns when top export-token `requested_by` concentration exceeds configured thresholds:
      - `OPS_DAILY_DIGEST_WARN_LINK_INBOX_EXPORT_TOKEN_TOP_REQUESTED_BY_SHARE_PCT` (24h)
      - `OPS_DAILY_DIGEST_WARN_LINK_INBOX_EXPORT_TOKEN_TOP_REQUESTED_BY_SHARE_PCT_7D` (7d)
    - metrics/text now include concentration status (`ok|warn`) per window.
  - preflight guard JSON:
    - `GET /admin/ops/preflight-guards.json?include_env_rows=1` now appends safe `_env_row` metadata rows for drift audits.
  - preflight guard CSV export:
    - `GET /admin/ops/preflight-guards/export.csv?include_env_rows=1`
    - includes flattened guard rows + optional env rows with secret-safe redaction (`[set]`/`[unset]`).
- 2026-02-21: Added usage chart legend overlays for annotation markers (wave `I-627`):
  - `GET /admin/ops/alerts-monitor/export-usage.png`:
    - now draws legend overlay keys for marker annotations:
      - `L` = latest
      - `M` = max
    - response header now includes:
      - `X-Usage-Legend: L=latest,M=max`
  - `GET /admin/ops/alerts-monitor/export-usage.svg`:
    - now includes annotation overlays + visible legend (`L latest`, `M max`)
    - response header now includes:
      - `X-Usage-Legend: L=latest,M=max`
- 2026-02-21: Added synthetic zero-history failed-nonzero highlight in readiness (wave `I-626`):
  - readiness:
    - `/admin/ops/readiness` synthetic zero-history table now visually highlights rows where:
      - `status=failed|error`
      - `total_filtered > 0`
    - highlighted status label renders as `failed (non-zero)` to separate true export failures from benign zero-volume streaks.
- 2026-02-21: Added readiness docs-link drift view + synthetic zero-history CSV export (wave `I-624`,`I-625`):
  - readiness:
    - `Responder Docs-Link Mode` now includes drift vs previous UTC day:
      - baseline presence/day
      - new/resolved/unchanged docs-link error sets.
    - docs-link snapshots are persisted per day under `RESPONDER_WORKFLOW_DOCS_LINK_HISTORY_DIR`
      (default `/home/vets-coin/logs/responder_docs_link_history`).
  - new export endpoint:
    - `GET /admin/ops/readiness/synthetic-zero-history.csv?limit=10&days=45`
    - exports recent synthetic zero-history rows (`executed_at`, `status`, `total_filtered`, `message`) for postmortem attachments.
  - guard snapshot endpoint:
    - `/admin/ops/preflight-guards.json` now includes responder docs-link `history_dir`.
- 2026-02-21: Added docs-link enforcement cutover surfaces + guard snapshot endpoint (wave `I-621`,`I-622`,`I-623`,`I-629`,`I-630`):
  - readiness:
    - added standalone `Responder Docs-Link Mode` card with mode, linkage status, paths, and active errors.
  - admin ops endpoint:
    - `GET /admin/ops/preflight-guards.json` returns key preflight guard modes/toggles (docs-link, synthetic thresholds, digest/retention knobs).
  - docs-link checker script:
    - `check_responder_workflow_docs_link.py` now supports machine-readable output:
      - `--format json` (or `--json`)
  - preflight:
    - added one-off CLI override `--enforce-docs-link` to force docs-link hard-fail behavior for that invocation.
  - runbook:
    - added dry-run to enforced cutover checklist in `docs/ops/deploy_preflight.md`.
- 2026-02-21: Added readiness docs-link dry-run gate + synthetic zero-history table (wave `I-605`,`I-606`):
  - readiness:
    - launch gate `Responder workflow docs linkage` now supports dry-run warn mode before hard-fail cutover.
    - synthetic export card now includes recent zero-volume history rows (`executed/status/total_filtered/message`).
  - preflight:
    - responder docs-link check now warns in dry-run mode by default.
    - set `RESPONDER_WORKFLOW_DOCS_LINK_ENFORCE_FAIL=1` to fail preflight when linkage is broken.
  - env:
    - `LINK_INBOX_EVENTS_EXPORT_SYNTHETIC_ZERO_HISTORY_LIMIT` controls readiness history row count.
- 2026-02-21: Added PNG incident annotations + digest top-requester metric (wave `I-602`,`I-604`):
  - alert monitor PNG usage export now annotates:
    - latest-day total marker (`L:<total>`)
    - max-day marker (`M:<total>`)
  - `GET /admin/ops/alerts-monitor/export-usage.png` now emits headers:
    - `X-Usage-Annotated`
    - `X-Usage-Latest-Total`
    - `X-Usage-Max-Total`
  - daily ops digest metrics/text now include top token `requested_by` actor summary for:
    - 24h window
    - trailing 7d window
    - including per-window share percent.
- 2026-02-21: Added usage SVG export + telemetry requester filtering (wave `I-601`,`I-603`):
  - alert monitor usage exports:
    - `GET /admin/ops/alerts-monitor/export-usage.svg?days=7&source=all|export|token&w=900&h=240`
  - telemetry endpoint:
    - `GET /admin/ops/link-inbox/events/export-telemetry.json` supports
      `requested_by=<value>|all` filtering.
  - alert monitor UI:
    - added `Usage SVG` quick action beside CSV/JSON/PNG usage exports.
- 2026-02-21: Added export usage PNG + synthetic zero-guard unification + responder helper upgrades (wave `I-591`..`I-600`):
  - alert monitor usage exports:
    - `GET /admin/ops/alerts-monitor/export-usage.png?days=7&source=all|export|token&w=800&h=220`
    - usage CSV/JSON now include token-request `requested_by` top sources.
  - export telemetry:
    - `GET /admin/ops/link-inbox/events/export-telemetry.json` now includes `requested_by` per row + `requested_by_counts`.
  - responder helper script:
    - added `--expires-at-utc` (mutually exclusive with `--ttl-seconds`)
    - added `--print-curl`
    - added `--max-rows` policy warning threshold.
  - synthetic zero-guard:
    - shared parser utility now drives preflight/readiness/digest/checker behavior.
    - readiness includes `Synthetic export zero-volume streak` launch gate.
    - digest includes synthetic zero-guard status/streak/thresholds/latest total.
  - preflight:
    - now validates responder workflow docs linkage (`check_responder_workflow_docs_link.py`).
    - synthetic zero-volume advisory now supports warn/fail thresholds via:
      `LINK_INBOX_EVENTS_EXPORT_SYNTHETIC_ZERO_STREAK_WARN_DAYS` and
      `LINK_INBOX_EVENTS_EXPORT_SYNTHETIC_ZERO_STREAK_FAIL_DAYS`.
- 2026-02-21: Added synthetic/export guardrails + responder helper upgrades (wave `I-580`..`I-590`):
  - digest:
    - weekly export-mode adoption snippet (`json/csv/token` share %) in daily digest text/metrics.
    - synthetic export check trend (last 7 runs) with `ok|warn|failed|other` counts + sparkline.
  - readiness:
    - `/admin/ops/readiness` now adds fail-gate:
      `Synthetic export required when digest enabled (48h)`.
  - alert monitor exports:
    - `GET /admin/ops/alerts-monitor/export-usage.json?days=7&source=all|export|token`
    - `GET /admin/ops/alerts-monitor/export-usage.csv?days=7&source=all|export|token`
  - alert monitor UI:
    - synthetic-export status chip + quick link to filtered ops jobs view.
  - responder helper script:
    - added `--format shell`, `--incident-id`, and `--verify-token` options.
  - preflight:
    - advisory warning when synthetic export `total_filtered` remains zero across consecutive runs (`LINK_INBOX_EVENTS_EXPORT_SYNTHETIC_ZERO_DAYS_WARN`, now legacy warn alias).
- 2026-02-21: Added responder URL helper + alert-monitor usage CSV + synthetic-check readiness card (wave `I-560`,`I-571`,`I-573`):
  - helper script for responders:
    - `/home/vets-coin/flask_api/scripts/generate_link_inbox_export_download_url.py`
    - emits signed `export-download.csv` URL with explicit `--ttl-seconds` and required `--audit-note`.
  - alert-monitor usage export:
    - `GET /admin/ops/alerts-monitor/export-usage.csv?days=7`
  - readiness:
    - `/admin/ops/readiness` now includes `Synthetic Export Check` card (`link_inbox_export_synthetic` cron status/age/trend).
- 2026-02-21: Added export-usage monitor trend + nightly synthetic check + digest preset usage (wave `I-556`,`I-557`,`I-559`):
  - alert monitor UI:
    - `/admin/ops/alerts-monitor` now surfaces 7-day link-inbox export usage trend (`json/csv/token`).
  - synthetic export check:
    - added runner script:
      `/home/vets-coin/flask_api/scripts/run_link_inbox_export_synthetic_check.py`
    - added wrapper (daily via ops digest wrapper when enabled):
      `/home/vets-coin/scripts/run_link_inbox_export_synthetic_check.sh`
    - cron row job name:
      `link_inbox_export_synthetic`
  - digest metrics/text:
    - includes recent window-preset usage counts (`last_outage`, `last_digest_warn`, `none`, `total`).
  - preflight:
    - checks synthetic export wrapper exists when `LINK_INBOX_EVENTS_EXPORT_SYNTHETIC_ENABLED=1`.
- 2026-02-21: Expanded export telemetry + preset UX + preflight warning semantics (wave `I-551`,`I-552`,`I-553`,`I-555`,`I-558`):
  - `/admin/ops/link-inbox` quick-actions now include `window_preset` selector for Verify Events exports.
  - CSV export preset debug comments are now opt-in:
    - `debug=1` includes `window_preset_applied` and `window_preset_reason` comment lines.
  - new telemetry endpoint:
    - `GET /admin/ops/link-inbox/events/export-telemetry.json`
  - digest metrics now include token failure counters:
    - `link_inbox_export_token_fail_secret_missing`
    - `link_inbox_export_token_fail_decode_error`
    - `link_inbox_export_token_fail_expired`
  - preflight behavior:
    - token-flow check still fails on sign/verify errors
    - preflight now emits `WARN` when explicit `LINK_INBOX_EVENTS_EXPORT_TOKEN_SECRET` is unset and fallback secret is used
- 2026-02-21: Expanded export presets/token safety checks (wave `I-532`,`I-535`,`I-540`):
  - events export preset windows:
    - `window_preset=last_digest_warn|last_outage` (applies `at_from`/`at_to` when manual window is not provided)
  - events export metadata:
    - `window_preset`, `window_preset_applied`, `window_preset_reason`
  - digest warn trigger:
    - emits warning when token mode is used and `LINK_INBOX_EVENTS_EXPORT_TOKEN_SECRET` is unset
      (`link_inbox_export_token_secret_unset token_requests=...`)
  - preflight:
    - added token sign/verify dry-run:
      `/home/vets-coin/flask_api/scripts/check_link_inbox_export_token_flow.py`
- 2026-02-21: Expanded link-inbox export controls + readiness guardrails (wave `I-531`,`I-534`,`I-536`,`I-539`):
  - events export metadata:
    - hard-limit telemetry: `requested_limit`, `max_rows`, `effective_limit`, `total_filtered`, `returned_count`, `truncated`
  - events JSON fast-count mode:
    - `count_only=1` (returns counts/metadata with empty `events`)
  - events CSV/GZIP optional checksum header:
    - `checksum=1` returns `X-Export-SHA256`
  - readiness gate:
    - `Link-Inbox Export Token Secret` pass/warn signal
  - env:
    - `LINK_INBOX_EVENTS_EXPORT_MAX_ROWS` hard ceiling
- 2026-02-21: Expanded resolved-verify export/readiness/preflight tooling (wave `I-521..I-530`):
  - events export filters:
    - `at_from` / `at_to` (UTC timestamps)
    - `status_code_family` (`2xx|4xx|5xx|timeout|other`)
  - JSON projection:
    - `fields` (repeatable or CSV list from export column set)
  - CSV signed download mode:
    - generate token: `GET /admin/ops/link-inbox/events/export.csv?...&download_token=1`
    - consume token: `GET /admin/ops/link-inbox/events/export-download.csv?download_token=...`
  - digest warnings:
    - `OPS_DAILY_DIGEST_WARN_RESOLVED_VERIFY_SKIP_NO_URL_MAX_COUNT`
    - `OPS_DAILY_DIGEST_WARN_RESOLVED_VERIFY_SKIP_NO_URL_MAX_SHARE_PCT`
  - read-model normalization:
    - `summary.resolved_verify_events_count` guaranteed non-negative and backfilled from `checked_total + skipped_total` when missing
  - readiness/preflight/tooling:
    - readiness now shows `ops_digest_retention` 7-run status sparkline
    - preflight checks latest `ops_digest_retention` cron row freshness (default 48h)
    - added timer installer helper: `/home/vets-coin/scripts/install_ops_digest_retention_timer.sh`
- 2026-03-10: Expanded resolved-verification digest/admin/runbook surfaces (waves `I-471..I-490`):
  - digest analytics:
    - abrupt restart detector on `events_scanned` drop vs previous artifact
    - sparse median-baseline marker (`compare_reference_sparse_baseline`) with trend-confidence degradation
    - median compare range timestamps (`compare_reference_oldest_point_at_utc`, `compare_reference_latest_point_at_utc`)
    - carry-forward annotation now includes `carry_forward_previous_artifact_at_utc`
    - owner coverage metrics (`reopened_with_owner_count`, `reopened_with_owner_pct`) and top owner regression (`top_owner_regression_owner`, `top_owner_regression_delta`)
    - confidence now includes skip-share contribution, confidence sparkline trend, and optional warn floor (`OPS_DAILY_DIGEST_RESOLVED_VERIFY_CONFIDENCE_MIN`)
    - error taxonomy expanded to `dns_tls|connect|read|timeout|other` with percentage shares (`error_family_share_pct`)
    - combined deep link for skip+reopened verification event export
    - resolved-verification sub-schema marker (`resolved_verify_schema_version`)
  - admin endpoints/UI:
    - added `GET /admin/ops/link-inbox/verification-summary.json`
    - `/admin/ops/config` now shows a one-row resolved-verification threshold preview card
  - runbook checks:
    - added `resolved_verify_compare_mode` validation check for compare-mode env values
    - supports alias env `OPS_DAILY_DIGEST_RESOLVED_VERIFY_TREND_MODE=prev|median7`
- 2026-02-21: Expanded resolved-verify automation surfaces (wave `I-511..I-520`):
  - events export filters:
    - `skip_reason` (`no_url|cooldown|other`)
    - `issue_id`
    - `url_contains`
  - CSV gzip mode:
    - `GET /admin/ops/link-inbox/events/export.csv?...&compress=1`
  - digest enhancements:
    - `resolved_verify_skip_no_url_top_issue_ids` line
    - stale-event-age warn trigger via `OPS_DAILY_DIGEST_WARN_RESOLVED_VERIFY_LAST_EVENT_AGE_HOURS`
  - read-model additions:
    - `warn` boolean
    - `summary.compare_status` (`improving|regressing|flat|unknown`)
  - readiness/preflight:
    - readiness now tracks `ops_digest_retention` health
    - preflight verifies digest-retention wrapper executable when enabled
- 2026-02-21: Expanded resolved-verification exports/read-model/preflight (wave `I-501..I-510`):
  - added CSV timeline export:
    - `GET /admin/ops/link-inbox/events/export.csv`
  - added `event` multi-select filters to JSON/CSV events exports (supports aliases: `ok`, `reopened`, `skip`, `triage`)
  - resolved-verification digest now includes `resolved_verify_events_count`
  - digest artifact now includes top-level `artifact_schema_version`
  - read-model endpoint now includes:
    - `artifact_schema_version`
    - `reopened_only_inbox_url` (absolute when `WEB_DOMAIN` is set)
    - cache headers (`ETag`, `Last-Modified`, `Cache-Control`) with `304` support
  - preflight now validates digest artifact freshness via:
    - `/home/vets-coin/flask_api/scripts/check_ops_digest_freshness.py`
  - added daily retention wrapper:
    - `/home/vets-coin/scripts/run_ops_digest_retention_daily.sh`
- 2026-02-21: Added resolved-verification operational surfaces (wave `I-427..I-430`):
  - digest reopened-only inbox shortcut (`/admin/ops/link-inbox?status=assigned&verify_result=reopened`)
  - digest drill-down events link (`/admin/ops/link-inbox/events/export.json?event_prefix=resolved_verify_`)
  - admin events export endpoint:
    - `GET /admin/ops/link-inbox/events/export.json`
  - admin digest read-model endpoint:
    - `GET /admin/ops/digest/resolved-verification.json`
  - artifact retention helper script:
    - `/home/vets-coin/flask_api/scripts/retain_ops_digest_artifacts.py`
- 2026-02-21: Expanded resolved-verification digest analytics (wave `I-421..I-426`):
  - status-family deltas vs previous artifact (`2xx/4xx/5xx/timeout/other`)
  - 5xx-share and timeout-share thresholds with warn-trigger telemetry
  - zero-check streak warning suppression in scheduled UTC downtime windows
  - explicit streak-reset annotation when checks resume
  - trend-confidence marker based on previous artifact freshness/same-day context
- 2026-02-21: Expanded resolved-verification digest analytics (wave `I-414..I-420`):
  - restart/truncation indicator for resolved-verify event stream
  - carry-forward warning when compare baseline is unavailable
  - compare mode toggle (`previous` vs `median_7d`)
  - reopened owner attribution and owner rollup
  - recency line (`last_event_at`, `last_event_age_hours`)
  - verification error-family taxonomy (`timeout`, `dns_tls`, `http_failures`, `other_exceptions`)
  - compact confidence score (`confidence_score`, `confidence_band`)
- 2026-02-21: Expanded daily ops digest resolved-verification analytics and artifact schema:
  - confidence/min-sample note
  - reopened anomaly flag vs rolling weekly median
  - pass-rate sparkline history points
  - pass-rate SLA threshold evaluation
  - verification throughput (`checks/hour`)
- 2026-02-17: Normalized admin incident severity aliases (`warning`, `failed|fail|error`) across:
  - `/admin/ops/incidents`
  - `/admin/ops/incidents/export`
  - `/admin/ops/incidents/export.json`
- 2026-02-17: Added alert/status log retention telemetry to alert monitor surfaces:
  - UI: `/admin/ops/alerts-monitor`
  - JSON: `/admin/ops/alerts-monitor/export.json`
- 2026-02-17: Added alert monitor export bundle endpoint:
  - `GET /admin/ops/alerts-monitor/export.zip`
- 2026-02-17: Added alert monitor run-history CSV endpoint:
  - `GET /admin/ops/alerts-monitor/runs/export`
- 2026-02-17: Added admin incident detail endpoint with neighbor context:
  - `GET /admin/ops/incidents/detail.json`
- 2026-02-17: Alert monitor ZIP export now includes checksum manifest:
  - `alerts_monitor_export_manifest.json`
- 2025-12-18: Added Salutes partner API (credit/debit/balance) with HMAC auth, idempotency, and ledger storage.
- 2025-12-18: Added admin Salutes JSON ledger endpoint (`/api/salutes/ledger`) and partner rate limiting option.
- 2025-12-18: Added wallet connect + wallet info endpoints and admin backup list/download endpoints.
- 2026-01-03: Added partner user lookup, partner wallet info, and partner donation-claim endpoint.
- 2026-01-03: Added partner user provisioning + partner webhooks with delivery queue and retry script.
- 2026-02-13: Added admin webhook delivery operations (event replay + CSV export) in partner dashboard.
- 2026-02-13: Published OpenAPI spec at `GET /api/openapi.yaml` (see `flask_api/docs/openapi.yaml`).
- 2026-02-13: Added partner sandbox key mode + CIDR support for `allowed_ips` (admin-managed).
- 2026-02-16: Added transparency anomaly export endpoints with filter support:
  - `GET /transparency/audit-anomalies/export`
  - `GET /transparency/audit-anomalies/export.json`
- 2026-02-16: Added selected-run vs latest anomaly-type diff exports:
  - `GET /transparency/audit-anomalies/diff/export`
  - `GET /transparency/audit-anomalies/diff/export.json`
- 2026-02-16: Removed deprecated admin backup compatibility endpoint:
  - `POST /admin/trigger-backup` (use `POST /admin/backup/run`)
- 2026-02-16: Added public anomaly metadata JSON endpoints:
  - `GET /transparency/audit-anomalies/runs.json`
  - `GET /transparency/audit-anomalies/trend.json`
- 2026-02-16: Added public anomaly summary endpoint:
  - `GET /transparency/audit-anomalies/summary.json`
- 2026-02-16: Extended anomaly diff/trend exports:
  - diff CSV now includes `pct_delta_percent`
  - trend JSON accepts `metric=sigs|rows`
- 2026-02-16: Added arbitrary run-to-run diff API:
  - `GET /transparency/audit-anomalies/diff/compare.json?run_a=&run_b=`
- 2026-02-16: Added run-to-run diff CSV export:
  - `GET /transparency/audit-anomalies/diff/compare.csv?run_a=&run_b=`
- 2026-02-16: Published transparency OpenAPI supplement:
  - `GET /api/openapi-transparency.yaml`
- 2026-02-16: Added transparency alert snapshot endpoint:
  - `GET /transparency/audit-anomalies/alerts.json`
  - `GET /transparency/audit-anomalies/alerts.csv`

## Ops Digest Artifact (Internal Automation)

Daily digest writes a machine-readable artifact JSON file:
- Path: `OPS_DAILY_DIGEST_JSON_FILE` (default `/home/vets-coin/logs/ops_daily_digest_latest.json`)
- Top-level schema/version marker:
  - `artifact_schema_version` (int)

Relevant path for resolved verification fields:
- `snapshot.link_diff.resolved_verification`

Resolved verification sub-object fields:
- `resolved_verify_schema_version` (int; resolved-verification sub-schema marker)
- `available` (bool)
- `window_hours` (int)
- `checked_total` (int)
- `reopened_total` (int)
- `passed_total` (int)
- `skipped_total` (int)
- `resolved_verify_events_count` (int; count of `resolved_verify_*` events within the digest window)
- `skip_reason_counts` (object: `no_url`, `cooldown`, `other`)
- `top_skip_no_url_issue_ids` (array of `{issue_id, count}`)
- `top_skip_no_url_urls` (array of `{url, count}`)
- `top_skip_cooldown_issue_ids` (array of `{issue_id, count}`)
- `resolved_verify_skip_telemetry_available` (bool)
- `status_family_counts` (object: `2xx`, `4xx`, `5xx`, `timeout`, `other`)
- `top_reopened_urls` (array of rows)
- `pass_rate_pct` (float or null)
- `previous_pass_rate_pct` (float or null)
- `pass_rate_delta_pp` (float or null)
- `pass_rate_trend` (`up|down|flat|n/a`)
- `pass_rate_trend_symbol` (`^|v|=|n/a`)
- `has_previous_snapshot` (bool)
- `previous_checked_total` (int or null)
- `previous_reopened_total` (int or null)
- `previous_passed_total` (int or null)
- `checked_delta` (int or null)
- `reopened_delta` (int or null)
- `passed_delta` (int or null)
- `skipped_delta` (int or null)
- `compare_status` (`improving|regressing|flat|n/a`)
- `compare_schema_compatible` (bool)
- `compare_deltas_suppressed` (bool)
- `compare_suppressed_reason` (string)
- `previous_artifact_generated_at_utc` (UTC timestamp or empty string)
- `passed_to_reopened_ratio` (float or null)
- `previous_passed_to_reopened_ratio` (float or null)
- `passed_to_reopened_ratio_delta` (float or null)
- `checks_per_hour` (float)
- `min_sample` (int)
- `confidence_low` (bool)
- `pass_rate_sla_min_pct` (float)
- `pass_rate_sla_breach` (bool)
- `pass_rate_history_points` (array of `{generated_at_utc, checked_total, pass_rate_pct}`)
- `pass_rate_sparkline` (ASCII sparkline)
- `compare_mode` (`previous|median_7d`)
- `compare_mode_provenance` (`from_previous_artifact|from_median_history`)
- `compare_reference_label` (string)
- `compare_reference_pass_rate_pct` (float or null)
- `compare_reference_points` (int)
- `compare_reference_available` (bool)
- `compare_reference_oldest_point_at_utc` (UTC timestamp or empty string)
- `compare_reference_latest_point_at_utc` (UTC timestamp or empty string)
- `compare_reference_sparse_baseline` (bool)
- `compare_reference_sparse_min_points` (int)
- `carry_forward_warning` (bool)
- `carry_forward_reason` (string)
- `carry_forward_previous_artifact_at_utc` (UTC timestamp or empty string)
- `first_event_at` (UTC timestamp or empty string)
- `last_event_at` (UTC timestamp or empty string)
- `last_event_age_hours` (float or null)
- `status_family_delta_share_pp` (object of per-family percentage-point deltas vs previous artifact)
- `reopened_owner_heatmap_7d` (array of `{owner, reopened_total}`)
- `resolved_verify_event_link` (admin event-log drill-down URL for the current digest window)
- `resolved_verify_feature_flags` (machine-safe feature map for downstream parsers)
- `reopened_weekly_counts` (array of 7 daily counts, oldest->newest)
- `reopened_weekly_median` (float)
- `reopened_daily_equiv` (float)
- `reopened_spike_min` (int)
- `reopened_spike_flag` (bool)
- `stream_restart_detected` (bool)
- `stream_restart_reason` (string)
- `stream_restart_prev_last_event_at` (UTC timestamp or empty string)
- `stream_restart_curr_last_event_at` (UTC timestamp or empty string)
- `stream_restart_prev_events_scanned` (int or null)
- `stream_restart_curr_events_scanned` (int or null)
- `stream_restart_events_scanned_drop_flag` (bool)
- `events_scanned_delta` (int or null)
- `events_scanned_drop_ratio_pct` (float)
- `events_scanned_drop_threshold_pct` (float)
- `stream_restart_repeat_count_7d` (int)
- `stream_restart_repeat_window_runs` (int)
- `stream_restart_repeat_threshold` (int)
- `reopened_owner_counts` (object of assignee -> count)
- `reopened_owner_primary_counts` (object of owner.primary -> count)
- `top_reopen_owners` (array of `{assignee, count}`)
- `top_reopened_owner_hints` (array of `{issue_id, owner_primary, url}`)
- `reopened_with_owner_count` (int)
- `reopened_with_owner_pct` (float)
- `top_owner_regression_owner` (string)
- `top_owner_regression_delta` (int)
- `status_family_deltas` (object: `2xx`, `4xx`, `5xx`, `timeout`, `other`; values are int deltas or null)
- `family_5xx_share_pct` (float)
- `family_5xx_share_max_pct` (float)
- `family_5xx_share_breach` (bool)
- `family_timeout_share_pct` (float)
- `family_timeout_share_max_pct` (float)
- `family_timeout_share_breach` (bool)
- `downtime_window_utc` (string; `HH-HH` or empty)
- `zero_streak_warn_suppressed` (bool)
- `zero_streak_reset` (bool)
- `zero_streak_previous_days` (int)
- `previous_artifact_age_hours` (float or null)
- `trend_confidence` (`low|medium|high`)
- `trend_confidence_reason` (string)
- `error_family_counts` (object: `dns_tls`, `connect`, `read`, `timeout`, `other`)
- `error_family_share_pct` (object: percent share per error family)
- `confidence_score` (float `0..100`)
- `confidence_band` (`low|medium|high`)
- `confidence_sample_ratio_pct` (float)
- `confidence_stability_ratio_pct` (float)
- `confidence_skip_quality_ratio_pct` (float)
- `confidence_skip_share_pct` (float)
- `confidence_min` (float; configured warn floor)
- `confidence_history_points` (array of `{generated_at_utc, confidence_score}`)
- `confidence_score_sparkline` (ASCII sparkline)
- `zero_checked_streak_days` (int)

## Admin Ops Resolved-Verify Read Model

Internal admin endpoints for dashboard/triage automation:
- `GET /admin/ops/link-inbox/events/export.json`
- `GET /admin/ops/link-inbox/events/export.csv`
  - `GET /admin/ops/link-inbox/events/export-download.csv` (short-lived signed token mode)
  - Query:
    - `hours` (default `24`)
    - `limit` (default `500`)
    - `event_prefix` (default `resolved_verify_`)
    - `event` (repeatable or CSV list; supports aliases `ok`, `reopened`, `skip`, `triage`)
    - `skip_reason` (repeatable or CSV list; `no_url|cooldown|other`)
    - `status_code_family` (repeatable or CSV list; `2xx|4xx|5xx|timeout|other`)
    - `issue_id` (exact match)
    - `url_contains` (substring match, case-insensitive)
    - `at_from` / `at_to` (UTC timestamp; `YYYY-MM-DDTHH:MM:SSZ`)
    - `window_preset` (`last_digest_warn|last_outage`; ignored when `at_from`/`at_to` are explicitly provided)
    - `fields` (JSON export only; repeatable or CSV list from `at,event,issue_id,url,status_code,skip_reason,to_status,assignee,user_id,error`)
    - `count_only` (`0|1`; JSON export only; when `1`, returns counts/metadata with `events=[]`)
    - `include_triage` (`0|1`, default `0`)
    - `compress` (`0|1`; when `1`, returns `application/gzip` as `link_inbox_events.csv.gz`)
    - `checksum` (`0|1`; CSV/GZIP exports only; when `1`, response includes `X-Export-SHA256`)
    - `one_time` (`0|1`; token mint only; when `1`, token replay is blocked after first successful download)
    - `download_token`:
      - `1` on `/export.csv` returns signed URL metadata JSON
      - signed token value on `/export-download.csv` returns CSV/GZIP payload
    - `debug` (`0|1`; CSV export only; when `1`, includes preset-resolution debug comment lines)
  - export metadata fields:
    - `requested_limit`, `max_rows`, `effective_limit`, `total_filtered`, `returned_count`, `truncated`
    - `window_preset`, `window_preset_applied`, `window_preset_reason`
- `GET /admin/ops/link-inbox/events/export-telemetry.json`
  - Query:
    - `hours` (default `24`)
    - `limit` (default `200`, max `2000`)
    - `source` (`all|export|token`)
    - `requested_by` (`all` default, or specific requester tag such as `ops_primary`)
  - Returns recent `event_logs` telemetry rows for:
    - `ops_link_inbox_events_export`
    - `ops_link_inbox_export_token_request`
  - Includes summary counters:
    - `event_type_counts`, `outcome_counts`, `mode_counts`, `window_preset_counts`, `requested_by_counts`
    - `token_failure_counts` (`secret_missing`, `decode_error`, `expired`, `replay`)
  - Includes selected filter echo:
    - `requested_by_filter`
- `POST /admin/ops/link-inbox/events/export-checksum/verify.json`
  - Admin helper endpoint for uploaded evidence bundles (`multipart/form-data` file field `bundle` or `file`).
  - Returns SHA-256 for raw upload plus optional gunzip hash/preview when payload is GZIP.
  - Optional `expected_sha256` compares expected checksum against raw and gunzip variants.
- `POST /admin/ops/link-inbox/triage/bulk-no-url`
  - Bulk no-url triage helper for remediation waves.
  - Applies status/assignee updates to matching `resolved_verify_result=no_url` issues and records remediation metadata note tags.
- Responder helper:
  - TTL mode:
    - `python3 /home/vets-coin/flask_api/scripts/generate_link_inbox_export_download_url.py --ttl-seconds 900 --audit-note \"INC-123 export\" --incident-id \"INC-123\" --window-preset last_outage --one-time --verify-token --print-curl --format shell`
  - Absolute-expiry mode:
    - `python3 /home/vets-coin/flask_api/scripts/generate_link_inbox_export_download_url.py --expires-at-utc 2026-02-22T01:30:00Z --audit-note \"INC-123 export\" --incident-id \"INC-123\" --window-preset last_outage --one-time --max-rows 1000 --verify-token --format shell`
  - Generates signed `/admin/ops/link-inbox/events/export-download.csv?download_token=...` URL with audit metadata in token payload.
- `GET /admin/ops/digest/resolved-verification.json`
  - Returns latest artifact-derived resolved verification summary, relevant warn reasons, and triage links.
  - Includes cache headers (`ETag`, `Last-Modified`, `Cache-Control`) and supports conditional `304`.
  - Includes:
    - `warn` (bool, true when any resolved-verify warn reasons are active)
    - `summary.compare_status`
    - `summary.resolved_verify_events_count` (normalized contract field)
    - `summary.skip_no_url_trend_sparkline_7d` / `summary.skip_no_url_share_trend_sparkline_7d`
    - `links.resolved_verify_event_link` (direct `/admin/event-logs` drill-down link)
- `GET /admin/ops/link-inbox/verification-summary.json`
  - Returns latest resolved-verification summary block from ops digest artifact for link-inbox workflows.
  - Includes:
    - `summary` (compact normalized metrics/status)
    - `resolved_verification` (full sub-object passthrough)
    - `links.reopened_only_compare`
    - `links.skip_reopened_events`
    - `links.resolved_verify_event_link`

## Authentication (Partner HMAC)

Headers:
- X-Partner-Key: key_id
- X-Partner-Timestamp: unix epoch seconds
- X-Partner-Signature: hex hmac_sha256(secret, "{ts}.{method}.{path}.{body}")
- X-Partner-Nonce: replay-protection nonce (required by default for mutation endpoints)
- Idempotency-Key: idempotency key (required by default for mutation endpoints)

Notes:
- `path` excludes query string (e.g. `/api/salutes/balance`)
- `body` is canonical JSON (sorted keys, no whitespace). Empty body is `""`.
- Timestamp window: ±5 minutes.
- Optional rate limit via `PARTNER_RATE_LIMIT_PER_MINUTE`.
- Partner key allowlists (`allowed_ips`) support exact IPs and CIDR blocks (comma-separated).
- Sandbox keys (admin flag) are forced to a lower rate limit:
  - `PARTNER_SANDBOX_RATE_LIMIT_PER_MINUTE` (default 30)
- Scopes are stored per key (CSV). Common scopes: `read`, `credit`, `debit`, `ledger`, `donation`, `users`, `webhooks`.
- Responses include `X-Request-ID` for trace correlation.

OpenAPI:
- `GET /api/openapi.yaml`
- `GET /api/openapi-transparency.yaml` (public transparency supplement)

Generated SDK starters:
- `GET /developers/sdk/manifest.json`
- `GET /developers/sdk/manifest.sig` (manifest signature envelope)
- `GET /developers/sdk/python-starter.zip`
- `GET /developers/sdk/typescript-starter.zip`
- `manifest.json` includes `version` + `version_source` for build provenance.

OpenAPI changelog:
- `GET /developers/openapi-changelog.md`
- `GET /developers/openapi-changelog.json`
- `GET /developers/openapi-changelog.rss`
- `GET /developers/openapi-changelog.atom`

API deprecation migration artifacts:
- `GET /developers/deprecations.json`
- `GET /developers/deprecations-playbook.md`

Regenerate deprecation migration playbook:
```bash
python3 /home/vets-coin/flask_api/scripts/generate_api_deprecation_playbook.py \
  --config /home/vets-coin/flask_api/config/api_deprecations.json \
  --out-md /home/vets-coin/flask_api/docs/deprecations/migration_playbook.md
```

Regenerate SDK starters from OpenAPI:
```bash
python3 /home/vets-coin/flask_api/scripts/generate_sdk_starters.py \
  --spec /home/vets-coin/flask_api/docs/openapi.yaml \
  --spec /home/vets-coin/flask_api/docs/openapi-transparency.yaml \
  --out-dir /home/vets-coin/flask_api/docs/sdk
```
Version stamping priority:
- `--version` CLI flag
- `SDK_VERSION` / `APP_RELEASE_VERSION` / `RELEASE_VERSION` / `APP_VERSION_TAG`
- `APP_GIT_SHA` / `VETS_GIT_SHA`
- fallback: `0.1.0-dev`

OpenAPI lint + breaking-change check:
```bash
python3 /home/vets-coin/flask_api/scripts/check_openapi_contracts.py \
  --spec /home/vets-coin/flask_api/docs/openapi.yaml \
  --spec /home/vets-coin/flask_api/docs/openapi-transparency.yaml \
  --baseline-dir /home/vets-coin/flask_api/docs/openapi/baseline
```
Lint policy:
- missing `operationId` is a lint error by default
- override for temporary migration only: `--allow-missing-operation-id`

Generate OpenAPI changelog artifacts:
```bash
python3 /home/vets-coin/flask_api/scripts/generate_openapi_changelog.py \
  --spec /home/vets-coin/flask_api/docs/openapi.yaml \
  --spec /home/vets-coin/flask_api/docs/openapi-transparency.yaml \
  --baseline-dir /home/vets-coin/flask_api/docs/openapi/baseline \
  --out-md /home/vets-coin/flask_api/docs/openapi/changelog/latest.md \
  --out-json /home/vets-coin/flask_api/docs/openapi/changelog/latest.json
```

## Quickstart (Partner)

1. Ask an admin to create a Partner Key in the admin UI.
2. Use the key to call `GET /api/partner/capabilities` to verify HMAC auth, scopes, and time sync.

Recommended: use the signing helper script (never hardcode secrets into source control):
```bash
python3 /home/vets-coin/flask_api/scripts/sign_partner_request.py \
  --method GET \
  --path /api/partner/capabilities \
  --key-id CHANGE_ME_KEY_ID \
  --secret CHANGE_ME_SECRET
```

Raw `curl` example (placeholders are literal; replace them):
```bash
TS="$(date +%s)"
METHOD="GET"
PATH="/api/partner/capabilities"
BODY=""  # empty for GET

# SIGNATURE = hex(hmac_sha256(SECRET, "{ts}.{method}.{path}.{body}"))
curl -sS -D - \
  -H "X-Partner-Key: CHANGE_ME_KEY_ID" \
  -H "X-Partner-Timestamp: ${TS}" \
  -H "X-Partner-Signature: CHANGE_ME_SIGNATURE" \
  -H "X-Partner-Nonce: $(uuidgen | tr '[:upper:]' '[:lower:]')" \
  "https://vets-coin.com${PATH}"
```

Note:
- `https://vets-coin.com` is the current canonical base URL.
- `https://api.vets-coin.com` is planned, but do not use it until the TLS certificate explicitly includes that subdomain.

## Error Responses (Partner)

Partner endpoints generally return:
```json
{"success":false,"error":"unauthorized"}
```

Common error values:
- `unauthorized` (HTTP 401): missing/invalid HMAC headers, stale timestamp, unknown key, IP not allowed, nonce required/invalid
- `forbidden` (HTTP 403): valid key but missing scope
- `rate_limited` (HTTP 429): request rate exceeded
- `replay_detected` (HTTP 409): nonce replay detected (send a fresh `X-Partner-Nonce`)
- `idempotency_required` (HTTP 400): mutation endpoint called without `Idempotency-Key`
- `idempotency_invalid` (HTTP 400): malformed `Idempotency-Key`
- `idempotency_replay` (HTTP 409): duplicate `Idempotency-Key` for the same partner key

## Partner capabilities (HMAC)

### GET /api/partner/capabilities
Returns allowed scopes and a list of partner-relevant endpoints.

Caching:
- Supports `ETag` / `If-None-Match`.
- Supports `Last-Modified` / `If-Modified-Since`.
- Returns `304 Not Modified` when validators match.

Response:
```json
{"success":true,"partner":"PartnerCo","key_id":"...","scopes":["read","credit"],"endpoints":[...]}
```

Helper script:
`python3 /home/vets-coin/flask_api/scripts/sign_partner_request.py --method POST --path /api/salutes/credit --key-id CHANGE_ME_KEY_ID --secret CHANGE_ME_SECRET --json '{"user_id":"4","amount":100}'`

## Salutes API (Partner)

### POST /api/salutes/credit
Credits Salutes to a user.

Body:
```json
{"user_id":"4","amount":100,"reason":"event_participation","source":"patriotchat"}
```

Response:
```json
{"success":true,"user_id":"4","balance":100}
```

### POST /api/salutes/debit
Debits Salutes from a user.

Body:
```json
{"user_id":"4","amount":25,"reason":"content_boost","source":"patriotchat"}
```

Response:
```json
{"success":true,"user_id":"4","balance":75}
```

### GET /api/salutes/balance?user_id=4
Returns current balance.

Response:
```json
{"success":true,"user_id":"4","balance":75}
```

### GET /api/salutes/ledger?user_id=4
Admin-only JSON ledger (requires admin session) or partner access with `ledger` scope.
Partner access returns entries filtered to the partner's key.

Response:
```json
{"success":true,"user_id":"4","balance":75,"ledger":[...]}
```

## Partner Identity API (HMAC)

### GET /api/partner/user-lookup?email=...&username=...&wallet=...
Lookup a user by email, username, or wallet. Returns a minimal profile for mapping to `user_id`.

Optional query params:
- `q` legacy alias (deprecated; sunset target `2026-06-30T00:00:00Z`)
- `include_wallets=1` to include known wallets
- `cursor=<last_seen_user_id>` for write-resilient paging
- `limit` (max 50)
- `offset` (legacy paging)
- invalid cursor values return `400 {"error_code":"invalid_cursor"}`.

Response:
```json
{"success":true,"count":1,"users":[{"id":4,"username":"mark","display_name":"Mark","status":"active","is_verified":true,"wallet_address":"...","wallets":[...]}]}
```

### GET /api/partner/users
List users linked to the current partner key.

Optional query params:
- `status=active|suspended|banned|pending`
- `q=<search text>` (username/display name/email/external_id)
- `include_wallets=1`
- `cursor=<last_seen_user_id>`
- `limit` / `offset`
- invalid cursor values return `400 {"error_code":"invalid_cursor"}`.

### GET /api/partner/wallet-info/<wallet>
Returns SOL + VETS balances for a wallet (HMAC required, no session lock).

Response:
```json
{"success":true,"wallet":"...","sol_balance":1.23,"vets_balance":456.0,"lp_mint":null,"lp_amount":null}
```

## Partner Donation Claims (HMAC)

### POST /api/partner/donation-claim
Partner-authenticated version of the donation webhook (issues a faucet claim if enabled).

Body:
```json
{"campaign_id":"spring_drive","amount":50,"email":"donor@example.com","wallet_address":"...","faucet_campaign_id":"12"}
```

Response:
```json
{"status":"success","claim_code":"...","claim_url":"...","email_sent":true,"claim_status":"issued","claim_campaign_id":"12","partner_key_id":"..."}
```

## Partner User Provisioning (HMAC)

### POST /api/partner/users
Create or link a user to an external ID.

Body:
```json
{"external_id":"patriotchat-123","email":"user@example.com","display_name":"Jane","wallet_address":"...","link_existing":true}
```

Response:
```json
{"success":true,"user":{"id":12,"username":"...","status":"active"},"external_id":"patriotchat-123"}
```

### GET /api/partner/users/<id>
Fetch a user owned by this partner. Use `include_wallets=1` to include known wallets.

### PATCH /api/partner/users/<id>
Update display name or status.

Body:
```json
{"display_name":"New Name","status":"active"}
```

### POST /api/partner/users/<id>/wallets
Link a wallet to a partner-owned user.

Body:
```json
{"wallet_address":"...","label":"Primary","is_primary":true}
```

## Partner Webhooks (HMAC)

### GET /api/partner/webhooks
List current webhooks.

### POST /api/partner/webhooks
Create a webhook for an event type.

Body:
```json
{"event_type":"salutes.credit","target_url":"https://partner.example.com/webhooks/vets","secret":"optional"}
```

### DELETE /api/partner/webhooks/<id>
Disable a webhook.

### POST /api/partner/webhooks/<id>/test
Queue a test event to the webhook.

Webhook headers:
- `X-Webhook-Event`
- `X-Webhook-Timestamp`
- `X-Webhook-Signature` (HMAC SHA256 of `{ts}.{body}`)
- `X-Webhook-Id`

Webhook payload:
```json
{"event_id":"123","event_type":"salutes.credit","data":{...}}
```

Retry processing:
```
python3 /home/vets-coin/flask_api/scripts/process_partner_webhooks.py
```

Admin delivery ops (admin session required):
- `POST /admin/partners/webhook-events/<event_id>/replay`
- `GET /admin/partners/webhook-events/export?webhook_status=&webhook_key=&limit=`

### GET /api/partner/analytics/usage
Per-key usage analytics snapshot (requests, errors, optional latency percentiles, webhook delivery health).

Query params:
- `hours` (default `24`, max `720`)

### GET /api/partner/webhook-events
Partner-facing webhook event feed with status/range filters for replay workflows.

Query params:
- `status=all|pending|failed|delivered|dead_letter`
- `reason_tag=<string>`
- `from=<ISO8601 UTC>`
- `to=<ISO8601 UTC>`
- `webhook_id=<id>`
- `limit`, `offset`, `cursor`

### POST /api/partner/webhook-events/replay
Batch replay webhook events by id (requires `Idempotency-Key`).

Body:
```json
{"event_ids":[101,102,103],"reason_tag":"receiver_fix","note":"receiver deployed fix"}
```

### POST /api/partner/webhooks/signature/verify
Webhook signature verification test endpoint for partner receiver debugging.

Body:
```json
{"secret":"...","timestamp":"1700000000","payload":{"event_id":"123","event_type":"salutes.credit","data":{}},"signature":"<hex>"}
```

### GET /api/partner/webhooks/dlq
Dead-letter queue summary with reason-tag rollups and remediation playbook links.

### GET /api/partner/status
Partner status summary with endpoint percentile snapshot, webhook DLQ health, and incident-impact hints.

### GET /api/salutes/conversion-policy
Returns the active conversion policy settings (fixed rate, caps, enablement).

Response:
```json
{"success":true,"salutes_per_vets":1000000,"daily_cap_salutes":1000000,"monthly_cap_salutes":10000000,"conversion_enabled":false,"redemption_enabled":false,"mode":"fixed"}
```

### POST /api/salutes/convert
Placeholder for Salute -> VETS conversion. Returns `conversion_disabled` or `redemption_disabled` unless enabled.

## Transparency Exports (Public, Read-Only)

These endpoints do not require partner HMAC auth. They are intended for transparency dashboards, reporting, and external reconciliation.

### GET /transparency/audit-anomalies
Human-readable anomalies page with filters.

Query params:
- `run`: `latest` (default) or historical run token like `20260215T113203Z`
- `severity`: `bad` or `warn`
- `signature`: substring match
- `types`: substring match on anomaly types
- `min_abs_delta`: minimum absolute delta threshold
- `limit`: max rows (25-2000)

### GET /transparency/audit-anomalies/export
Downloads filtered anomalies as CSV.
Supports the same query params as `/transparency/audit-anomalies`, including `run`.

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/export?severity=bad&min_abs_delta=1000&limit=100" -o audit_anomalies.csv
```

### GET /transparency/audit-anomalies/export.json
Returns filtered anomalies as JSON.
Supports the same query params as `/transparency/audit-anomalies`, including `run`.

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/export.json?severity=bad&limit=50"
```

Response:
```json
{"success":true,"filters":{"severity":"bad","types":"","signature":"","min_abs_delta":0.0,"limit":50},"count":1,"rows":[...]}
```

### GET /transparency/audit-anomalies/diff/export
Downloads selected historical run vs latest run anomaly-type deltas as CSV.

Query params:
- `run`: required historical run token (example: `20260215T113203Z`)

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/diff/export?run=20260215T113203Z" -o audit_anomaly_type_diff.csv
```

If `run` is missing or resolves to `latest`, returns `400`.

CSV columns:
- `type`
- `selected`
- `latest`
- `delta`
- `pct_delta_percent`

CSV files include leading `#` metadata lines (selected run + generation metadata).

### GET /transparency/audit-anomalies/diff/export.json
Returns selected historical run vs latest run anomaly-type deltas as JSON.

Query params:
- `run`: required historical run token (example: `20260215T113203Z`)
- `include_rows`: optional (`true|false`, default false). When true, includes selected/latest row context arrays.
- `row_limit`: optional context row cap (default 100, max 250)

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/diff/export.json?run=20260215T113203Z"
```

Response:
```json
{"success":true,"selected_run":"20260215T113203Z","selected_label":"2026-02-15 11:32 UTC","latest_generated_at":"2026-02-16T07:00:00Z","selected_total":12,"latest_total":8,"total_delta":4,"count":3,"rows":[...]}
```

### GET /transparency/audit-anomalies/diff/compare.json
Returns anomaly-type deltas between any two run selectors.

Query params:
- `run_a`: required (`latest` or historical token like `20260215T113203Z`)
- `run_b`: required (`latest` or historical token like `20260214T100000Z`)
- `include_rows`: optional (`true|false`, default false). When true, includes run A/B row context arrays.
- `row_limit`: optional context row cap (default 100, max 250)

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/diff/compare.json?run_a=20260215T113203Z&run_b=latest"
```

### GET /transparency/audit-anomalies/diff/compare.csv
Downloads anomaly-type deltas between any two run selectors as CSV.

Query params:
- `run_a`: required (`latest` or historical token like `20260215T113203Z`)
- `run_b`: required (`latest` or historical token like `20260214T100000Z`)
- `include_rows`: optional (`true|false`, default false). When true, appends context row sections.
- `row_limit`: optional context row cap (default 100, max 250)

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/diff/compare.csv?run_a=20260215T113203Z&run_b=latest" -o audit_anomaly_compare.csv
```

CSV files include leading `#` metadata lines (run labels + generated-at).

### GET /transparency/audit-anomalies/summary.json
Returns the selected run summary payload and optional selected-vs-latest comparison metadata.

Query params:
- `run`: optional run selector (`latest` default)
- `include_top_anomalies`: optional (`true|false`, default false)
- `top_limit`: optional (default 10, max 50; only used when `include_top_anomalies=true`)

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/summary.json?run=20260215T113203Z"
```

### GET /transparency/audit-anomalies/runs.json
Returns available anomaly run options (latest + historical), selection state, and completeness flags.

Query params:
- `run`: optional run selector (`latest` default); invalid values return latest with `selection_warning`.

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/runs.json"
```

### GET /transparency/audit-anomalies/trend.json
Returns trend points used by the anomalies run-trend UI.

Query params:
- `run`: optional selected run (`latest` default)
- `metric`: optional `sigs` (default) or `rows`
- `include_status_counts`: optional (`true|false`, default false), returns aggregated `ok/warn/bad/other` counts
- supports filter params for generated `href` links:
  - `severity`, `signature`, `types`, `min_abs_delta`, `limit`

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/trend.json?severity=bad&limit=100"
```

### GET /transparency/audit-anomalies/alerts.json
Returns threshold-evaluated alert snapshot for a selected run (or latest).

Query params:
- `run`: optional selected run (`latest` default)
- `sigs_increase_threshold_pct`: optional percent threshold for signature spikes (default env-backed, 50)
- `rows_increase_threshold_pct`: optional percent threshold for row spikes (default env-backed, 50)
- `include_recommendations`: optional (`true|false`, default true)

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/alerts.json?sigs_increase_threshold_pct=50&rows_increase_threshold_pct=50"
```

Response:
```json
{"success":true,"selected_run":"latest","snapshot":{"alert_level":"warn","should_alert":true,"alerts":[...]}}
```

### GET /transparency/audit-anomalies/alerts.csv
Returns a one-row CSV snapshot for spreadsheet workflows, including:
- current alert level and boolean `should_alert`
- current/baseline run ids
- current run delta values
- configured threshold values
- emitted alert codes and messages

Example:
```bash
curl -sS "https://vets-coin.com/transparency/audit-anomalies/alerts.csv" -o audit_anomaly_alerts.csv
```

## Wallet API (App)

### GET /wallet-connect/<wallet>
Links a wallet to a user session; creates user if needed.

### GET /api/wallet-info/<wallet>
Returns live SOL + VETS balances (RPC).

### GET /api/wallet-proof/challenge?wallet=...
Returns a signed-message challenge for wallet verification (login required).

### POST /api/wallet-proof/verify
Verifies signed challenge and marks wallet as verified (login required).

### POST /api/log
Client event logger (records to event_logs).

Body:
```json
{"wallet_address":"...","event_type":"wallet_connected","details":"phantom"}
```

## Public Stats

### GET /api/public-stats
Returns token stats. Uses on-chain supply/treasury and DB fallbacks for volume.

Response:
```json
{"success":true,"stats":{"total_supply":...,"circulating_supply":...,"holders":...,"volume_24h":...}}
```
Rate limit: `RATE_LIMIT_PUBLIC_API_PER_MIN`

### GET /api/public/system-status
Returns a public readiness snapshot for core API health, audit freshness, alert-monitor freshness, and automation jobs.

Response:
```json
{"success":true,"status":{"generated_at":"...","overall":"ok","checks":{"api":{},"audit_anomalies":{},"alert_monitor":{},"ops_jobs":{"jobs":[]}}}}
```
Rate limit: `RATE_LIMIT_PUBLIC_API_PER_MIN`

Alias:
- `GET /status.json` (same payload, same rate limit)

### GET /api/public/system-status/trend?limit=144
Returns rolling status history from server-side snapshot persistence (JSONL file).

Response:
```json
{"success":true,"limit":144,"count":144,"counts":{"ok":120,"warn":24,"bad":0,"other":0},"points":[...]}
```
Notes:
- `limit` optional, clamped to `10..1000`.
- History source defaults to `/home/vets-coin/logs/status_history.jsonl`.

### GET /api/public/system-status/incidents?hours=168&limit=30
Returns incident windows derived from status history points.

Response:
```json
{"success":true,"hours":168,"limit":30,"points_considered":240,"counts":{"total":2,"active":0,"resolved":2,"bad":1,"warn":1},"incidents":[...]}
```
Notes:
- `hours` optional, clamped to `1..4320` (180 days).
- `limit` optional, clamped to `1..200`.
- Incident rows include `started_at`, `resolved_at`, `duration_seconds`, `level`, and `affected_checks`.

### GET /api/public/system-status/incidents.rss?hours=168&limit=30
RSS feed companion for incident windows, intended for external subscribers and status inbox rules.

Notes:
- Uses the same `hours`, `limit`, and maintenance filters as JSON incidents endpoint.
- Feed item description includes duration + affected checks.

### GET /api/public/system-status/uptime?hours=168
Returns windowed uptime percentages for overall status and each core check.

Response:
```json
{"success":true,"allowed_hours":[24,168,720],"selected_hours":168,"point_count":240,"overall":{"ok_pct":99.1,"warn_pct":0.9,"bad_pct":0.0,"degraded_pct":0.9},"checks":{"api":{},"audit_anomalies":{},"alert_monitor":{},"ops_jobs":{}}}
```
Notes:
- `hours` supports `24`, `168`, or `720` (default `168`).
- `degraded_pct` is `warn + bad`.

### GET /api/public/release-manifest
Returns a signed release manifest containing deploy metadata, checksum entries, and migration-note snippets.

Response:
```json
{"success":true,"manifest":{"source":"public_release_manifest.v1","version":"...","deploy_utc":"...","entries":[{"name":"openapi.yaml","sha256":"...","bytes":12345}],"migration_notes":["..."],"signature_alg":"hmac-sha256","signature":"..."}}
```
Notes:
- Alias: `GET /api/public/release-manifest.json`
- Signature companion: `GET /api/public/release-manifest.sig`

### GET /api/public/data-retention
Returns the public retention matrix (data class, storage, retention window, purpose, delete path).

Response:
```json
{"success":true,"retention":{"generated_at":"...","count":11,"rows":[{"data":"Partner request logs","storage":"MySQL: partner_request_logs","retention":"90 day rolling window","purpose":"...","delete_path":"..."}]}}
```
Notes:
- HTML companion page: `GET /data-retention`

### GET /api/public/latency-percentiles?hours=24
Returns public smoke latency percentiles (`p50/p95/p99`) per endpoint.

Response:
```json
{"success":true,"latency":{"window_hours":24,"endpoint_count":20,"endpoints":[{"endpoint":"/status","sample_count":30,"error_rate_pct":0.0,"p50_ms":180.0,"p95_ms":410.0,"p99_ms":620.0}]}}
```
Notes:
- Alias: `GET /api/public/latency-percentiles.json`
- `hours` supports `24`, `168`, or `720` (default `24`).

### GET /api/public/latency-percentiles.rss?hours=24
Returns RSS outlier feed for endpoints currently at `warn`/`bad` percentile/error-rate levels.

Notes:
- Uses same `hours` window semantics as JSON percentile endpoint.
- Emits only warn/bad rows, sorted by severity + `p95`.

### GET /api/public/status-feeds.json
Returns machine-readable feed index for status incidents, anomaly alerts, changelog, and latency feeds.

Response:
```json
{"success":true,"count":6,"health_url":"https://vets-coin.com/api/public/status-feeds/health.json","feeds":[{"name":"system_status_incidents_rss","url":"https://vets-coin.com/api/public/system-status/incidents.rss","content_type":"application/rss+xml","etag":"a1b2c3d4e5f6","cache_ttl_seconds":120,"recommended_poll_seconds":300}]}
```
Notes:
- Each feed row includes subscriber tuning metadata:
  - `etag`
  - `cache_ttl_seconds`
  - `recommended_poll_seconds`
- Supports HTTP `If-None-Match` with `ETag` response header.

### GET /api/public/status-feeds/health.json
Returns per-feed last-build telemetry (freshness + generation lag).

Response:
```json
{"success":true,"count":6,"counts":{"ok":6,"warn":0,"bad":0},"status_feeds_url":"https://vets-coin.com/api/public/status-feeds.json","feeds":[{"name":"system_status_incidents_rss","last_build_utc":"2026-03-07T00:12:00Z","generation_lag_seconds":180,"freshness_status":"ok","stale_after_seconds":21600}]}
```
Notes:
- Designed for machine polling/alerting around stale feed artifacts.
- Supports HTTP `If-None-Match` with `ETag` response header.

### GET /api/public/status-feeds/health.csv
Returns spreadsheet-friendly CSV companion for feed-health telemetry.

Notes:
- Mirrors the same feed-health fields as JSON endpoint.
- Useful for SOC/operator dashboards that ingest CSV directly.

### Status Endpoint Quick Map
Use these as the default operator/partner entry points:

| Endpoint | Best use | Default cURL |
|---|---|---|
| `GET /status.json` | Alias for latest public status payload. | `curl -sS "https://vets-coin.com/status.json"` |
| `GET /api/public/system-status` | Top-level readiness snapshot. | `curl -sS "https://vets-coin.com/api/public/system-status"` |
| `GET /api/public/system-status/uptime?hours=168` | 7-day SLO/uptime summary. | `curl -sS "https://vets-coin.com/api/public/system-status/uptime?hours=168"` |
| `GET /api/public/system-status/incidents?hours=168&limit=30` | Last 7 days of incident windows. | `curl -sS "https://vets-coin.com/api/public/system-status/incidents?hours=168&limit=30"` |
| `GET /api/public/system-status/incidents.rss?hours=168&limit=30` | RSS feed for incident subscribers. | `curl -sS "https://vets-coin.com/api/public/system-status/incidents.rss?hours=168&limit=30"` |
| `GET /api/public/latency-percentiles?hours=24` | Endpoint latency percentiles from smoke telemetry. | `curl -sS "https://vets-coin.com/api/public/latency-percentiles?hours=24"` |
| `GET /api/public/latency-percentiles.rss?hours=24` | RSS feed for latency outlier subscribers. | `curl -sS "https://vets-coin.com/api/public/latency-percentiles.rss?hours=24"` |
| `GET /api/public/status-feeds.json` | Feed index with URLs/content-types for machine-readable subscribers. | `curl -sS "https://vets-coin.com/api/public/status-feeds.json"` |
| `GET /api/public/status-feeds/health.json` | Feed freshness/generation-lag telemetry for subscriber alerting. | `curl -sS "https://vets-coin.com/api/public/status-feeds/health.json"` |
| `GET /api/public/status-feeds/health.csv` | CSV companion for feed-health telemetry. | `curl -sS "https://vets-coin.com/api/public/status-feeds/health.csv"` |
| `GET /api/public/release-manifest` | Signed release artifact with checksums and deploy notes. | `curl -sS "https://vets-coin.com/api/public/release-manifest"` |
| `GET /api/public/data-retention` | Public retention policy matrix for operational datasets. | `curl -sS "https://vets-coin.com/api/public/data-retention"` |

### GET /api/transactions?limit=200
Returns recent on-chain transactions from the local index.

Notes:
- `limit` is optional; defaults to `API_TRANSACTIONS_DEFAULT_LIMIT` (200).
- Hard cap at `API_TRANSACTIONS_MAX_LIMIT` (1000).

### GET /api/transactions/latest?limit=50
Returns the most recent on-chain transactions from the local index.

Notes:
- `limit` is optional; defaults to `API_TRANSACTIONS_LATEST_DEFAULT_LIMIT` (50).
- Hard cap at `API_TRANSACTIONS_MAX_LIMIT` (1000).

## Public API Quickstart (Copy/Paste)

Base URL: `https://vets-coin.com`

### Token stats
```
curl -s https://vets-coin.com/api/public-stats
```

### Public system status
```
curl -s https://vets-coin.com/api/public/system-status
```

### Public system status alias
```
curl -s https://vets-coin.com/status.json
```

### Public system status trend
```
curl -s "https://vets-coin.com/api/public/system-status/trend?limit=288"
```

### Public system incidents
```
curl -s "https://vets-coin.com/api/public/system-status/incidents?hours=168&limit=20"
```

### Public uptime summary
```
curl -s "https://vets-coin.com/api/public/system-status/uptime?hours=168"
```

### Latest transactions (limited)
```
curl -s "https://vets-coin.com/api/transactions/latest?limit=50"
```

### Transactions (recent window)
```
curl -s "https://vets-coin.com/api/transactions?limit=200"
```

### Swap URL (Jupiter)
```
curl -s https://vets-coin.com/api/vets/swap-url
```

### Donation claim config
```
curl -s https://vets-coin.com/api/vets/donation-claim
```

### Donation webhook (signed POST)
`POST /webhook/donation` accepts JSON donation payloads. In secure mode, include:
- `X-Webhook-Timestamp`: unix epoch seconds
- `X-Webhook-Signature`: `sha256=<hex>` or raw hex of `HMAC_SHA256("{timestamp}.{raw_body}")`
- `X-Webhook-Nonce` (optional but recommended): unique delivery id for replay detection

Example (signature generation + POST):
```bash
ts="$(date +%s)"
body='{"campaign_id":"demo","amount":10,"email":"donor@example.com","wallet_address":"DemoWallet"}'
sig="$(printf '%s.%s' "$ts" "$body" | openssl dgst -sha256 -hmac "$DONATION_WEBHOOK_SECRET" -hex | awk '{print $2}')"
curl -sS -X POST "https://vets-coin.com/webhook/donation" \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Timestamp: $ts" \
  -H "X-Webhook-Signature: sha256=$sig" \
  -H "X-Webhook-Nonce: demo-$(uuidgen 2>/dev/null || echo nonce)" \
  -d "$body"
```

Auth mode controls:
- `DONATION_WEBHOOK_AUTH_MODE=off`: no signature check.
- `DONATION_WEBHOOK_AUTH_MODE=log`: signature failures are logged (`donation_webhook_auth_warn`) but request continues.
- `DONATION_WEBHOOK_AUTH_MODE=enforce`: missing/invalid/replay signatures are rejected (`401`/`409`) and logged as `donation_webhook_auth_failed`.
- `DONATION_WEBHOOK_SIG_TTL_SECONDS` controls timestamp skew/replay window (default `300`, clamped `60..3600`).

### Wallet balances (SOL + VETS)
```
curl -s https://vets-coin.com/api/wallet-info/<WALLET_ADDRESS>
```

### Client event log (optional)
```
curl -s -X POST https://vets-coin.com/api/log \
  -H "Content-Type: application/json" \
  -d '{"wallet_address":"<WALLET>","event_type":"wallet_connected","details":"phantom"}'
```

## Status Codes (common)
- 200: success
- 400: validation error
- 401: unauthorized (HMAC invalid/missing)
- 403: forbidden (admin-only)
- 409: insufficient balance (debit)
- 429: rate limited
- 503: dependency unavailable (DB/RPC)

## Admin (Session) Endpoints

These require a logged-in admin session (`session.is_admin`):
- `/admin/overview`
- `/admin/users`
- `/admin/users/<id>`
- `/admin/users/export`
- `/admin/wallets`
- `/admin/wallets/export`
- `/admin/partner-usage`
- `/admin/faucet/analytics`
- `/admin/health`
- `/admin/chain/status` (RPC status + supply)
- `/admin/chain/balance?owner=...` (token balance lookup)
- `/admin/chain/transfer-plan` (POST, returns unsigned plan)
- `/admin/helius/check` (quick Helius token-transfers sanity check)
- `/admin/backups` (JSON list of archives)
- `/admin/backups/<filename>` (download)
- `/admin/backups/ui` (UI)
- `/admin/backup/run` (POST; canonical manual backup trigger from admin overview)
- `/admin/partner-keys` (UI create/revoke)
- `/admin/salutes` (UI)
- `/admin/token/distribution` (UI)
- `/admin/token/distribution/refresh` (POST)
- `/admin/token/distribution/export` (CSV)
- `/api/salutes/ledger` (JSON)
- `/admin/audit/export` (CSV)
- `/admin/user-activity/<id>`
- `/admin/faucet/campaigns` (create/list)
- `/admin/faucet/campaigns/<id>` (edit)
- `/admin/faucet/campaigns/<id>/keys` (generate/list)
- `/admin/faucet/claims` (view)
- `/admin/faucet/claims/export` (CSV)
- `/admin/faucet/bans` (add/lift)
- `/admin/faucet/bans/export` (CSV)
- `/admin/faucet/transfer-plan` (POST, build unsigned transfer plan)
- `/admin/ops/incidents` (UI timeline)
- `/admin/ops/incidents/export` (CSV)
- `/admin/ops/incidents/export.json` (JSON)
- `/admin/ops/incidents/detail.json` (JSON row drilldown + neighbors)
- `/admin/ops/incidents/draft.json` (JSON incident draft payload for automation)
- `/admin/ops/incidents/draft.md` (Markdown incident draft generated from `draft.json` payload; supports `template=v1|minimal`)
- `/admin/ops/incidents/draft.txt` (Plain-text incident draft generated from `draft.json` payload; supports `template=v1|minimal`)
  - shared filters: `hours`, `limit`, `source`, `severity` (`warn|warning|bad|failed|fail|error`), `since`, `until`
  - `since` / `until` format: UTC `YYYY-MM-DDTHH:MM:SSZ`
- `/admin/ops/readiness/403-noise/export.json` (JSON denied/probe/noise trend windows; includes top-level `summary_by_window`; supports `compact=1` summary-only mode and `include_windows_meta=1` for compact metadata rows)
- `/admin/ops/readiness/403-noise/export.csv` (CSV denied/probe/noise trend windows with suppression metadata; supports `mode=detail|summary` and `include_points=1` in summary mode)
- `/admin/ops/alerts-monitor` (UI)
- `/admin/ops/alerts-monitor/export` (CSV)
- `/admin/ops/alerts-monitor/export.json` (JSON, includes retention + `recent_runs`)
- `/admin/ops/alerts-monitor/export.zip` (ZIP bundle with CSV + JSON + checksum manifest)
- `/admin/ops/alerts-monitor/runs/export` (CSV, `recent_runs` focused)
- `/admin/ops/alerts-monitor/export-usage.csv` (CSV, usage trend; supports `days` + `source=all|export|token`; includes `requested_by_top` metadata comment)
- `/admin/ops/alerts-monitor/export-usage.json` (JSON mirror of usage trend; supports `days` + `source=all|export|token`; includes `requested_by_top`)
- `/admin/ops/alerts-monitor/export-usage.png` (PNG sparkline; supports `days` + `source=all|export|token` + `w` + `h`; includes latest/max annotations and `X-Usage-*` headers)
- `/admin/ops/alerts-monitor/export-usage.svg` (SVG sparkline; supports `days` + `source=all|export|token` + `w` + `h`)
- `/admin/ops/security` (webhook probe/auth telemetry + contact first-response SLA dashboard)
- `/admin/ops/security/export.json` (webhook probe/auth + contact SLA snapshot JSON; includes `contact_overdue_leaders` top-3 topics by `pending_overdue_24h` for triage routing)
- `/admin/ops/security/export.csv` (webhook probe/auth + contact SLA CSV export; supports `mode=summary` to emit counts + contact summary/leaders only)
- `/admin/ops/security/trend.json` (daily webhook probe/auth event trend, `days=1..90`)
- `/admin/ops/security/contact-sla/trend.json` (daily contact intake/first-response trend with backlog delta, `days=1..90`; supports `compact=1` to omit per-topic arrays for low-bandwidth polling)
- `/admin/ops/security/contact-sla/trend.csv` (CSV export of contact SLA trend by day/topic)
- `/admin/ops/security/contact-overdue-leaders.json` (top overdue contact topics for triage routing, supports `hours` + `limit`)
- `POST /admin/ops/security/contact-first-response` (admin action to record first response for a contact intake `contact_key`)

### Admin incident drilldown example (session-auth)

Request:
```bash
curl -sS "https://vets-coin.com/admin/ops/incidents/detail.json?hours=72&limit=250&source=cron_logs&severity=bad&index=0&context=1" \
  -H "Cookie: session=YOUR_ADMIN_SESSION_COOKIE"
```

Response shape:
```json
{
  "success": true,
  "count": 12,
  "index": 0,
  "context": 1,
  "previous_index": null,
  "next_index": 1,
  "selected": {"incident_id":"...","index":0,"total":12,"occurred_at":"...","severity":"bad","source":"cron_logs","title":"...","detail":"...","occurred_at_display":"..."},
  "neighbors": [{"incident_id":"...","selected":true}, {"incident_id":"...","selected":false}]
}
```

### Alert monitor ZIP manifest example (session-auth)

Export bundle:
```bash
curl -sS "https://vets-coin.com/admin/ops/alerts-monitor/export.zip?lines=120" \
  -H "Cookie: session=YOUR_ADMIN_SESSION_COOKIE" \
  -o alerts_monitor_export_bundle.zip
```

Manifest payload (`alerts_monitor_export_manifest.json`):
```json
{
  "generated_at": "2026-02-17T04:03:00Z",
  "source": "admin_ops_alert_monitor_export_zip",
  "entries": [
    {"name":"alerts_monitor_export.csv","sha256":"...","bytes":12345},
    {"name":"alerts_monitor_export.json","sha256":"...","bytes":6789}
  ]
}
```

## Admin (Token) Endpoints

Legacy token endpoints (deprecated; admin session required):
- `/admin/download-backup` (removed; returns 410)
- `/admin/send-alert` (removed; returns 410)
- `/admin/alert` (removed; returns 410)

## Public / Other

- `/api/public-stats` (public)
- `/api/public/system-status` (public)
- `/api/public/system-status/trend` (public, `limit` query param)
- `/api/public/system-status/uptime` (public, `hours=24|168|720`)
- `/api/public/system-status/incidents` (public, `hours` + `limit` query params)
- `/api/public/system-status/incidents.rss` (public RSS companion)
- `/api/public/latency-percentiles` (public, `hours=24|168|720`)
- `/api/public/latency-percentiles.rss` (public RSS companion)
- `/api/public/status-feeds.json` (public machine-readable feed index)
- `/api/public/status-feeds/health.json` (public per-feed freshness telemetry)
- `/api/public/status-feeds/health.csv` (public CSV telemetry companion)
- `/api/public/release-manifest` + `/api/public/release-manifest.sig` (public signed release metadata)
- `/api/public/data-retention` + `/data-retention` (public retention matrix JSON + HTML)
- `/api/transactions` and `/api/transactions/latest` (public, `limit` query param)
- `/api/vets/swap-url` (public, swap link + label)
- `/api/vets/donation-claim` (public, donation-claim config + webhook URL)
- `/transparency/token-distribution` (public)
- `/transparency/token-distribution.csv` (public)
- `/api/test-db` (admin-only)
- `/health` (public)
- `/webhook/donation` (public POST, validates internally)

## Debug (Should be restricted in production)

- `/debug/session`
- `/debug/whoami`
- `/debug/testuser-check`

## Rate Limits (Config)

Environment variables:
- `RATE_LIMIT_PUBLIC_API_PER_MIN` (default 120) for `/api/public-stats`, `/api/public/system-status`, `/api/public/system-status/trend`, `/api/public/system-status/uptime`, `/api/public/system-status/incidents`, `/api/public/system-status/incidents.rss`, `/api/public/latency-percentiles`, `/api/public/latency-percentiles.rss`, `/api/public/status-feeds.json`, `/api/public/status-feeds/health.json`, `/api/public/status-feeds/health.csv`, `/api/public/release-manifest`, `/api/public/release-manifest.sig`, `/api/public/data-retention`, `/api/transactions`, `/api/transactions/latest`, `/api/vets/swap-url`, `/api/vets/donation-claim`, `/api/wallet-info/<wallet>`, `/api/log`
- `PUBLIC_STATUS_HISTORY_FILE` (default `/home/vets-coin/logs/status_history.jsonl`)
- `PUBLIC_STATUS_HISTORY_MAX_LINES` (default `5000`)
- `PUBLIC_STATUS_HISTORY_TRIM_BYTES` (default `2000000`)
- `RATE_LIMIT_WEBHOOK_PER_MIN` (default 60) for `/webhook/donation`
- `DONATION_WEBHOOK_AUTH_MODE` (`off|log|enforce`) for `/webhook/donation`
- `DONATION_WEBHOOK_SECRET` shared HMAC secret for donation webhook auth
- `DONATION_WEBHOOK_SIG_TTL_SECONDS` timestamp skew/replay window in seconds
- `WEBHOOK_PROBE_MAX_PER_MIN` non-POST `/webhook/*` probe threshold before temporary IP blocklist escalation
- `PARTNER_RATE_LIMIT_PER_MINUTE` (optional global cap for partner HMAC endpoints)
- `PARTNER_NONCE_REQUIRED` (default `0`; global strict mode for all partner endpoints)
- `PARTNER_IDEMPOTENCY_ENABLED` (default `1`)
- `PARTNER_IDEMPOTENCY_REQUIRED` (default `1` for mutation endpoints)
- `PARTNER_IDEMPOTENCY_TTL_SECONDS` (default `86400`)
- `PARTNER_WEBHOOK_MAX_ATTEMPTS` + `PARTNER_WEBHOOK_TIMEOUT_SECONDS` for webhook delivery
- `RATE_LIMIT_FAUCET_PER_MIN` (default 30) for `/claim-faucet`
- `API_TRANSACTIONS_DEFAULT_LIMIT` (default 200) for `/api/transactions`
- `API_TRANSACTIONS_LATEST_DEFAULT_LIMIT` (default 50) for `/api/transactions/latest`
- `API_TRANSACTIONS_MAX_LIMIT` (default 1000) cap for `/api/transactions` and `/api/transactions/latest`
