{
  "ok": true,
  "status": "blocked_before_model_adapter_call",
  "scope": "role_chat_model_adapter_plan_preview",
  "roleId": "wf-moonlit-bookseller",
  "roleName": "月下书店老板",
  "sourceDocument": "docs/20角色卡片温度与酒馆系参考补充-2026-06-12.md",
  "pointsLedger": {
    "status": "blocked_before_points_ledger",
    "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",
      "points_ledger_live_transaction_missing",
      "points_balance_check_missing",
      "refund_transaction_missing",
      "duplicate_turn_charge_guard_missing"
    ],
    "requiredLedgerEntries": [
      "reserve",
      "settle",
      "refund"
    ]
  },
  "policyGate": {
    "decision": "allow",
    "status": "preview_passed",
    "effect": "model_request_can_be_planned_after_real_key_and_ledger_hold"
  },
  "provider": {
    "provider": "deepseek",
    "mode": "openai_compatible_chat_completion",
    "adapterFile": "server/src/adapters/model.js",
    "credentialSource": "server_environment_only",
    "timeoutMs": 30000,
    "retryPolicy": "one_retry_only_after_safe_retryable_error",
    "streamMode": "disabled_until_streaming_storage_and_refund_are_verified"
  },
  "requestEnvelope": {
    "status": "blocked_until_live_model_adapter_ready",
    "clientTurnId": "preview-client-turn-id",
    "serverTurnId": "preview-preview-client-turn-id",
    "stream": false,
    "model": "configured_by_server_adapter",
    "temperature": 0.72,
    "maxTokens": 700,
    "messages": [
      {
        "role": "system",
        "content": "角色：月下书店老板。语气：低声、安稳、像夜里仍然亮着的灯。。边界：只做暧昧互动小说和情感陪伴，不输出露骨色情、暴力细节或高敏隐私。"
      },
      {
        "role": "user",
        "content": "称呼：访客。偏好语气：慢一点、更多关心。用户消息：今天有点累，想在这里待一会儿。"
      }
    ],
    "redaction": [
      "no_model_api_key_in_response",
      "no_database_url_in_response",
      "no_internal_prompt_blocks_in_public_api"
    ]
  },
  "responseHandling": {
    "successPath": [
      "parse_assistant_text",
      "run_assistant_output_policy_check",
      "persist_assistant_message_with_model_call_id",
      "settle_reserved_points"
    ],
    "failureMappings": [
      {
        "error": "timeout",
        "recovery": "refund_reserved_points"
      },
      {
        "error": "provider_5xx",
        "recovery": "refund_reserved_points_and_allow_retry"
      },
      {
        "error": "rate_limited",
        "recovery": "refund_reserved_points_and_show_retry_later"
      },
      {
        "error": "invalid_or_empty_output",
        "recovery": "refund_reserved_points_and_mark_turn_failed"
      },
      {
        "error": "assistant_output_policy_block",
        "recovery": "refund_reserved_points_and_return_safe_companion_response"
      }
    ]
  },
  "outputPolicy": {
    "requiredChecks": [
      "assistant_output_safety_check",
      "no_exposed_system_prompt",
      "no_high_sensitive_memory_saved_without_user_opt_in",
      "no_underage_or_forced_or_illegal_content"
    ],
    "blockedOutputRecovery": "safe_companion_response_without_points_charge"
  },
  "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",
    "points_ledger_live_transaction_missing",
    "points_balance_check_missing",
    "refund_transaction_missing",
    "duplicate_turn_charge_guard_missing",
    "model_adapter_live_call_missing",
    "model_response_normalizer_missing",
    "assistant_output_policy_log_missing",
    "model_timeout_and_retry_not_verified"
  ],
  "next": [
    "connect_server_side_model_key",
    "implement_model_response_normalizer",
    "bind_output_policy_to_assistant_message_persistence",
    "verify_timeout_refund_and_retry_contract",
    "keep_prompt_and_model_key_out_of_public_response"
  ],
  "boundaries": [
    "model_adapter_plan_preview_only",
    "does_not_call_real_model",
    "does_not_expose_model_api_key",
    "does_not_expose_internal_prompt_blocks",
    "does_not_reserve_or_charge_points",
    "does_not_write_production_database",
    "does_not_store_user_message"
  ]
}