{
  "contract_version": "experience.plan.v1",
  "experience_id": "adaptive_welcome_care",
  "implementation_status": "runtime_policy_connected_physical_e2e_pending",
  "lifecycle": "design_fixture",
  "runtime_experience_contract": {
    "contract_version": "a2a-experience-policy-v1",
    "experience_id": "adaptive_welcome_care",
    "goal_summary": "사용자의 귀가를 감지하고 기기 상태와 환경을 확인해 안전한 환영, 필요한 청정, 맞춤 브리핑을 제공한 뒤 기기를 안정 상태로 복귀시킨다.",
    "observation_policy": {
      "subscriptions": [
        {
          "contract_id": "security.person_detected",
          "decision_mode": "supervisor",
          "step_ids": ["confirm_presence"]
        },
        {
          "contract_id": "security.verification_result",
          "decision_mode": "supervisor",
          "step_ids": ["confirm_presence"]
        },
        {
          "contract_id": "vision.low_light_changed",
          "decision_mode": "supervisor",
          "step_ids": ["confirm_presence"]
        },
        {
          "contract_id": "network.aws_iot_session_changed",
          "decision_mode": "supervisor",
          "step_ids": ["observe_connectivity", "deliver_briefing"]
        },
        {
          "contract_id": "voice_llm.pipeline_state_changed",
          "decision_mode": "supervisor",
          "step_ids": ["deliver_briefing"]
        }
      ]
    },
    "decision_budget": {
      "max_decisions": 3
    }
  },
  "workflow_correlation_gaps": {
    "network.aws_iot_session_changed": "producer is currently unscoped",
    "voice_llm.pipeline_state_changed": "producer is currently unscoped",
    "security.person_detected": "correlation currently belongs to TaskManager-started Security workflow, not generic welcome interaction",
    "vision.low_light_changed": "correlation currently belongs to active Security workflow"
  },
  "semantic_authority": {
    "execution_source": "typed_action",
    "required_fields": [
      "capability_id",
      "operation_id",
      "arguments"
    ],
    "natural_language_role": "explanation_and_legacy_fallback_only"
  },
  "runtime_binding_snapshot": {
    "contract_version": "deviceagent-cloud-runtime-binding.v1",
    "connected_step_count": 7,
    "partial_step_count": 3,
    "blocked_step_count": 0,
    "partial_step_ids": [
      "run_welcome_interaction",
      "confirm_presence",
      "deliver_briefing"
    ],
    "policy": "blocked_steps_are_not_admitted_and_partial_steps_require_their_documented_adapter_or_terminal_boundary"
  },
  "step_result_contract": {
    "contract_version": "a2a-step-result-binding-v1",
    "runtime_enforced": false,
    "runtime_transport_contract": "a2a-task-orchestration-v1",
    "runtime_status": "workflow_step_result_storage_connected_generic_binding_partial",
    "binding_policy": "typed_output_key_and_input_from_only",
    "utterance_reparse": false,
    "required_envelope_fields": [
      "step_id",
      "output_key",
      "status",
      "observed_at_ms",
      "source",
      "result"
    ],
    "result_policy": "Only bounded domain summaries and terminal evidence may be consumed by later steps.",
    "current_limit": "Cloud workflow state preserves output_key and step_results for matching COMPLETED or WORKFLOW_STEP_COMPLETED events, but capability-specific result allowlists and a generic input_from runtime binder are not complete."
  },
  "condition_policy": {
    "fact_states": [
      "known",
      "unknown",
      "stale"
    ],
    "unknown_or_stale": "block_or_refresh_never_execute_unconditionally",
    "unsupported_operator": "reject_plan",
    "missing_context_path": "block_step"
  },
  "goal": {
    "summary": "사용자의 귀가를 감지하고 기기 상태와 환경을 확인해 안전한 환영, 필요한 청정, 맞춤 브리핑을 제공한 뒤 기기를 안정 상태로 복귀시킨다.",
    "success_criteria": [
      "arrival interaction was admitted by DeviceAgent policy",
      "user presence was handled without exposing raw vision data",
      "comfort action matched fresh environment and battery evidence",
      "voice content did not block physical safety actions",
      "device returned to a safe idle or charging state"
    ],
    "constraints": [
      "DeviceAgent policy and resource admission always win",
      "raw frames, bbox, credentials, signed URLs, and unrestricted logs never enter the general LLM prompt",
      "normal progress does not invoke Cloud replanning",
      "user cancellation interrupts all subordinate work",
      "context-only capabilities never become arbitrary device methods"
    ]
  },
  "implementation_profiles": {
    "current_device_demo": {
      "trigger": "manual text or voice request",
      "enabled_steps": [
        "observe_space",
        "observe_health",
        "observe_air",
        "decide_comfort_action",
        "start_cleaning_if_admitted",
        "deliver_briefing",
        "return_safe"
      ],
      "disabled_or_shadowed": [
        "observe_connectivity",
        "run_welcome_interaction",
        "confirm_presence"
      ],
      "dependency_overrides": {
        "decide_comfort_action": [
          "observe_health",
          "observe_air"
        ],
        "deliver_briefing": [
          "decide_comfort_action"
        ],
        "return_safe": [
          "deliver_briefing"
        ]
      },
      "input_from_overrides": {
        "decide_comfort_action": {
          "device_health": "device_health.result",
          "air_assessment": "air_assessment.result"
        },
        "deliver_briefing": {
          "comfort_decision": "comfort_decision.result"
        },
        "return_safe": {
          "device_health": "device_health.result"
        }
      }
    },
    "target_agentic": {
      "trigger": "product schedule or fresh AWS/GPS arrival event",
      "enabled_steps": "all",
      "required_contracts": [
        "device_context.v2 network domain",
        "device_context.v2 perception domain",
        "ordered durable task-event relay",
        "resource lease registry",
        "typed user-presence semantic events"
      ]
    }
  },
  "admission_context": [
    "core",
    "battery",
    "spatial",
    "environment",
    "voice_llm",
    "policy",
    "network",
    "perception",
    "task_manager",
    "capabilities"
  ],
  "resource_lease": {
    "exclusive": [
      "interaction_session",
      "amr_motion"
    ],
    "conditional": [
      "cleaning_actuator",
      "microphone",
      "voice_session"
    ],
    "shared": [
      "speaker",
      "air_sensor",
      "network"
    ],
    "policy": {
      "voice_interruption": "pause domain interaction locally, then resume or bounded-replan",
      "low_battery": "skip optional cleaning and return to station",
      "privacy_enabled": "disable presence-dependent adaptation",
      "network_unavailable": "use local interaction content and queue Cloud summary"
    }
  },
  "steps": [
    {
      "step_id": "observe_space",
      "capability_id": "spatial_context_assessment",
      "operation_id": "read_current_spatial_state",
      "arguments": {
        "requiredFreshnessMs": 5000
      },
      "purpose": "현재 위치, 실제 공간 목록, 이동 상태를 확인한다.",
      "depends_on": [],
      "output_key": "spatial_state",
      "input_from": {},
      "wait_for": "fresh semantic snapshot",
      "execution_target": "cloud",
      "executor_role": "context_projection",
      "implementation_status": "current"
    },
    {
      "step_id": "observe_health",
      "capability_id": "device_health_assessment",
      "operation_id": "assess_current_health",
      "arguments": {
        "assessmentWindowMs": 5000
      },
      "purpose": "배터리와 작업 가능 상태를 평가한다.",
      "depends_on": [],
      "output_key": "device_health",
      "input_from": {},
      "wait_for": "fresh semantic snapshot",
      "execution_target": "cloud",
      "executor_role": "context_projection",
      "implementation_status": "partial"
    },
    {
      "step_id": "observe_connectivity",
      "capability_id": "connectivity_assessment",
      "operation_id": "read_current_connectivity",
      "arguments": {
        "requiredFreshnessMs": 5000
      },
      "purpose": "AWS와 Wi-Fi 연결 상태, 관찰 시각, 마지막 오류를 평가한다.",
      "depends_on": [],
      "output_key": "network_health",
      "input_from": {},
      "wait_for": "fresh transport semantic state",
      "execution_target": "cloud",
      "executor_role": "context_projection",
      "implementation_status": "contract_gap"
    },
    {
      "step_id": "observe_air",
      "capability_id": "air_quality_assessment",
      "operation_id": "assess_current_air_quality",
      "arguments": {
        "comparisonWindowMs": 300000
      },
      "purpose": "실내 공기질을 사용자 경험 관점의 의미 상태로 해석한다.",
      "depends_on": [],
      "output_key": "air_assessment",
      "input_from": {},
      "wait_for": "fresh air-quality snapshot",
      "execution_target": "cloud",
      "executor_role": "context_projection",
      "implementation_status": "current"
    },
    {
      "step_id": "run_welcome_interaction",
      "capability_id": "product_interaction",
      "operation_id": "start_interaction",
      "arguments": {
        "interaction_type": "welcomeWeather"
      },
      "runtime_grounding": {
        "required_argument": "schedule_id",
        "source": "device_context.interactions.registered_schedules",
        "on_missing": "block_step"
      },
      "purpose": "기존 제품 interaction domain을 통해 환영 동작을 수행한다.",
      "depends_on": [
        "observe_space",
        "observe_health"
      ],
      "output_key": "welcome_result",
      "input_from": {
        "spatial_state": "spatial_state.result",
        "device_health": "device_health.result"
      },
      "wait_for": "interaction.arrived or interaction.completed",
      "execution_target": "device",
      "implementation_status": "cloud_adapter_connected_schedule_grounding_gap"
    },
    {
      "step_id": "confirm_presence",
      "capability_id": "perception_presence_assessment",
      "operation_id": "assess_person_presence",
      "arguments": {
        "observationPurpose": "welcome_continuation"
      },
      "purpose": "원본 영상 없이 사람 존재, 부재, 불확실 상태만 확인한다.",
      "depends_on": [
        "run_welcome_interaction"
      ],
      "output_key": "presence_summary",
      "input_from": {
        "welcome_result": "welcome_result.result"
      },
      "wait_for": "debounced person semantic event",
      "execution_target": "cloud",
      "executor_role": "semantic_observation_reducer",
      "implementation_status": "contract_gap"
    },
    {
      "step_id": "decide_comfort_action",
      "capability_id": "experience_supervision",
      "operation_id": "choose_comfort_action",
      "arguments": {
        "allowedOutcomes": [
          "clean",
          "skip",
          "ask"
        ]
      },
      "purpose": "공기질, 배터리, 사용자의 존재와 현재 task를 근거로 청정, 생략, 질문 중 하나를 선택한다.",
      "depends_on": [
        "observe_health",
        "observe_air",
        "observe_connectivity"
      ],
      "output_key": "comfort_decision",
      "input_from": {
        "device_health": "device_health.result",
        "air_assessment": "air_assessment.result",
        "network_health": "network_health.result"
      },
      "optional_evidence_from": [
        "confirm_presence"
      ],
      "wait_for": "bounded semantic decision",
      "execution_target": "cloud",
      "executor_role": "experience_supervisor",
      "implementation_status": "shadow"
    },
    {
      "step_id": "start_cleaning_if_admitted",
      "capability_id": "start_room_cleaning",
      "operation_id": "start_current_room_cleaning",
      "arguments": {
        "action": "start",
        "targetSelector": "current_room"
      },
      "purpose": "청정이 필요하고 DeviceAgent admission이 허용한 경우에만 현재 공간 청정을 시작한다.",
      "depends_on": [
        "decide_comfort_action",
        "observe_space"
      ],
      "output_key": "comfort_cleaning_result",
      "input_from": {
        "decision": "comfort_decision.result",
        "spatial_state": "spatial_state.result"
      },
      "wait_for": "cleaning.started",
      "execution_target": "device",
      "implementation_status": "current",
      "conditions": [
        {
          "path": "step_results.decide_comfort_action.outcome",
          "operator": "eq",
          "value": "clean"
        }
      ]
    },
    {
      "step_id": "deliver_briefing",
      "capability_id": "voice_content",
      "operation_id": "compose_and_speak",
      "arguments": {
        "contentGoal": "welcome_and_environment_briefing"
      },
      "purpose": "사용자에게 환영 브리핑 또는 요청한 콘텐츠를 제공한다.",
      "depends_on": [
        "run_welcome_interaction",
        "decide_comfort_action",
        "observe_connectivity"
      ],
      "output_key": "briefing_result",
      "input_from": {
        "welcome_result": "welcome_result.result",
        "comfort_decision": "comfort_decision.result",
        "network_health": "network_health.result"
      },
      "wait_for": "content response accepted",
      "execution_target": "cloud",
      "executor_role": "content_composer",
      "delivery_target": "on_device_tts",
      "implementation_status": "partial",
      "overlap_policy": "may overlap cleaning but never blocks safety actions"
    },
    {
      "step_id": "return_safe",
      "capability_id": "return_to_station",
      "operation_id": "return_and_dock",
      "arguments": {},
      "purpose": "환영 경험이 끝나거나 배터리·취소 조건이 발생하면 스테이션으로 복귀한다.",
      "depends_on": [
        "run_welcome_interaction",
        "observe_health"
      ],
      "output_key": "return_result",
      "input_from": {
        "welcome_result": "welcome_result.result",
        "device_health": "device_health.result"
      },
      "wait_for": "movement.stationCharging",
      "execution_target": "device",
      "implementation_status": "current"
    }
  ],
  "observation_rules": [
    {
      "event": "interaction.arrived",
      "local_action": "continue interaction lifecycle",
      "cloud_action": "none"
    },
    {
      "event": "perception.personPresent",
      "local_action": "mark presence confirmed",
      "cloud_action": "continue current experience"
    },
    {
      "event": "perception.personAbsent",
      "local_action": "bounded wait then finish interaction",
      "cloud_action": "only if user-facing follow-up is useful"
    },
    {
      "event": "battery.low",
      "local_action": "skip optional cleaning and return",
      "cloud_action": "summarize changed plan"
    },
    {
      "event": "network.awsDisconnected",
      "local_action": "continue local interaction and queue outbound events",
      "cloud_action": "none until transport recovers"
    },
    {
      "event": "voice.sessionStarted",
      "local_action": "pause conflicting interaction state",
      "cloud_action": "resume or change goal after the voice turn"
    },
    {
      "event": "task.failed",
      "local_action": "apply one bounded domain retry when recoverable",
      "cloud_action": "choose skip, alternative, ask, or abort after retry exhaustion"
    },
    {
      "event": "user.cancelled",
      "local_action": "cancel subordinate workflow and compensate",
      "cloud_action": "acknowledge cancellation only"
    }
  ],
  "replan_budget": {
    "local_retries_per_step": 1,
    "cloud_replans_total": 2,
    "user_questions_total": 1
  },
  "current_blockers": [
    "AWS and LLM semantic observations are unscoped from the active experience workflow",
    "generic VisionAIManager scenarios are not a central semantic observation source",
    "voice-content playback completion is not a canonical terminal event",
    "functional resource leases remain distributed across domains",
    "current Planner context projector is not driven by capability context_reads",
    "WSS correlation is limited to TaskManager-started Security sessions",
    "DIRECT task completion can represent request acceptance rather than physical completion",
    "platform-signed observation-policy-to-replan physical E2E is not verified"
  ]
}
