{
  "ok": true,
  "status": "preview_only",
  "version": "role-database-preflight-2026-06-13-v1",
  "sourceContractVersion": "role-data-contract-2026-06-13-v1",
  "targetEntities": [
    "role_cards",
    "role_prompt_versions",
    "role_review_logs",
    "role_memory_candidates"
  ],
  "requiredPolicies": [
    {
      "name": "enable_rls_on_role_tables",
      "appliesTo": [
        "role_cards",
        "role_prompt_versions",
        "role_review_logs",
        "role_memory_candidates"
      ],
      "required": true
    },
    {
      "name": "deny_anon_role_management",
      "appliesTo": [
        "role_cards",
        "role_prompt_versions",
        "role_review_logs",
        "role_memory_candidates"
      ],
      "required": true
    },
    {
      "name": "public_can_read_published_safe_roles_only",
      "appliesTo": [
        "role_cards"
      ],
      "required": true
    },
    {
      "name": "admin_can_manage_drafts_after_auth",
      "appliesTo": [
        "role_cards",
        "role_prompt_versions",
        "role_review_logs"
      ],
      "required": true
    },
    {
      "name": "user_can_manage_own_memory_candidates_only",
      "appliesTo": [
        "role_memory_candidates"
      ],
      "required": true
    }
  ],
  "permissionChecks": [
    {
      "actor": "anon",
      "action": "read published role card list",
      "expected": "published_safe_roles_only"
    },
    {
      "actor": "anon",
      "action": "read drafts or prompt versions",
      "expected": "anon_denied"
    },
    {
      "actor": "authenticated_user",
      "action": "read another user memory candidates",
      "expected": "forbidden"
    },
    {
      "actor": "admin",
      "action": "approve draft or activate prompt version",
      "expected": "allowed_after_admin_auth"
    }
  ],
  "preflightCommands": [
    "run migration on temporary database copy",
    "PRAGMA integrity_check",
    "verify anon denied for drafts and prompt versions",
    "verify admin token required for write-like actions",
    "verify rollback migration can restore previous prompt version"
  ],
  "rollbackPlan": {
    "strategy": "apply reversible migration on temporary copy before live database",
    "steps": [
      "keep previous schema snapshot",
      "verify_previous_prompt_version_is_still_available",
      "revert role_prompt_versions activation flag",
      "restore published role list from approved snapshot",
      "block write traffic before live rollback"
    ]
  },
  "failureModes": [
    {
      "risk": "RLS disabled by default",
      "mitigation": "block production migration until policy checks pass"
    },
    {
      "risk": "anon reads draft or prompt data",
      "mitigation": "deny draft and prompt version tables to anon"
    },
    {
      "risk": "memory candidates leak across users",
      "mitigation": "bind userId to authenticated subject before persistence"
    }
  ],
  "boundaries": [
    "preview_only_not_real_migration",
    "does_not_run_migration",
    "does_not_touch_live_database",
    "does_not_create_database_tables",
    "does_not_grant_public_database_access",
    "requires_temp_database_replay_before_live"
  ]
}