report_type: service_downtime_recovery_state_contract
report_version: 1
generated_at: "2026-05-18T06:49:14.000Z"
source_chunk: "chunk-000238-service-downtime-contract-and-timestamp-metadata"
runtime_health_at_start:
  overall_health: "healthy"
  validation_status: "healthy"
  active_chunk_before_start: null
  services:
    - service_key: "operator-daemon"
      observed_status: "running or recently active"
    - service_key: "runtime-supervisor"
      observed_status: "running"
    - service_key: "approved-action-dispatcher"
      observed_status: "running"
    - service_key: "frontend-dev-server"
      observed_status: "reachable"
    - service_key: "telegram-bridge"
      observed_status: "RUNNING"
    - service_key: "runtime-api"
      observed_status: "running"
      observed_recovery_state: "not_requested"
canonical_rules:
  service_truth_owner: "Runtime/backend service projections"
  ui_truth_owner: "GraphQL Runtime Health snapshot"
  socket_role: "invalidation-only"
  frontend_local_inference_allowed: false
  manual_reload_counts_as_success: false
state_values:
  - healthy
  - planned_restart_pending
  - restart_in_progress
  - recovering
  - recovered
  - degraded
  - unavailable
  - failed
  - unknown
  - stale
reason_values:
  - planned_runtime_restart
  - planned_backend_restart
  - planned_frontend_restart
  - planned_telegram_restart
  - functional_probe_timeout
  - stale_generation
  - process_not_running
  - socket_disconnected
  - socket_reconnecting
  - admin_room_not_joined
  - auth_missing
  - transport_error
  - heartbeat_timeout
  - delivery_lag
  - delivery_failure
  - recovery_failed
  - unknown_failure
evidence_fields:
  - service_key
  - state
  - reason
  - planned
  - actor_role
  - action_id
  - supervisor_request_id
  - started_at
  - updated_at
  - completed_at
  - last_error
  - recovery_state
  - next_action
  - source_journal_sequence
  - mutates_authority_state
service_matrix:
  - service_key: "runtime-api"
    source_of_truth: "Runtime Health materialized read model and Runtime daemon probes"
    process_evidence: "daemon heartbeat/generation"
    functional_evidence: "Runtime Health snapshot/read-model freshness"
    journal_event_coverage: "Runtime State Journal and runtime supervisor events"
    ui_projection: "service row plus Runtime Health freshness diagnostics"
    browser_proof_status: "planned/unplanned proof pending under cfd-0024"
  - service_key: "backend-api"
    source_of_truth: "backend health endpoint and Runtime/backend service projection"
    process_evidence: "dev-server pid/process tree when supervised"
    functional_evidence: "/health HTTP probe and GraphQL availability"
    journal_event_coverage: "supervisor service events when restarted through typed supervisor"
    ui_projection: "service row, fail log, connection state/toasts"
    browser_proof_status: "planned/unplanned proof pending under cfd-0024"
  - service_key: "frontend-dev-server"
    source_of_truth: "backend Runtime Health service projection"
    process_evidence: "typed supervisor pid/process-tree cleanup"
    functional_evidence: "HTTP probe to frontend dev server"
    journal_event_coverage: "supervisor progress/result events"
    ui_projection: "service row and service fail log"
    browser_proof_status: "planned restart supervised proof exists; browser-visible toast proof pending"
  - service_key: "socket-io"
    source_of_truth: "backend Socket.IO registry and gateway diagnostics"
    process_evidence: "backend process plus namespace/gateway availability"
    functional_evidence: "authorized admin room/device membership"
    journal_event_coverage: "journal consumer emits invalidation; socket registry records issues"
    ui_projection: "socket diagnostics, connection banner/toasts"
    browser_proof_status: "baseline browser live-update proof exists; device cleanup/PWA proof pending under cfd-0014"
  - service_key: "telegram-bridge"
    source_of_truth: "Runtime service projection and Telegram state files"
    process_evidence: "bridge daemon/session status"
    functional_evidence: "outbox lag, sent age, failed delivery count"
    journal_event_coverage: "supervisor events when restarted; Telegram delivery health events where available"
    ui_projection: "service row and fail log"
    browser_proof_status: "browser downtime proof not primary; delivery health remains Telegram follow-up"
  - service_key: "runtime-supervisor"
    source_of_truth: "typed supervisor status files"
    process_evidence: "heartbeat, pending/running/results counts"
    functional_evidence: "request progress/result/error files"
    journal_event_coverage: "supervisor progress/result/error events"
    ui_projection: "service row and fail log"
    browser_proof_status: "standalone supervisor tests exist; browser restart proof pending"
  - service_key: "approved-action-dispatcher"
    source_of_truth: "dispatcher status/projection"
    process_evidence: "dispatcher daemon status"
    functional_evidence: "pending/result queue health"
    journal_event_coverage: "dispatcher/timeline events"
    ui_projection: "service row where projected"
    browser_proof_status: "outage proof pending if included in restart package"
  - service_key: "operator-daemon"
    source_of_truth: "operator daemon status/projection"
    process_evidence: "daemon status/recent activity"
    functional_evidence: "approval/action queue behavior"
    journal_event_coverage: "operator/timeline events"
    ui_projection: "service row where projected"
    browser_proof_status: "outage proof pending if included in restart package"
metadata_contract:
  created_completed_format: "UTC ISO-8601 timestamp, YYYY-MM-DDTHH:mm:ss.sssZ"
  pass_history_date_format: "UTC ISO-8601 timestamp, YYYY-MM-DDTHH:mm:ss.sssZ"
  historical_completed_chunks_retconned: false
  enforcement: "Runtime summary validation catches date-only metadata for active/ready chunks"
desired_state_recovery_policy:
  owner: "typed Runtime supervisor"
  record_scope: "one desired-state record per supervised service"
  desired_states:
    - running
    - stopped
    - maintenance_stopped
  restart_policies:
    - on_failure
    - always
    - manual
  rules:
    - "Unexpected failure while desired state is running should trigger bounded recovery where safe."
    - "Explicit maintenance suppression must prevent unwanted auto-resurrection and must be visible as intentional."
    - "If recovery is unavailable or fails, Runtime Health and the Action Panel must show recovery_failed or unavailable with a next action."
  research_basis:
    - "systemd Restart= service behavior separates expected stops from restart policies: https://www.freedesktop.org/software/systemd/man/254/systemd.service.html"
    - "Kubernetes liveness/readiness/startup probes separate process restart decisions from service readiness: https://kubernetes.io/docs/concepts/configuration/liveness-readiness-startup-probes/"
remaining_gaps:
  - "Browser-visible planned restart toast/projection proof still pending."
  - "Unplanned crash/failure browser proof still pending."
  - "Socket device cleanup and installed PWA proof still pending."
  - "Automatic or bounded Runtime API resurrection is not proven when supervisor is alive but Runtime Health snapshot fails/nulls."
