{
  "ok": true,
  "status": "blocked_before_turn_execution",
  "scope": "role_chat_turn_execution_plan_preview",
  "roleId": "wf-moonlit-bookseller",
  "roleName": "月下书店老板",
  "sourceDocument": "docs/20角色卡片温度与酒馆系参考补充-2026-06-12.md",
  "preflight": {
    "status": "blocked_before_model_call",
    "blockers": [
      "model_api_key_missing",
      "points_charge_not_live",
      "production_chat_storage_missing",
      "user_auth_not_live"
    ],
    "estimatedPointCost": 120,
    "modelCode": "waiting_for_model_key",
    "billingCode": "points_charge_disabled_without_payment_and_model"
  },
  "idempotency": {
    "required": true,
    "clientTurnId": "preview-client-turn-id",
    "serverTurnId": "preview-preview-client-turn-id",
    "duplicateHandling": "return_existing_turn_or_block_before_double_charge"
  },
  "policyGate": {
    "decision": "allow",
    "nextStep": "continue_to_model_adapter_after_real_policy_gate",
    "status": "preview_passed"
  },
  "orderedSteps": [
    {
      "code": "authenticate_user",
      "owner": "auth_adapter",
      "status": "blocked",
      "requiredEvidence": [
        "authenticated_user_id",
        "role_access_allowed"
      ],
      "rollback": "no_state_created"
    },
    {
      "code": "policy_gate",
      "owner": "content_policy",
      "status": "preview_passed",
      "requiredEvidence": [
        "message_safety_decision_allow",
        "policy_version_logged"
      ],
      "rollback": "return_safe_rewrite_or_manual_review_state"
    },
    {
      "code": "reserve_points_before_model_call",
      "owner": "billing_adapter",
      "status": "blocked",
      "requiredEvidence": [
        "points_balance_sufficient",
        "idempotent_ledger_hold",
        "refund_rule_ready"
      ],
      "rollback": "release_reserved_points_before_response"
    },
    {
      "code": "persist_user_message_pending",
      "owner": "chat_repository",
      "status": "blocked",
      "requiredEvidence": [
        "production_chat_storage_ready",
        "message_owner_bound_to_user"
      ],
      "rollback": "mark_turn_failed_without_assistant_message"
    },
    {
      "code": "call_model_adapter_after_policy_gate",
      "owner": "model_adapter",
      "status": "blocked",
      "requiredEvidence": [
        "model_api_key_configured",
        "timeout_policy_configured",
        "no_frontend_secret_exposure"
      ],
      "rollback": "refund_points_on_model_failure"
    },
    {
      "code": "persist_assistant_message_after_success",
      "owner": "chat_repository",
      "status": "blocked",
      "requiredEvidence": [
        "assistant_output_policy_checked",
        "message_saved_with_model_call_id"
      ],
      "rollback": "mark_assistant_message_failed_and_refund_points"
    },
    {
      "code": "commit_memory_candidates_after_user_control",
      "owner": "memory_repository",
      "status": "blocked",
      "requiredEvidence": [
        "memory_opt_in_confirmed",
        "high_sensitive_privacy_rejected",
        "forget_requests_excluded"
      ],
      "rollback": "do_not_add_candidate_memory"
    },
    {
      "code": "settle_points_after_success",
      "owner": "billing_adapter",
      "status": "blocked",
      "requiredEvidence": [
        "model_call_success",
        "points_ledger_commit",
        "balance_after_recorded"
      ],
      "rollback": "refund_points_on_model_failure"
    }
  ],
  "failureModePlan": [
    {
      "code": "policy_block",
      "recovery": "return_safe_companion_response_without_points_charge"
    },
    {
      "code": "insufficient_points",
      "recovery": "return_member_payment_entry_without_model_call"
    },
    {
      "code": "model_timeout",
      "recovery": "refund_points_on_model_failure"
    },
    {
      "code": "storage_write_failed",
      "recovery": "do_not_call_model_or_mark_turn_failed_before_charge"
    },
    {
      "code": "memory_delete_pending",
      "recovery": "exclude_deleted_memory_before_prompt_context"
    }
  ],
  "blockers": [
    "model_api_key_missing",
    "points_charge_not_live",
    "production_chat_storage_missing",
    "user_auth_not_live",
    "chat_turn_transaction_not_live",
    "idempotent_points_reservation_missing",
    "assistant_message_persistence_missing"
  ],
  "next": [
    "clear_invocation_preflight_blockers_before_turn_execution",
    "connect_auth_points_chat_storage_and_model_adapters",
    "verify_refund_and_idempotency_before_real_streaming"
  ],
  "boundaries": [
    "turn_plan_preview_only",
    "does_not_call_real_model",
    "does_not_reserve_or_charge_points",
    "does_not_write_production_database",
    "does_not_store_user_message",
    "does_not_store_user_memory",
    "does_not_expose_internal_prompt_blocks"
  ]
}