6467:                     "chat_id": row["provider_chat_id"],
6468:                     "topic_id": row["provider_topic_id"],
6469:                 },
6470:                 "owner_route": self._route_projection(owner),
6471:                 "draft_id": draft_id,
6472:                 "generation": generation.generation,
6473:                 "generation_record_digest": generation.record_digest,
6474:                 "checkin_revision": generation.checkin_revision,
6475:                 "draft_revision": generation.draft_revision,
6476:                 "approved_revision": row["approved_revision"],
6477:                 "approved_event_id": row["approved_event_id"],
6478:                 "payload_digest": row["canonical_payload_digest"],
6479:                 "approved_card": card,
6480:             }
6481:             capability = DraftDeliveryCapability(capability_id, issued, expires, bindings)
6482:             updated = dict(row)
6483:             updated["status"] = "pending"
6484:             updated["delivery_capability"] = {
6485:                 "schema": "draft-delivery-capability-v1",
6486:                 "capability_id": capability_id,
6487:                 "issued_at": issued.isoformat(),
6488:                 "expires_at": expires.isoformat(),
6489:                 "status": "issued",
6490:                 "bindings": bindings,
6491:             }
6492:             deliveries[key] = updated
6493:             self._write_json_private(self._delivery_ledger_path(), deliveries)
6494:             return capability
6495:
6496:     @staticmethod
6497:     def _ledger_error(_: DraftLedgerError) -> str:
6498:         return "draft_ledger_corrupt"
6499:     @contextmanager
6500:     def _delivery_lock(self) -> Iterator[None]:
6501:         """Serialize outbox compare-and-reserve transitions across callers."""
6502:         path = self._delivery_ledger_path()
6503:         path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
6504:         path.parent.chmod(0o700)
6505:         lock_path = path.with_name(f"{path.name}.lock")
6506:         with lock_path.open("a", encoding="utf-8") as handle:
6507:             lock_path.chmod(0o600)
6508:             fcntl.flock(handle.fileno(), fcntl.LOCK_EX)
6509:             try:
6510:                 yield
6511:             finally:
6512:                 fcntl.flock(handle.fileno(), fcntl.LOCK_UN)
6513:
6514:     @staticmethod
6515:     def _field(value: object, name: str, default: object = None) -> object:
6516:         if isinstance(value, Mapping):
6517:             return value.get(name, default)
6518:         return getattr(value, name, default)
6519:     def _current_customer(self, customer_key: str, fallback: CustomerRuntime) -> CustomerRuntime:
6520:         for candidate in getattr(self._registry, "customers", ()):
6521:             spec = getattr(candidate, "spec", None)
6522:             if getattr(spec, "customer_key", None) == customer_key:
6523:                 return candidate
6524:         return fallback
6525:
6526:     @classmethod
6527:     def _safety_value_has_hold(cls, value: object) -> bool:
6528:         if value is None:
6529:             return False
6530:         for name in (
6531:             "safety_signals",
6532:             "safety_reasons",
6533:             "signals",
6534:             "reasons",
6535:         ):
6536:             candidate = cls._field(value, name)
6537:             if candidate:
6538:                 return True
6539:         safety = cls._field(value, "safety")
6540:         if safety is None:
6541:             return False
6542:         if bool(cls._field(safety, "coaching_held", False)):
6543:             return True
6544:         level = cls._field(safety, "level")
6545:         level_value = getattr(level, "value", level)
6546:         return str(level_value or "").strip().lower() not in {"", "none"}
6547:
6548:     @classmethod
6549:     def _bridge_safety_hold(
6550:         cls,
6551:         resolved: ResolvedCustomer,
6552:         session_id: str,
6553:     ) -> bool:
6554:         bridge = resolved.bridge
6555:         safety_snapshot = getattr(bridge, "finalized_safety_snapshot", None)
6556:         if callable(safety_snapshot):
6557:             try:
6558:                 if safety_snapshot(session_id) is not None:
6559:                     return True
6560:             except Exception:
6561:                 return True
6562:         finalized_event = getattr(bridge, "finalized_event", None)
6563:         if callable(finalized_event):
=== def prepare_delivery lines 6811-6959 ===
6811:         if not isinstance(record, dict):
6812:             return None
6813:         customer_key = record.get("customer_key")
6814:         session_id = record.get("session_id")
6815:         if not isinstance(customer_key, str) or not isinstance(session_id, str):
6816:             return None
6817:         return customer_key, session_id
6818:
6819:     def prepare_delivery(
6820:         self,
6821:         draft_id: str,
6822:         owner: IncomingAddress,
6823:         *,
6824:         expected_generation: int | None = None,
6825:         expected_record_digest: str | None = None,
6826:         expected_checkin_revision: str | None = None,
6827:         expected_draft_revision: str | None = None,
6828:     ) -> DraftAction:
6829:         """Durably reserve an approved revision before any customer transport."""
6830:         if not self._ensure_live_registry():
6831:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
6832:         if owner.key != self.owner.key:
6833:             return DraftAction(False, draft_id=draft_id, error="owner_only")
6834:         with self._delivery_lock():
6835:             if not self._ensure_live_registry():
6836:                 return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
6837:             try:
6838:                 drafts = self._read_drafts()
6839:                 _ = self._read_requests()
6840:                 deliveries = self._read_deliveries()
6841:             except DraftLedgerError as exc:
6842:                 return DraftAction(False, draft_id=draft_id, error=self._ledger_error(exc))
6843:             return self._prepare_delivery_locked(
6844:                 draft_id,
6845:                 owner,
6846:                 drafts,
6847:                 deliveries,
6848:                 expected_generation=expected_generation,
6849:                 expected_record_digest=expected_record_digest,
6850:                 expected_checkin_revision=expected_checkin_revision,
6851:                 expected_draft_revision=expected_draft_revision,
6852:             )
6853:
6854:     def _prepare_delivery_locked(
6855:         self,
6856:         draft_id: str,
6857:         owner: IncomingAddress,
6858:         drafts: dict[str, dict[str, object]],
6859:         deliveries: dict[str, dict[str, object]],
6860:         *,
6861:         expected_generation: int | None = None,
6862:         expected_record_digest: str | None = None,
6863:         expected_checkin_revision: str | None = None,
6864:         expected_draft_revision: str | None = None,
6865:     ) -> DraftAction:
6866:         if not self._ensure_live_registry():
6867:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
6868:         record = drafts.get(draft_id)
6869:         eligibility_error = self._record_eligibility_error(record, owner)
6870:         if eligibility_error is not None:
6871:             return DraftAction(False, draft_id=draft_id, error=eligibility_error)
6872:         selection = self._draft_selection_from_record(record, owner)
6873:         if record is None or selection is None:
6874:             return DraftAction(False, draft_id=draft_id, error="draft_not_approved")
6875:         eligibility_error = self._selection_eligibility_error(selection)
6876:         if eligibility_error is not None:
6877:             return DraftAction(False, draft_id=draft_id, error=eligibility_error)
6878:         customer_spec = getattr(selection.customer, "spec", None)
6879:         if customer_spec is None:
6880:             return DraftAction(False, draft_id=draft_id, error="draft_customer_missing")
6881:         customer_key = str(getattr(customer_spec, "customer_key", ""))
6882:         approval_error = self._approved_record_error(draft_id, selection, record)
6883:         if record.get("status") not in {"approved", "sent"}:
6884:             return DraftAction(False, draft_id=draft_id, error="draft_not_approved")
6885:         text = str(record.get("text", "")).strip()
6886:         if telegram_utf16_length(text) > TELEGRAM_SINGLE_MESSAGE_LIMIT_UTF16:
6887:             return DraftAction(False, draft_id=draft_id, text=text, error="draft_text_too_long")
6888:         revision = self._draft_revision(text)
6889:         delivery_key = self._delivery_key(draft_id, text)
6890:         existing = deliveries.get(delivery_key)
6891:         capability = existing.get("delivery_capability") if isinstance(existing, dict) else None
6892:         if (
6893:             getattr(self, "_delivery_enabled", False) is not False
6894:             or not isinstance(capability, dict)
6895:             or capability.get("schema") != "draft-delivery-capability-v1"
6896:             or capability.get("status") not in {"issued", "consumed"}
6897:         ):
6898:             return DraftAction(
6899:                 False,
6900:                 draft_id=draft_id,
6901:                 error="delivery_capability_required",
6902:             )
6903:         try:
6904:             generation_history = self._read_draft_generations().get(draft_id)
6905:             if generation_history is None:
6906:                 return DraftAction(
6907:                     False,
6908:                     draft_id=draft_id,
6909:                     error="draft_generation_missing",
6910:                 )
6911:             current_generation = generation_history[-1]
6912:             receipt_boundary = deliveries.get(
6913:                 self._delivery_key(draft_id, text)
6914:             )
6915:             has_durable_provider_receipt = (
6916:                 current_generation.state
6917:                 is DraftGenerationState.DELIVERY_PENDING
6918:                 and isinstance(receipt_boundary, dict)
6919:                 and receipt_boundary.get("status") == "sent"
6920:                 and isinstance(receipt_boundary.get("message_id"), str)
6921:                 and bool(str(receipt_boundary["message_id"]).strip())
6922:             )
6923:             if approval_error is not None and not (
6924:                 approval_error == "draft_approval_evidence_missing"
6925:                 and (
6926:                     current_generation.state
6927:                     in {
6928:                         DraftGenerationState.DELIVERED,
6929:                         DraftGenerationState.SENT_AUDITED,
6930:                     }
6931:                     or has_durable_provider_receipt
6932:                 )
6933:             ):
6934:                 return DraftAction(False, draft_id=draft_id, error=approval_error)
6935:             if any(
6936:                 child_history[0].lineage_predecessor_digest
6937:                 == current_generation.record_digest
6938:                 for child_token, child_history in self._read_draft_generations().items()
6939:                 if child_token != draft_id
6940:             ):
6941:                 raise DraftGenerationTransitionError(
6942:                     "generation has an authoritative child intent"
6943:                 )
6944:             if (
6945:                 record.get("revision_binding_digest")
6946:                 != current_generation.checkin_revision
6947:                 or current_generation.draft_revision != revision
6948:                 or self._canonical_finalized_event_id(selection)
6949:                 != current_generation.checkin_event_id
6950:                 or expected_generation is None
6951:                 or expected_record_digest is None
6952:                 or expected_checkin_revision is None
6953:                 or expected_draft_revision is None
6954:                 or expected_generation != current_generation.generation
6955:                 or expected_record_digest != current_generation.record_digest
6956:                 or expected_checkin_revision != current_generation.checkin_revision
6957:                 or expected_draft_revision != current_generation.draft_revision
6958:             ):
6959:                 raise DraftGenerationTransitionError(
=== def claim_delivery_transport lines 2784-2932 ===
2784:                     self._delivery_ledger_path(),
2785:                     next_deliveries,
2786:                 )
2787:             except (OSError, ValueError):
2788:                 return False
2789:             return True
2790:
2791:
2792:     def claim_delivery_transport(
2793:         self,
2794:         draft_id: str,
2795:         owner: IncomingAddress,
2796:         destination: object,
2797:         text: str | None,
2798:         *,
2799:         card_route: IncomingAddress,
2800:         card_message_id: str,
2801:         card_nonce: str,
2802:         card_payload_digest: str,
2803:         now: datetime | None = None,
2804:         kst_date: date | datetime | None = None,
2805:     ) -> DeliveryDispatchClaim | None:
2806:         """Return an opaque claim only after capability consumption is durable."""
2807:         claimed = self.validate_delivery_transport(
2808:             draft_id, owner, destination, text, kst_date=kst_date,
2809:             card_route=card_route, card_message_id=card_message_id,
2810:             card_nonce=card_nonce, card_payload_digest=card_payload_digest, now=now,
2811:         )
2812:         if not claimed:
2813:             return None
2814:         return DeliveryDispatchClaim(hashlib.sha256(
2815:             f"{draft_id}\0{card_message_id}\0{card_nonce}".encode("utf-8")
2816:         ).hexdigest())
2817:
2818:     def record_customer_surface_receipt(
2819:         self,
2820:         claim: DeliveryDispatchClaim,
2821:         draft_id: str,
2822:         destination: object,
2823:         customer_text: str,
2824:         provider_message_id: str | int,
2825:     ) -> CustomerSurfaceReceipt:
2826:         """Corroborate a provider receipt without changing delivery state."""
2827:         message_id = str(provider_message_id).strip()
2828:         if (
2829:             not isinstance(claim, DeliveryDispatchClaim)
2830:             or not message_id
2831:             or len(message_id) > 128
2832:         ):
2833:             raise AdaptiveWorkflowError("customer surface receipt binding is invalid")
2834:         with self._delivery_lock():
2835:             try:
2836:                 deliveries = self._read_deliveries()
2837:                 row = deliveries.get(self._delivery_key(draft_id, customer_text))
2838:                 capability_value = (
2839:                     row.get("delivery_capability") if isinstance(row, dict) else None
2840:                 )
2841:                 capability = (
2842:                     cast(dict[str, object], capability_value)
2843:                     if isinstance(capability_value, dict)
2844:                     else None
2845:                 )
2846:                 bindings_value = capability.get("bindings") if capability is not None else None
2847:                 bindings = (
2848:                     cast(dict[str, object], bindings_value)
2849:                     if isinstance(bindings_value, dict)
2850:                     else None
2851:                 )
2852:                 history_value = self._read_draft_generations().get(draft_id)
2853:                 history = (
2854:                     tuple(
2855:                         DraftGenerationRecord.from_dict(record.as_dict())
2856:                         for record in history_value
2857:                     )
2858:                     if history_value
2859:                     else ()
2860:                 )
2861:                 if history:
2862:                     _validate_draft_generation_history(history)
2863:                 terminal_generation = history[-1] if history else None
2864:                 approved_generation = next(
2865:                     (
2866:                         record
2867:                         for record in history
2868:                         if record.generation == row.get("generation")
2869:                         and record.record_digest
2870:                         == row.get("generation_record_digest")
2871:                     ),
2872:                     None,
2873:                 ) if isinstance(row, dict) else None
2874:                 approved_card_value = row.get("approved_card") if isinstance(row, dict) else None
2875:                 approved_card = (
2876:                     cast(dict[str, object], approved_card_value)
2877:                     if isinstance(approved_card_value, dict)
2878:                     else None
2879:                 )
2880:                 expected_claim = (
2881:                     hashlib.sha256(
2882:                         f"{draft_id}\0{approved_card.get('message_id')}\0{approved_card.get('nonce')}".encode(
2883:                             "utf-8"
2884:                         )
2885:                     ).hexdigest()
2886:                     if approved_card is not None
2887:                     else ""
2888:                 )
2889:                 route = tuple(
2890:                     str(getattr(destination, field, "") or "")
2891:                     for field in ("user_id", "chat_id", "topic_id")
2892:                 )
2893:                 if (
2894:                     not isinstance(row, dict)
2895:                     or row.get("status") not in {"sent", "sent_audited"}
2896:                     or row.get("message_id") != message_id
2897:                     or row.get("text") != customer_text
2898:                     or row.get("draft_id") != draft_id
2899:                     or claim.claim_id != expected_claim
2900:                     or capability is None
2901:                     or capability.get("status") != "consumed"
2902:                     or bindings is None
2903:                     or approved_generation is None
2904:                     or approved_generation.state is not DraftGenerationState.APPROVED
2905:                     or terminal_generation is None
2906:                     or terminal_generation.generation <= approved_generation.generation
2907:                     or terminal_generation.customer_key != approved_generation.customer_key
2908:                     or terminal_generation.checkin_event_id
2909:                     != approved_generation.checkin_event_id
2910:                     or terminal_generation.checkin_revision
2911:                     != approved_generation.checkin_revision
2912:                     or terminal_generation.draft_revision
2913:                     != approved_generation.draft_revision
2914:                     or terminal_generation.model_contract_version
2915:                     != approved_generation.model_contract_version
2916:                     or terminal_generation.provider_contract_version
2917:                     != approved_generation.provider_contract_version
2918:                     or terminal_generation.delivery_provider_contract_version
2919:                     != approved_generation.delivery_provider_contract_version
2920:                     or terminal_generation.created_at != approved_generation.created_at
2921:                     or terminal_generation.max_attempts != approved_generation.max_attempts
2922:                     or terminal_generation.lineage_predecessor_digest
2923:                     != approved_generation.lineage_predecessor_digest
2924:                     or terminal_generation.lineage_parent_token
2925:                     != approved_generation.lineage_parent_token
2926:                     or terminal_generation.generation_provider_receipt
2927:                     != approved_generation.generation_provider_receipt
2928:                     or row.get("customer_key") != approved_generation.customer_key
2929:                     or row.get("checkin_revision")
2930:                     != approved_generation.checkin_revision
2931:                     or row.get("canonical_payload_digest")
2932:                     != approved_generation.draft_revision
=== def record_delivery_transport_receipt lines 7137-7285 ===
7137:     def prepare_send_draft(self, draft_id: str, owner: IncomingAddress) -> DraftAction:
7138:         """Compatibility name for :meth:`prepare_delivery`."""
7139:         return self.prepare_delivery(draft_id, owner)
7140:
7141:     def mark_delivery_pending(self, draft_id: str, owner: IncomingAddress) -> DraftAction:
7142:         """Ensure an approved revision has a durable pending reservation."""
7143:         return self.prepare_delivery(draft_id, owner)
7144:
7145:     def record_delivery_transport_receipt(
7146:         self,
7147:         draft_id: str,
7148:         owner: IncomingAddress,
7149:         message_id: str | int,
7150:         *,
7151:         expected_generation: int | None = None,
7152:         expected_record_digest: str | None = None,
7153:         expected_checkin_revision: str | None = None,
7154:         expected_draft_revision: str | None = None,
7155:     ) -> DraftAction:
7156:         """Durably bind a provider receipt before later delivery projections."""
7157:         action = self.prepare_delivery(
7158:             draft_id,
7159:             owner,
7160:             expected_generation=expected_generation,
7161:             expected_record_digest=expected_record_digest,
7162:             expected_checkin_revision=expected_checkin_revision,
7163:             expected_draft_revision=expected_draft_revision,
7164:         )
7165:         if not action.accepted or action.selection is None or action.text is None:
7166:             return action
7167:         receipt = str(message_id).strip()
7168:         if not receipt or len(receipt) > 128:
7169:             return DraftAction(
7170:                 False,
7171:                 draft_id=draft_id,
7172:                 error="delivery_message_id_invalid",
7173:             )
7174:         if action.status in {"sent", "delivered", "sent_audited"}:
7175:             if action.message_id != receipt:
7176:                 return DraftAction(
7177:                     False,
7178:                     draft_id=draft_id,
7179:                     error="delivery_receipt_conflict",
7180:                 )
7181:             return action
7182:         if action.status != "unknown_provider_outcome":
7183:             return DraftAction(
7184:                 False,
7185:                 draft_id=draft_id,
7186:                 error="delivery_outcome_not_unknown",
7187:             )
7188:         with self._delivery_lock():
7189:             try:
7190:                 record_gate = self._record_eligibility_error(
7191:                     self._read_drafts().get(draft_id),
7192:                     owner,
7193:                 )
7194:                 if record_gate is not None:
7195:                     return DraftAction(
7196:                         False,
7197:                         draft_id=draft_id,
7198:                         error=record_gate,
7199:                     )
7200:                 selection_gate = self._selection_eligibility_error(action.selection)
7201:                 if selection_gate is not None:
7202:                     return DraftAction(
7203:                         False,
7204:                         draft_id=draft_id,
7205:                         error=selection_gate,
7206:                     )
7207:                 deliveries = self._read_deliveries()
7208:                 key = self._delivery_key(draft_id, action.text)
7209:                 record = deliveries.get(key)
7210:                 if (
7211:                     record is None
7212:                     or record.get("status") != "unknown_provider_outcome"
7213:                 ):
7214:                     return DraftAction(
7215:                         False,
7216:                         draft_id=draft_id,
7217:                         error="delivery_outcome_not_unknown",
7218:                     )
7219:                 prior = record.get("message_id")
7220:                 if prior is not None and str(prior) != receipt:
7221:                     return DraftAction(
7222:                         False,
7223:                         draft_id=draft_id,
7224:                         error="delivery_receipt_conflict",
7225:                     )
7226:                 if prior is None:
7227:                     next_deliveries = dict(deliveries)
7228:                     recorded = dict(record)
7229:                     recorded["status"] = "sent"
7230:                     recorded["message_id"] = receipt
7231:                     next_deliveries[key] = recorded
7232:                     self._write_json_private(
7233:                         self._delivery_ledger_path(),
7234:                         next_deliveries,
7235:                     )
7236:             except (DraftLedgerError, OSError, ValueError):
7237:                 return DraftAction(
7238:                     False,
7239:                     draft_id=draft_id,
7240:                     error="delivery_receipt_write_failed",
7241:                 )
7242:         return replace(
7243:             action,
7244:             status="sent",
7245:             message_id=receipt,
7246:             transport_required=False,
7247:         )
7248:
7249:     def mark_delivered(
7250:         self,
7251:         draft_id: str,
7252:         owner: IncomingAddress,
7253:         message_id: str | int,
7254:         *,
7255:         expected_generation: int | None = None,
7256:         expected_record_digest: str | None = None,
7257:         expected_checkin_revision: str | None = None,
7258:         expected_draft_revision: str | None = None,
7259:     ) -> DraftAction:
7260:         """Persist the transport receipt before writing the canonical sent event."""
7261:         if not self._ensure_live_registry():
7262:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7263:         action = self.prepare_delivery(
7264:             draft_id,
7265:             owner,
7266:             expected_generation=expected_generation,
7267:             expected_record_digest=expected_record_digest,
7268:             expected_checkin_revision=expected_checkin_revision,
7269:             expected_draft_revision=expected_draft_revision,
7270:         )
7271:         if not action.accepted or action.selection is None or action.text is None:
7272:             return action
7273:         receipt = str(message_id).strip()
7274:         if not receipt or len(receipt) > 128:
7275:             return DraftAction(False, draft_id=draft_id, error="delivery_message_id_invalid")
7276:         if action.status == "unknown_provider_outcome":
7277:             action = self.record_delivery_transport_receipt(
7278:                 draft_id,
7279:                 owner,
7280:                 receipt,
7281:                 expected_generation=action.generation,
7282:                 expected_record_digest=action.generation_record_digest,
7283:                 expected_checkin_revision=action.generation_checkin_revision,
7284:                 expected_draft_revision=action.generation_draft_revision,
7285:             )
=== def mark_delivered lines 7241-7389 ===
7241:                 )
7242:         return replace(
7243:             action,
7244:             status="sent",
7245:             message_id=receipt,
7246:             transport_required=False,
7247:         )
7248:
7249:     def mark_delivered(
7250:         self,
7251:         draft_id: str,
7252:         owner: IncomingAddress,
7253:         message_id: str | int,
7254:         *,
7255:         expected_generation: int | None = None,
7256:         expected_record_digest: str | None = None,
7257:         expected_checkin_revision: str | None = None,
7258:         expected_draft_revision: str | None = None,
7259:     ) -> DraftAction:
7260:         """Persist the transport receipt before writing the canonical sent event."""
7261:         if not self._ensure_live_registry():
7262:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7263:         action = self.prepare_delivery(
7264:             draft_id,
7265:             owner,
7266:             expected_generation=expected_generation,
7267:             expected_record_digest=expected_record_digest,
7268:             expected_checkin_revision=expected_checkin_revision,
7269:             expected_draft_revision=expected_draft_revision,
7270:         )
7271:         if not action.accepted or action.selection is None or action.text is None:
7272:             return action
7273:         receipt = str(message_id).strip()
7274:         if not receipt or len(receipt) > 128:
7275:             return DraftAction(False, draft_id=draft_id, error="delivery_message_id_invalid")
7276:         if action.status == "unknown_provider_outcome":
7277:             action = self.record_delivery_transport_receipt(
7278:                 draft_id,
7279:                 owner,
7280:                 receipt,
7281:                 expected_generation=action.generation,
7282:                 expected_record_digest=action.generation_record_digest,
7283:                 expected_checkin_revision=action.generation_checkin_revision,
7284:                 expected_draft_revision=action.generation_draft_revision,
7285:             )
7286:             if not action.accepted:
7287:                 return action
7288:         with self._delivery_lock():
7289:             if not self._ensure_live_registry():
7290:                 return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7291:             try:
7292:                 return self._mark_delivered_locked(action, draft_id, owner, receipt)
7293:             except DraftLedgerError:
7294:                 return DraftAction(False, draft_id=draft_id, error="draft_ledger_corrupt")
7295:
7296:     def _mark_delivered_locked(
7297:         self,
7298:         action: DraftAction,
7299:         draft_id: str,
7300:         owner: IncomingAddress,
7301:         receipt: str,
7302:     ) -> DraftAction:
7303:         if not self._ensure_live_registry():
7304:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7305:         selection = action.selection
7306:         text = action.text
7307:         if selection is None or text is None:
7308:             return DraftAction(False, draft_id=draft_id, error="draft_delivery_state_invalid")
7309:         record_gate = self._record_eligibility_error(
7310:             self._read_drafts().get(draft_id),
7311:             owner,
7312:         )
7313:         if record_gate is not None:
7314:             return DraftAction(False, draft_id=draft_id, error=record_gate)
7315:         selection_gate = self._selection_eligibility_error(selection)
7316:         if selection_gate is not None:
7317:             return DraftAction(False, draft_id=draft_id, error=selection_gate)
7318:         if action.status == "sent_audited":
7319:             if action.message_id != receipt:
7320:                 return DraftAction(False, draft_id=draft_id, error="delivery_receipt_conflict")
7321:             return action
7322:         deliveries = self._read_deliveries()
7323:         key = self._delivery_key(draft_id, text)
7324:         record = deliveries.get(key)
7325:         if record is None or record.get("status") not in {"sent", "sent_audited"}:
7326:             return DraftAction(False, draft_id=draft_id, error="delivery_receipt_missing")
7327:         prior = record.get("message_id")
7328:         if prior is not None and str(prior) != receipt:
7329:             return DraftAction(False, draft_id=draft_id, error="delivery_receipt_conflict")
7330:         if record.get("status") == "sent_audited":
7331:             return replace(
7332:                 action,
7333:                 status="sent_audited",
7334:                 message_id=receipt,
7335:                 transport_required=False,
7336:             )
7337:         generation_history = self._read_draft_generations().get(draft_id)
7338:         if generation_history is None:
7339:             return DraftAction(False, draft_id=draft_id, error="draft_generation_missing")
7340:         delivered_generation = generation_history[-1]
7341:         if delivered_generation.state is DraftGenerationState.DELIVERED:
7342:             if delivered_generation.delivery_provider_receipt != receipt:
7343:                 return DraftAction(False, draft_id=draft_id, error="delivery_receipt_conflict")
7344:         else:
7345:             generation_plan = self._plan_draft_generation_transition(
7346:                 draft_id,
7347:                 DraftGenerationState.DELIVERED,
7348:                 owner=owner,
7349:                 expected_generation=action.generation,
7350:                 expected_record_digest=action.generation_record_digest,
7351:                 expected_checkin_revision=action.generation_checkin_revision,
7352:                 expected_draft_revision=action.generation_draft_revision,
7353:                 delivery_provider_receipt=receipt,
7354:             )
7355:             if generation_plan is None:
7356:                 return DraftAction(False, draft_id=draft_id, error="draft_generation_missing")
7357:             self._write_draft_generations(generation_plan)
7358:             delivered_generation = generation_plan[draft_id][-1]
7359:         return self._action_with_generation(
7360:             replace(
7361:                 action,
7362:                 status="delivered",
7363:                 message_id=receipt,
7364:                 transport_required=False,
7365:             ),
7366:             delivered_generation,
7367:         )
7368:
7369:     def mark_sent_audited(
7370:         self,
7371:         draft_id: str,
7372:         owner: IncomingAddress,
7373:         *,
7374:         expected_generation: int | None = None,
7375:         expected_record_digest: str | None = None,
7376:         expected_checkin_revision: str | None = None,
7377:         expected_draft_revision: str | None = None,
7378:     ) -> DraftAction:
7379:         """Reconcile a durable receipt into one canonical ``draft_sent`` event."""
7380:         if not self._ensure_live_registry():
7381:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7382:         action = self.prepare_delivery(
7383:             draft_id,
7384:             owner,
7385:             expected_generation=expected_generation,
7386:             expected_record_digest=expected_record_digest,
7387:             expected_checkin_revision=expected_checkin_revision,
7388:             expected_draft_revision=expected_draft_revision,
7389:         )
=== def mark_sent_audited lines 7361-7509 ===
7361:                 action,
7362:                 status="delivered",
7363:                 message_id=receipt,
7364:                 transport_required=False,
7365:             ),
7366:             delivered_generation,
7367:         )
7368:
7369:     def mark_sent_audited(
7370:         self,
7371:         draft_id: str,
7372:         owner: IncomingAddress,
7373:         *,
7374:         expected_generation: int | None = None,
7375:         expected_record_digest: str | None = None,
7376:         expected_checkin_revision: str | None = None,
7377:         expected_draft_revision: str | None = None,
7378:     ) -> DraftAction:
7379:         """Reconcile a durable receipt into one canonical ``draft_sent`` event."""
7380:         if not self._ensure_live_registry():
7381:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7382:         action = self.prepare_delivery(
7383:             draft_id,
7384:             owner,
7385:             expected_generation=expected_generation,
7386:             expected_record_digest=expected_record_digest,
7387:             expected_checkin_revision=expected_checkin_revision,
7388:             expected_draft_revision=expected_draft_revision,
7389:         )
7390:         if not action.accepted or action.selection is None or action.text is None:
7391:             return action
7392:         if action.status in {
7393:             "approved",
7394:             "pending",
7395:             "unknown_provider_outcome",
7396:         } or not action.message_id:
7397:             return DraftAction(
7398:                 False,
7399:                 draft_id=draft_id,
7400:                 text=action.text,
7401:                 status=action.status,
7402:                 selection=action.selection,
7403:                 error="delivery_receipt_pending",
7404:             )
7405:         with self._delivery_lock():
7406:             if not self._ensure_live_registry():
7407:                 return DraftAction(
7408:                     False,
7409:                     draft_id=draft_id,
7410:                     text=action.text,
7411:                     status=action.status,
7412:                     selection=action.selection,
7413:                     message_id=action.message_id,
7414:                     error="customer_registry_unavailable",
7415:                 )
7416:             try:
7417:                 return self._mark_sent_audited_locked(action, draft_id, owner)
7418:             except (DraftLedgerError, OSError, ValueError) as exc:
7419:                 return DraftAction(
7420:                     False,
7421:                     draft_id=draft_id,
7422:                     text=action.text,
7423:                     status="delivered",
7424:                     selection=action.selection,
7425:                     message_id=action.message_id,
7426:                     error=(
7427:                         "draft_ledger_corrupt"
7428:                         if isinstance(exc, DraftLedgerError)
7429:                         else f"draft_ledger_write_failed:{type(exc).__name__}"
7430:                     ),
7431:                 )
7432:
7433:     def _mark_sent_audited_locked(
7434:         self,
7435:         action: DraftAction,
7436:         draft_id: str,
7437:         owner: IncomingAddress,
7438:     ) -> DraftAction:
7439:         if not self._ensure_live_registry():
7440:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7441:         selection = action.selection
7442:         text = action.text
7443:         if selection is None or text is None:
7444:             return DraftAction(False, draft_id=draft_id, error="draft_delivery_state_invalid")
7445:         drafts = self._read_drafts()
7446:         draft_record = drafts.get(draft_id)
7447:         record_gate = self._record_eligibility_error(draft_record, owner)
7448:         if record_gate is not None:
7449:             return DraftAction(False, draft_id=draft_id, error=record_gate)
7450:         selection_gate = self._selection_eligibility_error(selection)
7451:         if selection_gate is not None:
7452:             return DraftAction(False, draft_id=draft_id, error=selection_gate)
7453:         if isinstance(draft_record, dict):
7454:             approval_error = self._approved_record_error(draft_id, selection, draft_record)
7455:             if approval_error is not None and not (
7456:                 approval_error == "draft_approval_evidence_missing"
7457:                 and action.status in {"delivered", "sent_audited"}
7458:             ):
7459:                 return DraftAction(False, draft_id=draft_id, error=approval_error)
7460:         deliveries = self._read_deliveries()
7461:         key = self._delivery_key(draft_id, text)
7462:         record = deliveries.get(key)
7463:         if record is None or not record.get("message_id"):
7464:             return DraftAction(False, draft_id=draft_id, error="delivery_receipt_missing")
7465:         generation_plan: dict[str, tuple[DraftGenerationRecord, ...]] | None = None
7466:         current_generation: DraftGenerationRecord | None = None
7467:         try:
7468:             generation_history = self._read_draft_generations().get(draft_id)
7469:             if generation_history is not None:
7470:                 current_generation = generation_history[-1]
7471:                 receipt = str(record["message_id"])
7472:                 if current_generation.state is DraftGenerationState.DELIVERED:
7473:                     generation_plan = self._plan_draft_generation_transition(
7474:                         draft_id,
7475:                         DraftGenerationState.SENT_AUDITED,
7476:                         owner=owner,
7477:                     )
7478:                 elif (
7479:                     current_generation.state is not DraftGenerationState.SENT_AUDITED
7480:                     or current_generation.delivery_provider_receipt != receipt
7481:                 ):
7482:                     raise DraftGenerationTransitionError(
7483:                         "generation delivery receipt is stale"
7484:                     )
7485:         except (DraftLedgerError, DraftGenerationTransitionError):
7486:             return DraftAction(
7487:                 False,
7488:                 draft_id=draft_id,
7489:                 error="draft_generation_stale",
7490:             )
7491:         if record.get("status") == "sent_audited":
7492:             if isinstance(draft_record, dict) and draft_record.get("status") != "sent":
7493:                 draft_record["status"] = "sent"
7494:                 drafts[draft_id] = draft_record
7495:                 self._write_json_private(self._drafts_path, drafts)
7496:             if generation_plan is not None:
7497:                 self._write_draft_generations(generation_plan)
7498:             return replace(
7499:                 action,
7500:                 status="sent_audited",
7501:                 message_id=str(record["message_id"]),
7502:                 transport_required=False,
7503:             )
7504:         if record.get("status") != "sent":
7505:             return DraftAction(False, draft_id=draft_id, error="delivery_receipt_missing")
7506:         if not self._ensure_live_registry():
7507:             return DraftAction(False, draft_id=draft_id, error="customer_registry_unavailable")
7508:         if not self._has_canonical_sent(
7509:             selection,
=== def persist_approved_delivery_card lines 6338-6486 ===
6338:     @staticmethod
6339:     def _route_projection(route: object) -> dict[str, str] | None:
6340:         projected = {
6341:             field: str(getattr(route, field, "") or "")
6342:             for field in ("user_id", "chat_id", "topic_id")
6343:         }
6344:         return projected if all(projected.values()) else None
6345:
6346:     def persist_approved_delivery_card(
6347:         self,
6348:         draft_id: str,
6349:         owner: IncomingAddress,
6350:         *,
6351:         card_route: IncomingAddress,
6352:         message_id: str,
6353:         nonce: str,
6354:         payload_digest: str,
6355:         expected_generation: int,
6356:         expected_record_digest: str,
6357:         expected_checkin_revision: str,
6358:         expected_draft_revision: str | None,
6359:     ) -> None:
6360:         """Persist the exact approved card only after Telegram confirms its edit."""
6361:         with self._delivery_lock():
6362:             drafts = self._read_drafts()
6363:             deliveries = self._read_deliveries()
6364:             record = drafts.get(draft_id)
6365:             selection = self._draft_selection_from_record(record, owner)
6366:             history = self._read_draft_generations().get(draft_id)
6367:             generation = history[-1] if history else None
6368:             route = self._route_projection(card_route)
6369:             if (
6370:                 getattr(self, "_delivery_enabled", False) is not False
6371:                 or owner.key != self.owner.key
6372:                 or not isinstance(record, dict)
6373:                 or selection is None
6374:                 or record.get("status") != "approved"
6375:                 or generation is None
6376:                 or generation.state is not DraftGenerationState.APPROVED
6377:                 or generation.generation != expected_generation
6378:                 or generation.record_digest != expected_record_digest
6379:                 or generation.checkin_revision != expected_checkin_revision
6380:                 or generation.draft_revision != expected_draft_revision
6381:                 or route is None
6382:                 or not message_id or len(message_id) > 128
6383:                 or re.fullmatch(r"[a-f0-9]{8}", nonce) is None
6384:                 or _DRAFT_GENERATION_DIGEST.fullmatch(payload_digest) is None
6385:             ):
6386:                 raise DraftGenerationTransitionError("approved delivery card is stale")
6387:             text = str(record["text"])
6388:             destination = selection.customer.spec.telegram
6389:             revision = self._draft_revision(text)
6390:             key = self._delivery_key(draft_id, text)
6391:             if deliveries.get(key) is not None:
6392:                 raise DraftGenerationTransitionError("approved delivery card already persisted")
6393:             deliveries[key] = {
6394:                 "draft_id": draft_id,
6395:                 "customer_key": str(selection.customer.spec.customer_key),
6396:                 "session_id": str(record["session_id"]),
6397:                 "text": text,
6398:                 "revision": revision,
6399:                 "approved_revision": str(record["approved_revision"]),
6400:                 "approved_event_id": str(record["approved_event_id"]),
6401:                 "checkin_revision": generation.checkin_revision,
6402:                 "generation": generation.generation,
6403:                 "generation_record_digest": generation.record_digest,
6404:                 "idempotency_key": self._delivery_idempotency_key(
6405:                     str(selection.customer.spec.customer_key),
6406:                     generation.checkin_revision,
6407:                     str(record["approved_revision"]),
6408:                 ),
6409:                 "canonical_payload_digest": revision,
6410:                 "provider_user_id": str(destination.user_id),
6411:                 "provider_chat_id": str(destination.chat_id),
6412:                 "provider_topic_id": str(destination.topic_id),
6413:                 "status": "awaiting_capability",
6414:                 "approved_card": {
6415:                     "route": route,
6416:                     "message_id": message_id,
6417:                     "nonce": nonce,
6418:                     "payload_digest": payload_digest,
6419:                 },
6420:             }
6421:             self._write_json_private(self._delivery_ledger_path(), deliveries)
6422:
6423:     def issue_delivery_capability(
6424:         self,
6425:         draft_id: str,
6426:         owner: IncomingAddress,
6427:         *,
6428:         launch_authorization: DeliveryLaunchAuthorization,
6429:         capability_id: str,
6430:         issued_at: datetime,
6431:         expected_generation: int,
6432:         expected_record_digest: str,
6433:         expected_checkin_revision: str,
6434:         expected_draft_revision: str | None,
6435:     ) -> DraftDeliveryCapability:
6436:         """Embed one fixed-ten-minute capability in the existing delivery ledger."""
6437:         if issued_at.tzinfo is None or not capability_id or len(capability_id) > 128:
6438:             raise ValueError("delivery capability issuance is invalid")
6439:         issued = issued_at.astimezone(timezone.utc)
6440:         expires = issued + timedelta(minutes=10)
6441:         with self._delivery_lock():
6442:             deliveries = self._read_deliveries()
6443:             matches = [
6444:                 (key, row) for key, row in deliveries.items()
6445:                 if row.get("draft_id") == draft_id
6446:             ]
6447:             if len(matches) != 1 or owner.key != self.owner.key or getattr(self, "_delivery_enabled", False) is not False:
6448:                 raise DraftGenerationTransitionError("delivery capability target is unavailable")
6449:             key, row = matches[0]
6450:             card = row.get("approved_card")
6451:             history = self._read_draft_generations().get(draft_id)
6452:             generation = history[-1] if history else None
6453:             if (
6454:                 row.get("status") != "awaiting_capability"
6455:                 or not isinstance(card, dict)
6456:                 or generation is None
6457:                 or generation.generation != expected_generation
6458:                 or generation.record_digest != expected_record_digest
6459:                 or generation.checkin_revision != expected_checkin_revision
6460:                 or generation.draft_revision != expected_draft_revision
6461:             ):
6462:                 raise DraftGenerationTransitionError("delivery capability target is stale")
6463:             bindings: dict[str, object] = {
6464:                 **asdict(launch_authorization),
6465:                 "customer_route": {
6466:                     "user_id": row["provider_user_id"],
6467:                     "chat_id": row["provider_chat_id"],
6468:                     "topic_id": row["provider_topic_id"],
6469:                 },
6470:                 "owner_route": self._route_projection(owner),
6471:                 "draft_id": draft_id,
6472:                 "generation": generation.generation,
6473:                 "generation_record_digest": generation.record_digest,
6474:                 "checkin_revision": generation.checkin_revision,
6475:                 "draft_revision": generation.draft_revision,
6476:                 "approved_revision": row["approved_revision"],
6477:                 "approved_event_id": row["approved_event_id"],
6478:                 "payload_digest": row["canonical_payload_digest"],
6479:                 "approved_card": card,
6480:             }
6481:             capability = DraftDeliveryCapability(capability_id, issued, expires, bindings)
6482:             updated = dict(row)
6483:             updated["status"] = "pending"
6484:             updated["delivery_capability"] = {
6485:                 "schema": "draft-delivery-capability-v1",
6486:                 "capability_id": capability_id,

[Showing lines 54-1050 of 1050 (50.0KB limit). Full output: /tmp/pi-bash-b12fcfb6e14eb668.log]


=== checkin_cli/nutrition_onboarding_clarification_policy.py ===
"""Deterministic clarification and safety policy for nutrition onboarding."""

from __future__ import annotations

from collections.abc import Mapping
from copy import deepcopy
from datetime import date
from decimal import Decimal, InvalidOperation
from typing import Literal, cast

from pydantic import BaseModel, ConfigDict

from checkin_cli.nutrition_onboarding_clarification_rules import (
    POLICY_DIGEST,
    POLICY_VERSION,
    QUESTION_COPY as _QUESTION_COPY,
    SENSITIVE_FIELDS as _SENSITIVE_FIELDS,
    VISIBLE_ISSUE_LIMIT as _VISIBLE_ISSUE_LIMIT,
)
from checkin_cli.nutrition_onboarding_contract import QUESTION_FIELDS, canonical_digest
from checkin_cli.nutrition_onboarding_models import (
    build_onboarding_baseline,
    canonical_equation_sex_basis,
    derive_adult_age,
)

class _PolicyModel(BaseModel):
    model_config = ConfigDict(extra="forbid", frozen=True)

class ClarificationIssue(_PolicyModel):
    issue_id: str
    field: str
    reason_code: str
    question_ko: str

class SafetyHold(_PolicyModel):
    field: str
    reason_code: Literal["sensitive_input_requires_clinical_review"]

class ClarificationPolicyResult(_PolicyModel):
    policy_version: str
    policy_digest: str
    reference_date: date
    answers: dict[str, object]
    answers_digest: str
    issues: tuple[ClarificationIssue, ...]
    visible_issue_ids: tuple[str, ...]
    holds: tuple[SafetyHold, ...]
    result_digest: str

def _canonical_decimal(value: object) -> str | None:
    if isinstance(value, bool) or not isinstance(value, (str, int, float, Decimal)):
        return None
    parsed = _decimal(value)
    if parsed is None or not parsed.is_finite():
        return None
    rendered = format(parsed.normalize(), "f")
    return rendered.rstrip("0").rstrip(".") if "." in rendered else rendered

def canonicalize_answer(field: str, value: object) -> object:
    """Canonicalize one boundary value without accepting an invalid type."""
    if field == "equation_sex_basis":
        return canonical_equation_sex_basis(value) or value
    if field in {"height_cm", "weight_kg", "target_weight_kg"} and value is not None:
        return _canonical_decimal(value) or value
    return deepcopy(value)

def _canonical_answers(answers: Mapping[str, object]) -> dict[str, object]:
    return {
        field: canonicalize_answer(field, answers[field])
        for field in QUESTION_FIELDS
        if field in answers
    }

def _is_ambiguous(value: object) -> bool:
    if isinstance(value, str):
        return any(marker in value for marker in (" 또는 ", " 혹은 "))
    if isinstance(value, Mapping):
        return any(_is_ambiguous(item) for item in value.values())
    if isinstance(value, (list, tuple)):
        return any(_is_ambiguous(item) for item in value)
    return False

def _valid_structured(value: object) -> bool:
    if not isinstance(value, dict) or set(value) != {"status", "items"}:
        return False
    structured = cast(dict[str, object], value)
    status = structured.get("status")
    items = structured.get("items")
    if not isinstance(items, list) or any(not isinstance(item, str) for item in items):
        return False
    typed_items = cast(list[str], items)
    return (status == "none" and not typed_items) or (
        status == "provided"
        and bool(typed_items)
        and all(item.strip() for item in typed_items)
    )

def _sensitive(field: str, value: object) -> bool:
    if field in {"conditions", "medications"}:
        return _valid_structured(value) and cast(
            dict[str, object], value
        ).get("status") == "provided"
    return (value is True or value is None) and field in {
        "pregnancy_breastfeeding",
        "eating_disorder_risk",
    }

def _safe_adult_dob(reference_date: date) -> str:
    try:
        return reference_date.replace(year=reference_date.year - 30).isoformat()
    except ValueError:
        return reference_date.replace(year=reference_date.year - 30, day=28).isoformat()

def _decimal(value: object) -> Decimal | None:
    try:
        return Decimal(str(value))
    except (InvalidOperation, TypeError, ValueError):
        return None

def _type_reasons(answers: Mapping[str, object], reasons: dict[str, str]) -> None:
    structured = {
        "allergies",
        "intolerances",
        "religious_ethical_exclusions",
        "disliked_foods",
        "dietary_preferences",
        "conditions",
        "medications",
    }
    for field in structured:
        if field in answers and not _valid_structured(answers[field]):
            reasons.setdefault(field, "invalid_value")
    for field in ("pregnancy_breastfeeding", "eating_disorder_risk"):
        if field in answers and answers[field] is not None and type(answers[field]) is not bool:
            reasons.setdefault(field, "invalid_value")
    if "meal_count" in answers and type(answers["meal_count"]) is not int:
        reasons.setdefault("meal_count", "invalid_value")

def _cross_field_reasons(answers: Mapping[str, object], reasons: dict[str, str]) -> None:
    goal = answers.get("goal_type")
    target_weight = answers.get("target_weight_kg")
    target_date = answers.get("target_date")
    if goal == "maintain":
        if target_weight is not None:
            reasons.setdefault("target_weight_kg", "target_not_allowed")
        if target_date is not None:
            reasons.setdefault("target_date", "target_not_allowed")
        return
    if goal not in {"loss", "gain"}:
        return
    if target_weight is None:
        reasons.setdefault("target_weight_kg", "target_required")
    if target_date is None:
        reasons.setdefault("target_date", "target_required")
    current = _decimal(answers.get("weight_kg"))
    target = _decimal(target_weight)
    if current is None or target is None:
        return
    if goal == "loss" and target >= current:
        reasons.setdefault("target_weight_kg", "target_direction_invalid")
    if goal == "gain" and target <= current:
        reasons.setdefault("target_weight_kg", "target_direction_invalid")

def _baseline_reasons(
    answers: Mapping[str, object],
    reasons: dict[str, str],
    reference_date: date,
) -> None:
    payload = dict(answers)
    raw_dob = payload.get("date_of_birth")
    try:
        if not isinstance(raw_dob, str):
            raise ValueError("date_of_birth is required")
        parsed_dob = date.fromisoformat(raw_dob)
        derive_adult_age(parsed_dob, as_of=reference_date)
    except (TypeError, ValueError):
        reasons.setdefault("date_of_birth", "invalid_date_of_birth")
        payload["date_of_birth"] = _safe_adult_dob(reference_date)
    payload.update(
        schema_version="1.0",
        customer_key="policy_validation",
        session_status="completed",
        review_decision="pending",
        publication_status="unpublished",
    )
    try:
        build_onboarding_baseline(payload, as_of=reference_date)
    except ValueError as exc:
        errors = getattr(exc, "errors", lambda: ())()
        for error in errors:
            location = error.get("loc", ())
            if not location:
                continue  # Explicit cross-field rules above own root errors.
            field = str(location[0])
            if field == "adult_age":
                field = "date_of_birth"
            if field in QUESTION_FIELDS:
                reasons.setdefault(field, "invalid_value")

def _issue(field: str, reason_code: str, value: object) -> ClarificationIssue:
    return ClarificationIssue(
        issue_id=canonical_digest(
            {
                "policy_version": POLICY_VERSION,
                "policy_digest": POLICY_DIGEST,
                "field": field,
                "reason_code": reason_code,
                "value_digest": canonical_digest(value),
            }
        ),
        field=field,
        reason_code=reason_code,
        question_ko=_QUESTION_COPY[field],
    )

def compile_clarification_policy(
    answers: Mapping[str, object],
    *,
    reference_date: date,
) -> ClarificationPolicyResult:
    """Compile every ordered issue and hold against an explicit reference date."""
    canonical = _canonical_answers(answers)
    answers_digest = canonical_digest(canonical)
    reasons: dict[str, str] = {}
    for field in QUESTION_FIELDS:
        if field not in canonical:
            reasons[field] = "missing_value"
        elif _is_ambiguous(canonical[field]):
            reasons[field] = (
                "multiple_measurements"
                if field in {"height_cm", "weight_kg", "target_weight_kg"}
                else "multiple_values"
            )
    _type_reasons(canonical, reasons)
    _cross_field_reasons(canonical, reasons)
    _baseline_reasons(canonical, reasons, reference_date)

    holds = tuple(
        SafetyHold(field=field, reason_code="sensitive_input_requires_clinical_review")
        for field in _SENSITIVE_FIELDS
        if field in canonical and _sensitive(field, canonical[field])
    )
    for hold in holds:
        reasons.pop(hold.field, None)
    issues = tuple(
        _issue(field, reasons[field], canonical.get(field))
        for field in QUESTION_FIELDS
        if field in reasons
    )
    visible_issue_ids = tuple(issue.issue_id for issue in issues[:_VISIBLE_ISSUE_LIMIT])
    result_payload = {
        "policy_version": POLICY_VERSION,
        "policy_digest": POLICY_DIGEST,
        "reference_date": reference_date.isoformat(),
        "answers_digest": answers_digest,
        "issues": [issue.model_dump(mode="json") for issue in issues],
        "visible_issue_ids": visible_issue_ids,
        "holds": [hold.model_dump(mode="json") for hold in holds],
    }
    return ClarificationPolicyResult(
        policy_version=POLICY_VERSION,
        policy_digest=POLICY_DIGEST,
        reference_date=reference_date,
        answers=canonical,
        answers_digest=answers_digest,
        issues=issues,
        visible_issue_ids=visible_issue_ids,
        holds=holds,
        result_digest=canonical_digest(result_payload),
    )

=== checkin_cli/nutrition_onboarding_authority.py ===
"""Current-authority checks for onboarding mutations."""

from __future__ import annotations

from pathlib import Path

from checkin_cli.customer_coaching import load_customer_registry
from checkin_cli.nutrition_onboarding_contract import (
    MessageEvidence,
    OnboardingAuthority,
)
from checkin_cli.nutrition_onboarding_models import NutritionOnboardingBaseline

def validate_authority(authority: OnboardingAuthority, *, customer_key: str) -> None:
    if authority.customer_key != customer_key:
        raise ValueError("customer authority mismatch")
    if not authority.consent_granted or authority.consent_notice_version != "privacy-v1":
        raise ValueError("current privacy-v1 consent is required")
    if authority.customer_enabled:
        raise ValueError("onboarding target must remain disabled")

def validate_route(
    authority: OnboardingAuthority,
    evidence: MessageEvidence,
    *,
    role: str,
) -> None:
    expected = (
        getattr(authority, f"{role}_user_id"),
        getattr(authority, f"{role}_chat_id"),
        getattr(authority, f"{role}_topic_id"),
    )
    actual = (evidence.actor_user_id, evidence.chat_id, evidence.topic_id)
    if actual != expected:
        raise ValueError(f"{role} route does not match")

def validate_current_registry_authority(
    profile_root: Path,
    authority: OnboardingAuthority,
) -> None:
    root = Path(profile_root)
    registry = load_customer_registry(
        root / "customers" / "registry.json",
        root,
    )
    matches = [
        customer
        for customer in registry.customers
        if customer.spec.customer_key == authority.customer_key
    ]
    if len(matches) != 1:
        raise ValueError("current onboarding customer authority is unavailable")
    customer = matches[0].spec
    if (
        customer.enabled
        or not customer.ai_processing_consent.granted
        or customer.ai_processing_consent.notice_version != "privacy-v1"
    ):
        raise ValueError("current onboarding consent or state is invalid")
    expected = (
        customer.telegram.key,
        registry.owner.key,
    )
    actual = (
        tuple(str(value) for value in (
            authority.customer_user_id,
            authority.customer_chat_id,
            authority.customer_topic_id,
        )),
        tuple(str(value) for value in (
            authority.owner_user_id,
            authority.owner_chat_id,
            authority.owner_topic_id,
        )),
    )
    if actual != expected:
        raise ValueError("current onboarding routes have changed")

def requires_safety_hold(baseline: NutritionOnboardingBaseline) -> bool:
    return (
        baseline.conditions.status.value == "provided"
        or baseline.medications.status.value == "provided"
        or baseline.pregnancy_breastfeeding is not False
        or baseline.eating_disorder_risk is not False
    )

=== checkin_cli/customer_cleanup_fs.py ===
"""Private filesystem and journal primitives for customer cleanup."""

from __future__ import annotations

import hashlib
import json
import os
import stat
from collections.abc import Iterable
from pathlib import Path

from checkin_cli.customer_cleanup_models import CleanupIntegrityError

PHASES = ("prepared", "copied_verified", "source_pruned", "committed")

def canonical(value: object) -> bytes:
    return json.dumps(value, ensure_ascii=True, sort_keys=True, separators=(",", ":")).encode()

def digest_bytes(value: bytes) -> str:
    return hashlib.sha256(value).hexdigest()

def ensure_private_dir(path: Path) -> None:
    path.mkdir(parents=True, exist_ok=True, mode=0o700)
    path.chmod(0o700)
    info = path.lstat()
    if stat.S_ISLNK(info.st_mode) or not stat.S_ISDIR(info.st_mode):
        raise CleanupIntegrityError("cleanup directory is not a regular directory")
    if info.st_uid != os.geteuid() or stat.S_IMODE(info.st_mode) != 0o700:
        raise CleanupIntegrityError("cleanup directory is not owner-only")

def validate_file(path: Path) -> os.stat_result:
    info = path.lstat()
    if stat.S_ISLNK(info.st_mode):
        raise CleanupIntegrityError(f"cleanup source symlink is forbidden: {path}")
    if not stat.S_ISREG(info.st_mode):
        raise CleanupIntegrityError(f"cleanup source is not regular: {path}")
    if info.st_nlink != 1:
        raise CleanupIntegrityError(f"cleanup source is hard-linked: {path}")
    if info.st_uid != os.geteuid() or stat.S_IMODE(info.st_mode) & 0o077:
        raise CleanupIntegrityError(f"cleanup source must be owner-only: {path}")
    return info

def safe_relative(path: Path, root: Path, customer_key: str) -> str:
    lexical = path.absolute()
    try:
        relative = lexical.relative_to(root)
    except ValueError as exc:
        raise CleanupIntegrityError("cleanup path traversal escapes profile") from exc
    current = root
    for part in relative.parts:
        current /= part
        if current.is_symlink():
            raise CleanupIntegrityError(f"cleanup source symlink is forbidden: {current}")
    parts = relative.parts
    for index, part in enumerate(parts[:-1]):
        if part == "customers" and parts[index + 1] != customer_key:
            raise CleanupIntegrityError("cross-customer cleanup path is forbidden")
    return relative.as_posix()

def source_inventory(
    root: Path, customer_key: str, candidates: Iterable[Path]
) -> list[dict[str, object]]:
    customer_root = root / "data" / "customers" / customer_key
    paths: set[Path] = set()
    if customer_root.exists() or customer_root.is_symlink():
        if customer_root.is_symlink():
            raise CleanupIntegrityError("cleanup customer root symlink is forbidden")
        for current, directories, files in os.walk(customer_root, followlinks=False):
            base = Path(current)
            for name in directories:
                child = base / name
                if child.is_symlink():
                    raise CleanupIntegrityError(f"cleanup source symlink is forbidden: {child}")
            paths.update(base / name for name in files)
    for candidate in candidates:
        path = candidate if candidate.is_absolute() else root / candidate
        relative = safe_relative(path, root, customer_key)
        if f"/customers/{customer_key}/" not in f"/{relative}" and customer_key not in Path(relative).name:
            raise CleanupIntegrityError("candidate path is not customer-scoped")
        paths.add(path)
    rows: list[dict[str, object]] = []
    for path in paths:
        relative = safe_relative(path, root, customer_key)
        info = validate_file(path)
        payload = path.read_bytes()
        after = path.stat()
        if (info.st_dev, info.st_ino, info.st_size) != (after.st_dev, after.st_ino, after.st_size):
            raise CleanupIntegrityError("cleanup source changed while inventoried")
        rows.append({
            "relative_path": relative,
            "mode": stat.S_IMODE(info.st_mode),
            "size": len(payload),
            "sha256": digest_bytes(payload),
        })
    return sorted(rows, key=lambda row: str(row["relative_path"]))

def write_private(path: Path, payload: bytes, *, exclusive: bool = False) -> None:
    ensure_private_dir(path.parent)
    flags = os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_NOFOLLOW
    flags |= os.O_EXCL if exclusive else os.O_TRUNC
    descriptor = os.open(path, flags, 0o600)
    try:
        os.fchmod(descriptor, 0o600)
        remaining = memoryview(payload)
        while remaining:
            remaining = remaining[os.write(descriptor, remaining) :]
        os.fsync(descriptor)
    finally:
        os.close(descriptor)

def append_phase(
    journal: Path,
    phase: str,
    operation_id: str,
    *,
    manifest_sha256: str | None = None,
) -> None:
    rows = read_journal(journal)
    expected = PHASES[len(rows)] if len(rows) < len(PHASES) else None
    if phase != expected:
        raise CleanupIntegrityError("cleanup journal phase is not forward-only")
    previous = digest_bytes(canonical(rows[-1])) if rows else "0" * 64
    row = {"operation_id": operation_id, "phase": phase, "previous_digest": previous}
    if manifest_sha256 is not None:
        row["manifest_sha256"] = manifest_sha256
    ensure_private_dir(journal.parent)
    descriptor = os.open(journal, os.O_APPEND | os.O_CREAT | os.O_WRONLY | os.O_NOFOLLOW, 0o600)
    try:
        os.fchmod(descriptor, 0o600)
        remaining = memoryview(canonical(row) + b"\n")
        while remaining:
            remaining = remaining[os.write(descriptor, remaining) :]
        os.fsync(descriptor)
    finally:
        os.close(descriptor)

def read_journal(path: Path) -> list[dict[str, object]]:
    if not path.exists():
        return []
    validate_file(path)
    try:
        rows = [json.loads(line) for line in path.read_text().splitlines() if line]
    except (OSError, json.JSONDecodeError) as exc:
        raise CleanupIntegrityError("cleanup journal is invalid") from exc
    if [row.get("phase") for row in rows] != list(PHASES[: len(rows)]):
        raise CleanupIntegrityError("cleanup journal phase is not forward-only")
    operation_ids = {row.get("operation_id") for row in rows}
    if len(operation_ids) > 1:
        raise CleanupIntegrityError("cleanup journal operation changed")
    for index, row in enumerate(rows):
        expected = "0" * 64 if index == 0 else digest_bytes(canonical(rows[index - 1]))
        if row.get("previous_digest") != expected:
            raise CleanupIntegrityError("cleanup journal digest chain is invalid")
    return rows

def copy_inventory(root: Path, archive: Path, rows: list[dict[str, object]]) -> None:
    files_root = archive / "files"
    ensure_private_dir(files_root)
    for row in rows:
        source = root / str(row["relative_path"])
        validate_file(source)
        payload = source.read_bytes()
        if len(payload) != row["size"] or digest_bytes(payload) != row["sha256"]:
            raise CleanupIntegrityError("cleanup source changed before archive copy")
        destination = files_root / str(row["relative_path"])
        write_private(destination, payload, exclusive=not destination.exists())

def verify_archive(archive: Path, rows: list[dict[str, object]]) -> None:
    for row in rows:
        path = archive / "files" / str(row["relative_path"])
        try:
            validate_file(path)
            payload = path.read_bytes()
        except (OSError, CleanupIntegrityError) as exc:
            raise CleanupIntegrityError("archive verification failed") from exc
        if len(payload) != row["size"] or digest_bytes(payload) != row["sha256"]:
            raise CleanupIntegrityError("archive verification failed")

def prune_sources(root: Path, rows: list[dict[str, object]], customer_key: str) -> None:
    for row in rows:
        path = root / str(row["relative_path"])
        if not path.exists():
            continue
        validate_file(path)
        payload = path.read_bytes()
        if len(payload) != row["size"] or digest_bytes(payload) != row["sha256"]:
            raise CleanupIntegrityError("cleanup source changed before pruning")
        path.unlink()
    customer_root = root / "data" / "customers" / customer_key
    if customer_root.exists():
        for path in sorted(customer_root.rglob("*"), key=lambda item: len(item.parts), reverse=True):
            if path.is_dir():
                path.rmdir()
        customer_root.rmdir()

def freeze_archive(archive: Path) -> None:
    for path in archive.rglob("*"):
        path.chmod(0o500 if path.is_dir() else 0o400)
    archive.chmod(0o500)

=== checkin_cli/customer_cleanup_inventory.py ===
"""Independent post-cleanup customer authority inventory."""

from __future__ import annotations

import hashlib
import json
from pathlib import Path
from typing import Any

from checkin_cli.customer_admin import (
    CustomerAdminError,
    _require_customer_key,
    _resolve_profile_root,
    _resolve_registry_path,
)
from checkin_cli.customer_cleanup_fs import read_journal, validate_file, verify_archive
from checkin_cli.customer_cleanup_models import (
    AuthorityInventory,
    CleanupIntegrityError,
)
from checkin_cli.customer_cleanup_shared import (
    shared_authority_counts,
    verify_shared_projections,
)

_CATEGORIES = (
    "registry", "bootstrap", "onboarding", "outbox", "key", "owner_action",
    "service_state", "event", "customer_data", "activation", "sent_event",
    "candidate",
)
_PENDING_STATES = {"prepared", "sending", "delivered", "audit_pending"}
_UNKNOWN_STATES = {"unknown", "delivery_unknown"}
_JSONL_AUTHORITIES = {
    "customer-activation-audit.jsonl",
    "scheduled-deliveries.jsonl",
}
_ACTIVATION_JOURNAL = "customer-activation-journal.json"
_ACTIVATION_JOURNAL_REQUIRED_STRINGS = (
    "transaction_id",
    "customer_id",
    "registry_path",
    "data_root",
    "checklist_evidence_path",
    "audit_path",
    "registry_sha256",
    "previous_registry_sha256",
    "audit_record_sha256",
    "created_at",
    "prepared_at",
)

def read_registry_state(root: Path, key: str) -> tuple[bool, bool, bytes]:
    path = _resolve_registry_path(root)
    validate_file(path)
    payload = path.read_bytes()
    try:
        document = json.loads(payload)
        customer = next(row for row in document["customers"] if row["customer_key"] == key)
    except (KeyError, TypeError, StopIteration, json.JSONDecodeError) as exc:
        raise CustomerAdminError(f"unknown customer: {key}") from exc
    consent = customer.get("ai_processing_consent")
    granted = consent.get("granted") if isinstance(consent, dict) else None
    return customer.get("enabled") is False, granted is False, payload

def _customer_binding(row: dict[str, Any]) -> str:
    customer_key = row.get("customer_key")
    customer_id = row.get("customer_id")
    bindings = [
        value
        for value in (customer_key, customer_id)
        if isinstance(value, str) and value
    ]
    if not bindings or len(set(bindings)) != 1:
        raise TypeError("authority customer binding is invalid")
    if customer_key is not None and customer_key != bindings[0]:
        raise TypeError("authority customer_key is invalid")
    if customer_id is not None and customer_id != bindings[0]:
        raise TypeError("authority customer_id is invalid")
    return bindings[0]

def _validate_activation_journal(row: object) -> dict[str, Any]:
    if not isinstance(row, dict):
        raise TypeError("activation journal must be an object")
    if type(row.get("version")) is not int or row["version"] not in {1, 2, 3}:
        raise TypeError("activation journal version is invalid")
    if any(not isinstance(row.get(field), str) or not row[field] for field in _ACTIVATION_JOURNAL_REQUIRED_STRINGS):
        raise TypeError("activation journal required field is invalid")
    if not isinstance(row.get("state"), str) or not row["state"]:
        raise TypeError("activation journal state is invalid")
    if not isinstance(row.get("recovery_required"), bool):
        raise TypeError("activation journal recovery binding is invalid")
    if not isinstance(row.get("previous_registry"), dict):
        raise TypeError("activation journal rollback registry is invalid")
    previous_audit = row.get("previous_audit_sha256")
    if previous_audit is not None and (
        not isinstance(previous_audit, str) or not previous_audit
    ):
        raise TypeError("activation journal previous audit binding is invalid")
    if row["state"] == "committed" and (
        not isinstance(row.get("committed_at"), str) or not row["committed_at"]
    ):
        raise TypeError("activation journal commit binding is invalid")
    if row["state"] == "abandoned" and (
        not isinstance(row.get("abandoned_at"), str) or not row["abandoned_at"]
    ):
        raise TypeError("activation journal abandonment binding is invalid")
    if row["version"] in {2, 3} and not isinstance(
        row.get("nutrition_activation_receipt"), dict
    ):
        raise TypeError("activation journal nutrition receipt is invalid")
    if row["version"] == 3 and any(
        not isinstance(row.get(field), str) or not row[field]
        for field in (
            "staff_membership_evidence_path",
            "staff_membership_evidence_sha256",
            "staff_chat_inventory_sha256",
            "membership_subscription_epoch_id",
        )
    ):
        raise TypeError("activation journal membership binding is invalid")
    _customer_binding(row)
    return row

def relevant_rows(path: Path, key: str) -> list[dict[str, Any]]:
    if path.name != _ACTIVATION_JOURNAL and path.name not in _JSONL_AUTHORITIES:
        raise CleanupIntegrityError(f"unsupported authority file: {path}")
    if not path.exists():
        return []
    validate_file(path)
    try:
        payload = path.read_text(encoding="utf-8")
        if path.name == _ACTIVATION_JOURNAL:
            row = _validate_activation_journal(json.loads(payload))
            return [row] if _customer_binding(row) == key else []
        rows: list[dict[str, Any]] = []
        for line in payload.splitlines():
            value = json.loads(line)
            if not isinstance(value, dict):
                raise TypeError("authority row must be an object")
            if _customer_binding(value) == key:
                rows.append(value)
        return rows
    except (OSError, TypeError, UnicodeDecodeError, json.JSONDecodeError) as exc:
        raise CleanupIntegrityError(f"authority file is invalid: {path}") from exc

def _load_inventory_manifest(path: Path) -> dict[str, Any]:
    try:
        validate_file(path)
        value = json.loads(path.read_text(encoding="utf-8"))
        if not isinstance(value, dict) or not isinstance(value.get("inventory"), list):
            raise TypeError
        return value
    except (OSError, TypeError, json.JSONDecodeError) as exc:
        raise CleanupIntegrityError("cleanup manifest is invalid") from exc

def post_cleanup_authority_inventory(
    profile_root: Path | str, customer_key: str
) -> AuthorityInventory:
    """Independently enumerate every supported customer authority namespace."""
    root = _resolve_profile_root(Path(profile_root))
    key = _require_customer_key(customer_key)
    disabled, nonconsenting, _ = read_registry_state(root, key)
    categories = dict.fromkeys(_CATEGORIES, 0)
    active = 0
    if not disabled or not nonconsenting:
        categories["registry"] = active = 1
    customer_root = root / "data/customers" / key
    customer_files = list(customer_root.rglob("*")) if customer_root.exists() else []
    for path in customer_files:
        if not path.is_file():
            continue
        label = path.relative_to(customer_root).as_posix().lower().replace("-", "_")
        category = next(
            (name for name in (
                "bootstrap", "onboarding", "outbox", "key", "owner_action",
                "service_state", "event",
            ) if name in label),
            "customer_data",
        )
        categories[category] += 1
        active += 1
    shared_active, pending, unknown, terminal_owner_actions = shared_authority_counts(root, key)
    active += shared_active
    categories["owner_action"] += shared_active + terminal_owner_actions
    schedule_path = root / "data/scheduled-deliveries.jsonl"
    for row in relevant_rows(schedule_path, key):
        state = str(row.get("state", row.get("status", "")))
        if state in _PENDING_STATES:
            pending += 1
        elif state in _UNKNOWN_STATES or not state:
            unknown += 1
        else:
            categories["sent_event"] += 1
    activation_paths = (
        root / "data/customer-activation-journal.json",
        root / "data/customer-activation-audit.jsonl",
    )
    for path in activation_paths:
        for row in relevant_rows(path, key):
            categories["activation"] += 1
            if path.name == _ACTIVATION_JOURNAL and (
                row.get("state") not in {"committed", "abandoned"}
                or row.get("recovery_required") is not False
            ):
                unknown += 1
    cleanup = root / "data/customer-cleanup"
    excluded = {schedule_path, *activation_paths}
    for path in (root / "data").rglob("*"):
        if not path.is_file() or path in excluded or cleanup in path.parents:
            continue
        if customer_root in path.parents:
            continue
        relative = path.relative_to(root).as_posix().lower().replace("-", "_")
        if key not in relative:
            continue
        category = next(
            (name for name in (
                "bootstrap", "onboarding", "outbox", "key", "owner_action",
                "service_state", "event",
            ) if name in relative),
            "candidate",
        )
        categories[category] += 1
        active += 1
    journal = cleanup / f"{key}.journal.jsonl"
    journal_rows = read_journal(journal)
    committed = bool(journal_rows and journal_rows[-1].get("phase") == "committed")
    verified = False
    if journal_rows:
        operation = str(journal_rows[0]["operation_id"])
        archive = cleanup / "archives" / operation
        try:
            manifest_path = archive / "manifest.json"
            manifest = _load_inventory_manifest(manifest_path)
            manifest_digest = hashlib.sha256(manifest_path.read_bytes()).hexdigest()
            if manifest_digest != journal_rows[0].get("manifest_sha256"):
                raise CleanupIntegrityError("cleanup manifest digest mismatch")
            verify_archive(archive, manifest["inventory"])
            verify_shared_projections(
                root,
                archive,
                key,
                manifest.get("shared_ledger_projections", []),
            )
            verified = True
        except CleanupIntegrityError:
            pass
    orphan = active if committed else 0
    return AuthorityInventory.build(
        customer_key=key,
        disabled=disabled,
        nonconsenting=nonconsenting,
        categories=categories,
        active_count=active,
        pending_count=pending,
        unknown_count=unknown,
        orphan_count=orphan,
        archive_verified=verified,
        journal_committed=committed,
    )


--- sensitive values, location and redacted matched key only ---
data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/projections/data/owner-actions/draft-generations.json 7 ['token']
data/owner-actions/draft-deliveries.json 1 ['authorization']
data/owner-actions/draft-generations.json 7 ['token']
data/source-activation-checklist.json 1 ['token']
installed-provenance.json 16 ['secret', 'token']
source-provenance.json 2 ['token']
task26-evidence/05-unknown_delivery_no_retry.json 1 ['authorization']
verification-tools/source_golden_path.py 6 ['authorization', 'token']
verification-tools/verify_source_golden_path.py 2 ['token']
--- final cleanup evidence ---
{"candidate_digest":"310632f25b112373d97355c5ce3290dc55fb6d036a735e2b53861d983c4fd648","clause":"cleanup_resume_terminal","invocation_id":"d981545b0b33dda950737b351413f525","payload":{"active_count":0,"fault_phase":"copied_verified","fault_seen":true,"journal_sha256":"7b51e0ad9a157bbb042f6b682276a56e1696304ce25051d69bd9d4225e457223","operation_id":"7d763fc3fdcd4dc6be48b64011e303d7","orphan_count":0,"pending_count":0,"terminal":true,"terminal_phase":"committed","unknown_count":0},"schema":"task26-native-artifact-v1"}
--- stored customer archive/private data modes ---
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/.lock ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/adjustment-policy-v1.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/baseline-candidate.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/baseline-v1.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/initial-plan-v1.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/readiness-current.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/readiness-receipt-v1.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/ready.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/restriction-reconciliation-v1.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding/session.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/.adaptive.lock ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/.authority-transition.lock ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/adaptive-overlays.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/authority-mirror-intents.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/canonical-sequence.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/config-epoch-journal.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/events.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/feature-epoch.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/food-catalog.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/meal-constraints.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/policy-audit.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/policy-revisions.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/policy.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/source-day-intents.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans/source-days.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/.events.lock ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/.wizard.lock ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/drafts/0607736a25c74e1dd9957e77ff05b32b.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/events.jsonl ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/telegram-bindings.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/telegram-bindings.json.lock ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/views/current.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/views/weekly.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/manifest.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/projections/data/owner-actions/draft-generations.json ->
400 f .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/client_001.journal.jsonl ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7 ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001 ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-onboarding ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/nutrition-plans ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/drafts ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/files/data/customers/client_001/wizard/views ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/projections ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/projections/data ->
500 d .omo/evidence/task26/task26-isolated-bound-wheelhouse-installed-st_01a01574-v10/installed-golden-bundle/data/customer-cleanup/archives/7d763fc3fdcd4dc6be48b64011e303d7/projections/data/owner-actions ->