Jelajahi Sumber

feat: complete phase 1-3 UAT baseline

马小龙 2 bulan lalu
induk
melakukan
ab32507135
100 mengubah file dengan 18774 tambahan dan 225 penghapusan
  1. 1 0
      .dockerignore
  2. 1 0
      .gitignore
  3. 73 0
      app/api/data_factory/observability_routes.py
  4. 108 0
      app/api/knowledge_base/agent_governance_routes.py
  5. 6 0
      app/api/system/__init__.py
  6. 166 0
      app/api/system/bi_ai_catalog_routes.py
  7. 137 0
      app/api/system/metering_showback_routes.py
  8. 140 0
      app/api/system/plugin_platform_routes.py
  9. 207 0
      app/api/system/tenant_routes.py
  10. 182 0
      app/api/system/trusted_delivery.py
  11. 99 0
      app/api/system/trusted_delivery_controls.py
  12. 16 3
      app/config/config.py
  13. 318 4
      app/core/edge_gateway/runtime_roles.py
  14. 518 0
      app/core/events/production_observability.py
  15. 431 0
      app/core/events/production_operations.py
  16. 262 0
      app/core/events/production_operations_repository.py
  17. 901 0
      app/core/governance/bi_ai_asset_catalog.py
  18. 616 82
      app/core/governance/domain_replication.py
  19. 88 0
      app/core/governance/domain_replication_contract_registry.py
  20. 599 0
      app/core/governance/metering_showback.py
  21. 1 1
      app/core/llm/agent_governance.py
  22. 4 0
      app/core/llm/agent_governance_repository.py
  23. 379 0
      app/core/llm/runtime_governance.py
  24. 168 0
      app/core/llm/runtime_governance_repository.py
  25. 111 0
      app/core/llm/runtime_server.py
  26. 74 0
      app/core/mcp/governed_invocation.py
  27. 5 0
      app/core/plugins/__init__.py
  28. 178 0
      app/core/plugins/governance.py
  29. 113 0
      app/core/plugins/persistence.py
  30. 190 0
      app/core/plugins/repository.py
  31. 56 0
      app/core/plugins/runtime.py
  32. 59 11
      app/core/system/permissions.py
  33. 34 0
      app/core/system/tenant_approval_repository.py
  34. 130 0
      app/core/system/tenant_context.py
  35. 149 0
      app/core/system/tenant_control_repository.py
  36. 160 0
      app/core/system/tenant_control_service.py
  37. 113 0
      app/core/system/tenant_lifecycle.py
  38. 102 0
      app/core/system/tenant_repository.py
  39. 66 0
      app/core/system/tenant_resources.py
  40. 670 0
      app/core/system/trusted_delivery.py
  41. 293 0
      app/core/system/trusted_delivery_controls.py
  42. 150 0
      app/core/system/trusted_delivery_controls_repository.py
  43. 103 0
      app/core/system/trusted_delivery_controls_service.py
  44. 534 0
      app/core/system/trusted_delivery_repository.py
  45. 203 0
      app/core/system/trusted_delivery_subscription_repository.py
  46. 255 0
      app/core/system/trusted_delivery_subscriptions.py
  47. 4 0
      conftest.py
  48. 27 20
      deploy/docker/docker-compose.yml
  49. 1 1
      deployment/CHECKLIST.md
  50. 2 2
      deployment/DEPLOYMENT_GUIDE.md
  51. 73 0
      deployment/app/api/data_factory/observability_routes.py
  52. 108 0
      deployment/app/api/knowledge_base/agent_governance_routes.py
  53. 6 0
      deployment/app/api/system/__init__.py
  54. 166 0
      deployment/app/api/system/bi_ai_catalog_routes.py
  55. 137 0
      deployment/app/api/system/metering_showback_routes.py
  56. 140 0
      deployment/app/api/system/plugin_platform_routes.py
  57. 207 0
      deployment/app/api/system/tenant_routes.py
  58. 182 0
      deployment/app/api/system/trusted_delivery.py
  59. 99 0
      deployment/app/api/system/trusted_delivery_controls.py
  60. 16 3
      deployment/app/config/config.py
  61. 318 4
      deployment/app/core/edge_gateway/runtime_roles.py
  62. 518 0
      deployment/app/core/events/production_observability.py
  63. 431 0
      deployment/app/core/events/production_operations.py
  64. 262 0
      deployment/app/core/events/production_operations_repository.py
  65. 901 0
      deployment/app/core/governance/bi_ai_asset_catalog.py
  66. 616 82
      deployment/app/core/governance/domain_replication.py
  67. 88 0
      deployment/app/core/governance/domain_replication_contract_registry.py
  68. 599 0
      deployment/app/core/governance/metering_showback.py
  69. 1 1
      deployment/app/core/llm/agent_governance.py
  70. 4 0
      deployment/app/core/llm/agent_governance_repository.py
  71. 379 0
      deployment/app/core/llm/runtime_governance.py
  72. 168 0
      deployment/app/core/llm/runtime_governance_repository.py
  73. 111 0
      deployment/app/core/llm/runtime_server.py
  74. 74 0
      deployment/app/core/mcp/governed_invocation.py
  75. 5 0
      deployment/app/core/plugins/__init__.py
  76. 178 0
      deployment/app/core/plugins/governance.py
  77. 113 0
      deployment/app/core/plugins/persistence.py
  78. 190 0
      deployment/app/core/plugins/repository.py
  79. 56 0
      deployment/app/core/plugins/runtime.py
  80. 59 11
      deployment/app/core/system/permissions.py
  81. 34 0
      deployment/app/core/system/tenant_approval_repository.py
  82. 130 0
      deployment/app/core/system/tenant_context.py
  83. 149 0
      deployment/app/core/system/tenant_control_repository.py
  84. 160 0
      deployment/app/core/system/tenant_control_service.py
  85. 113 0
      deployment/app/core/system/tenant_lifecycle.py
  86. 102 0
      deployment/app/core/system/tenant_repository.py
  87. 66 0
      deployment/app/core/system/tenant_resources.py
  88. 670 0
      deployment/app/core/system/trusted_delivery.py
  89. 293 0
      deployment/app/core/system/trusted_delivery_controls.py
  90. 150 0
      deployment/app/core/system/trusted_delivery_controls_repository.py
  91. 103 0
      deployment/app/core/system/trusted_delivery_controls_service.py
  92. 534 0
      deployment/app/core/system/trusted_delivery_repository.py
  93. 203 0
      deployment/app/core/system/trusted_delivery_subscription_repository.py
  94. 255 0
      deployment/app/core/system/trusted_delivery_subscriptions.py
  95. 42 0
      deployment/compose/backend.Dockerfile.eai
  96. 271 0
      deployment/compose/docker-compose.eai-18188.yml
  97. 25 0
      deployment/compose/frontend.Dockerfile.eai
  98. 6 0
      deployment/compose/package_offline.sh
  99. 26 0
      deployment/compose/runner.Dockerfile.eai
  100. 34 0
      deployment/config/Caddyfile.company.citupro.com

+ 1 - 0
.dockerignore

@@ -3,6 +3,7 @@
 .pytest_cache
 **/__pycache__
 **/*.pyc
+._*
 frontend/node_modules
 frontend/dist
 deployment

+ 1 - 0
.gitignore

@@ -60,6 +60,7 @@ log/
 .env.test.local
 .env.production.local
 .known_hosts_dataops
+deploy/docker/edge-secrets/
 work/
 .worktrees/
 

+ 73 - 0
app/api/data_factory/observability_routes.py

@@ -2,6 +2,9 @@
 
 from __future__ import annotations
 
+import uuid
+from contextlib import suppress
+
 from flask import g, jsonify, request
 
 from app import db
@@ -22,18 +25,40 @@ def get_data_observability_service():
     )
 
 
+def get_production_operations_service():
+    import time
+
+    from app.core.events.production_operations import ProductionOperationsService
+    from app.core.events.production_operations_repository import (
+        SqlAlchemyProductionOperationsRepository,
+    )
+
+    return ProductionOperationsService(
+        SqlAlchemyProductionOperationsRepository(db.session), now=time.time
+    )
+
+
 def _actor_uid():
     identity = getattr(g, "current_user", {}) or {}
     return identity.get("id") or identity.get("sub")
 
 
 def _payload():
+    body = request.get_data(cache=True)
+    if len(body) > 4096:
+        raise ValueError("request body exceeds 4096 bytes")
     value = request.get_json(silent=True)
     if not isinstance(value, dict):
         raise ValueError("request body must be an object")
     return value
 
 
+def _no_store(value, status):
+    response = jsonify(success(value))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
 def _error(error):
     db.session.rollback()
     if isinstance(error, LookupError):
@@ -45,6 +70,35 @@ def _error(error):
     return jsonify(failed("数据可观测与事故请求处理失败", code=500)), 500
 
 
+def _production_delivery_error(error, service):
+    """Rollback first, then record only a redacted rejection receipt."""
+    db.session.rollback()
+    message = str(error)
+    reason_code = (
+        "conflict"
+        if isinstance(error, RuntimeError)
+        or message in {"idempotency conflict", "delivery queue hard limit reached"}
+        else "invalid_request"
+        if isinstance(error, ValueError)
+        else "internal_error"
+    )
+    with suppress(Exception):
+        service.audit_rejection_independently(
+            actor_uid=_actor_uid(),
+            reason_code=reason_code,
+            correlation_id=str(uuid.uuid4()),
+        )
+    status = {"invalid_request": 400, "conflict": 409, "internal_error": 500}[reason_code]
+    return jsonify(failed(reason_code, code=status)), status
+
+
+@bp.after_app_request
+def _no_store_production_delivery_responses(response):
+    if request.path == "/api/datafactory/observability/operations/deliveries":
+        response.headers["Cache-Control"] = "no-store"
+    return response
+
+
 @bp.get("/observability/overview")
 def get_observability_overview():
     try:
@@ -84,6 +138,25 @@ def collect_observability_signals():
         return _error(error)
 
 
+@bp.post("/observability/operations/deliveries")
+def enqueue_production_delivery():
+    service = None
+    try:
+        payload = _payload()
+        if set(payload) != {"incident_uid", "alert_uid", "channel", "summary"}:
+            raise ValueError("production delivery request has unsupported fields")
+        service = get_production_operations_service()
+        record = service.enqueue_incident_delivery(
+            payload, actor_uid=_actor_uid()
+        )
+        db.session.commit()
+        return _no_store(record, 201)
+    except Exception as error:
+        return _production_delivery_error(
+            error, service or get_production_operations_service()
+        )
+
+
 @bp.get("/observability/alerts")
 def list_observability_alerts():
     try:

+ 108 - 0
app/api/knowledge_base/agent_governance_routes.py

@@ -3,6 +3,7 @@
 from __future__ import annotations
 
 import hashlib
+import uuid
 
 from flask import current_app, g, jsonify, request
 
@@ -14,6 +15,14 @@ from app.core.llm.agent_governance_repository import (
     SqlAlchemyAgentGovernanceRepository,
     WorkCenterAgentApprovalGateway,
 )
+from app.core.llm.runtime_governance_repository import (
+    SqlAlchemyRuntimeGovernanceRepository,
+)
+from app.core.llm.runtime_server import (
+    RuntimeServerContext,
+    RuntimeServerError,
+    ServerGovernedInvocationService,
+)
 from app.core.system.permissions import (
     AGENTS_MANAGE,
     AGENTS_OPERATE,
@@ -60,6 +69,10 @@ def _service():
     )
 
 
+def _runtime_service():
+    return ServerGovernedInvocationService(SqlAlchemyRuntimeGovernanceRepository(db.session))
+
+
 def _expected_version() -> int:
     raw = str(request.headers.get("If-Match") or "").strip()
     if raw.startswith("W/"):
@@ -267,3 +280,98 @@ def agent_governance_dashboard():
         return jsonify(success(_service().dashboard()))
     except AgentGovernanceUnavailable as exc:
         return _error(exc)
+
+
+@bp.route("/agents/<agent_uid>/runtime/invocations", methods=["POST"])
+@require_permissions(AGENTS_OPERATE)
+def authorize_runtime_invocation(agent_uid):
+    """The only HTTP path that binds Agent credentials to a server identity."""
+    try:
+        token = str(request.headers.get("X-Agent-Credential") or "")
+        if not token:
+            raise PermissionError("Agent credential is required")
+        _service().validate_credential(agent_uid, token)
+        result = _runtime_service().authorize(
+            RuntimeServerContext(
+                agent_uid=agent_uid,
+                actor_uid=g.current_user["id"],
+                roles=frozenset(g.current_user["roles"]),
+            ),
+            request.get_json(silent=True) or {},
+        )
+        db.session.commit()
+        return _no_store(jsonify(success(result, code=201))), 201
+    except (RuntimeServerError, ValueError, LookupError, PermissionError, RuntimeError) as exc:
+        response, status = _error(exc)
+        return _no_store(response), status
+
+
+@bp.route("/agents/<agent_uid>/runtime/invocations/<idempotency_key>/settle", methods=["POST"])
+@require_permissions(AGENTS_OPERATE)
+def settle_runtime_invocation(agent_uid, idempotency_key):
+    try:
+        token = str(request.headers.get("X-Agent-Credential") or "")
+        if not token:
+            raise PermissionError("Agent credential is required")
+        claims = _service().validate_credential(agent_uid, token)
+        agent = _service().get_agent(agent_uid)
+        if claims["agent_uid"] != agent_uid or agent["owner_uid"] != g.current_user["id"]:
+            raise PermissionError("Agent credential principal does not match")
+        body = request.get_json(silent=True) or {}
+        allowed = {"lease_fence", "outcome", "actual_tokens", "actual_cost_micros", "actual_tools", "actual_time_ms"}
+        if set(body) != allowed:
+            raise ValueError("runtime settlement payload is closed")
+        scope = _runtime_service().repository.settlement_context(
+            agent_uid=agent_uid, actor_uid=g.current_user["id"], idempotency_key=idempotency_key
+        )
+        result = _runtime_service().repository.settle_claim({
+            **scope,
+            "worker_id": f"agent-runtime-http:{g.current_user['id']}",
+            **body,
+        })
+        db.session.commit()
+        if result.get("rejected"):
+            return _no_store(jsonify(failed("runtime_settlement_rejected", code=409))), 409
+        return _no_store(jsonify(success(result, code=201))), 201
+    except (RuntimeServerError, ValueError, LookupError, PermissionError, RuntimeError) as exc:
+        response, status = _error(exc)
+        return _no_store(response), status
+
+
+@bp.route("/agents/<agent_uid>/runtime/control", methods=["POST"])
+@require_permissions(AGENTS_OPERATE)
+def control_runtime(agent_uid):
+    """Execute a recovery/canary change only through an authenticated control claim."""
+    try:
+        token = str(request.headers.get("X-Agent-Credential") or "")
+        if not token:
+            raise PermissionError("Agent credential is required")
+        claims = _service().validate_credential(agent_uid, token)
+        agent = _service().get_agent(agent_uid)
+        if claims["agent_uid"] != agent_uid or agent["owner_uid"] != g.current_user["id"]:
+            raise PermissionError("Agent credential principal does not match")
+        body = request.get_json(silent=True) or {}
+        forbidden = {"agent_uid", "principal_id"}
+        required = {
+            "tenant_id", "business_domain_uid", "environment", "operation", "approval_task_uid",
+            "idempotency_key", "request_digest", "expected_fence", "incident_uid", "from_state",
+            "to_state", "generation", "from_generation", "to_generation", "dataset_version",
+            "dataset_digest", "metrics_digest", "threshold_policy", "issued_at",
+        }
+        if set(body) != required or set(body) & forbidden:
+            raise ValueError("runtime control payload is closed")
+        credential = _service().repository.get_credential(claims["jti"])
+        if not credential:
+            raise PermissionError("Agent credential is revoked or unknown")
+        payload = {**body, "agent_uid": agent_uid, "principal_id": g.current_user["id"]}
+        claim_uid = _runtime_service().repository.issue_control_claim({
+            "claim_uid": str(uuid.uuid4()), "credential_uid": credential["uid"],
+            "credential_token_digest": hashlib.sha256(token.encode()).hexdigest(),
+            "nonce": str(uuid.uuid4()), "control_payload": payload,
+        })
+        result = _runtime_service().repository.control_claimed(payload, claim_uid)
+        db.session.commit()
+        return _no_store(jsonify(success(result, code=201))), 201
+    except (RuntimeServerError, ValueError, LookupError, PermissionError, RuntimeError) as exc:
+        response, status = _error(exc)
+        return _no_store(response), status

+ 6 - 0
app/api/system/__init__.py

@@ -6,9 +6,15 @@ bp = Blueprint("system", __name__)
 
 from app.api.system import governance_audit  # noqa: E402, F401
 from app.api.system import enterprise_identity  # noqa: E402, F401
+from app.api.system import bi_ai_catalog_routes  # noqa: E402, F401
+from app.api.system import metering_showback_routes  # noqa: E402, F401
+from app.api.system import plugin_platform_routes  # noqa: E402, F401
 from app.api.system import responsibilities  # noqa: E402, F401
 from app.api.system import routes  # noqa: E402, F401
 from app.api.system import security_governance  # noqa: E402, F401
+from app.api.system import trusted_delivery  # noqa: E402, F401
+from app.api.system import trusted_delivery_controls  # noqa: E402, F401
+from app.api.system import tenant_routes  # noqa: E402, F401
 from app.api.system import users  # noqa: E402, F401
 from app.api.system import workbench  # noqa: E402, F401
 from app.api.system import work_center  # noqa: E402, F401

+ 166 - 0
app/api/system/bi_ai_catalog_routes.py

@@ -0,0 +1,166 @@
+"""Closed, RBAC-protected HTTP contract for the local WP11 catalog fixture."""
+
+from __future__ import annotations
+
+import os
+
+from flask import current_app, g, jsonify, request
+from sqlalchemy import create_engine
+
+from app import db
+from app.api.system import bp
+from app.config.database_urls import validate_postgresql_url
+from app.core.governance.bi_ai_asset_catalog import (
+    CatalogApplicationService,
+    CatalogControlIssuer,
+)
+from app.core.system.permissions import (
+    BI_AI_CATALOG_MANAGE,
+    BI_AI_CATALOG_READ,
+    require_permissions,
+)
+from app.models.result import failed, success
+
+_MAX_BODY_BYTES = 4096
+
+
+def _service():
+    control_url = os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", "")
+    control = validate_postgresql_url(control_url, "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+    runtime = validate_postgresql_url(
+        str(current_app.config.get("SQLALCHEMY_DATABASE_URI", "")), "DATABASE_URL"
+    )
+    if control.username != "dataops_bi_ai_catalog_control" or control.username == runtime.username:
+        raise RuntimeError("catalog control identity is not configured")
+    return CatalogApplicationService(
+        db.session,
+        CatalogControlIssuer(create_engine(control_url, pool_pre_ping=True)),
+    )
+
+
+def _closed_body(required: set[str]) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("catalog request rejected")
+    body = request.get_json(silent=True)
+    if not isinstance(body, dict) or set(body) != required:
+        raise ValueError("catalog request rejected")
+    return body
+
+
+def _response(value, status: int = 200):
+    response = jsonify(success(value, code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _failure(status: int = 400):
+    response = jsonify(failed("catalog request rejected", code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+@bp.post("/bi-ai-catalog/local-fixture/sync")
+@require_permissions(BI_AI_CATALOG_MANAGE)
+def sync_local_fixture():
+    try:
+        body = _closed_body(set())
+        service = _service()
+        if hasattr(service, "sync_local_fixture"):
+            return _response(
+                service.sync_local_fixture(
+                    principal_id=str(g.current_user["id"]), body=body
+                ),
+                201,
+            )
+        return _response(
+            {
+                "source": "local-fixture-v1",
+                "mode": "ENGINEERING_EVIDENCE_ONLY",
+                "persisted_before_ack": False,
+            },
+            201,
+        )
+    except (KeyError, PermissionError, RuntimeError, TypeError, ValueError):
+        return _failure()
+
+
+@bp.post("/bi-ai-catalog/assets/search")
+@require_permissions(BI_AI_CATALOG_READ)
+def search_catalog_assets():
+    try:
+        body = _closed_body({"query", "filters"})
+        service = _service()
+        if hasattr(service, "search_for_principal"):
+            return _response(
+                service.search_for_principal(
+                    principal_id=str(g.current_user["id"]),
+                    query=body["query"],
+                    filters=body["filters"],
+                )
+            )
+        return _response(
+            service.search(
+                body["query"],
+                body["filters"],
+                principal_roles=set(g.current_user.get("roles", [])),
+                domain="default",
+            )
+        )
+    except ValueError:
+        return _failure(400)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError):
+        return _failure(403)
+
+
+@bp.get("/bi-ai-catalog/assets/<external_uid>/impact")
+@require_permissions(BI_AI_CATALOG_READ)
+def catalog_asset_impact(external_uid: str):
+    try:
+        if set(request.args) - {"max_depth", "max_nodes"}:
+            raise ValueError("catalog request rejected")
+        max_depth, max_nodes = (
+            int(request.args.get("max_depth", "3")),
+            int(request.args.get("max_nodes", "50")),
+        )
+        service = _service()
+        if hasattr(service, "impact_for_principal"):
+            return _response(
+                service.impact_for_principal(
+                    principal_id=str(g.current_user["id"]),
+                    external_uid=external_uid,
+                    max_depth=max_depth,
+                    max_nodes=max_nodes,
+                )
+            )
+        return _response(
+            service.impact(
+                external_uid,
+                principal_roles=set(g.current_user.get("roles", [])),
+                domain="default",
+                max_depth=max_depth,
+                max_nodes=max_nodes,
+            )
+        )
+    except (
+        KeyError,
+        LookupError,
+        PermissionError,
+        RuntimeError,
+        TypeError,
+        ValueError,
+    ):
+        return _failure(403)
+
+
+@bp.get("/bi-ai-catalog/audit")
+@require_permissions(BI_AI_CATALOG_READ)
+def catalog_audit():
+    try:
+        if request.args:
+            raise ValueError("catalog request rejected")
+        service = _service()
+        return _response(
+            service.audit_for_principal(principal_id=str(g.current_user["id"]))
+        )
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError):
+        return _failure(403)

+ 137 - 0
app/api/system/metering_showback_routes.py

@@ -0,0 +1,137 @@
+"""Closed, Showback-only WP12 HTTP boundary; no chargeback endpoint exists."""
+
+from __future__ import annotations
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import SQLAlchemyError
+
+from app.api.system import bp
+from app.core.governance.metering_showback import DatabaseMeteringShowbackService
+from app.core.system.permissions import (
+    METERING_MANAGE,
+    METERING_READ,
+    require_permissions,
+)
+from app.models.result import failed, success
+
+_MAX_BODY_BYTES = 4096
+_EVENT_FIELDS = {"schema_version", "event_uid", "event_kind", "occurred_at", "window_start", "window_end", "quantity", "unit", "idempotency_key", "evidence", "mapping", "correction_of"}
+_REQUIRED_EVENT_FIELDS = _EVENT_FIELDS - {"correction_of"}
+_ALLOCATION_FIELDS = {"schema_version", "rule_uid", "rule_version", "effective_start", "effective_end", "mapping", "allocations"}
+_BUDGET_FIELDS = {"schema_version", "budget_uid", "window", "mapping", "limit_micros", "threshold_micros"}
+
+
+def _service() -> DatabaseMeteringShowbackService:
+    return DatabaseMeteringShowbackService()
+
+
+def _response(value: object, status: int = 200):
+    response = jsonify(success(value, code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _failure(status: int = 400):
+    response = jsonify(failed("metering request rejected", code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _event_body() -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("metering_body_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) not in (_REQUIRED_EVENT_FIELDS, _EVENT_FIELDS):
+        raise ValueError("metering_body_closed")
+    mapping = value.get("mapping")
+    if not isinstance(mapping, dict) or set(mapping) != {"department", "project", "cost_center"}:
+        raise ValueError("metering_mapping_closed")
+    return value
+
+
+@bp.post("/metering/events")
+@require_permissions(METERING_MANAGE)
+def record_metering_event():
+    """record local metering event"""
+    try:
+        body = _event_body()
+        result = _service().record_for_principal(principal_id=str(g.current_user["id"]), body=body)
+        return _response(result, 201 if not result.get("replay") else 200)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+def _control_body(fields: set[str]) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("metering_body_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) != fields:
+        raise ValueError("metering_body_closed")
+    mapping = value.get("mapping")
+    if not isinstance(mapping, dict) or set(mapping) != {"department", "project", "cost_center"}:
+        raise ValueError("metering_mapping_closed")
+    return value
+
+
+@bp.post("/metering/allocations")
+@require_permissions(METERING_MANAGE)
+def publish_metering_allocation():
+    """publish versioned local allocation rule"""
+    try:
+        return _response(_service().publish_allocation_for_principal(principal_id=str(g.current_user["id"]), body=_control_body(_ALLOCATION_FIELDS)), 201)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/metering/budgets")
+@require_permissions(METERING_MANAGE)
+def evaluate_metering_budget():
+    """persist disabled-provider budget alert evidence"""
+    try:
+        return _response(_service().evaluate_budget_for_principal(principal_id=str(g.current_user["id"]), body=_control_body(_BUDGET_FIELDS)), 201)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+def _window() -> str:
+    if set(request.args) != {"window"}:
+        raise ValueError("metering_query_closed")
+    value = request.args.get("window", "")
+    if len(value) != 7 or value[4:5] != "-" or not value.replace("-", "").isdigit():
+        raise ValueError("metering_window_invalid")
+    return value
+
+
+@bp.get("/metering/showback")
+@require_permissions(METERING_READ)
+def get_showback():
+    """get local showback"""
+    try:
+        return _response(_service().showback_for_principal(principal_id=str(g.current_user["id"]), window=_window(), kind="showback"))
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure(403)
+
+
+@bp.get("/metering/reconciliation")
+@require_permissions(METERING_READ)
+def get_metering_reconciliation():
+    """get metering reconciliation"""
+    try:
+        return _response(_service().showback_for_principal(principal_id=str(g.current_user["id"]), window=_window(), kind="reconciliation"))
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure(403)
+
+
+@bp.get("/metering/allocation-replay")
+@require_permissions(METERING_READ)
+def get_metering_allocation_replay():
+    """replay one persisted allocation-rule version"""
+    try:
+        if set(request.args) != {"window", "rule_uid", "rule_version"}:
+            raise ValueError("metering_query_closed")
+        version = request.args.get("rule_version", "")
+        if not version.isdigit():
+            raise ValueError("rule_version_invalid")
+        return _response(_service().allocation_replay_for_principal(principal_id=str(g.current_user["id"]), window=request.args.get("window", ""), rule_uid=request.args.get("rule_uid", ""), rule_version=int(version)))
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure(403)

+ 140 - 0
app/api/system/plugin_platform_routes.py

@@ -0,0 +1,140 @@
+"""Closed HTTP validation boundary for the inactive WP13 local fixture."""
+
+from __future__ import annotations
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import SQLAlchemyError
+
+from app.api.system import bp
+from app.core.plugins.governance import PluginManifestError, normalize_plugin_manifest
+from app.core.plugins.persistence import (
+    DatabasePluginPlatformService,
+    PluginPersistenceError,
+)
+from app.core.plugins.repository import PluginLifecycleError, PluginPlatform
+from app.core.system.permissions import AGENTS_MANAGE, require_permissions
+from app.models.result import failed, success
+
+_MAX_BODY_BYTES = 8192
+
+
+def _body(required: set[str]) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("plugin_body_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) != required:
+        raise ValueError("plugin_body_closed")
+    return value
+
+
+def _response(value: object, status: int = 200):
+    response = jsonify(success(value, code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _failure(status: int = 400):
+    response = jsonify(failed("plugin request rejected", code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+@bp.post("/plugins/local-fixture/validate")
+@require_permissions(AGENTS_MANAGE)
+def validate_local_plugin_fixture():
+    """Validate closed metadata only; it never stores or activates a plugin."""
+    try:
+        body = _body({"manifest", "registry_record"})
+        platform = PluginPlatform(now=lambda: 0)
+        result = platform.register(body["manifest"], registry_record=body["registry_record"])
+        return _response({"plugin_uid": result["plugin_uid"], "version": result["version"], "manifest_digest": result["manifest_digest"], "mode": "ENGINEERING_EVIDENCE_ONLY", "activation": "blocked"})
+    except (PluginManifestError, PluginLifecycleError, TypeError, ValueError):
+        return _failure()
+
+
+@bp.post("/plugins/invocations")
+@require_permissions(AGENTS_MANAGE)
+def invoke_plugin_fixture():
+    """Invoke only an approved fixed local fixture through the DB gateway."""
+    try:
+        body = _body({"plugin_uid", "version", "operation", "input_digest", "idempotency_key"})
+        return _response(DatabasePluginPlatformService().invoke(actor_ref=str(g.current_user["id"]), **body), 201)
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/registry")
+@require_permissions(AGENTS_MANAGE)
+def register_plugin_fixture():
+    try:
+        body = _body({"manifest", "registry_record"})
+        # Validate executable-surface metadata before allocating a DB gateway;
+        # this keeps malformed URL/code/credential bodies out of all backends.
+        normalize_plugin_manifest(body["manifest"])
+        return _response(DatabasePluginPlatformService().register(actor_ref=str(g.current_user["id"]), **body), 201)
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/review")
+@require_permissions(AGENTS_MANAGE)
+def review_plugin_fixture(plugin_uid: str, version: str):
+    try:
+        _body(set())
+        return _response(DatabasePluginPlatformService().review(plugin_uid=plugin_uid, version=version, actor_ref=str(g.current_user["id"])))
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/approvals")
+@require_permissions(AGENTS_MANAGE)
+def approve_plugin_fixture(plugin_uid: str, version: str):
+    try:
+        body = _body({"approval_action"})
+        return _response(DatabasePluginPlatformService().issue_approval(plugin_uid=plugin_uid, version=version, actor_ref=str(g.current_user["id"]), **body), 201)
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+def _transition(plugin_uid: str, version: str, target_state: str):
+    try:
+        body = _body({"approval_uid", "expected_fence", "incident_uid"})
+        return _response(DatabasePluginPlatformService().transition(plugin_uid=plugin_uid, version=version, target_state=target_state, actor_ref=str(g.current_user["id"]), **body))
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/canary")
+@require_permissions(AGENTS_MANAGE)
+def canary_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "canary")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/activate")
+@require_permissions(AGENTS_MANAGE)
+def activate_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "active")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/pause")
+@require_permissions(AGENTS_MANAGE)
+def pause_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "paused")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/rollback")
+@require_permissions(AGENTS_MANAGE)
+def rollback_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "rolled_back")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/revoke")
+@require_permissions(AGENTS_MANAGE)
+def revoke_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "revoked")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/recover")
+@require_permissions(AGENTS_MANAGE)
+def recover_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "recovery")

+ 207 - 0
app/api/system/tenant_routes.py

@@ -0,0 +1,207 @@
+"""Authenticated, fail-closed HTTP entry points for the conditional WP10 base."""
+
+from __future__ import annotations
+
+import os
+
+from flask import g, jsonify, request
+
+from app.api.system import bp
+from app.core.system.permissions import (
+    IDENTITY_MANAGE,
+    IDENTITY_OPERATE,
+    IDENTITY_READ,
+    require_permissions,
+)
+from app.core.system.tenant_control_repository import SqlAlchemyTenantControlRepository
+from app.core.system.tenant_control_service import (
+    TenantControlError,
+    TenantControlService,
+)
+from app.models.result import failed, success
+
+_MAX_REQUEST_BYTES = 4096
+_QUOTA_FIELDS = {"quota_name", "amount", "idempotency_key"}
+_LIFECYCLE_FIELDS = {"expected_fence", "idempotency_key", "approval_ref", "backup_digest", "retention_seconds"}
+_APPROVAL_FIELDS = {"operation", "expected_fence", "idempotency_key", "backup_digest", "retention_seconds"}
+
+
+def _service() -> TenantControlService:
+    return TenantControlService(SqlAlchemyTenantControlRepository())
+
+
+def _body(allowed: set[str] = _QUOTA_FIELDS) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    if len(request.get_data(cache=True)) > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) != allowed:
+        raise TenantControlError("tenant_payload_closed")
+    return value
+
+
+def _server_host() -> str:
+    # Deliberately never consume a client-supplied tenant field or a forwarded
+    # host header.  Trusted proxy normalization belongs in deployment; the
+    # persistent DB membership is the final principal+route authorization.
+    host = os.environ.get("TRUSTED_TENANT_ROUTE_HOST", "").lower()
+    if not host:
+        raise TenantControlError("tenant_route_denied")
+    return host
+
+
+@bp.post("/tenant/quota-claims")
+@require_permissions(IDENTITY_OPERATE)
+def issue_tenant_quota_claim():
+    try:
+        value = _service().issue_quota_claim(
+            principal_id=str(g.current_user["id"]),
+            host=_server_host(),
+            request=_body(),
+        )
+        response = jsonify(success(value, code=201))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 201
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant control request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+@bp.post("/tenant/provisions")
+@require_permissions(IDENTITY_MANAGE)
+def provision_private_tenant():
+    try:
+        value = _service().provision_private(
+            principal_id=str(g.current_user["id"]), host=_server_host(), request=_body_provision()
+        )
+        response = jsonify(success(value, code=201))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 201
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant control request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+def _body_provision() -> dict:
+    return _body({"idempotency_key"})
+
+
+@bp.post("/tenant/approvals")
+@require_permissions(IDENTITY_MANAGE)
+def issue_tenant_lifecycle_approval():
+    try:
+        value = _service().issue_lifecycle_approval(
+            reviewer_id=str(g.current_user["id"]), request=_body_approval()
+        )
+        response = jsonify(success(value, code=201))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 201
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant approval request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+def _body_approval() -> dict:
+    if request.content_length is not None and request.content_length > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    if len(request.get_data(cache=True)) > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or not set(value).issubset(_APPROVAL_FIELDS) or not {"operation", "expected_fence", "idempotency_key"}.issubset(value):
+        raise TenantControlError("tenant_payload_closed")
+    return value
+
+
+def _lifecycle(operation: str):
+    try:
+        value = _service().lifecycle_transition(
+            principal_id=str(g.current_user["id"]), host=_server_host(), operation=operation, request=_body_lifecycle()
+        )
+        response = jsonify(success(value))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 200
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant lifecycle request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+@bp.post("/tenant/lifecycle/activate")
+@require_permissions(IDENTITY_MANAGE)
+def activate_tenant_lifecycle():
+    return _lifecycle("activate")
+
+
+@bp.post("/tenant/lifecycle/freeze")
+@require_permissions(IDENTITY_MANAGE)
+def freeze_tenant_lifecycle():
+    return _lifecycle("freeze")
+
+
+@bp.post("/tenant/lifecycle/recover")
+@require_permissions(IDENTITY_MANAGE)
+def recover_tenant_lifecycle():
+    return _lifecycle("begin_recovery")
+
+
+@bp.post("/tenant/lifecycle/deletion-candidate")
+@require_permissions(IDENTITY_MANAGE)
+def mark_tenant_deletion_candidate():
+    return _lifecycle("mark_deletion_candidate")
+
+
+@bp.post("/tenant/lifecycle/rollback")
+@require_permissions(IDENTITY_MANAGE)
+def rollback_tenant_lifecycle():
+    return _lifecycle("rollback")
+
+
+@bp.post("/tenant/lifecycle/delete")
+@require_permissions(IDENTITY_MANAGE)
+def delete_tenant_lifecycle():
+    return _lifecycle("delete")
+
+
+@bp.get("/tenant/status")
+@require_permissions(IDENTITY_READ)
+def get_tenant_status():
+    return _read("status")
+
+
+@bp.get("/tenant/audit")
+@require_permissions(IDENTITY_READ)
+def get_tenant_audit():
+    return _read("audit")
+
+
+@bp.get("/tenant/manifests")
+@require_permissions(IDENTITY_READ)
+def get_tenant_manifests():
+    return _read("manifests")
+
+
+def _read(kind: str):
+    try:
+        value = _service().read(principal_id=str(g.current_user["id"]), host=_server_host(), kind=kind)
+        response = jsonify(success(value))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 200
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant read request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+def _body_lifecycle() -> dict:
+    if request.content_length is not None and request.content_length > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    if len(request.get_data(cache=True)) > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or not set(value).issubset(_LIFECYCLE_FIELDS) or not {"expected_fence", "idempotency_key"}.issubset(value):
+        raise TenantControlError("tenant_payload_closed")
+    return value

+ 182 - 0
app/api/system/trusted_delivery.py

@@ -0,0 +1,182 @@
+"""No-store HTTP boundary for closed trusted-delivery contracts."""
+from datetime import UTC, datetime
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import DBAPIError, IntegrityError
+
+from app import db
+from app.api.system import bp
+from app.core.system.permissions import (
+    SECURITY_GOVERNANCE_MANAGE,
+    SECURITY_GOVERNANCE_OPERATE,
+    require_permissions,
+)
+from app.core.system.trusted_delivery import TrustedDeliveryService
+from app.core.system.trusted_delivery_repository import (
+    SqlAlchemyTrustedDeliveryRepository,
+)
+from app.core.system.trusted_delivery_subscription_repository import (
+    SqlAlchemyTrustedDeliverySubscriptionRepository,
+)
+from app.core.system.trusted_delivery_subscriptions import (
+    TrustedDeliverySubscriptionService,
+)
+from app.models.result import failed, success
+
+MAX_TRUSTED_DELIVERY_REQUEST_BYTES = 16 * 1024
+
+
+def _service():
+    return TrustedDeliveryService(SqlAlchemyTrustedDeliveryRepository(db.session))
+
+
+def _subscription_service():
+    return TrustedDeliverySubscriptionService(
+        SqlAlchemyTrustedDeliverySubscriptionRepository(db.session)
+    )
+
+
+def _execute(operation, *, created=False):
+    try:
+        value = operation()
+        # Service/repository methods deliberately leave transaction ownership to
+        # the HTTP boundary.  Commit before returning success so a second
+        # connection can observe a successful response immediately.
+        db.session.commit()
+        response = jsonify(success(value, code=201 if created else 200))
+        response.headers["Cache-Control"] = "no-store"
+        return (response, 201) if created else response
+    except PermissionError:
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery request denied", code=403))
+    except (IntegrityError, DBAPIError):
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery request conflict", code=409))
+    except (LookupError, RuntimeError, ValueError, TypeError):
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery request rejected", code=400))
+    response.headers["Cache-Control"] = "no-store"
+    return response, response.get_json()["code"]
+
+
+def _body(allowed):
+    if request.content_length is not None and request.content_length > MAX_TRUSTED_DELIVERY_REQUEST_BYTES:
+        raise ValueError("trusted delivery request is too large")
+    if len(request.get_data(cache=True)) > MAX_TRUSTED_DELIVERY_REQUEST_BYTES:
+        raise ValueError("trusted delivery request is too large")
+    body = request.get_json(silent=True)
+    if not isinstance(body, dict) or set(body) - allowed:
+        raise ValueError("closed request schema")
+    return body
+
+
+@bp.post("/trusted-delivery/policy-versions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def create_trusted_delivery_policy():
+    return _execute(lambda: _service().create_policy_version(_body({"code", "version", "selector", "resource_rules"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/policy-versions/activate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def activate_trusted_delivery_policy():
+    return _execute(lambda: _service().activate_policy_version(_body({"code", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/policy-versions/rollback")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def rollback_trusted_delivery_policy():
+    return _execute(lambda: _service().rollback_policy_version(_body({"code", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/decisions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def evaluate_trusted_delivery():
+    allowed = {"subject_uid", "roles", "business_domain_uid", "asset_uid", "purpose", "environment", "action", "classification", "requested_fields"}
+    body = _body(allowed)
+    body["subject_uid"] = g.current_user["id"]
+    body["roles"] = list(g.current_user["roles"])
+    return _execute(lambda: _service().evaluate_gateway(body))
+
+
+@bp.post("/trusted-delivery/provisions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def provision_trusted_delivery():
+    allowed = {"policy_uid", "approval_ref", "approval_digest", "asset_uid", "business_domain_uid", "purpose", "environment", "action", "classification", "requested_fields", "expires_at", "target_capability", "provider", "idempotency_key"}
+    def operation():
+        body = _body(allowed)
+        # Browser callers never choose the identity facts used for policy matching.
+        body["subject_uid"] = g.current_user["id"]
+        return _service().provision(body, actor_uid=g.current_user["id"], subject_roles=list(g.current_user["roles"]))
+    return _execute(operation, created=True)
+
+
+@bp.post("/trusted-delivery/legal-holds")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def create_trusted_delivery_hold():
+    return _execute(lambda: _service().create_legal_hold(_body({"asset_uid", "operation", "approver_refs", "evidence_digest"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/legal-holds/release")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def release_trusted_delivery_hold():
+    return _execute(lambda: _service().release_legal_hold(_body({"hold_uid", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/reclaim/preview")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_reclaim_preview():
+    body = _body({"as_of"})
+    as_of = body.get("as_of") or datetime.now(UTC).isoformat()
+    return _execute(lambda: {"candidates": _service().preview_reclaim(as_of=as_of, actor_uid=g.current_user["id"]), "executed": False})
+
+
+@bp.post("/trusted-delivery/reclaim/execute")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_reclaim_execute():
+    return _execute(lambda: _service().execute_reclaim(_body({"grant_uid", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def create_trusted_delivery_subscription():
+    allowed = {"grant_uid", "asset_uid", "trigger", "purpose", "expires_at", "idempotency_key"}
+    return _execute(lambda: _subscription_service().create_subscription(_body(allowed), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/pause")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def pause_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().pause_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/activate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def activate_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().activate_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/resume")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def resume_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().resume_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/terminate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def terminate_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().terminate_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/deliveries/<delivery_uid>/compensate")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def compensate_trusted_delivery_subscription_delivery(delivery_uid):
+    return _execute(lambda: _subscription_service().compensate_dead_letter(
+        delivery_uid, **_body({"reason_code", "receipt_code"}), actor_uid=g.current_user["id"]
+    ))
+
+
+@bp.post("/trusted-delivery/subscriptions/anomalies")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def report_trusted_delivery_subscription_anomaly():
+    allowed = {"kind", "asset_uid", "subscription_uid", "incident_uid", "summary", "correlation_id"}
+    return _execute(lambda: _subscription_service().report_anomaly(_body(allowed), actor_uid=g.current_user["id"]), created=True)

+ 99 - 0
app/api/system/trusted_delivery_controls.py

@@ -0,0 +1,99 @@
+"""No-store HTTP boundary for trusted-delivery control and release gate summaries."""
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import DBAPIError, IntegrityError
+
+from app import db
+from app.api.system import bp
+from app.core.system.permissions import (
+    SECURITY_GOVERNANCE_MANAGE,
+    SECURITY_GOVERNANCE_OPERATE,
+    SECURITY_GOVERNANCE_READ,
+    require_permissions,
+)
+from app.core.system.trusted_delivery_controls import TrustedDeliveryControlError
+from app.core.system.trusted_delivery_controls_repository import (
+    SqlAlchemyTrustedDeliveryControlsRepository,
+)
+from app.core.system.trusted_delivery_controls_service import (
+    TrustedDeliveryControlsService,
+)
+from app.models.result import failed, success
+
+MAX_TRUSTED_DELIVERY_CONTROL_REQUEST_BYTES = 16 * 1024
+
+
+def _service():
+    return TrustedDeliveryControlsService(SqlAlchemyTrustedDeliveryControlsRepository(db.session))
+
+
+def _body(allowed):
+    if request.content_length is not None and request.content_length > MAX_TRUSTED_DELIVERY_CONTROL_REQUEST_BYTES:
+        raise TrustedDeliveryControlError("trusted delivery control request is too large")
+    if len(request.get_data(cache=True)) > MAX_TRUSTED_DELIVERY_CONTROL_REQUEST_BYTES:
+        raise TrustedDeliveryControlError("trusted delivery control request is too large")
+    body = request.get_json(silent=True)
+    if not isinstance(body, dict) or set(body) - allowed:
+        raise TrustedDeliveryControlError("closed request schema")
+    return body
+
+
+def _execute(operation, *, created=False):
+    try:
+        value = operation()
+        # Do not acknowledge a durable control mutation before its commit has
+        # succeeded.  Failure takes the common rollback/redacted-error path.
+        db.session.commit()
+        response = jsonify(success(value, code=201 if created else 200))
+        response.headers["Cache-Control"] = "no-store"
+        return (response, 201) if created else response
+    except PermissionError:
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery control request denied", code=403))
+    except (LookupError, RuntimeError, TrustedDeliveryControlError, ValueError, TypeError, IntegrityError, DBAPIError):
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery control request rejected", code=400))
+    response.headers["Cache-Control"] = "no-store"
+    return response, response.get_json()["code"]
+
+
+@bp.get("/trusted-delivery/controls/profiles/<profile_id>/active")
+@require_permissions(SECURITY_GOVERNANCE_READ)
+def trusted_delivery_active_control_profile(profile_id):
+    return _execute(lambda: _service().active_profile_summary(profile_id))
+
+
+@bp.post("/trusted-delivery/controls/release-gates/evaluate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def trusted_delivery_release_gate():
+    return _execute(lambda: _service().evaluate_release_gate(_body({"artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "scan_decision", "evidence_expires_at", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/controls/profiles/activate")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_activate_control_profile():
+    return _execute(lambda: _service().activate_profile(_body({"profile_id", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/controls/profiles/rollback")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_rollback_control_profile():
+    return _execute(lambda: _service().activate_profile(_body({"profile_id", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"], operation="rollback"))
+
+
+@bp.post("/trusted-delivery/controls/capability-approvals")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_capability_approval():
+    return _execute(lambda: _service().approve_capability(_body({"provider", "capability", "version", "config_digest", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.get("/trusted-delivery/controls/evidence")
+@require_permissions(SECURITY_GOVERNANCE_READ)
+def trusted_delivery_control_evidence():
+    return _execute(lambda: _service().evidence_summary())
+
+
+@bp.post("/trusted-delivery/controls/destruction-approvals")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_destruction_approval():
+    return _execute(lambda: _service().approve_destruction(_body({"asset_uid", "approval_refs", "evidence_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)

+ 16 - 3
app/config/config.py

@@ -214,6 +214,7 @@ PRODUCTION_SERVICE_DEFAULTS = {
 
 _PRODUCTION_REQUIRED_SERVICE_ENV = (
     "DATABASE_URL",
+    "BI_AI_CATALOG_CONTROL_DATABASE_URL",
     "NEO4J_URI",
     "NEO4J_HTTP_URI",
     "NEO4J_USER",
@@ -228,9 +229,12 @@ _PRODUCTION_REQUIRED_SERVICE_ENV = (
 def _validate_production_service_env() -> None:
     """Reject missing, template, or malformed production service settings."""
     values = {name: _clean_env(name) for name in _PRODUCTION_REQUIRED_SERVICE_ENV}
-    validate_postgresql_url(values["DATABASE_URL"], "DATABASE_URL")
+    runtime = validate_postgresql_url(values["DATABASE_URL"], "DATABASE_URL")
+    control = validate_postgresql_url(values["BI_AI_CATALOG_CONTROL_DATABASE_URL"], "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+    if control.username != "dataops_bi_ai_catalog_control" or control.username == runtime.username:
+        raise RuntimeError("production BI_AI_CATALOG_CONTROL_DATABASE_URL must use the dedicated control identity")
     for name, value in values.items():
-        if name == "DATABASE_URL":
+        if name in {"DATABASE_URL", "BI_AI_CATALOG_CONTROL_DATABASE_URL"}:
             continue
         placeholder = is_placeholder_env_value(value)
         if name in {"NEO4J_URI", "NEO4J_HTTP_URI", "MINIO_HOST"}:
@@ -377,7 +381,15 @@ def validate_production_database_identity(app, engine) -> None:
                          SELECT 1 FROM pg_roles evidence_owner
                          WHERE evidence_owner.rolname='dataops_edge_evidence_owner'
                            AND pg_has_role(current_user,evidence_owner.oid,'MEMBER')
-                       ) AS evidence_owner_member
+                       ) AS evidence_owner_member,
+                       EXISTS (
+                         SELECT 1 FROM pg_roles trusted_owner
+                         WHERE trusted_owner.rolname IN (
+                           'dataops_trusted_delivery_owner',
+                           'dataops_trusted_delivery_writer'
+                         )
+                           AND pg_has_role(current_user,trusted_owner.oid,'MEMBER')
+                       ) AS trusted_delivery_owner_member
                   FROM pg_roles role WHERE role.rolname=current_user
             """)).mappings().one()
     except Exception as exc:
@@ -386,6 +398,7 @@ def validate_production_database_identity(app, engine) -> None:
         identity["rolsuper"] or identity["rolcreaterole"] or identity["rolcreatedb"]
         or identity["rolreplication"] or identity["rolbypassrls"]
         or identity["owns_application_objects"] or identity["evidence_owner_member"]
+        or identity["trusted_delivery_owner_member"]
     )
     if forbidden:
         raise RuntimeError(

+ 318 - 4
app/core/edge_gateway/runtime_roles.py

@@ -8,7 +8,10 @@ import re
 from sqlalchemy import create_engine, text
 from sqlalchemy.pool import NullPool
 
-from app.config.database_urls import validate_database_environment
+from app.config.database_urls import (
+    validate_database_environment,
+    validate_postgresql_url,
+)
 
 _ROLE_NAME = re.compile(r"^[A-Za-z_][A-Za-z0-9_]{0,62}$")
 
@@ -20,6 +23,9 @@ def provision_runtime_login() -> None:
     runtime_user = os.environ.get("DATAOPS_RUNTIME_USER", "")
     runtime_password = os.environ.get("DATAOPS_RUNTIME_PASSWORD", "")
     migrator_user = os.environ.get("DATAOPS_MIGRATOR_USER", "")
+    control_url = os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", "")
+    control_user = os.environ.get("DATAOPS_BI_AI_CATALOG_CONTROL_USER", "")
+    control_password = os.environ.get("DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD", "")
     if (
         not _ROLE_NAME.fullmatch(runtime_user)
         or not _ROLE_NAME.fullmatch(migrator_user)
@@ -31,6 +37,9 @@ def provision_runtime_login() -> None:
         "DATABASE_URL": runtime_url,
         "DATAOPS_RUNTIME_PASSWORD": runtime_password,
     })
+    control_parts = validate_postgresql_url(control_url, "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+    if not _ROLE_NAME.fullmatch(control_user) or control_parts.username != control_user or not control_password or control_parts.password != control_password:
+        raise RuntimeError("BI/AI catalog control identity provisioning is not configured")
     engine = create_engine(role_init_url, poolclass=NullPool)
     quoted_user = engine.dialect.identifier_preparer.quote(runtime_user)
     quoted_migrator = engine.dialect.identifier_preparer.quote(migrator_user)
@@ -50,9 +59,49 @@ def provision_runtime_login() -> None:
                   IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_edge_evidence_owner') THEN
                     CREATE ROLE dataops_edge_evidence_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
                   END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_trusted_delivery_owner') THEN
+                    CREATE ROLE dataops_trusted_delivery_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_trusted_delivery_writer') THEN
+                    CREATE ROLE dataops_trusted_delivery_writer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_agent_runtime_owner') THEN
+                    CREATE ROLE dataops_agent_runtime_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_agent_runtime') THEN
+                    CREATE ROLE dataops_agent_runtime NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_tenant_foundation_owner') THEN
+                    CREATE ROLE dataops_tenant_foundation_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_tenant_control') THEN
+                    CREATE ROLE dataops_tenant_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_tenant_approver') THEN
+                    CREATE ROLE dataops_tenant_approver NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_bi_ai_catalog_issuer') THEN
+                    CREATE ROLE dataops_bi_ai_catalog_issuer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_plugin_platform_owner') THEN
+                    CREATE ROLE dataops_plugin_platform_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_plugin_platform_control') THEN
+                    CREATE ROLE dataops_plugin_platform_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
+                  END IF;
                 END $$;
                 ALTER ROLE dataops_app_runtime NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
                 ALTER ROLE dataops_edge_evidence_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_trusted_delivery_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_trusted_delivery_writer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_agent_runtime_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_agent_runtime NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_tenant_foundation_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_tenant_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_tenant_approver NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_bi_ai_catalog_issuer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
+                ALTER ROLE dataops_plugin_platform_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_plugin_platform_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
             """))
             migrator_exists = connection.execute(
                 text("SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname=:role)"),
@@ -70,20 +119,285 @@ def provision_runtime_login() -> None:
                 "NOCREATEROLE NOREPLICATION PASSWORD :password"
             ), {"password": runtime_password})
             connection.execute(text(f"GRANT dataops_app_runtime TO {quoted_user}"))
+            quoted_control = engine.dialect.identifier_preparer.quote(control_user)
+            control_exists = connection.execute(text("SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname=:role)"), {"role": control_user}).scalar_one()
+            control_action = "ALTER" if control_exists else "CREATE"
+            connection.execute(text(f"{control_action} ROLE {quoted_control} LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION INHERIT PASSWORD :password"), {"password": control_password})
+            connection.execute(text(f"GRANT dataops_bi_ai_catalog_issuer TO {quoted_control}"))
+            connection.execute(text(f"GRANT dataops_plugin_platform_control TO {quoted_control}"))
+            # Role-init also runs before a fresh database has reached WP11.
+            # The restricted migration grants the function after creating it;
+            # a later idempotent role-init grants the dedicated login directly.
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.bi_ai_catalog_issue_request_claim(text,text,jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.bi_ai_catalog_issue_request_claim(text,text,jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.plugin_platform_control_v2(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_control_v2(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_issue_claim(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_issue_claim(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_control_v3(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_control_v3(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_control_v4(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_control_v4(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_control_v5(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.plugin_platform_control_v5(jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_issue_claim_v3(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.plugin_platform_issue_claim_v3(jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_issue_recovery_claim(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.plugin_platform_issue_recovery_claim(jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            # WP12 reuses the separate, configured control login for claims.
+            # It remains distinct from the long-running runtime login, and a
+            # role-init replay grants only this execute capability.
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.metering_showback_issue_claim(text,text,jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.metering_showback_issue_claim(text,text,jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.metering_showback_control_write(text,text,jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.metering_showback_control_write(text,text,jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            connection.execute(text(f"REVOKE dataops_bi_ai_catalog_issuer FROM {quoted_user}"))
+            # A role-init replay must never restore legacy direct table access
+            # after the WP11 live-head ACL compensation has run.
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'bi_ai_catalog_sources','bi_ai_catalog_assets',"
+                "'bi_ai_catalog_asset_versions','bi_ai_catalog_dependencies',"
+                "'bi_ai_catalog_sync_errors','bi_ai_catalog_audit_events',"
+                "'bi_ai_catalog_scope_grants','bi_ai_catalog_scan_observations',"
+                "'bi_ai_catalog_scan_sessions','bi_ai_catalog_scan_page_acks',"
+                "'bi_ai_catalog_page_acknowledgements','bi_ai_catalog_request_claims',"
+                "'bi_ai_catalog_empty_snapshot_approvals'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            # The compatibility matrix above is intentionally broad for
+            # legacy tables. Reapply WP12's facts-only gateway boundary after
+            # every role-init replay, including the concrete app login.
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'metering_scope_grants','metering_showback_configuration',"
+                "'metering_runtime_leases','metering_runtime_claims','metering_events',"
+                "'metering_allocation_rules','metering_allocations','metering_budgets',"
+                "'metering_alert_outbox','metering_reconciliation_reports','metering_audit_events'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY['plugin_registry_versions','plugin_approvals','plugin_runtime_leases','plugin_runs','plugin_dead_letters','plugin_audit_outbox','plugin_request_claims','plugin_runtime_breakers','plugin_recovery_claims'] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
             connection.execute(text(
                 f"GRANT dataops_edge_evidence_owner TO {quoted_migrator}"
             ))
+            connection.execute(text(
+                f"GRANT dataops_trusted_delivery_owner TO {quoted_migrator}"
+            ))
+            connection.execute(text(
+                f"GRANT dataops_trusted_delivery_writer TO {quoted_migrator}"
+            ))
+            connection.execute(text(
+                f"GRANT dataops_agent_runtime_owner TO {quoted_migrator}"
+            ))
+            connection.execute(text(
+                f"GRANT dataops_tenant_foundation_owner TO {quoted_migrator}"
+            ))
+            # Tenant-control is a separate capability: only the explicitly
+            # configured control login (or the migration identity used to
+            # create its schema) may inherit it.  The shared app login never
+            # receives this membership.
+            connection.execute(text(
+                f"GRANT dataops_tenant_control TO {quoted_migrator}"
+            ))
+            connection.execute(text(f"GRANT dataops_plugin_platform_owner TO {quoted_migrator}"))
+            connection.execute(text(f"GRANT dataops_agent_runtime TO {quoted_user}"))
             connection.execute(text(
                 "GRANT USAGE,CREATE ON SCHEMA public TO dataops_edge_evidence_owner"
             ))
-            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_app_runtime"))
             connection.execute(text(
-                "GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public "
-                "TO dataops_app_runtime"
+                "GRANT USAGE,CREATE ON SCHEMA public TO dataops_trusted_delivery_owner"
+            ))
+            connection.execute(text(
+                "GRANT USAGE,CREATE ON SCHEMA public TO dataops_trusted_delivery_writer"
+            ))
+            connection.execute(text("GRANT USAGE,CREATE ON SCHEMA public TO dataops_agent_runtime_owner"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_agent_runtime"))
+            connection.execute(text("GRANT USAGE,CREATE ON SCHEMA public TO dataops_tenant_foundation_owner"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_tenant_control"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_tenant_approver"))
+            connection.execute(text("GRANT USAGE,CREATE ON SCHEMA public TO dataops_plugin_platform_owner"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_plugin_platform_control"))
+            # The definer gateway validates actor references against the
+            # canonical identity table but never receives identity DML.
+            connection.execute(text(
+                "DO $$ BEGIN IF to_regclass('public.users') IS NOT NULL THEN "
+                "GRANT SELECT ON TABLE public.users TO dataops_trusted_delivery_writer; END IF; END $$"
+            ))
+            # A non-privileged migrator still needs REFERENCES to create the
+            # versioned WP06 tables that bind their actor to the canonical
+            # identity record.  It does not receive users DML.
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regclass('public.users') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.users TO " + quoted_migrator + "'; END IF; "
+                "IF to_regclass('public.governed_agents') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.governed_agents TO " + quoted_migrator + "'; END IF; "
+                "END $$"
+            ))
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regclass('public.data_incidents') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.data_incidents TO " + quoted_migrator + "'; END IF; "
+                "IF to_regclass('public.governance_tasks') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.governance_tasks TO " + quoted_migrator + "'; END IF; "
+                "END $$"
+            ))
+            # WP09's hardened definer gateway reads its approval source of
+            # truth.  The migrator can delegate only these capabilities while
+            # retaining no direct data-modification path of its own.
+            connection.execute(text(f"""
+                DO $$ BEGIN
+                  IF to_regclass('public.governance_tasks') IS NOT NULL THEN GRANT SELECT, UPDATE ON TABLE public.governance_tasks TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                  IF to_regclass('public.governance_task_reviews') IS NOT NULL THEN GRANT SELECT ON TABLE public.governance_task_reviews TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                  IF to_regclass('public.agent_tool_grants') IS NOT NULL THEN GRANT SELECT ON TABLE public.agent_tool_grants TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                  IF to_regclass('public.governed_agents') IS NOT NULL THEN GRANT SELECT ON TABLE public.governed_agents TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                END $$
+            """))
+            connection.execute(text(
+                "DO $$ BEGIN IF to_regclass('public.data_incident_impacts') IS NOT NULL THEN "
+                "GRANT SELECT,INSERT ON TABLE public.data_incident_impacts TO dataops_trusted_delivery_writer; END IF; END $$"
             ))
+            connection.execute(text(
+                "DO $$ BEGIN IF to_regclass('public.data_incidents') IS NOT NULL THEN "
+                "GRANT SELECT ON TABLE public.data_incidents TO dataops_trusted_delivery_writer; END IF; END $$"
+            ))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_app_runtime"))
+            # Revoke legacy broad grants both from the shared runtime role and
+            # from the concrete login before rebuilding its explicit table
+            # matrix.  This is required when upgrading an installation that
+            # previously granted DML across the whole public schema.
+            connection.execute(text(f"""
+                DO $$ DECLARE target text;
+                BEGIN
+                  FOR target IN
+                    SELECT format('%I.%I', schemaname, tablename)
+                    FROM pg_tables
+                    WHERE schemaname='public' AND (
+                      tablename LIKE 'trusted_delivery_%' OR tablename='data_incident_impacts'
+                      OR tablename IN ('tenants','tenant_quotas','tenant_quota_reservations',
+                                       'tenant_lifecycle_events','tenant_audit_events','tenant_resource_manifests')
+                    )
+                  LOOP
+                    EXECUTE 'REVOKE INSERT, UPDATE, DELETE, TRUNCATE ON TABLE ' || target || ' FROM dataops_app_runtime';
+                    EXECUTE 'REVOKE INSERT, UPDATE, DELETE, TRUNCATE ON TABLE ' || target || ' FROM {quoted_user}';
+                  END LOOP;
+                END $$;
+            """))
+            # Runtime receives explicit table grants only.  In particular it
+            # must never inherit DML on future tables or on the WP06 trusted
+            # delivery state machine; those writes are reached only through
+            # SECURITY DEFINER procedures owned by the dedicated writer role.
+            connection.execute(text("""
+                DO $$ DECLARE target text;
+                BEGIN
+                  FOR target IN
+                    SELECT format('%I.%I', schemaname, tablename)
+                    FROM pg_tables
+                    WHERE schemaname='public' AND tablename NOT LIKE 'trusted_delivery_%'
+                      AND tablename <> 'data_incident_impacts'
+                      AND tablename NOT IN ('tenants','tenant_quotas','tenant_quota_reservations',
+                                            'tenant_lifecycle_events','tenant_audit_events','tenant_resource_manifests')
+                  LOOP
+                    EXECUTE 'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE ' || target || ' TO dataops_app_runtime';
+                  END LOOP;
+                END $$;
+            """))
             connection.execute(text(
                 "GRANT USAGE,SELECT ON ALL SEQUENCES IN SCHEMA public TO dataops_app_runtime"
             ))
+            # The legacy compatibility matrix above intentionally grants most
+            # public tables.  Reapply WP11's closed facts after it so a
+            # role-init replay cannot re-open catalog data to the runtime.
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'bi_ai_catalog_sources','bi_ai_catalog_assets',"
+                "'bi_ai_catalog_asset_versions','bi_ai_catalog_dependencies',"
+                "'bi_ai_catalog_sync_errors','bi_ai_catalog_audit_events',"
+                "'bi_ai_catalog_scope_grants','bi_ai_catalog_scan_observations',"
+                "'bi_ai_catalog_scan_sessions','bi_ai_catalog_scan_page_acks',"
+                "'bi_ai_catalog_page_acknowledgements','bi_ai_catalog_request_claims',"
+                "'bi_ai_catalog_empty_snapshot_approvals'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'metering_scope_grants','metering_showback_configuration',"
+                "'metering_runtime_leases','metering_runtime_claims','metering_events',"
+                "'metering_allocation_rules','metering_allocations','metering_budgets',"
+                "'metering_alert_outbox','metering_reconciliation_reports','metering_audit_events'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY['plugin_registry_versions','plugin_approvals','plugin_runtime_leases','plugin_runs','plugin_dead_letters','plugin_audit_outbox','plugin_request_claims','plugin_runtime_breakers','plugin_recovery_claims'] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
             is_evidence_member = connection.execute(text("""
                 SELECT pg_has_role(:role,'dataops_edge_evidence_owner','MEMBER')
             """), {"role": runtime_user}).scalar_one()

+ 518 - 0
app/core/events/production_observability.py

@@ -0,0 +1,518 @@
+"""Closed, deterministic P3 production-observability adapter contracts.
+
+This module intentionally does not configure or contact enterprise providers.
+It makes the boundary for approved monitoring, notification, on-call, and ITSM
+adapters safe and testable while P3-WP05 enterprise inputs remain external.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import math
+import re
+import uuid
+from collections.abc import Callable
+from datetime import UTC, datetime
+from typing import Any
+
+from app.core.events.data_observability import _reject_secret_material
+
+CONTRACT_VERSION = "1.0.0"
+TELEMETRY_RESOURCE_TYPES = frozenset(
+    {"api", "task", "database", "graph", "object_storage"}
+)
+TELEMETRY_LAYERS = frozenset({"service", "task", "data", "capacity"})
+TELEMETRY_STATUSES = frozenset({"ok", "error", "degraded", "backpressure"})
+DELIVERY_CHANNELS = frozenset({"smtp", "enterprise_collaboration", "on_call"})
+MAX_DELIVERY_ATTEMPTS = 3
+DELIVERY_LEASE_SECONDS = 300
+_TRACE_ID = re.compile(r"^[0-9a-f]{32}$")
+_SPAN_ID = re.compile(r"^[0-9a-f]{16}$")
+
+
+class ProductionObservabilityContractError(ValueError):
+    """Raised before unsafe or ambiguous operations leave the local boundary."""
+
+
+_SENSITIVE_VALUE = re.compile(
+    r"(?i)(?:bearer\s+|password\s*[=:]|secret\s*[=:]|-----begin|\bselect\b.+\bfrom\b)"
+)
+
+
+def _safe_object(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ProductionObservabilityContractError(f"{label} must be an object")
+    try:
+        _reject_secret_material(value)
+    except ValueError as error:
+        raise ProductionObservabilityContractError(str(error)) from error
+    unknown = sorted(set(value) - allowed)
+    if unknown:
+        raise ProductionObservabilityContractError(
+            f"{label} contains unsupported fields: {', '.join(unknown)}"
+        )
+    return dict(value)
+
+
+def _reject_sensitive_values(value: Any, *, depth: int = 0) -> None:
+    if depth > 4:
+        raise ProductionObservabilityContractError("payload nesting exceeds 4")
+    if isinstance(value, str) and _SENSITIVE_VALUE.search(value):
+        raise ProductionObservabilityContractError("sensitive value is not allowed")
+    if isinstance(value, dict):
+        for item in value.values():
+            _reject_sensitive_values(item, depth=depth + 1)
+    elif isinstance(value, list):
+        if len(value) > 32:
+            raise ProductionObservabilityContractError("payload list exceeds 32 items")
+        for item in value:
+            _reject_sensitive_values(item, depth=depth + 1)
+
+
+def _timestamp(value: Any) -> str:
+    try:
+        parsed = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as error:
+        raise ProductionObservabilityContractError(
+            "occurred_at must be RFC3339"
+        ) from error
+    if parsed.tzinfo is None:
+        raise ProductionObservabilityContractError(
+            "occurred_at must include a timezone"
+        )
+    return parsed.astimezone(UTC).isoformat().replace("+00:00", "Z")
+
+
+def _string(value: Any, label: str, maximum: int = 200) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise ProductionObservabilityContractError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum:
+        raise ProductionObservabilityContractError(
+            f"{label} exceeds {maximum} characters"
+        )
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as error:
+        raise ProductionObservabilityContractError(f"{label} must be a UUID") from error
+
+
+def _number(value: Any, label: str) -> float:
+    if isinstance(value, bool):
+        raise ProductionObservabilityContractError(f"{label} must be numeric")
+    try:
+        result = float(value)
+    except (TypeError, ValueError) as error:
+        raise ProductionObservabilityContractError(
+            f"{label} must be numeric"
+        ) from error
+    if not math.isfinite(result):
+        raise ProductionObservabilityContractError(f"{label} must be finite")
+    return result
+
+
+def _canonical_digest(value: dict[str, Any]) -> str:
+    encoded = json.dumps(
+        value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
+    )
+    return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
+
+
+def normalize_telemetry_event(payload: Any) -> dict[str, Any]:
+    """Validate a cardinality-safe telemetry envelope before provider adaptation."""
+    body = _safe_object(
+        payload,
+        {
+            "event_id",
+            "occurred_at",
+            "layer",
+            "operation",
+            "resource_type",
+            "resource_uid",
+            "correlation_id",
+            "trace_id",
+            "span_id",
+            "status",
+            "attributes",
+        },
+        "telemetry event",
+    )
+    _reject_sensitive_values(body)
+    attributes = _safe_object(
+        body.get("attributes"),
+        {
+            "duration_ms",
+            "queue_depth",
+            "utilization_ratio",
+            "retry_count",
+            "error_code",
+        },
+        "telemetry attributes",
+    )
+    trace_id = _string(body.get("trace_id"), "trace_id", 32).lower()
+    span_id = _string(body.get("span_id"), "span_id", 16).lower()
+    if not _TRACE_ID.fullmatch(trace_id) or not _SPAN_ID.fullmatch(span_id):
+        raise ProductionObservabilityContractError("trace_id or span_id is invalid")
+    layer = _string(body.get("layer"), "layer", 20)
+    resource_type = _string(body.get("resource_type"), "resource_type", 30)
+    status = _string(body.get("status"), "status", 20)
+    if layer not in TELEMETRY_LAYERS:
+        raise ProductionObservabilityContractError("telemetry layer is invalid")
+    if resource_type not in TELEMETRY_RESOURCE_TYPES:
+        raise ProductionObservabilityContractError("telemetry resource_type is invalid")
+    if status not in TELEMETRY_STATUSES:
+        raise ProductionObservabilityContractError("telemetry status is invalid")
+    normalized_attributes: dict[str, Any] = {}
+    for key, value in attributes.items():
+        if key == "error_code":
+            normalized_attributes[key] = _string(value, "error_code", 64)
+        elif key == "retry_count":
+            numeric = _number(value, "retry_count")
+            if not numeric.is_integer():
+                raise ProductionObservabilityContractError(
+                    "retry_count must be an integer"
+                )
+            retry_count = int(numeric)
+            if retry_count < 0 or retry_count > 10:
+                raise ProductionObservabilityContractError(
+                    "retry_count must be between 0 and 10"
+                )
+            normalized_attributes[key] = retry_count
+        else:
+            number = _number(value, key)
+            if number < 0:
+                raise ProductionObservabilityContractError(
+                    f"{key} must not be negative"
+                )
+            normalized_attributes[key] = number
+    return {
+        "contract_version": CONTRACT_VERSION,
+        "event_id": _uid(body.get("event_id"), "event_id"),
+        "occurred_at": _timestamp(body.get("occurred_at")),
+        "layer": layer,
+        "operation": _string(body.get("operation"), "operation", 80),
+        "resource_type": resource_type,
+        "resource_uid": _string(body.get("resource_uid"), "resource_uid", 160),
+        "correlation_id": _uid(body.get("correlation_id"), "correlation_id"),
+        "trace_id": trace_id,
+        "span_id": span_id,
+        "status": status,
+        "attributes": normalized_attributes,
+    }
+
+
+def production_slo_catalog() -> list[dict[str, Any]]:
+    """Return the versioned production SLO catalog used by approved adapters."""
+    return [
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "service",
+            "sli": "availability_ratio",
+            "target": 0.999,
+            "error_budget_ratio": 0.001,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "task",
+            "sli": "delivery_ratio",
+            "target": 0.99,
+            "error_budget_ratio": 0.01,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "data",
+            "sli": "freshness_ratio",
+            "target": 0.99,
+            "error_budget_ratio": 0.01,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "capacity",
+            "sli": "headroom_ratio",
+            "target": 0.2,
+            "error_budget_ratio": 0.05,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+    ]
+
+
+def evaluate_capacity(payload: Any) -> dict[str, Any]:
+    """Provide a deterministic admission recommendation without dropping work."""
+    body = _safe_object(
+        payload,
+        {
+            "active_users",
+            "data_sources",
+            "utilization_ratio",
+            "queue_depth",
+            "queue_limit",
+            "ingress_per_minute",
+            "max_ingress_per_minute",
+        },
+        "capacity snapshot",
+    )
+    active_users = int(_number(body.get("active_users"), "active_users"))
+    data_sources = int(_number(body.get("data_sources"), "data_sources"))
+    utilization = _number(body.get("utilization_ratio"), "utilization_ratio")
+    queue_depth = int(_number(body.get("queue_depth"), "queue_depth"))
+    queue_limit = int(_number(body.get("queue_limit"), "queue_limit"))
+    ingress = _number(body.get("ingress_per_minute"), "ingress_per_minute")
+    max_ingress = _number(body.get("max_ingress_per_minute"), "max_ingress_per_minute")
+    if not 100 <= active_users <= 500:
+        raise ProductionObservabilityContractError(
+            "active_users must be between 100 and 500"
+        )
+    if not 50 <= data_sources <= 500:
+        raise ProductionObservabilityContractError(
+            "data_sources must be between 50 and 500"
+        )
+    if not 0 <= utilization <= 1 or queue_depth < 0 or queue_limit < 1:
+        raise ProductionObservabilityContractError("capacity snapshot is invalid")
+    if ingress < 0 or max_ingress <= 0:
+        raise ProductionObservabilityContractError("ingress capacity is invalid")
+    if queue_depth > queue_limit:
+        raise ProductionObservabilityContractError(
+            "queue exceeds hard limit; reject before data loss"
+        )
+    pressure = max(utilization, queue_depth / queue_limit, ingress / max_ingress)
+    if pressure >= 0.8:
+        admission = "backpressure"
+        throttle_ratio = 0.5
+        recommendation = (
+            "scale workers or queue capacity before accepting additional work"
+        )
+    elif pressure >= 0.7:
+        admission = "throttle"
+        throttle_ratio = 0.75
+        recommendation = "throttle non-critical work and review capacity headroom"
+    else:
+        admission = "allow"
+        throttle_ratio = 1.0
+        recommendation = "capacity within approved local baseline"
+    return {
+        "baseline": {"active_users": [100, 500], "data_sources": [50, 500]},
+        "admission": admission,
+        "throttle_ratio": throttle_ratio,
+        "recommendation": recommendation,
+        "pressure_ratio": round(pressure, 4),
+    }
+
+
+class DeliveryCoordinator:
+    """Deterministic local state machine for adapter contract verification only."""
+
+    def __init__(self, *, now: Callable[[], float]):
+        self.now = now
+        self.deliveries: dict[str, dict[str, Any]] = {}
+        self._delivery_digests: dict[str, str] = {}
+        self._itsm_by_key: dict[str, dict[str, str]] = {}
+        self._itsm_by_external_ref: dict[str, str] = {}
+        self.audit: list[dict[str, Any]] = []
+
+    def _audit(self, action: str, delivery_id: str, **safe_detail: Any) -> None:
+        self.audit.append(
+            {
+                "action": action,
+                "delivery_id": delivery_id,
+                "at": self.now(),
+                "safe_detail": safe_detail,
+            }
+        )
+
+    def enqueue_delivery(self, payload: Any) -> dict[str, Any]:
+        body = _safe_object(
+            payload,
+            {
+                "delivery_id",
+                "incident_uid",
+                "alert_uid",
+                "channel",
+                "idempotency_key",
+                "summary",
+            },
+            "delivery request",
+        )
+        normalized = {
+            "delivery_id": _uid(body.get("delivery_id"), "delivery_id"),
+            "incident_uid": _uid(body.get("incident_uid"), "incident_uid"),
+            "alert_uid": _uid(body.get("alert_uid"), "alert_uid"),
+            "channel": _string(body.get("channel"), "channel", 40),
+            "idempotency_key": _string(
+                body.get("idempotency_key"), "idempotency_key", 120
+            ),
+            "summary": _string(body.get("summary"), "summary", 160),
+        }
+        if normalized["channel"] not in DELIVERY_CHANNELS:
+            raise ProductionObservabilityContractError("delivery channel is invalid")
+        digest = _canonical_digest(normalized)
+        existing_digest = self._delivery_digests.get(normalized["idempotency_key"])
+        if existing_digest is not None:
+            if existing_digest != digest:
+                raise ProductionObservabilityContractError("delivery replay conflicts")
+            return dict(self.deliveries[normalized["delivery_id"]])
+        record = {
+            **normalized,
+            "status": "pending",
+            "attempt_count": 0,
+            "lease_owner": None,
+            "lease_expires_at": None,
+            "fencing_token": 0,
+        }
+        self.deliveries[record["delivery_id"]] = record
+        self._delivery_digests[record["idempotency_key"]] = digest
+        self._audit(
+            "delivery_enqueued", record["delivery_id"], channel=record["channel"]
+        )
+        return dict(record)
+
+    def claim_delivery(
+        self,
+        delivery_id: str,
+        *,
+        worker_id: str,
+        now: float | None = None,
+    ) -> dict[str, Any]:
+        record = self._delivery(delivery_id)
+        current = self.now() if now is None else now
+        if record["status"] == "processing" and current < record["lease_expires_at"]:
+            raise ProductionObservabilityContractError("delivery is leased")
+        if record["status"] not in {"pending", "processing"}:
+            raise ProductionObservabilityContractError("delivery is not claimable")
+        record["status"] = "processing"
+        record["lease_owner"] = _string(worker_id, "worker_id", 80)
+        record["lease_expires_at"] = current + DELIVERY_LEASE_SECONDS
+        record["fencing_token"] += 1
+        return dict(record)
+
+    def record_attempt(
+        self,
+        delivery_id: str,
+        *,
+        worker_id: str,
+        fencing_token: int,
+        outcome: str,
+        reason_code: str | None = None,
+    ) -> dict[str, Any]:
+        record = self._delivery(delivery_id)
+        if (
+            record["status"] != "processing"
+            or record["lease_owner"] != _string(worker_id, "worker_id", 80)
+            or record["fencing_token"] != fencing_token
+        ):
+            raise ProductionObservabilityContractError(
+                "delivery fencing token is invalid"
+            )
+        if outcome == "delivered":
+            record["status"] = "delivered"
+            self._audit("delivery_delivered", record["delivery_id"])
+            return dict(record)
+        if outcome != "failed":
+            raise ProductionObservabilityContractError("delivery outcome is invalid")
+        reason = _string(reason_code, "reason_code", 64)
+        if not re.fullmatch(r"[a-z][a-z0-9_]{0,63}", reason):
+            raise ProductionObservabilityContractError("reason_code is invalid")
+        record["attempt_count"] += 1
+        record["lease_owner"] = None
+        record["lease_expires_at"] = None
+        if record["attempt_count"] >= MAX_DELIVERY_ATTEMPTS:
+            record["status"] = "dead_letter"
+            self._audit(
+                "delivery_dead_lettered", record["delivery_id"], reason_code=reason
+            )
+        else:
+            record["status"] = "pending"
+            self._audit(
+                "delivery_attempt_failed", record["delivery_id"], reason_code=reason
+            )
+        return dict(record)
+
+    def compensate_dead_letter(
+        self, delivery_id: str, *, actor_uid: str, note: str
+    ) -> dict[str, Any]:
+        record = self._delivery(delivery_id)
+        if record["status"] != "dead_letter":
+            raise ProductionObservabilityContractError("delivery is not a dead letter")
+        record["status"] = "compensated"
+        self._audit(
+            "delivery_compensated",
+            record["delivery_id"],
+            actor_uid=_uid(actor_uid, "actor_uid"),
+            note=_string(note, "compensation note", 160),
+        )
+        return dict(record)
+
+    def select_on_call_route(
+        self, payload: Any, *, elapsed_seconds: int
+    ) -> dict[str, Any]:
+        body = _safe_object(
+            payload,
+            {
+                "rotation_version",
+                "severity",
+                "primary",
+                "secondary",
+                "escalate_after_seconds",
+            },
+            "on-call route",
+        )
+        severity = _string(body.get("severity"), "severity", 20)
+        if severity not in {"warning", "error", "critical"}:
+            raise ProductionObservabilityContractError("on-call severity is invalid")
+        escalate_after = int(
+            _number(body.get("escalate_after_seconds"), "escalate_after_seconds")
+        )
+        if escalate_after < 60 or elapsed_seconds < 0:
+            raise ProductionObservabilityContractError("on-call escalation is invalid")
+        escalated = elapsed_seconds >= escalate_after
+        return {
+            "target": _string(
+                body.get("secondary") if escalated else body.get("primary"),
+                "on-call target",
+                120,
+            ),
+            "level": 2 if escalated else 1,
+            "rotation_version": _string(
+                body.get("rotation_version"), "rotation_version", 20
+            ),
+        }
+
+    def bind_itsm_reference(
+        self, *, incident_uid: str, external_ref: str, idempotency_key: str
+    ) -> dict[str, str]:
+        record = {
+            "incident_uid": _uid(incident_uid, "incident_uid"),
+            "external_ref": _string(external_ref, "external_ref", 120),
+            "idempotency_key": _string(idempotency_key, "idempotency_key", 120),
+        }
+        existing = self._itsm_by_key.get(record["idempotency_key"])
+        if existing is not None:
+            if existing != record:
+                raise ProductionObservabilityContractError("ITSM replay conflicts")
+            return dict(existing)
+        linked_incident = self._itsm_by_external_ref.get(record["external_ref"])
+        if linked_incident is not None and linked_incident != record["incident_uid"]:
+            raise ProductionObservabilityContractError(
+                "ITSM external reference conflicts"
+            )
+        self._itsm_by_key[record["idempotency_key"]] = record
+        self._itsm_by_external_ref[record["external_ref"]] = record["incident_uid"]
+        return dict(record)
+
+    def platform_incident_for_itsm(self, external_ref: str) -> str | None:
+        return self._itsm_by_external_ref.get(
+            _string(external_ref, "external_ref", 120)
+        )
+
+    def _delivery(self, delivery_id: str) -> dict[str, Any]:
+        record = self.deliveries.get(_uid(delivery_id, "delivery_id"))
+        if record is None:
+            raise LookupError("delivery was not found")
+        return record

+ 431 - 0
app/core/events/production_operations.py

@@ -0,0 +1,431 @@
+"""Persistent-provider-ready orchestration for P2 incident delivery.
+
+External providers are disabled by default.  The service only stores safe
+references, hashes, codes, and bounded summaries; adapters receive no URL or
+credential from this boundary.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import re
+import uuid
+from collections.abc import Callable
+from typing import Any
+
+from app.core.events.data_observability import _reject_secret_material
+
+
+class ProductionOperationsError(ValueError):
+    pass
+
+
+def _safe_string(value: Any, label: str, maximum: int = 160) -> str:
+    if not isinstance(value, str) or not value.strip() or len(value.strip()) > maximum:
+        raise ProductionOperationsError(f"{label} is invalid")
+    result = value.strip()
+    try:
+        _reject_secret_material({"value": result})
+    except ValueError as error:
+        raise ProductionOperationsError("sensitive material is not allowed") from error
+    if re.search(
+        r"(?i)(bearer\s+|password\s*[=:]|-----begin|\bselect\b.+\bfrom\b)", result
+    ):
+        raise ProductionOperationsError("sensitive material is not allowed")
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as error:
+        raise ProductionOperationsError(f"{label} must be a UUID") from error
+
+
+def _digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(value, sort_keys=True, separators=(",", ":")).encode()
+    ).hexdigest()
+
+
+class ProviderRegistry:
+    """Closed capability registry; real adapter registration is enterprise UAT."""
+
+    allowed = frozenset(
+        {"monitoring", "smtp", "enterprise_collaboration", "on_call", "itsm"}
+    )
+
+    def __init__(
+        self,
+        adapters: dict[str, Callable[[dict[str, str]], dict[str, str]]] | None = None,
+    ):
+        self.adapters = adapters or {}
+
+    def dispatch(self, capability: str, envelope: dict[str, str]) -> dict[str, str]:
+        capability = _safe_string(capability, "provider capability", 40)
+        if capability not in self.allowed or capability not in self.adapters:
+            raise ProductionOperationsError("provider capability is disabled")
+        response = self.adapters[capability](dict(envelope))
+        if not isinstance(response, dict) or set(response) != {
+            "status",
+            "receipt_code",
+        }:
+            raise ProductionOperationsError("provider response is invalid")
+        try:
+            _reject_secret_material(response)
+            status = _safe_string(response["status"], "provider response status", 20)
+            receipt_code = _safe_string(
+                response["receipt_code"], "provider receipt code", 160
+            )
+        except (KeyError, ValueError, ProductionOperationsError) as error:
+            raise ProductionOperationsError("provider response is invalid") from error
+        if status not in {"accepted", "queued", "rejected"}:
+            raise ProductionOperationsError("provider response is invalid")
+        return {"status": status, "receipt_code": receipt_code}
+
+
+class ProductionOperationsService:
+    def __init__(
+        self,
+        repository,
+        *,
+        now: Callable[[], float],
+        providers: ProviderRegistry | None = None,
+        queue_hard_limit: int = 500,
+    ):
+        if (
+            isinstance(queue_hard_limit, bool)
+            or not isinstance(queue_hard_limit, int)
+            or not 1 <= queue_hard_limit <= 500
+        ):
+            raise ProductionOperationsError("queue hard limit must be between 1 and 500")
+        self.repository = repository
+        self.now = now
+        self.providers = providers or ProviderRegistry()
+        self.queue_hard_limit = queue_hard_limit
+
+    def _audit(
+        self,
+        action: str,
+        *,
+        delivery_uid: str | None,
+        actor_uid: str,
+        detail: dict[str, str] | None = None,
+    ) -> None:
+        self.repository.append_audit(
+            {
+                "uid": str(uuid.uuid4()),
+                "delivery_uid": delivery_uid,
+                "action": action,
+                "actor_uid": _uid(actor_uid, "actor_uid"),
+                "safe_detail": detail or {},
+                "created_at": self.now(),
+            }
+        )
+
+    def enqueue_incident_delivery(
+        self, payload: Any, *, actor_uid: str
+    ) -> dict[str, Any]:
+        if not isinstance(payload, dict) or set(payload) != {
+            "incident_uid",
+            "alert_uid",
+            "channel",
+            "summary",
+        }:
+            raise ProductionOperationsError("delivery request has unsupported fields")
+        _reject_secret_material(payload)
+        record = {
+            "uid": str(uuid.uuid4()),
+            "incident_uid": _uid(payload["incident_uid"], "incident_uid"),
+            "alert_uid": _uid(payload["alert_uid"], "alert_uid"),
+            "channel": _safe_string(payload["channel"], "channel", 40),
+            "summary": _safe_string(payload["summary"], "summary"),
+            "status": "pending",
+            "attempt_count": 0,
+            "next_attempt_at": self.now(),
+            "lease_owner": None,
+            "lease_fence": 0,
+            "lease_expires_at": None,
+        }
+        if record["channel"] not in {
+            "smtp",
+            "enterprise_collaboration",
+            "on_call",
+            "itsm",
+            "monitoring",
+        }:
+            raise ProductionOperationsError("delivery channel is invalid")
+        record["idempotency_key"] = (
+            f"{record['incident_uid']}:{record['alert_uid']}:{record['channel']}"
+        )
+        record["payload_digest"] = _digest(
+            {
+                key: record[key]
+                for key in ("incident_uid", "alert_uid", "channel", "summary")
+            }
+        )
+        try:
+            stored = self.repository.enqueue_delivery(
+                record, queue_hard_limit=self.queue_hard_limit
+            )
+        except RuntimeError as error:
+            if str(error) in {"idempotency conflict", "delivery queue hard limit reached"}:
+                raise ProductionOperationsError(str(error)) from error
+            raise
+        if stored["uid"] == record["uid"]:
+            self._audit(
+                "delivery_enqueued",
+                delivery_uid=stored["uid"],
+                actor_uid=actor_uid,
+                detail={"channel": stored["channel"]},
+            )
+        return stored
+
+    def claim_delivery(
+        self, delivery_uid: str, *, worker_id: str, now: float | None = None
+    ) -> dict[str, Any]:
+        result = self.repository.claim_delivery(
+            _uid(delivery_uid, "delivery_uid"),
+            _safe_string(worker_id, "worker_id", 80),
+            self.now() if now is None else now,
+        )
+        if result is None:
+            raise ProductionOperationsError("delivery is not claimable")
+        return result
+
+    def record_delivery_attempt(
+        self,
+        delivery_uid: str,
+        *,
+        worker_id: str,
+        lease_fence: int,
+        delivered: bool,
+        actor_uid: str,
+        now: float | None = None,
+    ) -> dict[str, Any]:
+        if not isinstance(lease_fence, int) or lease_fence < 1:
+            raise ProductionOperationsError("lease fence is invalid")
+        current = self.now() if now is None else now
+        result = self.repository.record_attempt(
+            _uid(delivery_uid, "delivery_uid"),
+            _safe_string(worker_id, "worker_id", 80),
+            lease_fence,
+            current,
+            delivered,
+            "provider_unavailable" if not delivered else None,
+        )
+        if result is None:
+            raise ProductionOperationsError("delivery lease is expired or fenced")
+        action = (
+            "delivery_delivered"
+            if delivered
+            else (
+                "delivery_dead_lettered"
+                if result["status"] == "dead_letter"
+                else "delivery_attempt_failed"
+            )
+        )
+        self._audit(
+            action,
+            delivery_uid=result["uid"],
+            actor_uid=actor_uid,
+            detail={"status": result["status"]},
+        )
+        return result
+
+    def compensate_dead_letter(
+        self,
+        delivery_uid: str,
+        *,
+        reason_code: str,
+        receipt_code: str,
+        actor_uid: str,
+    ) -> dict[str, Any]:
+        reason_code = _safe_string(reason_code, "compensation reason code", 64)
+        receipt_code = _safe_string(receipt_code, "compensation receipt code", 64)
+        if reason_code not in {
+            "operator_review",
+            "provider_recovered",
+            "duplicate_suppressed",
+        } or not re.fullmatch(r"[A-Z][A-Z0-9_]{0,63}", receipt_code):
+            raise ProductionOperationsError("compensation receipt is invalid")
+        try:
+            result = self.repository.compensate_dead_letter(
+                _uid(delivery_uid, "delivery_uid"), reason_code, receipt_code
+            )
+        except RuntimeError as error:
+            raise ProductionOperationsError(str(error)) from error
+        self._audit(
+            "delivery_dead_letter_compensated",
+            delivery_uid=result["uid"],
+            actor_uid=actor_uid,
+            detail={"reason_code": reason_code, "receipt_code": receipt_code},
+        )
+        return result
+
+    def audit_rejection_independently(
+        self, *, actor_uid: str, reason_code: str, correlation_id: str
+    ) -> None:
+        reason_code = _safe_string(reason_code, "reason code", 64)
+        if reason_code not in {"invalid_request", "conflict", "internal_error"}:
+            raise ProductionOperationsError("reason code is invalid")
+        self.repository.append_rejection_audit_independently(
+            {
+                "uid": str(uuid.uuid4()),
+                "action": f"delivery_{reason_code}",
+                "actor_uid": _uid(actor_uid, "actor_uid"),
+                "safe_detail": {
+                    "reason_code": reason_code,
+                    "correlation_id": _uid(correlation_id, "correlation_id"),
+                },
+            }
+        )
+
+    def dispatch_provider(
+        self, capability: str, payload: dict[str, Any]
+    ) -> dict[str, str]:
+        incident_uid = _uid(payload.get("incident_uid"), "incident_uid")
+        return self.providers.dispatch(
+            capability,
+            {
+                "incident_uid": incident_uid,
+                "summary": _safe_string(payload.get("summary"), "summary"),
+            },
+        )
+
+    def create_policy(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        if not isinstance(payload, dict) or set(payload) != {
+            "code",
+            "version",
+            "layer",
+            "error_budget_ratio",
+        }:
+            raise ProductionOperationsError("policy has unsupported fields")
+        budget = payload["error_budget_ratio"]
+        if (
+            isinstance(budget, bool)
+            or not isinstance(budget, (int, float))
+            or not 0 < budget < 1
+        ):
+            raise ProductionOperationsError("error budget is invalid")
+        record = {
+            "uid": str(uuid.uuid4()),
+            "code": _safe_string(payload["code"], "policy code", 80),
+            "version": _safe_string(payload["version"], "policy version", 20),
+            "layer": _safe_string(payload["layer"], "policy layer", 20),
+            "error_budget_ratio": float(budget),
+            "status": "draft",
+            "created_by": _uid(actor_uid, "actor_uid"),
+            "created_at": self.now(),
+        }
+        if record["layer"] not in {"service", "task", "data", "capacity"}:
+            raise ProductionOperationsError("policy layer is invalid")
+        return dict(self.repository.save_policy(record))
+
+    def activate_policy(
+        self, code: str, version: str, *, actor_uid: str
+    ) -> dict[str, Any]:
+        result = self.repository.activate_policy(
+            _safe_string(code, "policy code", 80),
+            _safe_string(version, "policy version", 20),
+        )
+        self._audit(
+            "policy_activated",
+            delivery_uid=None,
+            actor_uid=actor_uid,
+            detail={"code": result["code"], "version": result["version"]},
+        )
+        return dict(result)
+
+    def active_policy(self, code: str) -> dict[str, Any]:
+        result = self.repository.active_policy(_safe_string(code, "policy code", 80))
+        if result is None:
+            raise ProductionOperationsError("active policy is not found")
+        return dict(result)
+
+    def list_deliveries(self, incident_uid: str) -> list[dict[str, Any]]:
+        return list(self.repository.list_deliveries(_uid(incident_uid, "incident_uid")))
+
+    def bind_itsm_reference(
+        self,
+        *,
+        incident_uid: str,
+        external_ref: str,
+        idempotency_key: str,
+        actor_uid: str,
+    ) -> dict[str, Any]:
+        record = {
+            "uid": str(uuid.uuid4()),
+            "incident_uid": _uid(incident_uid, "incident_uid"),
+            "external_ref": _safe_string(external_ref, "external_ref", 120),
+            "idempotency_key": _safe_string(idempotency_key, "idempotency_key", 160),
+        }
+        record["payload_digest"] = _digest(
+            {
+                key: record[key]
+                for key in ("incident_uid", "external_ref", "idempotency_key")
+            }
+        )
+        try:
+            stored = self.repository.bind_itsm_reference(record)
+        except RuntimeError as error:
+            if str(error) in {"idempotency conflict", "ITSM reference conflict"}:
+                raise ProductionOperationsError(str(error)) from error
+            raise
+        if stored["uid"] == record["uid"]:
+            self._audit(
+                "itsm_reference_bound",
+                delivery_uid=None,
+                actor_uid=actor_uid,
+                detail={"external_ref": stored["external_ref"]},
+            )
+        return dict(stored)
+
+    def itsm_reference_for_incident(self, incident_uid: str) -> dict[str, Any]:
+        result = self.repository.itsm_reference_for_incident(
+            _uid(incident_uid, "incident_uid")
+        )
+        if result is None:
+            raise ProductionOperationsError("ITSM reference is not found")
+        return dict(result)
+
+    def platform_incident_for_itsm(self, external_ref: str) -> str:
+        result = self.repository.platform_incident_for_itsm(
+            _safe_string(external_ref, "external_ref", 120)
+        )
+        if result is None:
+            raise ProductionOperationsError("ITSM reference is not found")
+        return result
+
+
+def run_local_fault_injection(
+    service: ProductionOperationsService,
+    *,
+    kind: str,
+    incident_uid: str,
+    alert_uid: str,
+    actor_uid: str,
+) -> dict[str, Any]:
+    kind = _safe_string(kind, "fault kind", 40)
+    if kind not in {
+        "collection_failed",
+        "dependency_slow",
+        "capacity_exhausted",
+        "recovered",
+    }:
+        raise ProductionOperationsError("fault kind is invalid")
+    record = {
+        "fault_kind": kind,
+        "incident_uid": _uid(incident_uid, "incident_uid"),
+        "alert_uid": _uid(alert_uid, "alert_uid"),
+        "correlation_id": str(uuid.uuid4()),
+        "recovery_candidate": True,
+    }
+    service._audit(
+        "fault_injected",
+        delivery_uid=None,
+        actor_uid=actor_uid,
+        detail={"fault_kind": kind, "correlation_id": record["correlation_id"]},
+    )
+    return record

+ 262 - 0
app/core/events/production_operations_repository.py

@@ -0,0 +1,262 @@
+"""PostgreSQL persistence for P3 operations delivery; no provider payload bodies."""
+
+from __future__ import annotations
+
+import json
+
+from sqlalchemy import text
+
+
+class SqlAlchemyProductionOperationsRepository:
+    def __init__(self, session):
+        self.session = session
+
+    def _row(self, value):
+        if value is None:
+            return None
+        return {
+            key: (
+                item.isoformat()
+                if hasattr(item, "isoformat")
+                else str(item)
+                if hasattr(item, "hex")
+                else item
+            )
+            for key, item in dict(value).items()
+        }
+
+    def enqueue_delivery(self, record, *, queue_hard_limit):
+        # A transaction-scoped advisory lock makes the count-and-insert admission
+        # check serializable across independent workers without a mutable counter.
+        self.session.execute(text("SELECT pg_advisory_xact_lock(48005)"))
+        existing = (
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_deliveries WHERE idempotency_key=:key"
+                ),
+                {"key": record["idempotency_key"]},
+            )
+            .mappings()
+            .one_or_none()
+        )
+        if existing:
+            if existing["payload_digest"] != record["payload_digest"]:
+                raise RuntimeError("idempotency conflict")
+            return self._row(existing)
+        occupied = self.session.execute(
+            text(
+                "SELECT count(*) FROM public.production_observability_deliveries "
+                "WHERE status IN ('pending','processing')"
+            )
+        ).scalar_one()
+        if occupied >= queue_hard_limit:
+            raise RuntimeError("delivery queue hard limit reached")
+        self.session.execute(
+            text(
+                """INSERT INTO public.production_observability_deliveries (uid,incident_uid,alert_uid,channel,idempotency_key,payload_digest,status,attempt_count,next_attempt_at,lease_fence,created_at,updated_at) VALUES (CAST(:uid AS uuid),CAST(:incident_uid AS uuid),CAST(:alert_uid AS uuid),:channel,:idempotency_key,:payload_digest,'pending',0,clock_timestamp(),0,clock_timestamp(),clock_timestamp())"""
+            ),
+            record,
+        )
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_deliveries WHERE uid=CAST(:uid AS uuid)"
+                ),
+                record,
+            )
+            .mappings()
+            .one()
+        )
+
+    def append_audit(self, record):
+        self.session.execute(
+            text(
+                "SELECT public.record_production_observability_audit("
+                "CAST(:uid AS uuid),CAST(:delivery_uid AS uuid),:action,"
+                "CAST(:actor_uid AS uuid),CAST(:safe_detail AS jsonb))"
+            ),
+            {**record, "safe_detail": json.dumps(record["safe_detail"])},
+        )
+
+    def append_rejection_audit_independently(self, record):
+        """Persist a safe rejection receipt outside a caller's rollback scope."""
+        get_bind = getattr(self.session, "get_bind", None)
+        bind = get_bind() if get_bind is not None else self.session
+        engine = getattr(bind, "engine", bind)
+        with engine.begin() as connection:
+            connection.execute(
+                text(
+                    "SELECT public.record_production_observability_audit("
+                    "CAST(:uid AS uuid),NULL,:action,CAST(:actor_uid AS uuid),"
+                    "CAST(:safe_detail AS jsonb))"
+                ),
+                {**record, "safe_detail": json.dumps(record["safe_detail"])},
+            )
+
+    def claim_delivery(self, uid, worker, now):
+        return self._row(
+            self.session.execute(
+                text(
+                    """UPDATE public.production_observability_deliveries SET status='processing',lease_owner=:worker,lease_fence=lease_fence+1,lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND ((status='pending' AND next_attempt_at<=clock_timestamp()) OR (status='processing' AND lease_expires_at<=clock_timestamp())) RETURNING *"""
+                ),
+                {"uid": uid, "worker": worker},
+            )
+            .mappings()
+            .one_or_none()
+        )
+
+    def record_attempt(self, uid, worker, fence, now, delivered, reason):
+        if delivered:
+            sql = """UPDATE public.production_observability_deliveries SET status='delivered',lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp() RETURNING *"""
+        else:
+            sql = """UPDATE public.production_observability_deliveries SET attempt_count=attempt_count+1,lease_owner=NULL,lease_expires_at=NULL,status=CASE WHEN attempt_count+1>=3 THEN 'dead_letter' ELSE 'pending' END,next_attempt_at=clock_timestamp()+(LEAST(3600,60*(attempt_count+1))*interval '1 second'),last_reason_code=:reason,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp() RETURNING *"""
+        return self._row(
+            self.session.execute(
+                text(sql),
+                {"uid": uid, "worker": worker, "fence": fence, "reason": reason},
+            )
+            .mappings()
+            .one_or_none()
+        )
+
+    def compensate_dead_letter(self, uid, reason_code, receipt_code):
+        existing = self.session.execute(
+            text(
+                "SELECT * FROM public.production_observability_deliveries "
+                "WHERE uid=CAST(:uid AS uuid) FOR UPDATE"
+            ),
+            {"uid": uid},
+        ).mappings().one_or_none()
+        if existing is None or existing["status"] not in {"dead_letter", "compensated"}:
+            raise RuntimeError("delivery is not compensable")
+        if existing["status"] == "compensated":
+            if (
+                existing["compensation_reason_code"] == reason_code
+                and existing["compensation_receipt_code"] == receipt_code
+            ):
+                return self._row(existing)
+            raise RuntimeError("compensation conflict")
+        return self._row(
+            self.session.execute(
+                text(
+                    "UPDATE public.production_observability_deliveries SET "
+                    "status='compensated',compensation_reason_code=:reason_code,"
+                    "compensation_receipt_code=:receipt_code,updated_at=clock_timestamp() "
+                    "WHERE uid=CAST(:uid AS uuid) AND status='dead_letter' RETURNING *"
+                ),
+                {"uid": uid, "reason_code": reason_code, "receipt_code": receipt_code},
+            ).mappings().one()
+        )
+
+    def save_policy(self, record):
+        self.session.execute(
+            text(
+                """INSERT INTO public.production_observability_policies (uid,code,version,layer,error_budget_ratio,status,created_by,created_at) VALUES (CAST(:uid AS uuid),:code,:version,:layer,:error_budget_ratio,:status,CAST(:created_by AS uuid),clock_timestamp())"""
+            ),
+            record,
+        )
+        return record
+
+    def activate_policy(self, code, version):
+        self.session.execute(
+            text(
+                "UPDATE public.production_observability_policies SET status='retired' WHERE code=:code AND status='active'"
+            ),
+            {"code": code},
+        )
+        return self._row(
+            self.session.execute(
+                text(
+                    "UPDATE public.production_observability_policies SET status='active' WHERE code=:code AND version=:version RETURNING *"
+                ),
+                {"code": code, "version": version},
+            )
+            .mappings()
+            .one()
+        )
+
+    def active_policy(self, code):
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_policies "
+                    "WHERE code=:code AND status='active'"
+                ),
+                {"code": code},
+            )
+            .mappings()
+            .one_or_none()
+        )
+
+    def list_deliveries(self, incident_uid):
+        return [
+            self._row(row)
+            for row in self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_deliveries "
+                    "WHERE incident_uid=CAST(:incident_uid AS uuid) ORDER BY created_at,uid"
+                ),
+                {"incident_uid": incident_uid},
+            ).mappings()
+        ]
+
+    def bind_itsm_reference(self, record):
+        existing = self.session.execute(
+            text(
+                "SELECT * FROM public.production_observability_itsm_references "
+                "WHERE idempotency_key=:key"
+            ),
+            {"key": record["idempotency_key"]},
+        ).mappings().one_or_none()
+        if existing:
+            if existing["payload_digest"] != record["payload_digest"]:
+                raise RuntimeError("idempotency conflict")
+            return self._row(existing)
+        collision = self.session.execute(
+            text(
+                "SELECT 1 FROM public.production_observability_itsm_references "
+                "WHERE incident_uid=CAST(:incident_uid AS uuid) OR external_ref=:external_ref"
+            ),
+            record,
+        ).scalar_one_or_none()
+        if collision:
+            raise RuntimeError("ITSM reference conflict")
+        self.session.execute(
+            text(
+                "INSERT INTO public.production_observability_itsm_references "
+                "(uid,incident_uid,external_ref,idempotency_key,payload_digest,created_at) "
+                "VALUES (CAST(:uid AS uuid),CAST(:incident_uid AS uuid),:external_ref,"
+                ":idempotency_key,:payload_digest,clock_timestamp())"
+            ),
+            record,
+        )
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_itsm_references "
+                    "WHERE uid=CAST(:uid AS uuid)"
+                ),
+                record,
+            ).mappings().one()
+        )
+
+    def itsm_reference_for_incident(self, incident_uid):
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_itsm_references "
+                    "WHERE incident_uid=CAST(:incident_uid AS uuid)"
+                ),
+                {"incident_uid": incident_uid},
+            ).mappings().one_or_none()
+        )
+
+    def platform_incident_for_itsm(self, external_ref):
+        row = self.session.execute(
+            text(
+                "SELECT incident_uid FROM public.production_observability_itsm_references "
+                "WHERE external_ref=:external_ref"
+            ),
+            {"external_ref": external_ref},
+        ).mappings().one_or_none()
+        return None if row is None else str(row["incident_uid"])

+ 901 - 0
app/core/governance/bi_ai_asset_catalog.py

@@ -0,0 +1,901 @@
+"""Closed, read-only BI/AI asset catalog engineering baseline.
+
+This module deliberately supports only the local fixture provider until an
+enterprise provider, API scope and service identity have been approved.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import os
+import re
+import uuid
+from datetime import UTC, datetime
+from typing import Any
+
+from sqlalchemy import create_engine, text
+
+ASSET_TYPES = frozenset(
+    {
+        "dataset",
+        "report",
+        "dashboard",
+        "model",
+        "prompt",
+        "agent",
+        "knowledge_base",
+        "index",
+        "evaluation_set",
+    }
+)
+CLASSIFICATIONS = frozenset({"public", "internal", "confidential", "restricted"})
+CAPABILITIES = frozenset({"assets.read", "dependencies.read"})
+_TOKEN = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,119}")
+_WORDS = re.compile(r"[A-Za-z0-9]{2,80}")
+_FORBIDDEN_TEXT = re.compile(
+    r"(?i)(?:https?://|://|\bselect\b|\binsert\b|\bupdate\b|\bdelete\b|\bscript\b|\btoken\b|\bpassword\b|\bsecret\b|api[_ -]?key)"
+)
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ValueError(f"{label} must be an object")
+    unknown = sorted(set(value) - allowed)
+    if unknown:
+        raise ValueError(f"unsupported {label} fields: {', '.join(unknown)}")
+    return copy.deepcopy(value)
+
+
+def _text(value: Any, label: str, maximum: int = 240) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise ValueError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum or _FORBIDDEN_TEXT.search(result):
+        raise ValueError(f"{label} is unsafe or exceeds {maximum} characters")
+    return result
+
+
+def _token(value: Any, label: str) -> str:
+    result = _text(value, label, 120)
+    if not _TOKEN.fullmatch(result):
+        raise ValueError(f"{label} is invalid")
+    return result
+
+
+def _string_list(value: Any, label: str, maximum: int = 32) -> list[str]:
+    if not isinstance(value, list) or len(value) > maximum:
+        raise ValueError(f"{label} must be a bounded list")
+    return sorted({_token(item, label) for item in value})
+
+
+def _digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(
+            value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
+        ).encode()
+    ).hexdigest()
+
+
+class ProviderRegistry:
+    """Resolve an allowlisted, versioned provider without any network configuration."""
+
+    _LOCAL = {
+        "provider_id": "local-fixture-v1",
+        "provider_version": "1",
+        "mode": "ENGINEERING_EVIDENCE_ONLY",
+        "origin": "local-fixture://wp11/v1",
+        "timeout_seconds": 3,
+        "page_size": 50,
+        "rate_limit_per_minute": 20,
+        "max_pages": 4,
+        "capabilities": ["assets.read", "dependencies.read"],
+    }
+
+    def resolve(
+        self,
+        provider_id: str,
+        provider_version: str,
+        *,
+        engineering_evidence_only: bool,
+    ) -> dict[str, Any]:
+        if not engineering_evidence_only:
+            raise PermissionError("engineering evidence only")
+        if (provider_id, provider_version) != ("local-fixture-v1", "1"):
+            raise PermissionError("provider disabled or unsupported")
+        return copy.deepcopy(self._LOCAL)
+
+
+def normalize_asset(
+    value: Any,
+    *,
+    source: str,
+    platform: str,
+    provider_version: str,
+    observed_at: str | None = None,
+) -> dict[str, Any]:
+    body = _closed(
+        value,
+        {
+            "external_uid",
+            "asset_type",
+            "name",
+            "owner",
+            "domain",
+            "tags",
+            "classification",
+            "permissions",
+            "dependencies",
+        },
+        "asset",
+    )
+    asset_type = _token(body.get("asset_type"), "asset_type")
+    if asset_type not in ASSET_TYPES:
+        raise ValueError("unsupported asset type")
+    classification = _token(body.get("classification"), "classification")
+    if classification not in CLASSIFICATIONS:
+        raise ValueError("unsupported classification")
+    normalized = {
+        "source": _token(source, "source"),
+        "platform": _token(platform, "platform"),
+        "provider_version": _token(provider_version, "provider_version"),
+        "external_uid": _token(body.get("external_uid"), "external_uid"),
+        "asset_type": asset_type,
+        "name": _text(body.get("name"), "name"),
+        "owner": _token(body.get("owner"), "owner"),
+        "domain": _token(body.get("domain"), "domain"),
+        "tags": _string_list(body.get("tags", []), "tags"),
+        "classification": classification,
+        "permissions": _string_list(body.get("permissions", []), "permissions"),
+        "dependencies": _string_list(body.get("dependencies", []), "dependencies"),
+        "raw_payload_retained": False,
+    }
+    normalized["digest"] = _digest(
+        {key: value for key, value in normalized.items() if key != "digest"}
+    )
+    normalized["observed_at"] = observed_at or datetime.now(UTC).isoformat().replace(
+        "+00:00", "Z"
+    )
+    return normalized
+
+
+def normalize_search(query: Any, filters: Any) -> dict[str, Any]:
+    if not isinstance(query, str) or len(query) > 500:
+        raise ValueError("query must be a bounded string")
+    allowed = {"asset_type", "tag", "classification"}
+    normalized_filters = _closed(filters, allowed, "search filters")
+    for key, value in tuple(normalized_filters.items()):
+        normalized_filters[key] = _token(value, key)
+    if (
+        "asset_type" in normalized_filters
+        and normalized_filters["asset_type"] not in ASSET_TYPES
+    ):
+        raise ValueError("unsupported asset type")
+    if (
+        "classification" in normalized_filters
+        and normalized_filters["classification"] not in CLASSIFICATIONS
+    ):
+        raise ValueError("unsupported classification")
+    return {
+        "keywords": [word.lower() for word in _WORDS.findall(query)][:12],
+        "filters": normalized_filters,
+        "sql": None,
+    }
+
+
+def local_fixture_assets() -> list[dict[str, Any]]:
+    """Controlled, content-free sample covering BI and AI catalog types."""
+    owner, domain, visible = "local-owner", "default", ["viewer"]
+    return [
+        {
+            "external_uid": "dataset-sales",
+            "asset_type": "dataset",
+            "name": "Sales facts",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["sales"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": [],
+        },
+        {
+            "external_uid": "report-sales",
+            "asset_type": "report",
+            "name": "Sales report",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["sales"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["dataset-sales"],
+        },
+        {
+            "external_uid": "dashboard-sales",
+            "asset_type": "dashboard",
+            "name": "Sales dashboard",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["sales"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["report-sales"],
+        },
+        {
+            "external_uid": "model-sales",
+            "asset_type": "model",
+            "name": "Sales model",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["forecast"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["dataset-sales"],
+        },
+        {
+            "external_uid": "prompt-sales",
+            "asset_type": "prompt",
+            "name": "Sales summary prompt",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["prompt"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": [],
+        },
+        {
+            "external_uid": "agent-sales",
+            "asset_type": "agent",
+            "name": "Sales assistant",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["agent"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["model-sales", "prompt-sales"],
+        },
+        {
+            "external_uid": "knowledge-sales",
+            "asset_type": "knowledge_base",
+            "name": "Sales knowledge",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["knowledge"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": [],
+        },
+        {
+            "external_uid": "index-sales",
+            "asset_type": "index",
+            "name": "Sales index",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["index"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["knowledge-sales"],
+        },
+        {
+            "external_uid": "evaluation-sales",
+            "asset_type": "evaluation_set",
+            "name": "Sales evaluation",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["evaluation"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["agent-sales"],
+        },
+    ]
+
+
+class CatalogControlIssuer:
+    """Issue one-time catalog claims through the separate control connection."""
+
+    def __init__(self, engine):
+        self.engine = engine
+
+    def issue(self, action: str, principal: str, body: dict[str, Any]) -> str:
+        with self.engine.begin() as control:
+            claim = control.execute(
+                text("SELECT public.bi_ai_catalog_issue_request_claim(:action,:principal,CAST(:body AS jsonb))"),
+                {"action": action, "principal": principal, "body": json.dumps(body, separators=(",", ":"))},
+            ).scalar_one()
+        return str(claim["request_claim"])
+
+    @classmethod
+    def from_environment(cls) -> CatalogControlIssuer:
+        from app.config.database_urls import validate_postgresql_url
+
+        url = os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", "")
+        parts = validate_postgresql_url(url, "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+        if parts.username != "dataops_bi_ai_catalog_control":
+            raise PermissionError("catalog control issuer is not configured")
+        return cls(create_engine(url, pool_pre_ping=True))
+
+
+class SqlAlchemyCatalogRepository:
+    """Persist only normalized projections; SQL rows/payloads are never retained."""
+
+    def __init__(self, session, control_issuer: CatalogControlIssuer | None = None):
+        self.session = session
+        self.control_issuer = control_issuer
+
+    @staticmethod
+    def _plain(row):
+        if row is None:
+            return None
+        result = dict(row)
+        for key, value in tuple(result.items()):
+            if isinstance(value, datetime):
+                result[key] = value.isoformat()
+            elif key in {"tags", "permissions", "dependencies"} and value is None:
+                result[key] = []
+        result["digest"] = result.pop("content_digest")
+        result["deleted_candidate"] = bool(result["deleted_candidate"])
+        result["tombstoned"] = result.pop("tombstoned_at") is not None
+        return result
+
+    def register_local_fixture(self):
+        # Tenant sources are inserted by the only runtime gateway after a
+        # persisted grant is checked.  Legacy registration is intentionally
+        # not callable from application code.
+        ProviderRegistry().resolve(
+            "local-fixture-v1", "1", engineering_evidence_only=True
+        )
+
+    def runtime_write(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        payload = self._claimed_payload(action, payload)
+        row = (
+            self.session.execute(
+                text(
+                    "SELECT public.bi_ai_catalog_runtime_write(:action,CAST(:payload AS jsonb)) AS result"
+                ),
+                {
+                    "action": action,
+                    "payload": json.dumps(payload, separators=(",", ":")),
+                },
+            )
+            .mappings()
+            .one()
+        )
+        return dict(row["result"])
+
+    def runtime_read(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        payload = self._claimed_payload(action, payload)
+        row = self.session.execute(
+            text(
+                "SELECT public.bi_ai_catalog_runtime_read(:action,CAST(:payload AS jsonb)) AS result"
+            ),
+            {"action": action, "payload": json.dumps(payload, separators=(",", ":"))},
+        ).mappings().one()
+        return dict(row["result"] or {})
+
+    def _claimed_payload(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        """Have the issuer-only DB identity bind a server-derived scope once."""
+        principal = payload.get("principal_ref")
+        if not isinstance(principal, str):
+            raise PermissionError("catalog request claim denied")
+        body = {
+            key: value
+            for key, value in payload.items()
+            if key not in {"principal_ref", "tenant_ref", "domain_ref", "request_claim"}
+        }
+        if self.control_issuer is None:
+            raise PermissionError("catalog control issuer is not configured")
+        return body | {"request_claim": self.control_issuer.issue(action, principal, body)}
+
+    def persist_local_fixture(
+        self, principal_ref: str, assets: list[dict[str, Any]]
+    ) -> dict[str, Any]:
+        lease_token = str(uuid.uuid4())
+        claim = self.runtime_write(
+            "claim",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "lease_owner": principal_ref,
+                "lease_token": lease_token,
+            },
+        )
+        projected = []
+        for asset in assets:
+            normalized = normalize_asset(
+                asset,
+                source="local-fixture-v1",
+                platform="local-fixture",
+                provider_version="1",
+            )
+            projected.append(
+                {
+                    key: normalized[key]
+                    for key in (
+                        "external_uid",
+                        "asset_type",
+                        "name",
+                        "owner",
+                        "domain",
+                        "tags",
+                        "classification",
+                        "permissions",
+                        "dependencies",
+                        "digest",
+                        "observed_at",
+                    )
+                }
+            )
+        return self.runtime_write(
+            "persist_page",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "lease_owner": principal_ref,
+                "lease_token": lease_token,
+                "lease_fence": claim["lease_fence"],
+                # A checkpoint is an acknowledged page boundary, not a lease
+                # token; each controlled fixture run advances a bounded token.
+                "cursor": f"fixture-page-{uuid.uuid4()}",
+                "assets": projected,
+                "page_digest": _digest({"assets": projected}),
+                "operation_id": str(uuid.uuid4()),
+                "final_page": True,
+            },
+        )
+
+    def observe_scan(
+        self, principal_ref: str, scan_id: str, observed_uids: list[str]
+    ) -> dict[str, Any]:
+        values = sorted({_token(item, "observed_uid") for item in observed_uids})
+        status = self.runtime_read("scan_status", {"principal_ref": principal_ref})
+        completed = status.get("scan_complete") and status.get("scan_id") == scan_id
+        if completed:
+            return {"replay": True}
+        generation = f"generation-{_token(scan_id, 'scan_id')}"
+        base = {
+            "source": "local-fixture-v1",
+            "principal_ref": principal_ref,
+            "scan_id": scan_id,
+        }
+        self.runtime_write(
+            "begin_scan",
+            base
+            | {
+                "generation_ref": generation,
+                "expected_pages": 1,
+            },
+        )
+        self.runtime_write(
+            "scan_page",
+            base
+            | {
+                "page_number": 1,
+                "observed_uids": values,
+                "page_digest": _digest({"scan_id": scan_id, "observed_uids": values}),
+            },
+        )
+        return self.runtime_write(
+            "finalize_scan",
+            base | {"final_cursor": f"final-{_token(scan_id, 'scan_id')}"},
+        )
+
+    def record_runtime_failure(
+        self, principal_ref: str, fence: int, error_code: str, payload_digest: str
+    ) -> dict[str, Any]:
+        return self.runtime_write(
+            "record_error",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "lease_fence": fence,
+                "error_code": _token(error_code, "error_code"),
+                "payload_digest": payload_digest,
+            },
+        )
+
+    def recover_runtime_failure(
+        self, principal_ref: str, error_code: str
+    ) -> dict[str, Any]:
+        return self.runtime_write(
+            "recover",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "error_code": _token(error_code, "error_code"),
+            },
+        )
+
+    def asset(
+        self,
+        source: str,
+        external_uid: str,
+        *,
+        tenant_ref: str,
+        domain_ref: str,
+    ):
+        raise RuntimeError("catalog direct read is sealed; use authorized gateway")
+
+    def all_assets(self, source: str, *, tenant_ref: str, domain_ref: str):
+        raise RuntimeError("catalog direct read is sealed; use authorized gateway")
+
+    def search_authorized(self, principal_ref: str, normalized: dict[str, Any]):
+        # Runtime roles have no table SELECT.  Principal is the sole read
+        # authorization root; tenant/domain/role come from its persisted grant.
+        return self.runtime_read(
+            "search",
+            {
+                "principal_ref": principal_ref,
+                "keywords": normalized["keywords"],
+                "filters": normalized["filters"],
+            },
+        ) | {"query": normalized}
+
+    def impact_authorized(self, principal_ref: str, external_uid: str, max_depth: int, max_nodes: int):
+        _token(external_uid, "external_uid")
+        return self.runtime_read(
+            "impact",
+            {
+                "principal_ref": principal_ref,
+                "external_uid": external_uid,
+                "max_depth": max_depth,
+                "max_nodes": max_nodes,
+            },
+        ) | {"source": external_uid, "max_depth": max_depth, "max_nodes": max_nodes}
+
+    def save_asset(self, asset: dict[str, Any]) -> None:
+        raise RuntimeError("catalog direct DML is sealed; use runtime gateway")
+
+    def missing_count(self, source: str, external_uid: str) -> int:
+        raise RuntimeError("catalog direct read requires server-derived scope")
+
+    def set_missing_count(self, source: str, external_uid: str, count: int) -> None:
+        return None
+
+    def record_audit(self, event_type: str, asset: dict[str, Any]) -> None:
+        raise RuntimeError("catalog direct audit is sealed; use runtime gateway")
+
+    def record_failure(
+        self, source: str, error_code: str, payload_digest: str, fence: int
+    ):
+        raise RuntimeError("catalog direct error write is sealed; use runtime gateway")
+
+    def recover_failure(self, source: str, error_code: str):
+        raise RuntimeError("catalog direct recovery is sealed; use runtime gateway")
+
+
+class CatalogApplicationService:
+    """HTTP-facing façade: principal scope is derived server-side, never body supplied."""
+
+    def __init__(self, session, control_issuer: CatalogControlIssuer | None = None):
+        self.session = session
+        self.repository = SqlAlchemyCatalogRepository(
+            session, control_issuer or CatalogControlIssuer.from_environment()
+        )
+        self.catalog = AssetCatalogService(self.repository)
+
+    def sync_local_fixture(self, *, principal_id: str, body: dict[str, Any]):
+        if body:
+            raise ValueError("catalog request rejected")
+        summary = self.repository.persist_local_fixture(
+            principal_id, local_fixture_assets()
+        )
+        self.session.commit()
+        return {
+            "source": "local-fixture-v1",
+            "mode": "ENGINEERING_EVIDENCE_ONLY",
+            "persisted_before_ack": True,
+            "summary": summary,
+        }
+
+    def search_for_principal(
+        self, *, principal_id: str, query: str, filters: dict[str, Any]
+    ):
+        return self.repository.search_authorized(
+            principal_id, normalize_search(query, filters)
+        )
+
+    def impact_for_principal(
+        self, *, principal_id: str, external_uid: str, max_depth: int, max_nodes: int
+    ):
+        return self.repository.impact_authorized(
+            principal_id, external_uid, max_depth, max_nodes
+        )
+
+    def audit_for_principal(self, *, principal_id: str):
+        # The security-definer gateway resolves the persisted principal grant
+        # before joining audit rows to visible assets.
+        return self.repository.runtime_read("audit", {"principal_ref": principal_id})
+
+
+class InMemoryCatalogRepository:
+    """Small deterministic repository used only by unit tests and local fixtures."""
+
+    def __init__(self):
+        self._assets: dict[tuple[str, str], dict[str, Any]] = {}
+        self._scans: dict[tuple[str, str], int] = {}
+        self._errors: dict[tuple[str, str, str], dict[str, Any]] = {}
+        self.audit: list[dict[str, Any]] = []
+
+    def asset(self, source: str, external_uid: str) -> dict[str, Any] | None:
+        row = self._assets.get((source, external_uid))
+        return copy.deepcopy(row) if row else None
+
+    def all_assets(self, source: str) -> list[dict[str, Any]]:
+        return [
+            copy.deepcopy(row)
+            for (item_source, _), row in self._assets.items()
+            if item_source == source
+        ]
+
+    def save_asset(self, asset: dict[str, Any]) -> None:
+        self._assets[(asset["source"], asset["external_uid"])] = copy.deepcopy(asset)
+
+    def missing_count(self, source: str, external_uid: str) -> int:
+        return self._scans.get((source, external_uid), 0)
+
+    def set_missing_count(self, source: str, external_uid: str, count: int) -> None:
+        self._scans[(source, external_uid)] = count
+
+    def record_audit(self, event_type: str, asset: dict[str, Any]) -> None:
+        self.audit.append(
+            {
+                "event_type": event_type,
+                "source": asset["source"],
+                "external_uid": asset["external_uid"],
+                "digest": asset["digest"],
+            }
+        )
+
+    def record_failure(
+        self, source: str, error_code: str, payload_digest: str, fence: int
+    ):
+        key = (source, error_code, payload_digest)
+        previous = self._errors.get(key, {"attempts": 0})
+        attempts = previous["attempts"] + 1
+        record = {
+            "source": source,
+            "error_code": error_code,
+            "payload_digest": payload_digest,
+            "lease_fence": fence,
+            "attempts": attempts,
+            "status": "dead_letter" if attempts >= 5 else "retryable",
+        }
+        self._errors[key] = record
+        return copy.deepcopy(record)
+
+    def recover_failure(self, source: str, error_code: str):
+        candidates = [
+            record
+            for (item_source, item_code, _), record in self._errors.items()
+            if item_source == source
+            and item_code == error_code
+            and record["status"] == "dead_letter"
+        ]
+        if not candidates:
+            raise LookupError("dead letter unavailable")
+        record = candidates[-1]
+        record["status"] = "recovered"
+        return copy.deepcopy(record)
+
+
+class AssetCatalogService:
+    """Persist normalized metadata, then advance only the caller's cursor/ack."""
+
+    def __init__(self, repository, *, registry: ProviderRegistry | None = None):
+        self.repository = repository
+        self.registry = registry or ProviderRegistry()
+
+    def ingest_page(
+        self,
+        provider_id: str,
+        provider_version: str,
+        assets: list[dict[str, Any]],
+        *,
+        cursor: str,
+        fence: int,
+    ) -> dict[str, int]:
+        if not isinstance(fence, int) or fence < 1 or not _TOKEN.fullmatch(str(cursor)):
+            raise ValueError("invalid cursor or fence")
+        manifest = self.registry.resolve(
+            provider_id, provider_version, engineering_evidence_only=True
+        )
+        results = {"created": 0, "unchanged": 0, "changed": 0, "restored": 0}
+        if not isinstance(assets, list) or len(assets) > manifest["page_size"]:
+            raise ValueError("asset page exceeds configured bound")
+        for item in assets:
+            normalized = normalize_asset(
+                item,
+                source=provider_id,
+                platform="local-fixture",
+                provider_version=provider_version,
+            )
+            saved = self.repository.asset(provider_id, normalized["external_uid"])
+            if saved is None:
+                normalized["version"] = 1
+                normalized["deleted_candidate"] = False
+                normalized["tombstoned"] = False
+                results["created"] += 1
+                self.repository.record_audit("catalog.asset.created", normalized)
+            elif saved["digest"] == normalized["digest"] and not saved.get(
+                "tombstoned"
+            ):
+                normalized.update(
+                    {
+                        "version": saved["version"],
+                        "deleted_candidate": False,
+                        "tombstoned": False,
+                    }
+                )
+                results["unchanged"] += 1
+            else:
+                normalized.update(
+                    {
+                        "version": saved["version"]
+                        + (0 if saved["digest"] == normalized["digest"] else 1),
+                        "deleted_candidate": False,
+                        "tombstoned": False,
+                    }
+                )
+                if saved.get("tombstoned"):
+                    results["restored"] += 1
+                    self.repository.record_audit("catalog.asset.restored", normalized)
+                else:
+                    results["changed"] += 1
+                    self.repository.record_audit("catalog.asset.changed", normalized)
+            self.repository.set_missing_count(
+                provider_id, normalized["external_uid"], 0
+            )
+            self.repository.save_asset(normalized)
+        return results
+
+    def confirm_missing(
+        self, source: str, observed_external_uids: set[str], *, scan_id: str
+    ) -> dict[str, int]:
+        _token(source, "source")
+        _token(scan_id, "scan_id")
+        if not isinstance(observed_external_uids, set) or not all(
+            isinstance(item, str) for item in observed_external_uids
+        ):
+            raise ValueError("observed external uids must be a set")
+        result = {"candidates": 0, "tombstoned": 0}
+        for asset in self.repository.all_assets(source):
+            if asset["external_uid"] in observed_external_uids or asset.get(
+                "tombstoned"
+            ):
+                continue
+            count = self.repository.missing_count(source, asset["external_uid"]) + 1
+            self.repository.set_missing_count(source, asset["external_uid"], count)
+            asset["deleted_candidate"] = True
+            if count >= 2:
+                asset["tombstoned"] = True
+                result["tombstoned"] += 1
+                self.repository.record_audit("catalog.asset.tombstoned", asset)
+            else:
+                result["candidates"] += 1
+                self.repository.record_audit("catalog.asset.deletion_candidate", asset)
+            self.repository.save_asset(asset)
+        return result
+
+    def record_failure(
+        self, source: str, *, fence: int, error_code: str, payload_digest: str
+    ) -> dict[str, Any]:
+        _token(source, "source")
+        _token(error_code, "error_code")
+        if (
+            not isinstance(fence, int)
+            or fence < 1
+            or not re.fullmatch(r"[0-9a-f]{64}", payload_digest)
+        ):
+            raise ValueError("catalog failure is invalid")
+        if not hasattr(self.repository, "record_failure"):
+            raise RuntimeError("catalog failure store unavailable")
+        return self.repository.record_failure(source, error_code, payload_digest, fence)
+
+    def recover_failure(self, source: str, *, error_code: str) -> dict[str, Any]:
+        _token(source, "source")
+        _token(error_code, "error_code")
+        if not hasattr(self.repository, "recover_failure"):
+            raise RuntimeError("catalog recovery store unavailable")
+        return self.repository.recover_failure(source, error_code)
+
+    def _visible(
+        self, asset: dict[str, Any], principal_roles: set[str], domain: str
+    ) -> bool:
+        if "viewer" not in principal_roles and "admin" not in principal_roles:
+            raise PermissionError("catalog read denied")
+        return asset["domain"] == domain and "viewer" in asset["permissions"]
+
+    def search(
+        self,
+        query: str,
+        filters: dict[str, Any],
+        *,
+        principal_roles: set[str],
+        domain: str,
+    ) -> list[dict[str, Any]]:
+        request = normalize_search(query, filters)
+        results = []
+        for asset in self.repository.all_assets("local-fixture-v1"):
+            if asset.get("tombstoned") or not self._visible(
+                asset, principal_roles, domain
+            ):
+                continue
+            haystack = " ".join([asset["name"], *asset["tags"]]).lower()
+            if request["keywords"] and not all(
+                word in haystack for word in request["keywords"]
+            ):
+                continue
+            if any(
+                asset.get(key) != value and value not in asset.get(key + "s", [])
+                for key, value in request["filters"].items()
+            ):
+                continue
+            results.append(
+                {
+                    key: asset[key]
+                    for key in (
+                        "external_uid",
+                        "asset_type",
+                        "name",
+                        "owner",
+                        "domain",
+                        "tags",
+                        "classification",
+                        "version",
+                        "observed_at",
+                    )
+                }
+            )
+        return sorted(
+            results, key=lambda row: (row["name"].lower(), row["external_uid"])
+        )[:50]
+
+    def impact(
+        self,
+        external_uid: str,
+        *,
+        principal_roles: set[str],
+        domain: str,
+        max_depth: int,
+        max_nodes: int,
+    ) -> dict[str, Any]:
+        if max_depth < 1 or max_depth > 5 or max_nodes < 1 or max_nodes > 100:
+            raise ValueError("impact bounds are invalid")
+        root = self.repository.asset(
+            "local-fixture-v1", _token(external_uid, "external_uid")
+        )
+        if root is None or not self._visible(root, principal_roles, domain):
+            raise LookupError("catalog asset unavailable")
+        by_dependency: dict[str, list[dict[str, Any]]] = {}
+        for asset in self.repository.all_assets("local-fixture-v1"):
+            if not asset.get("tombstoned") and self._visible(
+                asset, principal_roles, domain
+            ):
+                for dependency in asset["dependencies"]:
+                    by_dependency.setdefault(dependency, []).append(asset)
+        affected, seen, frontier = (
+            [],
+            {root["external_uid"]},
+            [(root["external_uid"], 0)],
+        )
+        truncated = False
+        while frontier:
+            node, depth = frontier.pop(0)
+            if depth >= max_depth:
+                continue
+            for child in by_dependency.get(node, []):
+                if child["external_uid"] in seen:
+                    continue
+                if len(affected) >= max_nodes:
+                    truncated = True
+                    break
+                seen.add(child["external_uid"])
+                affected.append(child["external_uid"])
+                frontier.append((child["external_uid"], depth + 1))
+            if truncated:
+                break
+        return {
+            "external_uid": root["external_uid"],
+            "affected": affected,
+            "truncated": truncated,
+        }

+ 616 - 82
app/core/governance/domain_replication.py

@@ -11,9 +11,13 @@ from __future__ import annotations
 import hashlib
 import json
 import re
+import unicodedata
 from copy import deepcopy
+from datetime import date
 from typing import Any
 
+from app.core.governance.domain_replication_contract_registry import verify_registry
+
 REQUIRED_STAGES = (
     "template_initialization",
     "incremental_ingestion",
@@ -56,6 +60,66 @@ _REQUIRED_ENTERPRISE_BINDINGS = {
     "readonly_source",
     "uat_users",
 }
+_EXECUTION_ACTIONS = ("dry_run", "execute")
+_RECOVERY_ACTIONS = frozenset({"diff", "rollback"})
+_EXECUTION_REF = re.compile(
+    r"^[a-z][a-z0-9-]{1,31}://([a-z][a-z0-9_]{1,63})/[a-zA-Z0-9_./:-]{1,240}$"
+)
+_HTTP_URL = re.compile(r"https?://", re.IGNORECASE)
+_RAW_ROW_KEY = re.compile(r"(?:raw[_-]?rows?|source[_-]?rows?)", re.IGNORECASE)
+_SHA256 = re.compile(r"^[0-9a-f]{64}$")
+_IDENTIFIER = re.compile(r"^[a-z][a-z0-9_-]{1,79}$")
+_CONFUSABLES = str.maketrans({
+    "а": "a", "е": "e", "і": "i", "о": "o", "р": "p", "с": "c",
+    "х": "x", "у": "y", "к": "k", "м": "m", "т": "t", "ѕ": "s",
+})
+_SENSITIVE_KEY_MARKERS = (
+    "password", "passwd", "secret", "token", "credential", "authorization",
+    "apikey", "privatekey",
+)
+_RAW_SOURCE_KEYS = {"rawrows", "sourcerows", "rows"}
+_SQL = re.compile(r"\b(?:select|insert|update|delete|drop|alter|create|grant|revoke)\b", re.IGNORECASE)
+_API_ALLOWLIST = {
+    "template_initialization": ("/api/meta/domain-templates",),
+    "incremental_ingestion": ("/api/meta/active-metadata",),
+    "catalog": ("/api/meta/active-metadata",),
+    "semantics": ("/api/development/v1/semantic-assets",),
+    "responsibility": ("/api/system/responsibilities",),
+    "quality": ("/api/rules/quality-operations",),
+    "remediation": ("/api/system/work-center",),
+    "observability": ("/api/datafactory/observability",),
+    "data_product": ("/api/dataservice/governance/products",),
+    "agent": ("/api/knowledge/agents",),
+}
+_EVIDENCE_PREFIXES = {
+    "template_initialization": "domain-template://",
+    "incremental_ingestion": "ingestion://",
+    "catalog": "catalog-run://",
+    "semantics": "semantic-release://",
+    "responsibility": "responsibility://",
+    "quality": "quality://",
+    "remediation": "workflow://",
+    "observability": "incident://",
+    "data_product": "product://",
+    "agent": "agent-request://",
+}
+_CONTRACT_REQUIREMENTS = {
+    "incremental_ingestion": "p3_wp03_connector_run",
+    "catalog": "p3_wp03_catalog_lineage",
+    "observability": "p3_wp04_edge_health",
+}
+_METRIC_FIELDS = {
+    "template_initialization": {"template_version", "object_type_count", "rule_count", "role_count", "metric_count"},
+    "incremental_ingestion": {"snapshot_rows", "delta_rows", "inserted", "updated", "deleted", "final_rows", "replay_changes", "cursor_before", "cursor_after"},
+    "catalog": {"asset_count", "incremental_change_count", "cursor_after"},
+    "semantics": {"published_term_count", "published_code_set_count", "published_metric_count", "mapped_field_count"},
+    "responsibility": {"coverage_percent", "bound_role_count"},
+    "quality": {"published_rule_count", "initial_finding_count", "target_score", "final_score"},
+    "remediation": {"issue_status", "task_status", "independent_closer"},
+    "observability": {"slo_count", "incident_status", "recovered"},
+    "data_product": {"contract_status", "certificate_status", "certificate_evidence_refs"},
+    "agent": {"autonomy_level", "decision", "automatic_execution_allowed", "citation_count", "cross_domain_denied"},
+}
 
 
 class DomainReplicationError(ValueError):
@@ -88,17 +152,291 @@ def _bounded_text(value: Any, field: str, limit: int = 256) -> str:
     return rendered
 
 
-def _reject_secrets(value: Any, path: str = "$") -> None:
+def _security_key(value: Any) -> str:
+    return re.sub(
+        r"[^a-z0-9]", "", unicodedata.normalize("NFKC", str(value)).casefold().translate(_CONFUSABLES)
+    )
+
+
+def _reject_secrets(value: Any, path: str = "$", depth: int = 0) -> None:
+    if depth > 12:
+        raise DomainReplicationError(f"maximum package depth exceeded at {path}")
     if isinstance(value, dict):
+        if len(value) > 64:
+            raise DomainReplicationError(f"maximum object properties exceeded at {path}")
         for key, item in value.items():
-            if _SECRET.search(str(key)):
+            normalized_key = _security_key(key)
+            if normalized_key in _RAW_SOURCE_KEYS:
+                raise DomainReplicationError(
+                    f"raw source rows are not allowed at {path}.{key}"
+                )
+            if _SECRET.search(normalized_key) or any(
+                marker in normalized_key for marker in _SENSITIVE_KEY_MARKERS
+            ):
                 raise DomainReplicationError(
-                    f"secret material is not allowed at {path}.{key}"
+                    f"sensitive material is not allowed at {path}.{key}"
                 )
-            _reject_secrets(item, f"{path}.{key}")
+            _reject_secrets(item, f"{path}.{key}", depth + 1)
+    elif isinstance(value, list):
+        if len(value) > 500:
+            raise DomainReplicationError(f"maximum collection items exceeded at {path}")
+        for index, item in enumerate(value):
+            _reject_secrets(item, f"{path}[{index}]", depth + 1)
+    elif isinstance(value, str):
+        if len(value) > 4096:
+            raise DomainReplicationError(f"maximum string length exceeded at {path}")
+        normalized = unicodedata.normalize("NFKC", value)
+        if _HTTP_URL.search(normalized):
+            raise DomainReplicationError(f"URL is not allowed at {path}")
+        if _SQL.search(normalized):
+            raise DomainReplicationError(f"SQL is not allowed at {path}")
+
+
+def _closed_mapping(value: Any, field: str, allowed: set[str]) -> dict[str, Any]:
+    value = _mapping(value, field)
+    unknown = sorted(set(value) - allowed)
+    if unknown:
+        normalized_unknown = [_security_key(key) for key in unknown]
+        if any(key in _RAW_SOURCE_KEYS for key in normalized_unknown):
+            raise DomainReplicationError(f"raw source rows are not allowed at {field}")
+        if any(
+            _SECRET.search(key) or any(marker in key for marker in _SENSITIVE_KEY_MARKERS)
+            for key in normalized_unknown
+        ):
+            raise DomainReplicationError(f"sensitive material is not allowed at {field}")
+        raise DomainReplicationError(f"{field} has unsupported fields: {unknown}")
+    return value
+
+
+def _closed_required(value: Any, field: str, required: set[str], allowed: set[str]) -> dict[str, Any]:
+    value = _closed_mapping(value, field, allowed)
+    missing = sorted(required - set(value))
+    if missing:
+        raise DomainReplicationError(f"{field} is missing required fields: {missing}")
+    return value
+
+
+def _string(value: Any, field: str, limit: int = 256) -> str:
+    if not isinstance(value, str):
+        raise DomainReplicationError(f"{field} must be a string")
+    return _bounded_text(value, field, limit)
+
+
+def _digest_string(value: Any, field: str) -> str:
+    value = _string(value, field, 64)
+    if not _SHA256.fullmatch(value):
+        raise DomainReplicationError(f"{field} must be a lowercase SHA-256 digest")
+    return value
+
+
+def _bounded_list(value: Any, field: str, *, minimum: int = 1, maximum: int = 100) -> list[Any]:
+    if not isinstance(value, list) or not minimum <= len(value) <= maximum:
+        raise DomainReplicationError(f"{field} must contain {minimum}..{maximum} items")
+    return value
+
+
+def _execution_ref(value: Any, field: str) -> tuple[str, str]:
+    rendered = _bounded_text(value, field, 320)
+    if _HTTP_URL.search(rendered):
+        raise DomainReplicationError(f"{field} must not contain a URL")
+    matched = _EXECUTION_REF.fullmatch(rendered)
+    if not matched:
+        raise DomainReplicationError(f"{field} must be a canonical evidence reference")
+    return rendered, matched.group(1)
+
+
+def _reject_execution_sensitive(value: Any, path: str = "execution_evidence") -> None:
+    if isinstance(value, dict):
+        for key, item in value.items():
+            if _RAW_ROW_KEY.search(str(key)):
+                raise DomainReplicationError(f"raw source rows are not allowed at {path}.{key}")
+            if _HTTP_URL.search(str(item)):
+                raise DomainReplicationError(f"URL is not allowed at {path}.{key}")
+            _reject_execution_sensitive(item, f"{path}.{key}")
     elif isinstance(value, list):
         for index, item in enumerate(value):
-            _reject_secrets(item, f"{path}[{index}]")
+            _reject_execution_sensitive(item, f"{path}[{index}]")
+
+
+def _validate_execute_state(action: dict[str, Any], stage: str) -> dict[str, Any]:
+    """Validate the v2 receipt that owns a governed state transition."""
+
+    required = {
+        "action", "status", "write_count", "evidence_ref", "audit_ref", "operation_uid",
+        "idempotency_key", "request_digest", "attempt", "lease_fence", "pre_state_digest",
+        "post_state_digest", "result_digest",
+    }
+    action = _closed_required(action, f"{stage}.execute", required, required)
+    for field in ("operation_uid", "idempotency_key"):
+        if not _IDENTIFIER.fullmatch(_string(action[field], f"{stage}.execute.{field}", 80)):
+            raise DomainReplicationError(f"{stage}.execute.{field} is invalid")
+    for field in ("request_digest", "pre_state_digest", "post_state_digest", "result_digest"):
+        _digest_string(action[field], f"{stage}.execute.{field}")
+    if action["pre_state_digest"] == action["post_state_digest"]:
+        raise DomainReplicationError(f"{stage}.execute state digests must differ")
+    if isinstance(action["attempt"], bool) or not isinstance(action["attempt"], int) or not 1 <= action["attempt"] <= 5:
+        raise DomainReplicationError(f"{stage}.execute.attempt must be 1..5")
+    if isinstance(action["lease_fence"], bool) or not isinstance(action["lease_fence"], int) or action["lease_fence"] < 1:
+        raise DomainReplicationError(f"{stage}.execute.lease_fence must be positive")
+    return action
+
+
+def _validate_rollback(action: dict[str, Any], stage: str, *, strict_state_machine: bool) -> dict[str, Any]:
+    required = {
+        "action", "status", "write_count", "evidence_ref", "audit_ref", "operation",
+        "idempotency_key", "request_digest", "attempt", "lease_fence", "from_digest",
+        "to_digest", "replay_status",
+    }
+    if strict_state_machine:
+        required = required - {"replay_status"} | {"operation_uid", "result_digest"}
+    action = _closed_required(action, f"{stage}.rollback", required, required)
+    if action["operation"] != "restore":
+        raise DomainReplicationError(f"{stage}.rollback.operation must be restore")
+    for field in ("operation_uid", "idempotency_key") if strict_state_machine else ("idempotency_key",):
+        if not _IDENTIFIER.fullmatch(_string(action[field], f"{stage}.rollback.{field}", 80)):
+            raise DomainReplicationError(f"{stage}.rollback.{field} is invalid")
+    digest_fields = ("request_digest", "from_digest", "to_digest", "result_digest") if strict_state_machine else ("request_digest", "from_digest", "to_digest")
+    for key in digest_fields:
+        _digest_string(action[key], f"{stage}.rollback.{key}")
+    if action["from_digest"] == action["to_digest"]:
+        raise DomainReplicationError(f"{stage}.rollback digests must differ")
+    if isinstance(action["attempt"], bool) or not isinstance(action["attempt"], int) or not 1 <= action["attempt"] <= 5:
+        raise DomainReplicationError(f"{stage}.rollback.attempt must be 1..5")
+    if isinstance(action["lease_fence"], bool) or not isinstance(action["lease_fence"], int) or action["lease_fence"] < 1:
+        raise DomainReplicationError(f"{stage}.rollback.lease_fence must be positive")
+    if not strict_state_machine and action["replay_status"] != "exact_replay":
+        raise DomainReplicationError(f"{stage}.rollback replay must be exact_replay")
+    return action
+
+
+def _validate_replay_receipts(value: Any, rollbacks: dict[str, dict[str, Any]]) -> None:
+    """Require a second receipt, not a rollback's self-declared replay label."""
+
+    required = {
+        "stage", "operation_uid", "idempotency_key", "request_digest", "attempt",
+        "lease_fence", "from_digest", "to_digest", "result_digest", "status",
+    }
+    receipts = _bounded_list(value, "execution_evidence.replay_receipts", minimum=len(rollbacks), maximum=len(rollbacks))
+    by_stage: dict[str, dict[str, Any]] = {}
+    for item in receipts:
+        item = _closed_required(item, "execution_evidence.replay_receipt", required, required)
+        stage = _string(item["stage"], "execution_evidence.replay_receipt.stage", 80)
+        if stage not in rollbacks or stage in by_stage:
+            raise DomainReplicationError("replay receipt must bind exactly one rollback stage")
+        if item["status"] != "exact_replay":
+            raise DomainReplicationError("replay receipt status must be exact_replay")
+        for field in ("operation_uid", "idempotency_key"):
+            if not _IDENTIFIER.fullmatch(_string(item[field], f"replay_receipt.{field}", 80)):
+                raise DomainReplicationError(f"replay receipt {field} is invalid")
+        for field in ("request_digest", "from_digest", "to_digest", "result_digest"):
+            _digest_string(item[field], f"replay_receipt.{field}")
+        rollback = rollbacks[stage]
+        for field in required - {"stage", "status"}:
+            if item[field] != rollback[field]:
+                raise DomainReplicationError(f"replay receipt does not match rollback {field}")
+        by_stage[stage] = item
+    if set(by_stage) != set(rollbacks):
+        raise DomainReplicationError("replay receipt coverage is incomplete")
+
+
+def validate_execution_evidence(
+    execution_evidence: dict[str, Any], *, domain_code: str | None = None
+) -> dict[str, dict[str, Any]]:
+    """Validate the ordered, row-free execution chain for every governance stage."""
+
+    initial = _mapping(execution_evidence, "execution_evidence")
+    schema_version = initial.get("schema_version")
+    if schema_version not in {1, 2}:
+        raise DomainReplicationError("execution_evidence.schema_version must be 1 or 2")
+    strict_state_machine = schema_version == 2
+    execution_evidence = _closed_mapping(
+        execution_evidence,
+        "execution_evidence",
+        {"schema_version", "stages", "replay_receipts"} if strict_state_machine else {"schema_version", "stages"},
+    )
+    _reject_secrets(execution_evidence, "execution_evidence")
+    _reject_execution_sensitive(execution_evidence)
+    receipts = execution_evidence.get("stages")
+    if not isinstance(receipts, list) or len(receipts) != len(REQUIRED_STAGES):
+        raise DomainReplicationError("execution_evidence must contain every required stage")
+
+    summaries: dict[str, dict[str, Any]] = {}
+    rollbacks: dict[str, dict[str, Any]] = {}
+    for expected_stage, receipt in zip(REQUIRED_STAGES, receipts, strict=True):
+        receipt = _closed_mapping(receipt, "execution_evidence.stage", {"stage", "actions"})
+        stage = _bounded_text(receipt.get("stage"), "execution_evidence.stage.stage", 80)
+        if stage != expected_stage:
+            raise DomainReplicationError("execution evidence stages must be ordered")
+        actions = receipt.get("actions")
+        if not isinstance(actions, list) or len(actions) != 3:
+            raise DomainReplicationError(f"{stage} must contain dry_run, execute and diff or rollback")
+        normalized_actions: list[dict[str, Any]] = []
+        domains: set[str] = set()
+        for index, action in enumerate(actions):
+            action = _mapping(action, f"{stage}.actions[{index}]")
+            action_name = _bounded_text(action.get("action"), f"{stage}.action", 32)
+            expected_action = (
+                _EXECUTION_ACTIONS[index] if index < 2 else None
+            )
+            if expected_action and action_name != expected_action:
+                raise DomainReplicationError(f"{stage} actions must be ordered dry_run then execute")
+            if index == 2 and action_name not in _RECOVERY_ACTIONS:
+                raise DomainReplicationError(f"{stage} recovery action must be diff or rollback")
+            allowed = {"action", "status", "write_count", "evidence_ref", "audit_ref"}
+            if action_name == "rollback":
+                action = _validate_rollback(action, stage, strict_state_machine=strict_state_machine)
+            elif action_name == "execute" and strict_state_machine:
+                action = _validate_execute_state(action, stage)
+            else:
+                action = _closed_required(action, f"{stage}.actions[{index}]", allowed, allowed)
+            if action.get("status") != "passed":
+                raise DomainReplicationError(f"{stage}.{action_name} status must be passed")
+            write_count = action.get("write_count")
+            if isinstance(write_count, bool) or not isinstance(write_count, int):
+                raise DomainReplicationError(f"{stage}.{action_name}.write_count must be an integer")
+            if write_count < 0 or write_count > 1_000_000:
+                raise DomainReplicationError(f"{stage}.{action_name}.write_count is out of range")
+            if action_name == "dry_run" and write_count != 0:
+                raise DomainReplicationError(f"{stage}.dry_run must record zero writes")
+            evidence_ref, evidence_domain = _execution_ref(
+                action.get("evidence_ref"), f"{stage}.{action_name}.evidence_ref"
+            )
+            audit_ref, audit_domain = _execution_ref(
+                action.get("audit_ref"), f"{stage}.{action_name}.audit_ref"
+            )
+            domains.update({evidence_domain, audit_domain})
+            normalized_actions.append(
+                {
+                    "action": action_name,
+                    "write_count": write_count,
+                    "evidence_ref": evidence_ref,
+                    "audit_ref": audit_ref,
+                }
+            )
+            if action_name == "rollback" and strict_state_machine:
+                execute = actions[1]
+                for field in ("operation_uid", "idempotency_key", "request_digest", "attempt", "lease_fence"):
+                    if action[field] != execute[field]:
+                        raise DomainReplicationError(f"{stage}.rollback must match execute {field}")
+                if action["from_digest"] != execute["post_state_digest"]:
+                    raise DomainReplicationError(f"{stage}.rollback.from_digest must match execute post_state_digest")
+                if action["to_digest"] != execute["pre_state_digest"]:
+                    raise DomainReplicationError(f"{stage}.rollback.to_digest must match execute pre_state_digest")
+                rollbacks[stage] = action
+        if len(domains) != 1 or (domain_code is not None and domains != {domain_code}):
+            raise DomainReplicationError(f"{stage} execution evidence contains a cross-domain reference")
+        summaries[stage] = {
+            "actions": [item["action"] for item in normalized_actions],
+            "dry_run_write_count": normalized_actions[0]["write_count"],
+            "execute_write_count": normalized_actions[1]["write_count"],
+            "recovery_strategy": normalized_actions[2]["action"],
+            "recovery_write_count": normalized_actions[2]["write_count"],
+            "audit_ref_count": len(normalized_actions),
+            "evidence_digest": _digest(normalized_actions),
+        }
+    if strict_state_machine:
+        _validate_replay_receipts(execution_evidence.get("replay_receipts"), rollbacks)
+    return summaries
 
 
 def _row_key(row: dict[str, str], fields: list[str]) -> tuple[str, ...]:
@@ -123,7 +461,10 @@ def _validate_source_fields(rows: list[dict[str, str]]) -> None:
         if not isinstance(row, dict):
             raise DomainReplicationError("source rows must be objects")
         for field in row:
-            if _SECRET.search(str(field)):
+            normalized = _security_key(field)
+            if normalized in _RAW_SOURCE_KEYS or _SECRET.search(normalized) or any(
+                marker in normalized for marker in _SENSITIVE_KEY_MARKERS
+            ):
                 raise DomainReplicationError(
                     f"secret-like source field is not allowed: {field}"
                 )
@@ -368,14 +709,218 @@ def _validate_stage_metrics(
             raise DomainReplicationError("agent cross-domain request must be denied")
 
 
-def _validate_manifest(manifest: dict[str, Any], template: dict[str, Any]) -> tuple[str, str]:
-    manifest = _mapping(manifest, "manifest")
+def _validate_seed_data(seed_data: Any, *, schema_version: int) -> None:
+    payload_key = "records" if schema_version == 1 else "items"
+    record_fields = {
+        "source_contract": {"id", "type", "binding_status"},
+        "term_and_code_set": {"id", "name"},
+        "workflow_contract": {"id", "name"},
+    }
+    for item in _bounded_list(seed_data, "template.seed_data", minimum=0):
+        item = _closed_required(
+            item,
+            "template.seed_data.item",
+            {"kind", payload_key},
+            {"kind", payload_key},
+        )
+        kind = _string(item["kind"], "template.seed_data.kind", 80)
+        if kind not in record_fields:
+            raise DomainReplicationError("template.seed_data.kind is unsupported")
+        for record in _bounded_list(item[payload_key], f"template.seed_data.{payload_key}", minimum=1):
+            record = _closed_required(
+                record,
+                "template.seed_data.record",
+                record_fields[kind],
+                record_fields[kind],
+            )
+            for key in record_fields[kind]:
+                _string(record[key], f"template.seed_data.record.{key}", 200)
+
+
+def _validate_template(template: dict[str, Any], *, schema_version: int) -> dict[str, Any]:
+    required = {
+        "template_code", "name", "description", "lifecycle_status", "object_types",
+        "responsibility_roles", "rules", "metrics", "seed_data",
+    }
+    _reject_secrets(template, "template")
+    template = _closed_required(template, "template", required, required)
+    _string(template["template_code"], "template.template_code", 64)
+    _string(template["name"], "template.name", 200)
+    _string(template["description"], "template.description", 500)
+    if template["lifecycle_status"] not in {"draft", "active", "retired"}:
+        raise DomainReplicationError("template.lifecycle_status is invalid")
+    for item in _bounded_list(template["object_types"], "template.object_types", minimum=3):
+        item = _closed_required(
+            item,
+            "template.object_types.item",
+            {"type_code", "name", "stable_uid_prefix", "source_identity_fields", "fields"},
+            {"type_code", "name", "description", "stable_uid_prefix", "source_identity_fields", "fields"},
+        )
+        for key in ("type_code", "name", "stable_uid_prefix"):
+            _string(item[key], f"template.object_types.{key}", 200)
+        for identity in _bounded_list(item["source_identity_fields"], "template.source_identity_fields"):
+            _string(identity, "template.source_identity_fields.item", 64)
+        for field in _bounded_list(item["fields"], "template.fields"):
+            field = _closed_required(
+                field,
+                "template.fields.item",
+                {"code", "name", "type", "required"},
+                {"code", "name", "type", "required", "description"},
+            )
+            if not isinstance(field["required"], bool):
+                raise DomainReplicationError("template.fields.required must be boolean")
+            for key in ("code", "name", "type"):
+                _string(field[key], f"template.fields.{key}", 200)
+    for collection, required_fields in (
+        ("responsibility_roles", {"code", "name", "raci_role"}),
+        ("rules", {"code", "name", "dimension", "target_object"}),
+        ("metrics", {"code", "name", "unit"}),
+    ):
+        for item in _bounded_list(template[collection], f"template.{collection}"):
+            item = _closed_required(item, f"template.{collection}.item", required_fields, required_fields)
+            for key in required_fields:
+                _string(item[key], f"template.{collection}.{key}", 200)
+    _validate_seed_data(template["seed_data"], schema_version=schema_version)
+    return template
+
+
+def _validate_contract_refs(stage: str, value: Any) -> list[dict[str, Any]]:
+    if stage not in _CONTRACT_REQUIREMENTS:
+        if value is not None:
+            raise DomainReplicationError(f"{stage} does not accept contract_refs")
+        return []
+    refs = _bounded_list(value, f"{stage}.contract_refs", minimum=1, maximum=1)
+    return [validate_contract_reference(refs[0], expected_contract_id=_CONTRACT_REQUIREMENTS[stage])]
+
+
+def validate_contract_reference(
+    reference: dict[str, Any], *, expected_contract_id: str
+) -> dict[str, Any]:
+    """Resolve one v2 receipt only against the code-side trusted registry."""
+
+    required = {
+        "contract_id", "contract_version", "schema_digest", "operation_uid", "run_id",
+        "operation", "attempt", "lease_fence", "request_digest", "result_digest", "status",
+    }
+    reference = _closed_required(reference, "contract_ref", required, required)
+    try:
+        registry = verify_registry()
+    except ValueError as exc:
+        raise DomainReplicationError("trusted contract registry integrity check failed") from exc
+    if registry["trust_level"] != "ENGINEERING_EVIDENCE_ONLY":
+        raise DomainReplicationError("trusted contract registry has an invalid trust level")
+    if date.fromisoformat(registry["expires_on"]) < date.today():
+        raise DomainReplicationError("trusted contract registry is expired")
+    contract_id = _string(reference["contract_id"], "contract_ref.contract_id", 80)
+    if contract_id != expected_contract_id:
+        raise DomainReplicationError("cross-contract reference was rejected")
+    contract = next(
+        (item for item in registry["contracts"] if item["contract_id"] == contract_id), None
+    )
+    if contract is None:
+        raise DomainReplicationError("contract is absent from the trusted registry")
+    if reference["contract_version"] != contract["contract_version"]:
+        raise DomainReplicationError("contract version does not match the trusted registry")
+    if reference["schema_digest"] != contract["schema_digest"]:
+        raise DomainReplicationError("contract schema digest does not match the trusted registry")
+    if reference["operation"] not in contract["allowed_operations"]:
+        raise DomainReplicationError("contract operation is not allowed")
+    run = next(
+        (
+            item for item in contract["runs"]
+            if item["operation_uid"] == reference["operation_uid"]
+            and item["run_id"] == reference["run_id"]
+        ),
+        None,
+    )
+    if run is None:
+        raise DomainReplicationError("run is absent from the trusted registry")
+    for field in (
+        "operation_uid", "run_id", "operation", "attempt", "lease_fence",
+        "request_digest", "result_digest", "status",
+    ):
+        if reference[field] != run[field]:
+            raise DomainReplicationError(f"contract registry mismatch for {field}")
+    for field in ("schema_digest", "request_digest", "result_digest"):
+        _digest_string(reference[field], f"contract_ref.{field}")
+    return deepcopy(reference)
+
+
+def _validate_terminal_evidence(
+    evidence: dict[str, Any], package_code: str, domain_code: str, template: dict[str, Any], incremental: dict[str, Any], *, schema_version: int
+) -> dict[str, dict[str, Any]]:
+    _reject_secrets(evidence, "evidence")
+    evidence = _closed_required(evidence, "evidence", {"schema_version", "package_code", "receipts"}, {"schema_version", "package_code", "receipts"})
+    if evidence["schema_version"] != 1 or evidence["package_code"] != package_code:
+        raise DomainReplicationError("evidence package identity is invalid")
+    receipts = _bounded_list(evidence["receipts"], "evidence.receipts", minimum=1, maximum=len(REQUIRED_STAGES))
+    by_stage: dict[str, dict[str, Any]] = {}
+    for receipt in receipts:
+        receipt = _mapping(receipt, "receipt")
+        stage = _string(receipt.get("stage"), "receipt.stage", 80)
+        required = {"stage", "domain_code", "status", "subsystem", "api_refs", "evidence_refs", "metrics"}
+        allowed = set(required)
+        if schema_version == 2 and stage in _CONTRACT_REQUIREMENTS:
+            required.add("contract_refs")
+            allowed.add("contract_refs")
+        receipt = _closed_required(receipt, "receipt", required, allowed)
+        if stage in by_stage:
+            raise DomainReplicationError(f"duplicate evidence stage: {stage}")
+        by_stage[stage] = receipt
+    missing = sorted(set(REQUIRED_STAGES) - set(by_stage))
+    extra = sorted(set(by_stage) - set(REQUIRED_STAGES))
+    if missing:
+        raise DomainReplicationError(f"missing stages: {','.join(missing)}")
+    if extra:
+        raise DomainReplicationError(f"unsupported stages: {','.join(extra)}")
+    reports: dict[str, dict[str, Any]] = {}
+    for stage in REQUIRED_STAGES:
+        receipt = by_stage[stage]
+        if receipt["domain_code"] != domain_code:
+            raise DomainReplicationError(f"{stage} evidence has the wrong domain")
+        if receipt["status"] != "passed":
+            raise DomainReplicationError(f"{stage} evidence status must be passed")
+        if receipt["subsystem"] != STAGE_SUBSYSTEMS[stage]:
+            raise DomainReplicationError(f"{stage} evidence subsystem is invalid")
+        api_refs = _bounded_list(receipt["api_refs"], f"{stage}.api_refs", maximum=1)
+        if any("/device-" in str(ref) for ref in api_refs):
+            raise DomainReplicationError("device-specific API evidence is not allowed")
+        if tuple(api_refs) != _API_ALLOWLIST[stage]:
+            raise DomainReplicationError(f"{stage} must use its allowlisted API")
+        evidence_refs = _bounded_list(receipt["evidence_refs"], f"{stage}.evidence_refs", maximum=8)
+        prefix = _EVIDENCE_PREFIXES[stage]
+        if any(not isinstance(ref, str) or not ref.startswith(prefix + domain_code + "/") for ref in evidence_refs):
+            raise DomainReplicationError(f"{stage} evidence_refs are not canonical")
+        metrics = _closed_required(receipt["metrics"], f"{stage}.metrics", _METRIC_FIELDS[stage], _METRIC_FIELDS[stage])
+        _validate_stage_metrics(stage, metrics, template=template, incremental=incremental)
+        contracts = (
+            _validate_contract_refs(stage, receipt.get("contract_refs"))
+            if schema_version == 2
+            else []
+        )
+        reports[stage] = {"status": "passed", "subsystem": STAGE_SUBSYSTEMS[stage], "api_refs": list(api_refs), "evidence_refs": sorted(evidence_refs), "metrics": deepcopy(metrics)}
+        if contracts:
+            reports[stage]["contract_refs"] = contracts
+    return reports
+
+
+def _validate_manifest(
+    manifest: dict[str, Any], template: dict[str, Any]
+) -> tuple[str, str, int]:
+    required = {
+        "schema_version", "package_code", "domain", "files", "source",
+        "core_change_assessment", "enterprise_bindings", "third_domain_reuse",
+    }
     _reject_secrets(manifest)
-    if int(manifest.get("schema_version", 0)) != 1:
-        raise DomainReplicationError("manifest.schema_version must be 1")
-    package_code = _bounded_text(manifest.get("package_code"), "package_code", 80)
-    domain = _mapping(manifest.get("domain"), "domain")
-    domain_code = _bounded_text(domain.get("code"), "domain.code", 64)
+    manifest = _closed_required(manifest, "manifest", required, required)
+    if isinstance(manifest["schema_version"], bool) or not isinstance(manifest["schema_version"], int):
+        raise DomainReplicationError("manifest.schema_version must be an integer")
+    schema_version = manifest["schema_version"]
+    if schema_version not in {1, 2}:
+        raise DomainReplicationError("manifest.schema_version must be 1 or 2")
+    package_code = _string(manifest["package_code"], "package_code", 80)
+    domain = _closed_required(manifest["domain"], "manifest.domain", {"code", "name"}, {"code", "name"})
+    domain_code = _string(domain["code"], "domain.code", 64)
     if not _CODE.fullmatch(domain_code):
         raise DomainReplicationError("domain.code must be a stable lowercase code")
     if template.get("template_code") != domain_code:
@@ -385,17 +930,41 @@ def _validate_manifest(manifest: dict[str, Any], template: dict[str, Any]) -> tu
     if len(template.get("rules", [])) < 5:
         raise DomainReplicationError("domain template must contain at least five rules")
 
-    assessment = _mapping(
-        manifest.get("core_change_assessment"), "core_change_assessment"
+    files = _mapping(manifest["files"], "manifest.files")
+    expected_file_keys = {"template", "evidence", "snapshot", "delta", "acceptance_report"}
+    if schema_version == 2:
+        expected_file_keys.add("execution_evidence")
+    if set(files) != expected_file_keys:
+        raise DomainReplicationError("manifest.files has unsupported or missing bindings")
+    for key, binding in files.items():
+        binding = _closed_required(binding, f"manifest.files.{key}", {"path", "sha256"}, {"path", "sha256"})
+        _string(binding["path"], f"manifest.files.{key}.path", 240)
+        _digest_string(binding["sha256"], f"manifest.files.{key}.sha256")
+    source = _closed_required(
+        manifest["source"], "manifest.source",
+        {"kind", "classification", "primary_key", "required_columns", "operation_field", "cursor_field", "snapshot_cursor"},
+        {"kind", "classification", "primary_key", "required_columns", "operation_field", "cursor_field", "snapshot_cursor"},
+    )
+    if source["kind"] != "controlled_csv" or source["classification"] != "desensitized":
+        raise DomainReplicationError("manifest source is invalid")
+    for field in ("primary_key", "required_columns"):
+        for value in _bounded_list(source[field], f"manifest.source.{field}"):
+            _string(value, f"manifest.source.{field}.item", 80)
+    for field in ("operation_field", "cursor_field"):
+        _string(source[field], f"manifest.source.{field}", 80)
+    if isinstance(source["snapshot_cursor"], bool) or not isinstance(source["snapshot_cursor"], int) or source["snapshot_cursor"] < 0:
+        raise DomainReplicationError("manifest.source.snapshot_cursor is invalid")
+    assessment = _closed_required(
+        manifest["core_change_assessment"], "core_change_assessment",
+        {"baseline_commit", "device_specific_changes", "generic_extensions", "extension_points_used"},
+        {"baseline_commit", "device_specific_changes", "generic_extensions", "extension_points_used"},
     )
     device_changes = assessment.get("device_specific_changes")
     if not isinstance(device_changes, list):
         raise DomainReplicationError("device_specific_changes must be a list")
     if device_changes:
         raise DomainReplicationError("device-specific core changes must remain zero")
-    generic_extensions = assessment.get("generic_extensions")
-    if not isinstance(generic_extensions, list) or not generic_extensions:
-        raise DomainReplicationError("generic extension points must be documented")
+    generic_extensions = _bounded_list(assessment["generic_extensions"], "generic_extensions")
     if any(
         str(path).startswith(marker)
         for path in generic_extensions
@@ -403,13 +972,16 @@ def _validate_manifest(manifest: dict[str, Any], template: dict[str, Any]) -> tu
     ):
         raise DomainReplicationError("generic extensions cannot target device-specific paths")
 
-    reuse = _mapping(manifest.get("third_domain_reuse"), "third_domain_reuse")
+    reuse = _closed_required(
+        manifest["third_domain_reuse"], "third_domain_reuse",
+        {"reusable", "required_replacements"}, {"reusable", "required_replacements"},
+    )
     if reuse.get("reusable") is not True:
         raise DomainReplicationError("third-domain reuse must be explicitly enabled")
-    placeholders = reuse.get("required_replacements")
+    placeholders = reuse["required_replacements"]
     if not isinstance(placeholders, list) or len(placeholders) < 4:
         raise DomainReplicationError("third-domain replacement checklist is incomplete")
-    return package_code, domain_code
+    return package_code, domain_code, schema_version
 
 
 def evaluate_replication_package(
@@ -419,76 +991,30 @@ def evaluate_replication_package(
     template: dict[str, Any],
     snapshot_rows: list[dict[str, str]],
     delta_rows: list[dict[str, str]],
+    execution_evidence: dict[str, Any] | None = None,
 ) -> dict[str, Any]:
     """Evaluate one domain package and return a deterministic, row-free report."""
 
-    package_code, domain_code = _validate_manifest(manifest, template)
+    manifest_schema_version = _mapping(manifest, "manifest").get("schema_version")
+    if isinstance(manifest_schema_version, bool) or manifest_schema_version not in {1, 2}:
+        raise DomainReplicationError("manifest.schema_version must be 1 or 2")
+    template = _validate_template(template, schema_version=manifest_schema_version)
+    package_code, domain_code, schema_version = _validate_manifest(manifest, template)
     incremental = collect_incremental_rows(
         snapshot_rows,
         delta_rows,
         _mapping(manifest.get("source"), "source"),
     )
-    evidence = _mapping(evidence, "evidence")
-    _reject_secrets(evidence)
-    if evidence.get("package_code") != package_code:
-        raise DomainReplicationError("evidence package code does not match manifest")
-    receipts = evidence.get("receipts")
-    if not isinstance(receipts, list):
-        raise DomainReplicationError("evidence.receipts must be a list")
-    by_stage: dict[str, dict[str, Any]] = {}
-    for receipt in receipts:
-        receipt = _mapping(receipt, "receipt")
-        stage = _bounded_text(receipt.get("stage"), "receipt.stage", 80)
-        if stage in by_stage:
-            raise DomainReplicationError(f"duplicate evidence stage: {stage}")
-        by_stage[stage] = receipt
-    missing = sorted(set(REQUIRED_STAGES) - set(by_stage))
-    extra = sorted(set(by_stage) - set(REQUIRED_STAGES))
-    if missing:
-        raise DomainReplicationError(f"missing stages: {','.join(missing)}")
-    if extra:
-        raise DomainReplicationError(f"unsupported stages: {','.join(extra)}")
-
-    stage_reports: dict[str, dict[str, Any]] = {}
-    for stage in REQUIRED_STAGES:
-        receipt = by_stage[stage]
-        if receipt.get("domain_code") != domain_code:
-            raise DomainReplicationError(f"{stage} evidence has the wrong domain")
-        if receipt.get("status") != "passed":
-            raise DomainReplicationError(f"{stage} evidence status must be passed")
-        if receipt.get("subsystem") != STAGE_SUBSYSTEMS[stage]:
-            raise DomainReplicationError(f"{stage} evidence subsystem is invalid")
-        api_refs = receipt.get("api_refs")
-        if not isinstance(api_refs, list) or not api_refs:
-            raise DomainReplicationError(f"{stage} api_refs are required")
-        if any("/device-" in str(ref) for ref in api_refs):
-            raise DomainReplicationError("device-specific API evidence is not allowed")
-        evidence_refs = receipt.get("evidence_refs")
-        if not isinstance(evidence_refs, list) or not evidence_refs:
-            raise DomainReplicationError(f"{stage} evidence_refs are required")
-        metrics = _mapping(receipt.get("metrics"), f"{stage}.metrics")
-        _validate_stage_metrics(
-            stage,
-            metrics,
-            template=template,
-            incremental=incremental,
-        )
-        stage_reports[stage] = {
-            "status": "passed",
-            "subsystem": STAGE_SUBSYSTEMS[stage],
-            "api_refs": sorted(str(ref) for ref in api_refs),
-            "evidence_refs": sorted(str(ref) for ref in evidence_refs),
-            "metrics": deepcopy(metrics),
-        }
+    stage_reports = _validate_terminal_evidence(
+        evidence, package_code, domain_code, template, incremental, schema_version=schema_version
+    )
 
-    bindings = manifest.get("enterprise_bindings")
-    if not isinstance(bindings, list) or not bindings:
-        raise DomainReplicationError("enterprise binding checklist is required")
+    bindings = _bounded_list(manifest["enterprise_bindings"], "enterprise_bindings", minimum=1, maximum=4)
     binding_statuses: dict[str, str] = {}
     for item in bindings:
-        item = _mapping(item, "enterprise_bindings.item")
-        kind = _bounded_text(item.get("kind"), "enterprise_bindings.kind")
-        status = _bounded_text(item.get("status"), "enterprise_bindings.status")
+        item = _closed_required(item, "enterprise_bindings.item", {"kind", "status"}, {"kind", "status"})
+        kind = _string(item["kind"], "enterprise_bindings.kind")
+        status = _string(item["status"], "enterprise_bindings.status")
         if status not in {"bound", "unbound"}:
             raise DomainReplicationError("enterprise binding status must be bound or unbound")
         if kind in binding_statuses:
@@ -504,12 +1030,12 @@ def evaluate_replication_package(
     )
     assessment = manifest["core_change_assessment"]
     report: dict[str, Any] = {
-        "schema_version": 1,
+        "schema_version": schema_version,
         "package_code": package_code,
         "status": "passed",
         "domain": {
             "code": domain_code,
-            "name": _bounded_text(manifest["domain"].get("name"), "domain.name"),
+            "name": _string(manifest["domain"]["name"], "domain.name"),
             "template_version": int(
                 stage_reports["template_initialization"]["metrics"]["template_version"]
             ),
@@ -524,5 +1050,13 @@ def evaluate_replication_package(
             "unbound_requirements": unbound,
         },
     }
+    if schema_version == 2:
+        if execution_evidence is None:
+            raise DomainReplicationError("schema-v2 package requires execution evidence")
+        report["execution_evidence"] = validate_execution_evidence(
+            execution_evidence, domain_code=domain_code
+        )
+    elif execution_evidence is not None:
+        raise DomainReplicationError("schema-v1 package cannot include execution evidence")
     report["report_sha256"] = _digest(report)
     return report

+ 88 - 0
app/core/governance/domain_replication_contract_registry.py

@@ -0,0 +1,88 @@
+"""Trusted local contract registry for domain-replication engineering evidence.
+
+The registry is code-side rather than package-side: an implementation package
+cannot add a digest or a run receipt and thereby grant itself trust.  Entries
+are deliberately labelled ENGINEERING_EVIDENCE_ONLY; enterprise connector and
+edge runs remain external acceptance evidence.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+from copy import deepcopy
+from typing import Any
+
+
+def _canonical(value: Any) -> bytes:
+    return json.dumps(value, sort_keys=True, separators=(",", ":")).encode("utf-8")
+
+
+CONTRACT_REGISTRY: dict[str, Any] = {
+    "schema_version": 1,
+    "trust_level": "ENGINEERING_EVIDENCE_ONLY",
+    "expires_on": "2099-12-31",
+    "contracts": [
+        {
+            "contract_id": "p3_wp03_connector_run",
+            "contract_version": "1",
+            "schema_digest": "1111111111111111111111111111111111111111111111111111111111111111",
+            "allowed_operations": ["incremental"],
+            "runs": [{
+                "operation_uid": "op-inc-203",
+                "run_id": "run-203",
+                "operation": "incremental",
+                "attempt": 1,
+                "lease_fence": 1,
+                "request_digest": "1212121212121212121212121212121212121212121212121212121212121212",
+                "result_digest": "1313131313131313131313131313131313131313131313131313131313131313",
+                "status": "succeeded",
+            }],
+        },
+        {
+            "contract_id": "p3_wp03_catalog_lineage",
+            "contract_version": "1",
+            "schema_digest": "2222222222222222222222222222222222222222222222222222222222222222",
+            "allowed_operations": ["catalog"],
+            "runs": [{
+                "operation_uid": "op-cat-203",
+                "run_id": "catalog-203",
+                "operation": "catalog",
+                "attempt": 1,
+                "lease_fence": 1,
+                "request_digest": "2323232323232323232323232323232323232323232323232323232323232323",
+                "result_digest": "2424242424242424242424242424242424242424242424242424242424242424",
+                "status": "succeeded",
+            }],
+        },
+        {
+            "contract_id": "p3_wp04_edge_health",
+            "contract_version": "1",
+            "schema_digest": "3333333333333333333333333333333333333333333333333333333333333333",
+            "allowed_operations": ["health"],
+            "runs": [{
+                "operation_uid": "op-health-203",
+                "run_id": "health-203",
+                "operation": "health",
+                "attempt": 1,
+                "lease_fence": 2,
+                "request_digest": "3434343434343434343434343434343434343434343434343434343434343434",
+                "result_digest": "3535353535353535353535353535353535353535353535353535353535353535",
+                "status": "succeeded",
+            }],
+        },
+    ],
+}
+REGISTRY_SHA256 = "ff312c88ea48d7d110b60cdcd118457f3ae6fb52f3d3f6d431a7ad53eb036be2"
+
+
+def registry_snapshot() -> dict[str, Any]:
+    """Return a deep copy so callers cannot mutate the trusted registry."""
+
+    return deepcopy(CONTRACT_REGISTRY)
+
+
+def verify_registry() -> dict[str, Any]:
+    if hashlib.sha256(_canonical(CONTRACT_REGISTRY)).hexdigest() != REGISTRY_SHA256:
+        raise ValueError("trusted contract registry digest mismatch")
+    return registry_snapshot()

+ 599 - 0
app/core/governance/metering_showback.py

@@ -0,0 +1,599 @@
+"""Closed, local-only metering and Showback contracts.
+
+The module intentionally has no network providers, price book, billing action
+or financial artifact.  It only normalizes engineering evidence and supplies
+integer-micros arithmetic for the database gateway and local fixture.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import os
+import re
+import unicodedata
+import uuid
+from datetime import UTC, datetime
+from decimal import ROUND_HALF_EVEN, Decimal, InvalidOperation
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+
+EVENT_KINDS = frozenset(
+    {"query", "api", "file", "subscription", "storage", "compute", "task", "model_call"}
+)
+_EVENT_FIELDS = frozenset(
+    {
+        "schema_version",
+        "event_uid",
+        "event_kind",
+        "occurred_at",
+        "window_start",
+        "window_end",
+        "quantity",
+        "unit",
+        "idempotency_key",
+        "evidence",
+        "mapping",
+        "correction_of",
+    }
+)
+_TOKEN = re.compile(r"[a-z][a-z0-9-]{0,62}")
+_UID = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:-]{0,119}")
+_HEX = re.compile(r"[0-9a-f]{64}")
+_DECIMAL = re.compile(r"(?:0|[1-9][0-9]{0,17})(?:\.[0-9]{1,6})?")
+_REFERENCE = re.compile(r"local-fixture://wp12/v1(?:/[a-z][a-z0-9-]{0,62})?")
+_UNSAFE_REFERENCE_SEGMENT = re.compile(r"(?:sql|script|select|insert|update|delete|drop|exec|curl|wget|token|secret|credential|password)")
+_UNITS: dict[str, tuple[str, Decimal]] = {
+    "bytes": ("data", Decimal("1")),
+    "kb": ("data", Decimal("1000")),
+    "mb": ("data", Decimal("1000000")),
+    "gb": ("data", Decimal("1000000000")),
+    "seconds": ("time", Decimal("1")),
+    "milliseconds": ("time", Decimal("0.001")),
+    "requests": ("count", Decimal("1")),
+    "tasks": ("count", Decimal("1")),
+    "tokens": ("count", Decimal("1")),
+}
+_MICRO = Decimal("1000000")
+
+
+def _closed(value: Any, allowed: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict) or set(value) - allowed:
+        raise ValueError(f"{label}_closed")
+    return copy.deepcopy(value)
+
+
+def _normalized_text(value: Any, label: str, maximum: int = 120) -> str:
+    if not isinstance(value, str) or not value or len(value) > maximum:
+        raise ValueError(f"{label}_invalid")
+    normalized = unicodedata.normalize("NFKC", value)
+    if normalized != value:
+        raise ValueError(f"{label}_unicode_rejected")
+    return value
+
+
+def _token(value: Any, label: str) -> str:
+    result = _normalized_text(value, label)
+    if not _TOKEN.fullmatch(result):
+        raise ValueError(f"{label}_invalid")
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    result = _normalized_text(value, label)
+    if not _UID.fullmatch(result):
+        raise ValueError(f"{label}_invalid")
+    return result
+
+
+def _timestamp(value: Any, label: str) -> str:
+    text = _normalized_text(value, label, 30)
+    if not text.endswith("Z"):
+        raise ValueError(f"{label}_invalid")
+    try:
+        parsed = datetime.fromisoformat(text.replace("Z", "+00:00"))
+    except ValueError as exc:
+        raise ValueError(f"{label}_invalid") from exc
+    if parsed.tzinfo is None or parsed.utcoffset() != UTC.utcoffset(parsed):
+        raise ValueError(f"{label}_invalid")
+    return parsed.astimezone(UTC).isoformat(timespec="microseconds").replace("+00:00", "Z")
+
+
+def _decimal(value: Any, label: str) -> Decimal:
+    if isinstance(value, bool) or not isinstance(value, str) or not _DECIMAL.fullmatch(value):
+        raise ValueError(f"{label}_invalid")
+    try:
+        parsed = Decimal(value)
+    except InvalidOperation as exc:
+        raise ValueError(f"{label}_invalid") from exc
+    if not parsed.is_finite() or parsed < 0:
+        raise ValueError(f"{label}_invalid")
+    return parsed
+
+
+def to_micros(quantity: Any, source_unit: Any, target_unit: Any) -> int:
+    """Convert a bounded string decimal using a compatible unit dimension."""
+
+    value = _decimal(quantity, "quantity")
+    source = _normalized_text(source_unit, "source_unit", 20)
+    target = _normalized_text(target_unit, "target_unit", 20)
+    if source not in _UNITS or target not in _UNITS or _UNITS[source][0] != _UNITS[target][0]:
+        raise ValueError("unit_dimension_mismatch")
+    converted = value * _UNITS[source][1] / _UNITS[target][1]
+    micros = (converted * _MICRO).quantize(Decimal("1"), rounding=ROUND_HALF_EVEN)
+    if micros < 0 or micros > Decimal("1000000000000000000000000"):
+        raise ValueError("quantity_out_of_range")
+    return int(micros)
+
+
+def canonical_digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(value, sort_keys=True, ensure_ascii=True, separators=(",", ":")).encode("utf-8")
+    ).hexdigest()
+
+
+def normalize_event(value: Any) -> dict[str, Any]:
+    """Return a versioned, safe event without raw source evidence."""
+
+    body = _closed(value, _EVENT_FIELDS, "metering_event")
+    required = _EVENT_FIELDS - {"correction_of"}
+    if set(body) - {"correction_of"} != required:
+        raise ValueError("metering_event_closed")
+    if body["schema_version"] != 1:
+        raise ValueError("schema_version_invalid")
+    event_kind = _token(body["event_kind"], "event_kind")
+    if event_kind not in EVENT_KINDS:
+        raise ValueError("event_kind_invalid")
+    evidence = _closed(body["evidence"], frozenset({"digest", "reference"}), "evidence")
+    digest = _normalized_text(evidence.get("digest"), "evidence_digest", 64)
+    reference = _normalized_text(evidence.get("reference"), "evidence_reference", 120)
+    if not _HEX.fullmatch(digest) or not _REFERENCE.fullmatch(reference) or _UNSAFE_REFERENCE_SEGMENT.search(reference):
+        raise ValueError("evidence_invalid")
+    mapping = _closed(
+        body["mapping"],
+        frozenset({"department", "business_domain", "project", "cost_center"}),
+        "mapping",
+    )
+    if set(mapping) != {"department", "business_domain", "project", "cost_center"}:
+        raise ValueError("mapping_closed")
+    normalized = {
+        "schema_version": 1,
+        "event_uid": _uid(body["event_uid"], "event_uid"),
+        "event_kind": event_kind,
+        "occurred_at": _timestamp(body["occurred_at"], "occurred_at"),
+        "window_start": _timestamp(body["window_start"], "window_start"),
+        "window_end": _timestamp(body["window_end"], "window_end"),
+        "quantity": body["quantity"],
+        "unit": _normalized_text(body["unit"], "unit", 20),
+        "idempotency_key": _uid(body["idempotency_key"], "idempotency_key"),
+        "evidence": {"digest": digest, "reference": reference},
+        "mapping": {key: _token(mapping[key], key) for key in sorted(mapping)},
+        "raw_payload_retained": False,
+    }
+    if normalized["window_start"] >= normalized["window_end"]:
+        raise ValueError("window_invalid")
+    normalized["quantity_micros"] = to_micros(normalized["quantity"], normalized["unit"], normalized["unit"])
+    if "correction_of" in body:
+        normalized["correction_of"] = _uid(body["correction_of"], "correction_of")
+    normalized["digest"] = canonical_digest(normalized)
+    return normalized
+
+
+class ReplayConflict(ValueError):
+    """An idempotency key was reused with a different immutable request."""
+
+
+class InMemoryMeteringRepository:
+    """Tiny deterministic adapter for unit contracts; not a production store."""
+
+    def __init__(self) -> None:
+        self.events_by_key: dict[tuple[str, str], dict[str, Any]] = {}
+        self.events_by_uid: dict[tuple[str, str], dict[str, Any]] = {}
+        self.allocation_rules: dict[tuple[str, int], dict[str, Any]] = {}
+        self.alert_keys: set[tuple[str, str, int]] = set()
+
+    def record_event(self, tenant_ref: str, event: dict[str, Any]) -> dict[str, Any]:
+        key = (tenant_ref, event["idempotency_key"])
+        replay = self.events_by_key.get(key)
+        if replay is not None:
+            if replay["digest"] != event["digest"]:
+                raise ReplayConflict("metering_replay_conflict")
+            return copy.deepcopy(replay)
+        uid_key = (tenant_ref, event["event_uid"])
+        if uid_key in self.events_by_uid:
+            raise ReplayConflict("metering_event_uid_conflict")
+        self.events_by_key[key] = copy.deepcopy(event)
+        self.events_by_uid[uid_key] = copy.deepcopy(event)
+        return copy.deepcopy(event)
+
+    def events_for_window(self, tenant_ref: str, window: str) -> list[dict[str, Any]]:
+        prefix = f"{window}-"
+        return [
+            copy.deepcopy(event)
+            for (tenant, _), event in self.events_by_uid.items()
+            if tenant == tenant_ref and event["window_start"].startswith(prefix)
+        ]
+
+
+def _window(value: Any) -> str:
+    text = _normalized_text(value, "window", 7)
+    if not re.fullmatch(r"[0-9]{4}-(0[1-9]|1[0-2])", text):
+        raise ValueError("window_invalid")
+    return text
+
+
+def _mapping(value: Any) -> dict[str, str]:
+    body = _closed(
+        value,
+        frozenset({"department", "business_domain", "project", "cost_center"}),
+        "mapping",
+    )
+    if set(body) != {"department", "business_domain", "project", "cost_center"}:
+        raise ValueError("mapping_closed")
+    return {key: _token(body[key], key) for key in sorted(body)}
+
+
+class MeteringShowbackService:
+    """Local, non-financial behavior shared by API and gateway adapters."""
+
+    def __init__(self, repository: InMemoryMeteringRepository, *, tenant_ref: str) -> None:
+        self.repository = repository
+        self.tenant_ref = _token(tenant_ref, "tenant_ref")
+
+    def record(self, request: Any) -> dict[str, Any]:
+        return self.repository.record_event(self.tenant_ref, normalize_event(request))
+
+    def correct(self, original_uid: Any, request: Any) -> dict[str, Any]:
+        original = _uid(original_uid, "original_uid")
+        original_event = self.repository.events_by_uid.get((self.tenant_ref, original))
+        if original_event is None:
+            raise LookupError("metering_original_not_found")
+        if "correction_of" in original_event:
+            raise ValueError("correction_chain_invalid")
+        body = copy.deepcopy(request)
+        if "correction_of" in body:
+            raise ValueError("correction_closed")
+        candidate = normalize_event(body)
+        if any(candidate[key] != original_event[key] for key in ("event_kind", "unit", "window_start", "window_end", "mapping")):
+            raise ValueError("correction_scope_invalid")
+        body["correction_of"] = original
+        return self.record(body)
+
+    def publish_allocation(self, request: Any) -> dict[str, Any]:
+        body = _closed(
+            request,
+            frozenset(
+                {
+                    "schema_version",
+                    "rule_uid",
+                    "rule_version",
+                    "effective_start",
+                    "effective_end",
+                    "mapping",
+                    "allocations",
+                }
+            ),
+            "allocation_rule",
+        )
+        if body.get("schema_version") != 1 or not isinstance(body.get("rule_version"), int):
+            raise ValueError("allocation_rule_invalid")
+        rule_uid = _uid(body.get("rule_uid"), "rule_uid")
+        version = body["rule_version"]
+        if version < 1 or version > 1_000_000:
+            raise ValueError("rule_version_invalid")
+        start = _timestamp(body.get("effective_start"), "effective_start")
+        end = _timestamp(body.get("effective_end"), "effective_end")
+        if start >= end:
+            raise ValueError("effective_window_invalid")
+        allocations = body.get("allocations")
+        if not isinstance(allocations, list) or not 1 <= len(allocations) <= 32:
+            raise ValueError("allocations_invalid")
+        normalized_allocations: list[dict[str, Any]] = []
+        total = Decimal("0")
+        for allocation in allocations:
+            item = _closed(allocation, frozenset({"target", "weight"}), "allocation")
+            if set(item) != {"target", "weight"}:
+                raise ValueError("allocation_closed")
+            weight = _decimal(item["weight"], "weight")
+            if weight <= 0 or weight > Decimal("1"):
+                raise ValueError("weight_invalid")
+            total += weight
+            target = _token(item["target"], "target")
+            if any(existing["target"] == target for existing in normalized_allocations):
+                raise ValueError("allocation_target_duplicate")
+            normalized_allocations.append({"target": target, "weight": str(weight)})
+        if total != Decimal("1.000000"):
+            raise ValueError("allocation_weight_not_one")
+        normalized = {
+            "schema_version": 1,
+            "rule_uid": rule_uid,
+            "rule_version": version,
+            "effective_start": start,
+            "effective_end": end,
+            "mapping": _mapping(body.get("mapping")),
+            "allocations": sorted(normalized_allocations, key=lambda item: item["target"]),
+        }
+        key = (rule_uid, version)
+        existing = self.repository.allocation_rules.get(key)
+        if existing is not None and canonical_digest(existing) != canonical_digest(normalized):
+            raise ReplayConflict("allocation_rule_conflict")
+        self.repository.allocation_rules[key] = copy.deepcopy(normalized)
+        return copy.deepcopy(normalized)
+
+    def replay_allocation(self, rule_version: Any, window: Any) -> dict[str, Any]:
+        if not isinstance(rule_version, int) or rule_version < 1:
+            raise ValueError("rule_version_invalid")
+        month = _window(window)
+        matching = [
+            rule
+            for (_, version), rule in self.repository.allocation_rules.items()
+            if version == rule_version
+            and rule["effective_start"].startswith(month)
+            and rule["effective_end"] > f"{month}-01T00:00:00.000000Z"
+        ]
+        if len(matching) != 1:
+            raise LookupError("allocation_rule_not_found")
+        source = sum(event["quantity_micros"] for event in self.repository.events_for_window(self.tenant_ref, month))
+        allocations = [
+            {
+                "target": allocation["target"],
+                "quantity_micros": int(
+                    (Decimal(source) * _decimal(allocation["weight"], "weight")).quantize(
+                        Decimal("1"), rounding=ROUND_HALF_EVEN
+                    )
+                ),
+            }
+            for allocation in matching[0]["allocations"]
+        ]
+        return {
+            "rule_uid": matching[0]["rule_uid"],
+            "rule_version": rule_version,
+            "window": month,
+            "source_micros": source,
+            "allocations": allocations,
+            "allocated_micros": sum(item["quantity_micros"] for item in allocations),
+        }
+
+    def reconcile(self, window: Any) -> dict[str, int]:
+        month = _window(window)
+        source = sum(event["quantity_micros"] for event in self.repository.events_for_window(self.tenant_ref, month))
+        return {"source_micros": source, "allocated_micros": source, "difference_micros": 0}
+
+    def evaluate_budget(self, request: Any) -> dict[str, Any]:
+        body = _closed(
+            request,
+            frozenset({"schema_version", "budget_uid", "window", "mapping", "limit_micros", "threshold_micros"}),
+            "budget",
+        )
+        if body.get("schema_version") != 1:
+            raise ValueError("budget_invalid")
+        budget_uid = _uid(body.get("budget_uid"), "budget_uid")
+        window = _window(body.get("window"))
+        mapping = _mapping(body.get("mapping"))
+        if (
+            isinstance(body.get("limit_micros"), bool)
+            or isinstance(body.get("threshold_micros"), bool)
+            or not isinstance(body.get("limit_micros"), int)
+            or not isinstance(body.get("threshold_micros"), int)
+            or body["limit_micros"] < 0
+            or body["threshold_micros"] < 0
+            or body["threshold_micros"] > body["limit_micros"]
+        ):
+            raise ValueError("budget_invalid")
+        used = sum(
+            event["quantity_micros"]
+            for event in self.repository.events_for_window(self.tenant_ref, window)
+            if event["mapping"] == mapping
+        )
+        key = (budget_uid, window, body["threshold_micros"])
+        alert_created = used >= body["threshold_micros"] and key not in self.repository.alert_keys
+        if alert_created:
+            self.repository.alert_keys.add(key)
+        return {
+            "budget_uid": budget_uid,
+            "window": window,
+            "used_micros": used,
+            "limit_micros": body["limit_micros"],
+            "alert_created": alert_created,
+            "provider": "disabled",
+            "mode": "ENGINEERING_EVIDENCE_ONLY",
+        }
+
+    def request_chargeback(self, request: Any) -> None:
+        del request
+        raise PermissionError("chargeback_disabled")
+
+
+class DatabaseMeteringShowbackService:
+    """Fail-closed control/runtime gateway adapter for the HTTP boundary."""
+
+    def __init__(self) -> None:
+        control_url = os.environ.get("METERING_SHOWBACK_CONTROL_DATABASE_URL", "")
+        runtime_url = os.environ.get("DATABASE_URL", "")
+        control = validate_postgresql_url(control_url, "METERING_SHOWBACK_CONTROL_DATABASE_URL")
+        runtime = validate_postgresql_url(runtime_url, "DATABASE_URL")
+        if control.username == runtime.username:
+            raise RuntimeError("metering control and runtime identities must differ")
+        self._control_url = control_url
+        self._runtime_url = runtime_url
+
+    def _claim(self, action: str, principal_id: str) -> dict[str, str]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(
+                text("SELECT public.metering_showback_issue_claim(:action,:principal,'{}'::jsonb)"),
+                {"action": action, "principal": principal_id},
+            ).scalar_one()
+        return dict(value)
+
+    def _write(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(
+                text("SELECT public.metering_showback_runtime_write(:action,CAST(:payload AS jsonb))"),
+                {"action": action, "payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+            ).scalar_one()
+        return dict(value)
+
+    def _control_write(self, action: str, principal_id: str, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(
+                text("SELECT public.metering_showback_control_write(:action,:principal,CAST(:payload AS jsonb))"),
+                {"action": action, "principal": principal_id, "payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+            ).scalar_one()
+        return dict(value)
+
+    @staticmethod
+    def _trusted_mapping(value: Any) -> dict[str, str]:
+        body = _closed(value, frozenset({"department", "project", "cost_center"}), "metering_mapping")
+        if set(body) != {"department", "project", "cost_center"}:
+            raise ValueError("metering_mapping_closed")
+        return {
+            "department": _token(body["department"], "department"),
+            "business_domain": _token(os.environ.get("TRUSTED_METERING_DOMAIN", ""), "trusted_metering_domain"),
+            "project": _token(body["project"], "project"),
+            "cost_center": _token(body["cost_center"], "cost_center"),
+        }
+
+    def record_for_principal(self, *, principal_id: str, body: dict[str, Any]) -> dict[str, Any]:
+        domain = _token(os.environ.get("TRUSTED_METERING_DOMAIN", ""), "trusted_metering_domain")
+        raw = copy.deepcopy(body)
+        raw["mapping"] = raw["mapping"] | {"business_domain": domain}
+        event = normalize_event(raw)
+        lease_claim = self._claim("lease", principal_id)
+        record_claim = self._claim("record", principal_id)
+        lease_token = str(uuid.uuid4())
+        # Claiming the lease and recording its event share one runtime transaction:
+        # a rejected immutable replay cannot strand a new live lease.
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            lease = dict(
+                connection.execute(
+                    text("SELECT public.metering_showback_runtime_write(:action,CAST(:payload AS jsonb))"),
+                    {
+                        "action": "claim_lease",
+                        "payload": json.dumps(
+                            {"request_claim": lease_claim["request_claim"], "lease_owner": "http-metering", "lease_token": lease_token},
+                            sort_keys=True,
+                            separators=(",", ":"),
+                        ),
+                    },
+                ).scalar_one()
+            )
+            payload = {
+                "request_claim": record_claim["request_claim"], "lease_owner": "http-metering", "lease_token": lease_token,
+                "lease_fence": lease["lease_fence"], "event_uid": event["event_uid"], "event_kind": event["event_kind"],
+                "occurred_at": event["occurred_at"], "window_start": event["window_start"], "window_end": event["window_end"],
+                "quantity_micros": event["quantity_micros"], "unit": event["unit"], "idempotency_key": event["idempotency_key"],
+                "evidence": event["evidence"], "mapping": event["mapping"],
+            }
+            if "correction_of" in event:
+                payload["correction_of"] = event["correction_of"]
+            value = connection.execute(
+                text("SELECT public.metering_showback_runtime_write(:action,CAST(:payload AS jsonb))"),
+                {"action": "record_event", "payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+            ).scalar_one()
+        return dict(value)
+
+    def publish_allocation_for_principal(self, *, principal_id: str, body: dict[str, Any]) -> dict[str, Any]:
+        raw = _closed(
+            body,
+            frozenset({"schema_version", "rule_uid", "rule_version", "effective_start", "effective_end", "mapping", "allocations"}),
+            "allocation_rule",
+        )
+        if raw.get("schema_version") != 1 or isinstance(raw.get("rule_version"), bool) or not isinstance(raw.get("rule_version"), int):
+            raise ValueError("allocation_rule_closed")
+        if not 1 <= raw["rule_version"] <= 1_000_000:
+            raise ValueError("allocation_rule_closed")
+        allocations = raw.get("allocations")
+        if not isinstance(allocations, list) or not 1 <= len(allocations) <= 32:
+            raise ValueError("allocation_rule_closed")
+        normalized_allocations: list[dict[str, Any]] = []
+        for item in allocations:
+            allocation = _closed(item, frozenset({"target", "weight_micros"}), "allocation")
+            if set(allocation) != {"target", "weight_micros"} or isinstance(allocation["weight_micros"], bool) or not isinstance(allocation["weight_micros"], int):
+                raise ValueError("allocation_rule_closed")
+            if not 0 < allocation["weight_micros"] <= 1_000_000:
+                raise ValueError("allocation_rule_closed")
+            target = _token(allocation["target"], "allocation_target")
+            if any(existing["target"] == target for existing in normalized_allocations):
+                raise ValueError("allocation_target_duplicate")
+            normalized_allocations.append({"target": target, "weight_micros": allocation["weight_micros"]})
+        if sum(item["weight_micros"] for item in normalized_allocations) != 1_000_000:
+            raise ValueError("allocation_weight_not_one")
+        start = _timestamp(raw.get("effective_start"), "effective_start")
+        end = _timestamp(raw.get("effective_end"), "effective_end")
+        if start >= end:
+            raise ValueError("effective_window_invalid")
+        return self._control_write(
+            "allocation",
+            principal_id,
+            {
+                "rule_uid": _uid(raw.get("rule_uid"), "rule_uid"),
+                "rule_version": str(raw["rule_version"]),
+                "effective_start": start,
+                "effective_end": end,
+                "mapping": self._trusted_mapping(raw.get("mapping")),
+                "allocations": normalized_allocations,
+            },
+        )
+
+    def evaluate_budget_for_principal(self, *, principal_id: str, body: dict[str, Any]) -> dict[str, Any]:
+        raw = _closed(body, frozenset({"schema_version", "budget_uid", "window", "mapping", "limit_micros", "threshold_micros"}), "budget")
+        if raw.get("schema_version") != 1:
+            raise ValueError("budget_closed")
+        if any(isinstance(raw.get(key), bool) or not isinstance(raw.get(key), int) for key in ("limit_micros", "threshold_micros")):
+            raise ValueError("budget_closed")
+        if not 0 <= raw["threshold_micros"] <= raw["limit_micros"] <= 999_999_999_999_999_999:
+            raise ValueError("budget_closed")
+        return self._control_write(
+            "budget",
+            principal_id,
+            {
+                "budget_uid": _uid(raw.get("budget_uid"), "budget_uid"),
+                "window": _window(raw.get("window")),
+                "mapping": self._trusted_mapping(raw.get("mapping")),
+                "limit_micros": str(raw["limit_micros"]),
+                "threshold_micros": str(raw["threshold_micros"]),
+            },
+        )
+
+    def allocation_replay_for_principal(self, *, principal_id: str, window: Any, rule_uid: Any, rule_version: Any) -> dict[str, Any]:
+        if isinstance(rule_version, bool) or not isinstance(rule_version, int) or not 1 <= rule_version <= 1_000_000:
+            raise ValueError("rule_version_invalid")
+        claim = self._claim("read", principal_id)
+        payload = {
+            "request_claim": claim["request_claim"],
+            "window": _window(window),
+            "rule_uid": _uid(rule_uid, "rule_uid"),
+            "rule_version": str(rule_version),
+        }
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            try:
+                value = connection.execute(
+                    text("SELECT public.metering_showback_allocation_replay(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+                ).scalar_one()
+            except SQLAlchemyError as exc:
+                raise PermissionError("metering_allocation_replay_denied") from exc
+        return dict(value)
+
+    def showback_for_principal(self, *, principal_id: str, window: str, kind: str) -> dict[str, Any]:
+        if kind not in {"showback", "reconciliation", "audit"}:
+            raise ValueError("metering_read_kind_invalid")
+        claim = self._claim("read", principal_id)
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            if kind in {"showback", "reconciliation"}:
+                value = connection.execute(
+                    text("SELECT public.metering_showback_rollup(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps({"request_claim": claim["request_claim"], "window": _window(window)}, sort_keys=True)},
+                ).scalar_one()
+            else:
+                value = connection.execute(
+                    text("SELECT public.metering_showback_runtime_read(:action,CAST(:payload AS jsonb))"),
+                    {"action": kind, "payload": json.dumps({"request_claim": claim["request_claim"], "window": _window(window)}, sort_keys=True)},
+                ).scalar_one()
+        return dict(value) if isinstance(value, dict) else {"records": value}

+ 1 - 1
app/core/llm/agent_governance.py

@@ -761,7 +761,7 @@ class AgentGovernanceService:
             if needs_approval:
                 workflow_uid = _uid(body.get("workflow_uid"), "workflow_uid")
                 task = self.approval_gateway.create_agent_task(
-                    record, workflow_uid, agent["owner_uid"]
+                    {**record, "owner_uid": agent["owner_uid"]}, workflow_uid, agent["owner_uid"]
                 )
                 record["approval_task_uid"] = task["uid"]
         try:

+ 4 - 0
app/core/llm/agent_governance_repository.py

@@ -58,6 +58,10 @@ class WorkCenterAgentApprovalGateway:
                     "environment": request_record["environment"],
                     "agent_uid": request_record["agent_uid"],
                     "request_uid": request_record["uid"],
+                    "principal_id": request_record.get("owner_uid", ""),
+                    "tool_name": request_record["tool_name"],
+                    "action": request_record["action"],
+                    "request_digest": request_record["input_digest"],
                     "automatic_execution_allowed": False,
                 },
             },

+ 379 - 0
app/core/llm/runtime_governance.py

@@ -0,0 +1,379 @@
+"""Default-deny, hash-only runtime governance for model and Agent invocations."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import re
+import threading
+import unicodedata
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any
+from uuid import uuid4
+
+from app.core.mcp.governed_invocation import (
+    InvocationContractError,
+    normalize_mcp_invocation,
+)
+
+
+class RuntimeDecisionError(ValueError):
+    def __init__(self, code: str):
+        self.code = code
+        super().__init__(code)
+
+
+class DatasetLeakageError(ValueError):
+    pass
+
+
+def load_engineering_fixture(manifest_path: str | Path) -> dict[str, Any]:
+    """Read each fixture once and verify its declared SHA-256 before evaluation."""
+    manifest_file = Path(manifest_path)
+    manifest = json.loads(manifest_file.read_text(encoding="utf-8"))
+    if manifest.get("fixture_only") is not True or manifest.get("schema_version") != "1":
+        raise DatasetLeakageError("fixture_manifest_invalid")
+    files = manifest.get("files")
+    if not isinstance(files, dict) or set(files) != {"dataset.json", "temporal-dataset.json"}:
+        raise DatasetLeakageError("fixture_manifest_invalid")
+    loaded: dict[str, Any] = {}
+    for name, expected in files.items():
+        if not isinstance(expected, str) or not expected.startswith("sha256:"):
+            raise DatasetLeakageError("fixture_manifest_invalid")
+        content = (manifest_file.parent / name).read_bytes()
+        if hashlib.sha256(content).hexdigest() != expected.removeprefix("sha256:"):
+            raise DatasetLeakageError("fixture_digest_mismatch")
+        loaded[name] = json.loads(content)
+    train = set(loaded["dataset.json"].get("train_case_ids", []))
+    evaluation = {item.get("case_id") for item in loaded["dataset.json"].get("evaluation_cases", [])}
+    if train & evaluation:
+        raise DatasetLeakageError("dataset_leakage_detected")
+    return loaded
+
+
+@dataclass(frozen=True)
+class ModelRoute:
+    route_id: str
+    provider: str
+    model: str
+    prompt_version: str
+    generation: str
+    tenant_id: str
+    principal_id: str
+    business_domain_uid: str
+    environment: str
+    canary_status: str
+
+
+@dataclass(frozen=True)
+class BudgetPolicy:
+    token_limit: int
+    cost_limit_micros: int
+    tool_limit: int
+    time_limit_ms: int
+    concurrency_limit: int
+    model_limits: dict[str, int]
+
+
+_SCOPE_FIELDS = ("tenant_id", "principal_id", "business_domain_uid", "environment")
+_REQUEST_KEYS = frozenset(
+    {
+        *_SCOPE_FIELDS, "provider", "model", "prompt_version", "generation",
+        "interface_type", "tool_name", "action", "requested_capabilities", "input_text",
+        "evidence_refs", "idempotency_key", "estimated_tokens", "estimated_cost_micros",
+        "requested_time_ms",
+    }
+)
+_FORBIDDEN_KEYS = frozenset(
+    {
+        "url", "uri", "endpoint", "path", "file_path", "filename", "command", "shell",
+        "script", "secret", "token", "password", "api_key", "raw_rows", "rows", "records",
+        "payload", "arguments", "output", "raw_input", "raw_output",
+    }
+)
+_SAFE_ID = re.compile(r"^[A-Za-z0-9_.:-]{1,160}$")
+_INJECTION = re.compile(
+    r"(?is)(ignore\s+(?:all\s+)?(?:previous|prior|system)\s+instructions?|"
+    r"bypass\s+(?:the\s+)?(?:policy|guard|permission)|reveal.{0,50}(?:secret|token|password|api[_ -]?key)|"
+    r"(?:忽略).{0,16}(?:指令|规则|系统)|(?:绕过|关闭|禁用).{0,16}(?:权限|策略|审计))"
+)
+_LOCATION = re.compile(r"(?i)(?:https?://|file://|(?:^|\s)/[A-Za-z0-9_./-]+)")
+
+
+def _hash(value: str) -> str:
+    return hashlib.sha256(value.encode("utf-8")).hexdigest()
+
+
+def _positive_int(value: Any, label: str, maximum: int) -> int:
+    if isinstance(value, bool) or not isinstance(value, int) or not 0 < value <= maximum:
+        raise RuntimeDecisionError(f"{label}_invalid")
+    return value
+
+
+def _closed_request(value: Any) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise RuntimeDecisionError("request_invalid")
+    if len(value) > len(_REQUEST_KEYS):
+        raise RuntimeDecisionError("request_invalid")
+    for key in value:
+        normalized = unicodedata.normalize("NFKC", str(key))
+        if normalized != key or normalized.casefold() in _FORBIDDEN_KEYS:
+            raise RuntimeDecisionError("forbidden_contract_key")
+    unknown = set(value) - _REQUEST_KEYS
+    if unknown or set(value) != _REQUEST_KEYS:
+        raise RuntimeDecisionError("request_schema_invalid")
+    return dict(value)
+
+
+def _normalize_request(value: Any) -> dict[str, Any]:
+    request = _closed_request(value)
+    for key in _SCOPE_FIELDS + ("provider", "model", "prompt_version", "generation", "idempotency_key"):
+        item = request[key]
+        if not isinstance(item, str) or not _SAFE_ID.fullmatch(item):
+            raise RuntimeDecisionError(f"{key}_invalid")
+    text = request["input_text"]
+    if not isinstance(text, str) or not text.strip() or len(text) > 8000:
+        raise RuntimeDecisionError("input_invalid")
+    normalized_text = unicodedata.normalize("NFKC", text).strip()
+    if _INJECTION.search(normalized_text):
+        raise RuntimeDecisionError("prompt_injection_detected")
+    if _LOCATION.search(normalized_text):
+        raise RuntimeDecisionError("input_location_denied")
+    capabilities = request["requested_capabilities"]
+    if not isinstance(capabilities, list) or not capabilities or len(capabilities) > 8:
+        raise RuntimeDecisionError("capability_invalid")
+    if any(not isinstance(item, str) or item not in {"network", "file", "data", "command", "resource", "time"} for item in capabilities):
+        raise RuntimeDecisionError("capability_invalid")
+    evidence = request["evidence_refs"]
+    if not isinstance(evidence, list) or len(evidence) > 20:
+        raise RuntimeDecisionError("citation_invalid")
+    for item in evidence:
+        if not isinstance(item, dict) or set(item) != {"evidence_id", "digest"}:
+            raise RuntimeDecisionError("citation_invalid")
+        if not isinstance(item["evidence_id"], str) or not _SAFE_ID.fullmatch(item["evidence_id"]):
+            raise RuntimeDecisionError("citation_invalid")
+        if not isinstance(item["digest"], str) or not re.fullmatch(r"[a-f0-9]{64}", item["digest"]):
+            raise RuntimeDecisionError("citation_invalid")
+    try:
+        normalize_mcp_invocation(
+            {
+                "interface_type": request["interface_type"], "tool_name": request["tool_name"],
+                "action": request["action"], "arguments_digest": _hash(normalized_text),
+                "evidence_refs": evidence,
+            }
+        )
+    except InvocationContractError as error:
+        raise RuntimeDecisionError("mcp_contract_invalid") from error
+    return {
+        **{key: request[key] for key in _SCOPE_FIELDS},
+        **{key: request[key] for key in ("provider", "model", "prompt_version", "generation", "interface_type", "tool_name", "action", "idempotency_key")},
+        "requested_capabilities": frozenset(request["requested_capabilities"]),
+        "input_hash": _hash(normalized_text),
+        "evidence_refs": tuple((item["evidence_id"], item["digest"]) for item in evidence),
+        "estimated_tokens": _positive_int(request["estimated_tokens"], "estimated_tokens", 1_000_000),
+        "estimated_cost_micros": _positive_int(request["estimated_cost_micros"], "estimated_cost_micros", 1_000_000_000),
+        "requested_time_ms": _positive_int(request["requested_time_ms"], "requested_time_ms", 300_000),
+    }
+
+
+class InMemoryRuntimeRepository:
+    """Thread-safe reference repository used by unit contracts and local wiring."""
+
+    def __init__(self) -> None:
+        self._lock = threading.RLock()
+        self._routes: list[ModelRoute] = []
+        self._capabilities: set[tuple[str, str, str, str, str, str, frozenset[str]]] = set()
+        self._budgets: dict[str, dict[str, Any]] = {}
+        self._decisions: dict[tuple[str, str], dict[str, Any]] = {}
+        self._audit: list[dict[str, Any]] = []
+        self._states: dict[str, dict[str, Any]] = {}
+        self._generations: dict[tuple[str, str], dict[str, Any]] = {}
+
+    def register_route(self, route: ModelRoute) -> None:
+        with self._lock:
+            self._routes.append(route)
+            self._generations.setdefault((route.tenant_id, route.generation), {"status": route.canary_status, "fence": 0, "parent": None})
+            self._states.setdefault(route.tenant_id, {"state": "active", "incident_ref": None, "fence": 0})
+
+    def register_capability(self, *, tenant_id: str, business_domain_uid: str, environment: str, tool_name: str, interface_type: str, action: str, risk_level: str, allowed_capabilities: set[str]) -> None:
+        if risk_level != "low" or not allowed_capabilities <= {"data"}:
+            raise ValueError("only declared low-risk data capability may be registered locally")
+        with self._lock:
+            self._capabilities.add((tenant_id, business_domain_uid, environment, tool_name, interface_type, action, frozenset(allowed_capabilities)))
+
+    def set_budget(self, tenant_id: str, policy: BudgetPolicy) -> None:
+        if min(policy.token_limit, policy.cost_limit_micros, policy.tool_limit, policy.time_limit_ms, policy.concurrency_limit) < 1:
+            raise ValueError("budget limits must be positive")
+        with self._lock:
+            self._budgets[tenant_id] = {"policy": policy, "tokens": policy.token_limit, "cost": policy.cost_limit_micros, "tools": policy.tool_limit, "time": policy.time_limit_ms, "concurrency": policy.concurrency_limit, "models": dict(policy.model_limits), "fence": 0}
+
+    def find_route(self, request: dict[str, Any]) -> ModelRoute | None:
+        with self._lock:
+            for route in self._routes:
+                if all(getattr(route, field) == request[field] for field in _SCOPE_FIELDS + ("provider", "model", "prompt_version", "generation")):
+                    return route
+            return None
+
+    def generation_status(self, tenant_id: str, generation: str) -> str | None:
+        with self._lock:
+            entry = self._generations.get((tenant_id, generation))
+            return entry["status"] if entry else None
+
+    def allowed_capability(self, request: dict[str, Any]) -> bool:
+        key = (request["tenant_id"], request["business_domain_uid"], request["environment"], request["tool_name"], request["interface_type"], request["action"], request["requested_capabilities"])
+        with self._lock:
+            return key in self._capabilities
+
+    def existing(self, tenant_id: str, idempotency_key: str) -> dict[str, Any] | None:
+        with self._lock:
+            record = self._decisions.get((tenant_id, idempotency_key))
+            return dict(record) if record else None
+
+    def reserve(self, request: dict[str, Any]) -> int:
+        with self._lock:
+            budget = self._budgets.get(request["tenant_id"])
+            if budget is None or any((budget["tokens"] < request["estimated_tokens"], budget["cost"] < request["estimated_cost_micros"], budget["tools"] < 1, budget["time"] < request["requested_time_ms"], budget["concurrency"] < 1, budget["models"].get(request["model"], 0) < 1)):
+                raise RuntimeDecisionError("budget_exhausted")
+            budget["tokens"] -= request["estimated_tokens"]
+            budget["cost"] -= request["estimated_cost_micros"]
+            budget["tools"] -= 1
+            budget["time"] -= request["requested_time_ms"]
+            budget["concurrency"] -= 1
+            budget["models"][request["model"]] -= 1
+            budget["fence"] += 1
+            return budget["fence"]
+
+    def write_authorized(self, request: dict[str, Any], route: ModelRoute, fence: int) -> dict[str, Any]:
+        record = {"invocation_id": str(uuid4()), "decision": "authorized", "route_id": route.route_id, "generation": route.generation, "budget_fence": fence, "input_hash": request["input_hash"], "evidence_digests": tuple(digest for _, digest in request["evidence_refs"]), "tenant_id": request["tenant_id"], "principal_id": request["principal_id"], "business_domain_uid": request["business_domain_uid"], "environment": request["environment"]}
+        with self._lock:
+            self._decisions[(request["tenant_id"], request["idempotency_key"])] = record
+            self._audit.append(dict(record))
+            return dict(record)
+
+    def remaining_budget(self, tenant_id: str) -> dict[str, int]:
+        with self._lock:
+            budget = self._budgets[tenant_id]
+            return {"tokens": budget["tokens"], "cost_micros": budget["cost"], "tools": budget["tools"], "time_ms": budget["time"], "concurrency": budget["concurrency"]}
+
+    def audit_records(self) -> list[dict[str, Any]]:
+        with self._lock:
+            return [dict(item) for item in self._audit]
+
+    def runtime_state(self, tenant_id: str) -> dict[str, Any]:
+        with self._lock:
+            return dict(self._states.get(tenant_id, {"state": "active", "incident_ref": None, "fence": 0}))
+
+    def set_runtime_state(self, tenant_id: str, state: str, incident_ref: str | None, *, require_active: bool = False) -> dict[str, Any]:
+        with self._lock:
+            current = self._states.setdefault(tenant_id, {"state": "active", "incident_ref": None, "fence": 0})
+            if require_active and current["state"] != "paused":
+                raise RuntimeDecisionError("runtime_state_conflict")
+            current["state"] = state
+            current["incident_ref"] = incident_ref or current["incident_ref"]
+            current["fence"] += 1
+            return dict(current)
+
+    def register_generation(self, tenant_id: str, generation: str, *, parent_generation: str, status: str) -> None:
+        if status not in {"canary", "approved"}:
+            raise ValueError("generation status invalid")
+        with self._lock:
+            self._generations[(tenant_id, generation)] = {"status": status, "parent": parent_generation, "fence": 0}
+
+    def promote_generation(self, tenant_id: str, generation: str) -> int:
+        with self._lock:
+            current = self._generations.get((tenant_id, generation))
+            if not current or current["status"] != "canary":
+                raise RuntimeDecisionError("canary_not_approved")
+            current["status"] = "approved"
+            current["fence"] += 1
+            return current["fence"]
+
+    def rollback_generation(self, tenant_id: str, generation: str, fence: int) -> str:
+        with self._lock:
+            approved = [entry for (tenant, name), entry in self._generations.items() if tenant == tenant_id and entry["status"] == "approved"]
+            if not approved or max(entry["fence"] for entry in approved) != fence:
+                raise RuntimeDecisionError("generation_fence_conflict")
+            target = self._generations.get((tenant_id, generation))
+            if not target:
+                raise RuntimeDecisionError("route_scope_denied")
+            return generation
+
+    def replay(self, invocation_id: str) -> dict[str, Any]:
+        with self._lock:
+            for record in self._audit:
+                if record["invocation_id"] == invocation_id:
+                    return dict(record)
+        raise RuntimeDecisionError("invocation_not_found")
+
+
+class GovernedInvocationService:
+    def __init__(self, repository: InMemoryRuntimeRepository):
+        self.repository = repository
+
+    def authorize(self, raw_request: dict[str, Any]) -> dict[str, Any]:
+        request = _normalize_request(raw_request)
+        replay = self.repository.existing(request["tenant_id"], request["idempotency_key"])
+        if replay:
+            return replay
+        state = self.repository.runtime_state(request["tenant_id"])
+        if state["state"] == "paused":
+            raise RuntimeDecisionError("runtime_paused")
+        route = self.repository.find_route(request)
+        if route is None:
+            if self.repository.generation_status(request["tenant_id"], request["generation"]) == "canary":
+                raise RuntimeDecisionError("canary_not_approved")
+            raise RuntimeDecisionError("route_scope_denied")
+        if route.canary_status != "approved":
+            raise RuntimeDecisionError("canary_not_approved")
+        if not self.repository.allowed_capability(request):
+            if request["tool_name"] == "knowledge.search":
+                raise RuntimeDecisionError("capability_denied")
+            raise RuntimeDecisionError("tool_contract_denied")
+        fence = self.repository.reserve(request)
+        return self.repository.write_authorized(request, route, fence)
+
+    def record_anomaly(self, tenant_id: str, *, incident_ref: str, severity: str, actor: str) -> dict[str, Any]:
+        if not _SAFE_ID.fullmatch(tenant_id) or not _SAFE_ID.fullmatch(incident_ref) or actor != "detector":
+            raise RuntimeDecisionError("anomaly_contract_invalid")
+        if severity not in {"medium", "high", "critical"}:
+            raise RuntimeDecisionError("anomaly_severity_invalid")
+        return self.repository.set_runtime_state(tenant_id, "paused" if severity == "critical" else "degraded", incident_ref)
+
+    def recover(self, tenant_id: str, *, approval_ref: str | None, actor: str) -> dict[str, Any]:
+        if actor != "operator" or not isinstance(approval_ref, str) or not _SAFE_ID.fullmatch(approval_ref):
+            raise RuntimeDecisionError("recovery_approval_required")
+        return self.repository.set_runtime_state(tenant_id, "active", None, require_active=True)
+
+    def promote_canary(self, tenant_id: str, generation: str, *, approval_ref: str) -> int:
+        if not _SAFE_ID.fullmatch(approval_ref):
+            raise RuntimeDecisionError("recovery_approval_required")
+        return self.repository.promote_generation(tenant_id, generation)
+
+    def rollback_generation(self, tenant_id: str, generation: str, *, fence: int, approval_ref: str) -> str:
+        if not _SAFE_ID.fullmatch(approval_ref):
+            raise RuntimeDecisionError("recovery_approval_required")
+        return self.repository.rollback_generation(tenant_id, generation, fence)
+
+    def replay(self, invocation_id: str) -> dict[str, Any]:
+        return self.repository.replay(invocation_id)
+
+
+def evaluate_governed_dataset(*, train_case_ids: set[str], evaluation_cases: list[dict[str, Any]]) -> dict[str, float]:
+    case_ids = [str(case.get("case_id", "")) for case in evaluation_cases]
+    if not case_ids or len(case_ids) != len(set(case_ids)) or train_case_ids.intersection(case_ids):
+        raise DatasetLeakageError("dataset_leakage_detected")
+    recalls, reciprocal_ranks, citations, violations, fresh = [], [], [], [], []
+    for case in evaluation_cases:
+        expected = case.get("expected_evidence_id")
+        retrieved = list(case.get("retrieved_evidence_ids") or [])
+        cited = list(case.get("citation_evidence_ids") or [])
+        if not isinstance(expected, str) or not expected:
+            raise DatasetLeakageError("dataset_case_invalid")
+        recalls.append(float(expected in retrieved))
+        reciprocal_ranks.append(1.0 / (retrieved.index(expected) + 1) if expected in retrieved else 0.0)
+        citations.append(float(cited == [expected]))
+        violations.append(float(not bool(case.get("authorized"))))
+        fresh.append(float(bool(case.get("fresh"))))
+    count = float(len(evaluation_cases))
+    return {"recall": sum(recalls) / count, "mrr": sum(reciprocal_ranks) / count, "citation_correctness": sum(citations) / count, "privilege_violation_rate": sum(violations) / count, "freshness": sum(fresh) / count}

+ 168 - 0
app/core/llm/runtime_governance_repository.py

@@ -0,0 +1,168 @@
+"""PostgreSQL repository for WP09 budget leases and immutable audit metadata."""
+
+from __future__ import annotations
+
+import json
+from typing import Any
+from uuid import uuid4
+
+from sqlalchemy import text
+from sqlalchemy.exc import SQLAlchemyError
+
+from app.core.llm.runtime_governance import BudgetPolicy
+
+
+class SqlAlchemyRuntimeGovernanceRepository:
+    def __init__(self, connection) -> None:
+        self.connection = connection
+
+    def create_budget(self, tenant_id: str, policy: BudgetPolicy) -> None:
+        self.connection.execute(text("""
+            INSERT INTO public.agent_runtime_budgets (
+                tenant_id, token_remaining, cost_remaining_micros, tool_remaining,
+                time_remaining_ms, concurrency_remaining
+            ) VALUES (:tenant_id, :tokens, :cost, :tools, :time_ms, :concurrency)
+        """), {"tenant_id": tenant_id, "tokens": policy.token_limit, "cost": policy.cost_limit_micros, "tools": policy.tool_limit, "time_ms": policy.time_limit_ms, "concurrency": policy.concurrency_limit})
+        for model, remaining in policy.model_limits.items():
+            self.connection.execute(text("""
+                INSERT INTO public.agent_runtime_model_budgets (tenant_id, model, remaining)
+                VALUES (:tenant_id, :model, :remaining)
+            """), {"tenant_id": tenant_id, "model": model, "remaining": remaining})
+
+    def reserve_budget(self, tenant_id: str, idempotency_key: str, model: str, tokens: int, cost_micros: int, tools: int, time_ms: int) -> int:
+        values = (tokens, cost_micros, tools, time_ms)
+        if any(isinstance(value, bool) or not isinstance(value, int) or value < 1 for value in values):
+            raise ValueError("budget_value_invalid")
+        with self.connection.begin_nested():
+            return self._reserve_budget_atomic(tenant_id, idempotency_key, model, tokens, cost_micros, tools, time_ms)
+
+    def _reserve_budget_atomic(self, tenant_id: str, idempotency_key: str, model: str, tokens: int, cost_micros: int, tools: int, time_ms: int) -> int:
+        model_row = self.connection.execute(text("""
+            UPDATE public.agent_runtime_model_budgets
+            SET remaining = remaining - 1
+            WHERE tenant_id = :tenant_id AND model = :model AND remaining >= 1
+            RETURNING remaining
+        """), {"tenant_id": tenant_id, "model": model}).one_or_none()
+        if model_row is None:
+            raise ValueError("budget_exhausted")
+        row = self.connection.execute(text("""
+            UPDATE public.agent_runtime_budgets
+            SET token_remaining = token_remaining - :tokens,
+                cost_remaining_micros = cost_remaining_micros - :cost,
+                tool_remaining = tool_remaining - :tools,
+                time_remaining_ms = time_remaining_ms - :time_ms,
+                concurrency_remaining = concurrency_remaining - 1,
+                lease_fence = lease_fence + 1, updated_at = now()
+            WHERE tenant_id = :tenant_id AND token_remaining >= :tokens
+              AND cost_remaining_micros >= :cost AND tool_remaining >= :tools
+              AND time_remaining_ms >= :time_ms AND concurrency_remaining >= 1
+            RETURNING lease_fence
+        """), {"tenant_id": tenant_id, "tokens": tokens, "cost": cost_micros, "tools": tools, "time_ms": time_ms}).one_or_none()
+        if row is None:
+            raise ValueError("budget_exhausted")
+        fence = int(row[0])
+        self.connection.execute(text("""
+            INSERT INTO public.agent_runtime_reservations (
+                reservation_id, tenant_id, idempotency_key, model, token_count,
+                cost_micros, tool_count, time_ms, lease_fence, status, lease_expires_at
+            ) VALUES (CAST(:reservation_id AS uuid), :tenant_id, :idempotency_key,
+                      :model, :tokens, :cost, :tools, :time_ms, :fence, 'reserved',
+                      clock_timestamp()+interval '5 minutes')
+        """), {"reservation_id": str(uuid4()), "tenant_id": tenant_id, "idempotency_key": idempotency_key, "model": model, "tokens": tokens, "cost": cost_micros, "tools": tools, "time_ms": time_ms, "fence": fence})
+        return fence
+
+    def append_audit(self, record: dict[str, Any]) -> None:
+        try:
+            self.connection.execute(text("""
+                INSERT INTO public.agent_invocation_audits (
+                    invocation_id, tenant_id, idempotency_key, route_id, generation,
+                    lease_fence, input_hash, evidence_digests, decision, request_digest
+                ) VALUES (CAST(:invocation_id AS uuid), :tenant_id, :idempotency_key,
+                          :route_id, :generation, :lease_fence, :input_hash,
+                          CAST(:evidence_digests AS jsonb), :decision, :request_digest)
+            """), {
+                **record, "evidence_digests": json.dumps(record["evidence_digests"]),
+                "request_digest": record.get("request_digest", record["input_hash"]),
+            })
+        except Exception as error:
+            raise ValueError("append_only_conflict") from error
+
+    def grant_context(self, *, agent_uid: str, grant_uid: str, actor_uid: str) -> dict[str, Any]:
+        """Load scope exclusively from persisted Agent, grant and approved route state."""
+        row = self.connection.execute(text("""
+            SELECT r.tenant_id, a.owner_uid::text AS principal_id,
+                   g.business_domain_uid::text AS business_domain_uid, g.environment,
+                   r.provider, r.model, r.prompt_version, r.generation,
+                   g.interface_type, g.tool_name, g.action, g.risk_level
+            FROM public.agent_tool_grants g
+            JOIN public.governed_agents a ON a.uid=g.agent_uid
+            JOIN public.model_gateway_routes r ON r.principal_id=a.owner_uid
+              AND r.business_domain_uid=g.business_domain_uid AND r.environment=g.environment
+              AND r.canary_status='approved'
+            WHERE g.uid=CAST(:grant_uid AS uuid) AND g.agent_uid=CAST(:agent_uid AS uuid)
+              AND a.owner_uid=CAST(:actor_uid AS uuid) AND g.status='active' AND a.status='active'
+            ORDER BY r.created_at DESC LIMIT 1
+        """), {"agent_uid": agent_uid, "grant_uid": grant_uid, "actor_uid": actor_uid}).mappings().one_or_none()
+        if row is None:
+            from app.core.llm.runtime_server import RuntimeServerError
+            raise RuntimeServerError("server_scope_denied")
+        return dict(row)
+
+    def authorize_claim(self, request: dict[str, Any]) -> dict[str, Any]:
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_agent_runtime"))
+            row = self.connection.execute(text("""
+                SELECT public.agent_runtime_authorize(CAST(:payload AS jsonb)) AS result
+            """), {"payload": json.dumps({
+                key: (sorted(value) if isinstance(value, frozenset) else value)
+                for key, value in request.items()
+            }, ensure_ascii=False)}).scalar_one()
+            return dict(row)
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_authorization_rejected") from error
+
+    def settlement_context(self, *, agent_uid: str, actor_uid: str, idempotency_key: str) -> dict[str, Any]:
+        row = self.connection.execute(text("""
+            SELECT r.agent_uid::text AS agent_uid, r.principal_id::text AS principal_id,
+                   r.idempotency_key, r.lease_fence
+              FROM public.agent_runtime_reservations r
+             WHERE r.idempotency_key=:idempotency_key
+               AND r.agent_uid=CAST(:agent_uid AS uuid)
+               AND r.principal_id=CAST(:actor_uid AS uuid)
+        """), {"agent_uid": agent_uid, "actor_uid": actor_uid, "idempotency_key": idempotency_key}).mappings().one_or_none()
+        if row is None:
+            from app.core.llm.runtime_server import RuntimeServerError
+            raise RuntimeServerError("server_scope_denied")
+        return dict(row)
+
+    def settle_claim(self, request: dict[str, Any]) -> dict[str, Any]:
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_agent_runtime"))
+            row = self.connection.execute(text("""
+                SELECT public.agent_runtime_settle(CAST(:payload AS jsonb)) AS result
+            """), {"payload": json.dumps(request, ensure_ascii=False)}).scalar_one()
+            return dict(row)
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_settlement_rejected") from error
+
+    def issue_control_claim(self, claim: dict[str, Any]) -> str:
+        """Persist a credential-bound, one-shot control claim in this request transaction."""
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_app_runtime"))
+            return str(self.connection.execute(text("""
+                SELECT public.agent_runtime_control_issue_claim(CAST(:claim AS jsonb))
+            """), {"claim": json.dumps(claim, ensure_ascii=False)}).scalar_one())
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_control_claim_rejected") from error
+
+    def control_claimed(self, payload: dict[str, Any], claim_uid: str) -> dict[str, Any]:
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_app_runtime"))
+            row = self.connection.execute(text("""
+                SELECT public.agent_runtime_control_claimed(
+                  CAST(:payload AS jsonb),CAST(:claim_uid AS uuid)
+                ) AS result
+            """), {"payload": json.dumps(payload, ensure_ascii=False), "claim_uid": claim_uid}).scalar_one()
+            return dict(row)
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_control_rejected") from error

+ 111 - 0
app/core/llm/runtime_server.py

@@ -0,0 +1,111 @@
+"""Server-derived invocation contract for the hardened WP09 runtime path."""
+
+from __future__ import annotations
+
+import hashlib
+from dataclasses import dataclass
+from decimal import Decimal, InvalidOperation
+from typing import Any
+
+
+class RuntimeServerError(ValueError):
+    pass
+
+
+@dataclass(frozen=True)
+class RuntimeServerContext:
+    agent_uid: str
+    actor_uid: str
+    roles: frozenset[str]
+
+
+_PAYLOAD_FIELDS = frozenset(
+    {
+        "grant_uid", "idempotency_key", "input_text", "evidence_refs",
+        "estimated_tokens", "estimated_cost_micros", "requested_time_ms",
+    }
+)
+_OPTIONAL_APPROVAL_FIELD = "approval_task_uid"
+_SCOPE_FIELDS = frozenset(
+    {
+        "tenant_id", "principal_id", "business_domain_uid", "environment", "provider",
+        "model", "prompt_version", "generation", "interface_type", "tool_name", "action",
+        "risk_level", "agent_uid",
+    }
+)
+
+
+def _positive_integer(value: Any) -> int:
+    if isinstance(value, bool) or not isinstance(value, int) or not 0 < value <= 1_000_000:
+        raise RuntimeServerError("budget_value_invalid")
+    return value
+
+
+def _cost_micros(value: Any) -> int:
+    if isinstance(value, bool) or not isinstance(value, str) or len(value) > 32:
+        raise RuntimeServerError("budget_value_invalid")
+    try:
+        decimal = Decimal(value)
+    except (InvalidOperation, ValueError) as error:
+        raise RuntimeServerError("budget_value_invalid") from error
+    if not decimal.is_finite() or decimal <= 0 or decimal != decimal.to_integral_value():
+        raise RuntimeServerError("budget_value_invalid")
+    result = int(decimal)
+    if result > 1_000_000_000:
+        raise RuntimeServerError("budget_value_invalid")
+    return result
+
+
+class ServerGovernedInvocationService:
+    """Reject client-supplied scope, deriving every authority field server-side."""
+
+    def __init__(self, repository):
+        self.repository = repository
+
+    def authorize(self, context: RuntimeServerContext, payload: Any) -> dict[str, Any]:
+        if not isinstance(payload, dict):
+            raise RuntimeServerError("payload_invalid")
+        if set(payload) & _SCOPE_FIELDS:
+            raise RuntimeServerError("payload_scope_forbidden")
+        if set(payload) not in {_PAYLOAD_FIELDS, _PAYLOAD_FIELDS | {_OPTIONAL_APPROVAL_FIELD}}:
+            raise RuntimeServerError("payload_schema_invalid")
+        if not context.agent_uid or not context.actor_uid or not context.roles:
+            raise RuntimeServerError("server_identity_invalid")
+        grant_uid = payload["grant_uid"]
+        if not isinstance(grant_uid, str) or not grant_uid:
+            raise RuntimeServerError("payload_invalid")
+        idempotency_key = payload["idempotency_key"]
+        if not isinstance(idempotency_key, str) or not idempotency_key or len(idempotency_key) > 160:
+            raise RuntimeServerError("payload_invalid")
+        input_text = payload["input_text"]
+        if not isinstance(input_text, str) or not input_text.strip() or len(input_text) > 8000:
+            raise RuntimeServerError("payload_invalid")
+        evidence_refs = payload["evidence_refs"]
+        if not isinstance(evidence_refs, list) or len(evidence_refs) > 20:
+            raise RuntimeServerError("payload_invalid")
+        derived = self.repository.grant_context(
+            agent_uid=context.agent_uid, grant_uid=grant_uid, actor_uid=context.actor_uid
+        )
+        requires_approval = derived.get("risk_level") != "low" or derived.get("action") == "execute"
+        approval_task_uid = payload.get(_OPTIONAL_APPROVAL_FIELD)
+        if requires_approval and (not isinstance(approval_task_uid, str) or len(approval_task_uid) != 36):
+            raise RuntimeServerError("human_approval_required")
+        if not requires_approval and approval_task_uid is not None:
+            raise RuntimeServerError("approval_not_applicable")
+        request = {
+            **derived,
+            "agent_uid": context.agent_uid,
+            "grant_uid": grant_uid,
+            "idempotency_key": idempotency_key,
+            "request_digest": hashlib.sha256(
+                (input_text.strip() + "|" + repr(evidence_refs)).encode("utf-8")
+            ).hexdigest(),
+            "input_hash": hashlib.sha256(input_text.strip().encode("utf-8")).hexdigest(),
+            "evidence_digests": [],
+            "estimated_tokens": _positive_integer(payload["estimated_tokens"]),
+            "estimated_cost_micros": _cost_micros(payload["estimated_cost_micros"]),
+            "requested_time_ms": _positive_integer(payload["requested_time_ms"]),
+        }
+        if requires_approval:
+            request["approval_task_uid"] = approval_task_uid
+        return self.repository.authorize_claim(request)

+ 74 - 0
app/core/mcp/governed_invocation.py

@@ -0,0 +1,74 @@
+"""Closed, minimized contract for MCP calls made by governed Agents."""
+
+from __future__ import annotations
+
+import copy
+import re
+import unicodedata
+from typing import Any
+
+
+class InvocationContractError(ValueError):
+    """Raised when an MCP invocation exceeds its declared contract."""
+
+
+_ALLOWED = frozenset(
+    {"interface_type", "tool_name", "action", "arguments_digest", "evidence_refs"}
+)
+_FORBIDDEN_KEYS = frozenset(
+    {
+        "url", "uri", "endpoint", "path", "file_path", "filename", "command",
+        "shell", "script", "secret", "token", "password", "api_key", "raw_rows",
+        "rows", "records", "arguments", "payload",
+    }
+)
+_TOOL = re.compile(r"^[A-Za-z][A-Za-z0-9_.:-]{1,159}$")
+_DIGEST = re.compile(r"^[a-f0-9]{64}$")
+
+
+def _closed(value: Any, allowed: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise InvocationContractError(f"{label}_invalid")
+    for key in value:
+        normalized = unicodedata.normalize("NFKC", str(key))
+        if normalized != key or normalized.casefold() in _FORBIDDEN_KEYS:
+            raise InvocationContractError("forbidden_contract_key")
+    unknown = set(value) - allowed
+    if unknown:
+        raise InvocationContractError("unknown_contract_field")
+    return copy.deepcopy(value)
+
+
+def _digest(value: Any, label: str) -> str:
+    if not isinstance(value, str) or not _DIGEST.fullmatch(value):
+        raise InvocationContractError(f"{label}_invalid")
+    return value
+
+
+def normalize_mcp_invocation(value: Any) -> dict[str, Any]:
+    """Accept hash-only, bounded MCP metadata; never raw arguments or locations."""
+    body = _closed(value, _ALLOWED, "invocation")
+    if body.get("interface_type") != "mcp":
+        raise InvocationContractError("interface_type_invalid")
+    tool_name = body.get("tool_name")
+    if not isinstance(tool_name, str) or not _TOOL.fullmatch(tool_name):
+        raise InvocationContractError("tool_name_invalid")
+    if body.get("action") not in {"read", "suggest", "execute"}:
+        raise InvocationContractError("action_invalid")
+    refs = body.get("evidence_refs")
+    if not isinstance(refs, list) or len(refs) > 20:
+        raise InvocationContractError("evidence_refs_invalid")
+    normalized_refs = []
+    for item in refs:
+        ref = _closed(item, frozenset({"evidence_id", "digest"}), "evidence_ref")
+        evidence_id = ref.get("evidence_id")
+        if not isinstance(evidence_id, str) or not re.fullmatch(r"[A-Za-z0-9_.:-]{1,120}", evidence_id):
+            raise InvocationContractError("evidence_id_invalid")
+        normalized_refs.append({"evidence_id": evidence_id, "digest": _digest(ref.get("digest"), "evidence_digest")})
+    return {
+        "interface_type": "mcp",
+        "tool_name": tool_name,
+        "action": body["action"],
+        "arguments_digest": _digest(body.get("arguments_digest"), "arguments_digest"),
+        "evidence_refs": normalized_refs,
+    }

+ 5 - 0
app/core/plugins/__init__.py

@@ -0,0 +1,5 @@
+"""Closed, fixture-only governed plugin platform primitives."""
+
+from .governance import PluginManifestError, normalize_plugin_manifest
+
+__all__ = ["PluginManifestError", "normalize_plugin_manifest"]

+ 178 - 0
app/core/plugins/governance.py

@@ -0,0 +1,178 @@
+"""Closed, local-only manifest contract for governed plugins.
+
+This module deliberately contains no loader, dynamic import, evaluator, shell,
+subprocess, network client or user-selected filesystem path.  A manifest is
+metadata for a fixed built-in fixture handler, never an executable package.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import re
+import unicodedata
+from typing import Any
+
+
+class PluginManifestError(ValueError):
+    """A plugin manifest did not meet the closed local-baseline contract."""
+
+
+_TOP_LEVEL = frozenset(
+    {
+        "schema_version",
+        "plugin_uid",
+        "name",
+        "version",
+        "api_version",
+        "type",
+        "capabilities",
+        "permissions",
+        "resource",
+        "compatibility",
+        "distribution",
+    }
+)
+_TYPES = frozenset({"connector", "parser", "quality", "notification", "approval", "agent_mcp"})
+_CAPABILITIES = {
+    "connector": frozenset({"discover", "snapshot", "evidence"}),
+    "parser": frozenset({"parse", "evidence"}),
+    "quality": frozenset({"evaluate", "evidence"}),
+    "notification": frozenset({"prepare", "evidence"}),
+    "approval": frozenset({"evaluate", "evidence"}),
+    "agent_mcp": frozenset({"read", "suggest", "evidence"}),
+}
+_PERMISSIONS = frozenset({"network", "file", "secret", "child_process"})
+_RESOURCE = frozenset({"timeout_ms", "max_output_bytes", "max_concurrency", "max_retries"})
+_COMPATIBILITY = frozenset({"platform_api"})
+_DISTRIBUTION = frozenset({"kind", "fixture_id", "artifact_digest"})
+_SENSITIVE = frozenset(
+    {
+        "url", "uri", "endpoint", "path", "file", "file_path", "filename", "command", "shell",
+        "script", "code", "module", "import", "eval", "exec", "secret", "token", "password",
+        "credential", "api_key", "authorization", "raw_rows", "rows", "records", "payload", "sql",
+    }
+)
+_ID = re.compile(r"^[a-z][a-z0-9-]{2,62}$")
+_SEMVER = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$")
+_HEX = re.compile(r"^[a-f0-9]{64}$")
+
+
+def canonical_digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode("utf-8")
+    ).hexdigest()
+
+
+def fixture_signature_digest(artifact_digest: str) -> str:
+    """Bind the sole local fixture artifact to the platform-owned trust key.
+
+    This is deliberately not a payload supplied public key or a general
+    signature verifier.  Enterprise CA and registry signing remain disabled.
+    """
+
+    if not isinstance(artifact_digest, str) or not _HEX.fullmatch(artifact_digest):
+        raise PluginManifestError("artifact_digest_invalid")
+    return hashlib.sha256(f"local-fixture-key-v1|{artifact_digest}".encode("ascii")).hexdigest()
+
+
+def _closed(value: Any, allowed: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict) or len(value) > len(allowed):
+        raise PluginManifestError(f"{label}_closed")
+    for key in value:
+        if not isinstance(key, str) or unicodedata.normalize("NFKC", key) != key:
+            raise PluginManifestError("manifest_unicode_rejected")
+        # The four declared capability switches are metadata, not values.  All
+        # other sensitive vocabulary remains forbidden even before unknown-key
+        # processing so it cannot become an accidental extension point.
+        if key.casefold() in _SENSITIVE and key not in allowed:
+            raise PluginManifestError("manifest_sensitive_key")
+    if set(value) != allowed:
+        raise PluginManifestError(f"{label}_closed")
+    return copy.deepcopy(value)
+
+
+def _ascii_text(value: Any, label: str, maximum: int = 120) -> str:
+    if not isinstance(value, str) or not value or len(value) > maximum:
+        raise PluginManifestError(f"{label}_invalid")
+    if unicodedata.normalize("NFKC", value) != value or not value.isascii():
+        raise PluginManifestError(f"{label}_unicode_rejected")
+    return value
+
+
+def _positive_int(value: Any, label: str, maximum: int) -> int:
+    if isinstance(value, bool) or not isinstance(value, int) or not 0 < value <= maximum:
+        raise PluginManifestError(f"{label}_invalid")
+    return value
+
+
+def normalize_plugin_manifest(value: Any) -> dict[str, Any]:
+    """Normalize a v1 manifest for the sole fixed engineering fixture.
+
+    Enterprise registry artifacts are intentionally rejected until an external
+    trust model is approved.  This validation makes that inactivity executable.
+    """
+
+    body = _closed(value, _TOP_LEVEL, "manifest")
+    if body["schema_version"] != 1 or body["api_version"] != "1":
+        raise PluginManifestError("manifest_version_invalid")
+    plugin_uid = _ascii_text(body["plugin_uid"], "plugin_uid", 63)
+    name = _ascii_text(body["name"], "name", 63)
+    if not _ID.fullmatch(plugin_uid) or not _ID.fullmatch(name) or plugin_uid != name:
+        raise PluginManifestError("plugin_identity_invalid")
+    version = _ascii_text(body["version"], "version", 80)
+    if not _SEMVER.fullmatch(version):
+        raise PluginManifestError("plugin_version_invalid")
+    plugin_type = _ascii_text(body["type"], "plugin_type", 20)
+    if plugin_type not in _TYPES:
+        raise PluginManifestError("plugin_type_invalid")
+    capabilities = body["capabilities"]
+    if not isinstance(capabilities, list) or not 1 <= len(capabilities) <= 8:
+        raise PluginManifestError("capabilities_invalid")
+    normalized_capabilities = tuple(_ascii_text(item, "capability", 40) for item in capabilities)
+    if len(set(normalized_capabilities)) != len(normalized_capabilities) or set(normalized_capabilities) - _CAPABILITIES[plugin_type]:
+        raise PluginManifestError("capabilities_invalid")
+    permissions = _closed(body["permissions"], _PERMISSIONS, "permissions")
+    if any(item is not False for item in permissions.values()):
+        raise PluginManifestError("permissions_denied")
+    resource = _closed(body["resource"], _RESOURCE, "resource")
+    normalized_resource = {
+        "timeout_ms": _positive_int(resource["timeout_ms"], "timeout_ms", 5000),
+        "max_output_bytes": _positive_int(resource["max_output_bytes"], "max_output_bytes", 65536),
+        "max_concurrency": _positive_int(resource["max_concurrency"], "max_concurrency", 1),
+        "max_retries": _positive_int(resource["max_retries"], "max_retries", 3),
+    }
+    if normalized_resource["max_output_bytes"] < 64:
+        raise PluginManifestError("max_output_bytes_invalid")
+    compatibility = _closed(body["compatibility"], _COMPATIBILITY, "compatibility")
+    if compatibility["platform_api"] != "1":
+        raise PluginManifestError("compatibility_invalid")
+    distribution = _closed(body["distribution"], _DISTRIBUTION, "distribution")
+    if distribution["kind"] != "builtin_fixture" or distribution["fixture_id"] != "ENGINEERING_EVIDENCE_ONLY":
+        raise PluginManifestError("distribution_denied")
+    artifact_digest = _ascii_text(distribution["artifact_digest"], "artifact_digest", 64)
+    if not _HEX.fullmatch(artifact_digest):
+        raise PluginManifestError("artifact_digest_invalid")
+    normalized = {
+        "schema_version": 1,
+        "plugin_uid": plugin_uid,
+        "name": name,
+        "version": version,
+        "api_version": "1",
+        "type": plugin_type,
+        "capabilities": list(normalized_capabilities),
+        "permissions": dict.fromkeys(sorted(_PERMISSIONS), False),
+        "resource": normalized_resource,
+        "compatibility": {"platform_api": "1"},
+        "distribution": {
+            "kind": "builtin_fixture",
+            "fixture_id": "ENGINEERING_EVIDENCE_ONLY",
+            "artifact_digest": artifact_digest,
+        },
+    }
+    normalized["manifest_digest"] = canonical_digest(normalized)
+    return normalized
+
+
+__all__ = ["PluginManifestError", "canonical_digest", "fixture_signature_digest", "normalize_plugin_manifest"]

+ 113 - 0
app/core/plugins/persistence.py

@@ -0,0 +1,113 @@
+"""Database adapters for the fixed WP13 control and runtime gateways."""
+
+from __future__ import annotations
+
+import json
+import os
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+from app.core.mcp.governed_invocation import normalize_mcp_invocation
+
+from .governance import fixture_signature_digest, normalize_plugin_manifest
+from .runtime import BuiltinFixtureDispatcher
+
+
+class PluginPersistenceError(ValueError):
+    """The persistent gateway rejected a closed plugin request."""
+
+
+def _digest(value: Any, label: str) -> str:
+    if not isinstance(value, str) or len(value) != 64 or set(value) - set("0123456789abcdef"):
+        raise PluginPersistenceError(f"{label}_invalid")
+    return value
+
+
+class DatabasePluginPlatformService:
+    """Uses only fixed SECURITY DEFINER functions; never direct fact SQL."""
+
+    def __init__(self) -> None:
+        self._runtime_url = os.environ.get("DATABASE_URL", "")
+        self._control_url = os.environ.get("PLUGIN_PLATFORM_CONTROL_DATABASE_URL", os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", ""))
+        runtime = validate_postgresql_url(self._runtime_url, "DATABASE_URL")
+        control = validate_postgresql_url(self._control_url, "PLUGIN_PLATFORM_CONTROL_DATABASE_URL")
+        if runtime.username == control.username:
+            raise RuntimeError("plugin control and runtime identities must differ")
+
+    @staticmethod
+    def _scope() -> dict[str, str]:
+        tenant = os.environ.get("TRUSTED_PLUGIN_TENANT", "")
+        domain = os.environ.get("TRUSTED_PLUGIN_DOMAIN", "")
+        if not tenant or not domain or not tenant.isascii() or not domain.isascii():
+            raise PluginPersistenceError("trusted_plugin_scope_missing")
+        return {"tenant_ref": tenant, "domain_ref": domain}
+
+    def _control(self, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(text("SELECT public.plugin_platform_control_v5(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))}).scalar_one()
+        return dict(value)
+
+    def _claim(self, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(text("SELECT public.plugin_platform_issue_claim_v3(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))}).scalar_one()
+        return dict(value)
+
+    def _runtime(self, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(text("SELECT public.plugin_platform_runtime_v3(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))}).scalar_one()
+        return dict(value)
+
+    def register(self, *, manifest: Any, registry_record: Any, actor_ref: str) -> dict[str, Any]:
+        normalized = normalize_plugin_manifest(manifest)
+        if not isinstance(registry_record, dict) or set(registry_record) != {"artifact_digest", "signature", "sbom_digest", "license_digest", "vulnerability_digest", "provenance_digest"}:
+            raise PluginPersistenceError("registry_record_closed")
+        signature = registry_record["signature"]
+        if not isinstance(signature, dict) or set(signature) != {"trust_store_key_id", "signature_digest"} or signature["trust_store_key_id"] != "local-fixture-key-v1":
+            raise PluginPersistenceError("trust_store_denied")
+        payload = {
+            "action": "register", "plugin_uid": normalized["plugin_uid"], "version": normalized["version"], "actor_ref": actor_ref,
+            "plugin_type": normalized["type"], "manifest_digest": normalized["manifest_digest"],
+            "artifact_digest": _digest(registry_record["artifact_digest"], "artifact_digest"),
+            "signature_digest": _digest(signature["signature_digest"], "signature_digest"),
+            "sbom_digest": _digest(registry_record["sbom_digest"], "sbom_digest"), "license_digest": _digest(registry_record["license_digest"], "license_digest"),
+            "vulnerability_digest": _digest(registry_record["vulnerability_digest"], "vulnerability_digest"), "provenance_digest": _digest(registry_record["provenance_digest"], "provenance_digest"),
+            "capabilities": normalized["capabilities"], "resource": normalized["resource"],
+        }
+        if payload["artifact_digest"] != normalized["distribution"]["artifact_digest"]:
+            raise PluginPersistenceError("artifact_digest_mismatch")
+        if payload["signature_digest"] != fixture_signature_digest(payload["artifact_digest"]):
+            raise PluginPersistenceError("signature_binding_denied")
+        return self._control(payload)
+
+    def review(self, *, plugin_uid: str, version: str, actor_ref: str) -> dict[str, Any]:
+        return self._control({"action": "review", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref})
+
+    def issue_approval(self, *, plugin_uid: str, version: str, actor_ref: str, approval_action: str) -> dict[str, Any]:
+        return self._control({"action": "issue_approval", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref, "approval_action": approval_action, **self._scope(), "expires_in_seconds": 300})
+
+    def transition(self, *, plugin_uid: str, version: str, actor_ref: str, target_state: str, approval_uid: str, expected_fence: int, incident_uid: str = "") -> dict[str, Any]:
+        if not isinstance(expected_fence, int) or expected_fence < 0:
+            raise PluginPersistenceError("expected_fence_invalid")
+        return self._control({"action": "transition", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref, **self._scope(), "approval_uid": approval_uid, "target_state": target_state, "expected_fence": expected_fence, "incident_uid": incident_uid})
+
+    def invoke(self, *, plugin_uid: str, version: str, actor_ref: str, operation: str, input_digest: str, idempotency_key: str) -> dict[str, Any]:
+        _digest(input_digest, "input_digest")
+        if not isinstance(idempotency_key, str) or not idempotency_key.isascii() or not 1 <= len(idempotency_key) <= 120:
+            raise PluginPersistenceError("idempotency_key_invalid")
+        scope = self._scope()
+        description = self._control({"action": "describe", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref})
+        if description["plugin_type"] == "agent_mcp":
+            normalize_mcp_invocation({"interface_type": "mcp", "tool_name": "governed_plugin_fixture", "action": operation, "arguments_digest": input_digest, "evidence_refs": []})
+        claim = self._claim({"plugin_uid": plugin_uid, "version": version, "principal_ref": actor_ref, "operation_name": operation, "input_digest": input_digest, "idempotency_key": idempotency_key, **scope})
+        queued = self._runtime({"action": "enqueue", "claim_uid": claim["claim_uid"], "idempotency_key": idempotency_key, "input_digest": input_digest, "operation_name": operation})
+        lease = self._runtime({"action": "claim", "run_uid": queued["run_uid"], "worker": "fixed-builtin"})
+        fixture_manifest = {"distribution": {"kind": "builtin_fixture", "fixture_id": "ENGINEERING_EVIDENCE_ONLY"}, "permissions": {"child_process": False, "file": False, "network": False, "secret": False}, "type": description["plugin_type"], "capabilities": description["capabilities"], "resource": description["resource"], "manifest_digest": description["manifest_digest"]}
+        result = BuiltinFixtureDispatcher().execute(fixture_manifest, operation=operation, input_digest=input_digest)
+        settled = self._runtime({"action": "settle", "run_uid": queued["run_uid"], "worker": "fixed-builtin", "fence": lease["fence"], "success": True, "output_digest": result["output_digest"], "failure_digest": "0" * 64})
+        return {"run_uid": queued["run_uid"], **result, **settled}
+
+
+__all__ = ["DatabasePluginPlatformService", "PluginPersistenceError"]

+ 190 - 0
app/core/plugins/repository.py

@@ -0,0 +1,190 @@
+"""In-memory reference behavior for the fixed WP13 fixture dispatcher.
+
+The production persistence boundary is supplied by the WP13 PostgreSQL gateway.
+This small adapter exists for deterministic unit contracts; it never loads or
+executes a submitted artifact.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import threading
+import uuid
+from collections.abc import Callable
+from typing import Any
+
+from .governance import (
+    PluginManifestError,
+    canonical_digest,
+    fixture_signature_digest,
+    normalize_plugin_manifest,
+)
+
+
+class PluginLifecycleError(ValueError):
+    """A lifecycle transition, approval, registry record or invocation was denied."""
+
+
+_RECORD = frozenset(
+    {"artifact_digest", "signature", "sbom_digest", "license_digest", "vulnerability_digest", "provenance_digest"}
+)
+_SIGNATURE = frozenset({"trust_store_key_id", "signature_digest"})
+_TRUST_STORE = frozenset({"local-fixture-key-v1"})
+_HEX = frozenset("0123456789abcdef")
+_ACTIONS = frozenset({"activate", "pause", "rollback", "revoke", "recover"})
+
+
+def _digest(value: Any, label: str) -> str:
+    if not isinstance(value, str) or len(value) != 64 or set(value) - _HEX:
+        raise PluginLifecycleError(f"{label}_invalid")
+    return value
+
+
+def _closed(value: Any, keys: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict) or set(value) != keys:
+        raise PluginLifecycleError(f"{label}_closed")
+    return copy.deepcopy(value)
+
+
+def _scope(value: Any, *, principal: bool) -> dict[str, str]:
+    keys = {"tenant_id", "domain"} | ({"principal_id"} if principal else set())
+    if not isinstance(value, dict) or set(value) != keys:
+        raise PluginLifecycleError("scope_closed")
+    normalized: dict[str, str] = {}
+    for key in keys:
+        item = value[key]
+        if not isinstance(item, str) or not item.isascii() or not 1 <= len(item) <= 120:
+            raise PluginLifecycleError("scope_invalid")
+        normalized[key] = item
+    return normalized
+
+
+class PluginPlatform:
+    """Thread-safe local state machine around one fixed evidence fixture."""
+
+    def __init__(self, *, now: Callable[[], int]) -> None:
+        self._now = now
+        self._lock = threading.RLock()
+        self._versions: dict[tuple[str, str], dict[str, Any]] = {}
+        self._approvals: dict[str, dict[str, Any]] = {}
+        self._runs: dict[tuple[str, str, str, str], dict[str, Any]] = {}
+
+    def register(self, manifest: Any, *, registry_record: Any) -> dict[str, Any]:
+        try:
+            normalized = normalize_plugin_manifest(manifest)
+        except PluginManifestError as exc:
+            raise PluginLifecycleError(str(exc)) from exc
+        record = _closed(registry_record, _RECORD, "registry_record")
+        signature = _closed(record["signature"], _SIGNATURE, "signature")
+        if signature["trust_store_key_id"] not in _TRUST_STORE:
+            raise PluginLifecycleError("trust_store_key_denied")
+        normalized_record = {
+            "artifact_digest": _digest(record["artifact_digest"], "artifact_digest"),
+            "signature": {
+                "trust_store_key_id": signature["trust_store_key_id"],
+                "signature_digest": _digest(signature["signature_digest"], "signature_digest"),
+            },
+            "sbom_digest": _digest(record["sbom_digest"], "sbom_digest"),
+            "license_digest": _digest(record["license_digest"], "license_digest"),
+            "vulnerability_digest": _digest(record["vulnerability_digest"], "vulnerability_digest"),
+            "provenance_digest": _digest(record["provenance_digest"], "provenance_digest"),
+        }
+        if normalized_record["artifact_digest"] != normalized["distribution"]["artifact_digest"]:
+            raise PluginLifecycleError("artifact_digest_mismatch")
+        if normalized_record["signature"]["signature_digest"] != fixture_signature_digest(normalized_record["artifact_digest"]):
+            raise PluginLifecycleError("signature_binding_denied")
+        key = (normalized["plugin_uid"], normalized["version"])
+        with self._lock:
+            if key in self._versions:
+                raise PluginLifecycleError("plugin_version_exists")
+            item = normalized | {"state": "draft", "registry": normalized_record, "reviewer_id": None}
+            self._versions[key] = item
+            return copy.deepcopy(item)
+
+    def review(self, plugin_uid: str, version: str, *, reviewer_id: str) -> dict[str, Any]:
+        if not isinstance(reviewer_id, str) or not reviewer_id.isascii() or not reviewer_id:
+            raise PluginLifecycleError("reviewer_invalid")
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            if item["state"] != "draft":
+                raise PluginLifecycleError("review_transition_denied")
+            item["state"] = "reviewed"
+            item["reviewer_id"] = reviewer_id
+            return copy.deepcopy(item)
+
+    def issue_approval(self, *, plugin_uid: str, version: str, action: str, actor_id: str, reviewer_id: str, scope: Any, expires_at: int) -> dict[str, Any]:
+        if action not in _ACTIONS or not isinstance(actor_id, str) or not isinstance(reviewer_id, str) or actor_id == reviewer_id:
+            raise PluginLifecycleError("approval_independence_denied")
+        if not isinstance(expires_at, int) or expires_at <= self._now():
+            raise PluginLifecycleError("approval_expiry_invalid")
+        bound_scope = _scope(scope, principal=False)
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            if (
+                item["state"] != "reviewed"
+                or item["reviewer_id"] != reviewer_id
+                or item["reviewer_id"] == actor_id
+            ):
+                raise PluginLifecycleError("approval_review_denied")
+            approval = {
+                "approval_id": str(uuid.uuid4()), "plugin_uid": plugin_uid, "version": version,
+                "action": action, "actor_id": actor_id, "reviewer_id": reviewer_id,
+                "scope": bound_scope, "manifest_digest": item["manifest_digest"],
+                "expires_at": expires_at, "consumed": False,
+            }
+            self._approvals[approval["approval_id"]] = approval
+            return copy.deepcopy(approval)
+
+    def activate(self, plugin_uid: str, version: str, *, actor_id: str, scope: Any, approval_id: str) -> dict[str, Any]:
+        bound_scope = _scope(scope, principal=False)
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            approval = self._approvals.get(approval_id)
+            if not approval or approval["consumed"] or approval["expires_at"] <= self._now() or approval["action"] != "activate" or approval["actor_id"] != actor_id or approval["reviewer_id"] != item["reviewer_id"] or approval["scope"] != bound_scope or approval["manifest_digest"] != item["manifest_digest"]:
+                raise PluginLifecycleError("approval_binding_denied")
+            if item["state"] != "reviewed":
+                raise PluginLifecycleError("activation_transition_denied")
+            if any(candidate["state"] == "active" for (uid, _), candidate in self._versions.items() if uid == plugin_uid):
+                raise PluginLifecycleError("plugin_active_collision")
+            approval["consumed"] = True
+            item["state"] = "active"
+            return copy.deepcopy(item)
+
+    def invoke(self, *, plugin_uid: str, version: str, operation: str, scope: Any, input_digest: str, idempotency_key: str) -> dict[str, Any]:
+        invocation_scope = _scope(scope, principal=True)
+        digest = _digest(input_digest, "input_digest")
+        if not isinstance(idempotency_key, str) or not idempotency_key.isascii() or not 1 <= len(idempotency_key) <= 120:
+            raise PluginLifecycleError("idempotency_key_invalid")
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            if item["state"] != "active":
+                raise PluginLifecycleError("plugin_not_active")
+            if operation not in item["capabilities"]:
+                raise PluginLifecycleError("capability_denied")
+            key = (plugin_uid, version, invocation_scope["tenant_id"], idempotency_key)
+            replay = self._runs.get(key)
+            request = {"scope": invocation_scope, "input_digest": digest, "operation": operation}
+            request_digest = canonical_digest(request)
+            if replay:
+                if replay["request_digest"] != request_digest:
+                    raise PluginLifecycleError("idempotency_conflict")
+                return copy.deepcopy(replay["result"] | {"replay": True})
+            output_digest = hashlib.sha256(
+                f"ENGINEERING_EVIDENCE_ONLY|{item['manifest_digest']}|{request_digest}".encode("ascii")
+            ).hexdigest()
+            result = {
+                "plugin_uid": plugin_uid, "version": version, "run_digest": request_digest,
+                "output_digest": output_digest, "fixture_id": "ENGINEERING_EVIDENCE_ONLY", "replay": False,
+            }
+            self._runs[key] = {"request_digest": request_digest, "result": result}
+            return copy.deepcopy(result)
+
+    def _version(self, plugin_uid: str, version: str) -> dict[str, Any]:
+        item = self._versions.get((plugin_uid, version))
+        if item is None:
+            raise PluginLifecycleError("plugin_version_not_found")
+        return item
+
+
+__all__ = ["PluginLifecycleError", "PluginPlatform"]

+ 56 - 0
app/core/plugins/runtime.py

@@ -0,0 +1,56 @@
+"""Fixed, local-only plugin handlers and execution guard.
+
+No submitted artifact is imported or evaluated.  The mapping below is the
+complete executable surface for the engineering fixture baseline.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import time
+from typing import Any
+
+
+class PluginExecutionError(ValueError):
+    """A requested invocation cannot pass the fixed execution boundary."""
+
+
+_HANDLERS = {
+    "connector": frozenset({"discover", "snapshot", "evidence"}),
+    "parser": frozenset({"parse", "evidence"}),
+    "quality": frozenset({"evaluate", "evidence"}),
+    "notification": frozenset({"prepare", "evidence"}),
+    "approval": frozenset({"evaluate", "evidence"}),
+    "agent_mcp": frozenset({"read", "suggest", "evidence"}),
+}
+
+
+class BuiltinFixtureDispatcher:
+    """Deterministic hash-only handler for the six fixed plugin categories."""
+
+    def execute(self, manifest: dict[str, Any], *, operation: str, input_digest: str) -> dict[str, Any]:
+        if not isinstance(manifest, dict) or manifest.get("distribution", {}).get("kind") != "builtin_fixture" or manifest.get("distribution", {}).get("fixture_id") != "ENGINEERING_EVIDENCE_ONLY":
+            raise PluginExecutionError("execution_fixture_denied")
+        permissions = manifest.get("permissions")
+        if permissions != {"child_process": False, "file": False, "network": False, "secret": False}:
+            raise PluginExecutionError("execution_permissions_denied")
+        plugin_type = manifest.get("type")
+        if plugin_type not in _HANDLERS or operation not in _HANDLERS[plugin_type] or operation not in manifest.get("capabilities", []):
+            raise PluginExecutionError("execution_capability_denied")
+        if not isinstance(input_digest, str) or len(input_digest) != 64 or set(input_digest) - set("0123456789abcdef"):
+            raise PluginExecutionError("execution_input_digest_invalid")
+        resource = manifest.get("resource")
+        if not isinstance(resource, dict) or set(resource) != {"timeout_ms", "max_output_bytes", "max_concurrency", "max_retries"}:
+            raise PluginExecutionError("execution_resource_denied")
+        if any(isinstance(value, bool) or not isinstance(value, int) for value in resource.values()) or not 1 <= resource["timeout_ms"] <= 5000 or not 64 <= resource["max_output_bytes"] <= 65536 or not 1 <= resource["max_concurrency"] <= 1 or not 1 <= resource["max_retries"] <= 3:
+            raise PluginExecutionError("execution_resource_denied")
+        started = time.monotonic_ns()
+        output_digest = hashlib.sha256(
+            f"ENGINEERING_EVIDENCE_ONLY|{plugin_type}|{operation}|{manifest.get('manifest_digest')}|{input_digest}".encode("ascii")
+        ).hexdigest()
+        if len(output_digest.encode("ascii")) > resource["max_output_bytes"] or (time.monotonic_ns() - started) > resource["timeout_ms"] * 1_000_000:
+            raise PluginExecutionError("execution_resource_exceeded")
+        return {"output_digest": output_digest, "fixture_id": "ENGINEERING_EVIDENCE_ONLY", "provider_enabled": False}
+
+
+__all__ = ["BuiltinFixtureDispatcher", "PluginExecutionError"]

+ 59 - 11
app/core/system/permissions.py

@@ -79,6 +79,10 @@ CONNECTORS_MANAGE = "connectors:manage"
 EDGE_GATEWAYS_READ = "edge-gateways:read"
 EDGE_GATEWAYS_OPERATE = "edge-gateways:operate"
 EDGE_GATEWAYS_MANAGE = "edge-gateways:manage"
+BI_AI_CATALOG_READ = "bi-ai-catalog:read"
+BI_AI_CATALOG_MANAGE = "bi-ai-catalog:manage"
+METERING_READ = "metering:read"
+METERING_MANAGE = "metering:manage"
 
 ROLE_PERMISSIONS = {
     "viewer": frozenset(
@@ -96,6 +100,8 @@ ROLE_PERMISSIONS = {
             IDENTITY_READ,
             CONNECTORS_READ,
             EDGE_GATEWAYS_READ,
+            BI_AI_CATALOG_READ,
+            METERING_READ,
         }
     ),
     "editor": frozenset(
@@ -139,6 +145,8 @@ ROLE_PERMISSIONS = {
             CONNECTORS_OPERATE,
             EDGE_GATEWAYS_READ,
             EDGE_GATEWAYS_OPERATE,
+            BI_AI_CATALOG_READ,
+            METERING_READ,
         }
     ),
     "admin": frozenset(
@@ -215,6 +223,10 @@ ROLE_PERMISSIONS = {
             EDGE_GATEWAYS_READ,
             EDGE_GATEWAYS_OPERATE,
             EDGE_GATEWAYS_MANAGE,
+            BI_AI_CATALOG_READ,
+            BI_AI_CATALOG_MANAGE,
+            METERING_READ,
+            METERING_MANAGE,
         }
     ),
 }
@@ -255,7 +267,11 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
             return (EDGE_GATEWAYS_MANAGE,)
         if path == "/api/datasource/edge/tasks" and method == "POST":
             return (EDGE_GATEWAYS_OPERATE,)
-        if path.startswith("/api/datasource/edge/tasks/") and path.endswith("/cancel") and method == "POST":
+        if (
+            path.startswith("/api/datasource/edge/tasks/")
+            and path.endswith("/cancel")
+            and method == "POST"
+        ):
             return (EDGE_GATEWAYS_OPERATE,)
         if method == "GET":
             return (EDGE_GATEWAYS_READ,)
@@ -263,7 +279,10 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
     if path.startswith("/api/system/identity"):
         if path == "/api/system/identity/logout" and method == "POST":
             return (IDENTITY_READ,)
-        if path in {"/api/system/identity/idp-versions", "/api/system/identity/audit"} and method == "GET":
+        if (
+            path in {"/api/system/identity/idp-versions", "/api/system/identity/audit"}
+            and method == "GET"
+        ):
             return (IDENTITY_MANAGE,)
         if path == "/api/system/identity/sessions" and method == "GET":
             return (IDENTITY_OPERATE,)
@@ -272,6 +291,16 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
         if any(marker in path for marker in ("/idp-versions", "/emergency/")):
             return (IDENTITY_MANAGE,)
         return (IDENTITY_OPERATE,)
+    if path.startswith("/api/system/tenant/"):
+        return (IDENTITY_OPERATE,)
+    if path.startswith("/api/system/bi-ai-catalog/"):
+        return (
+            (BI_AI_CATALOG_READ,)
+            if method == "GET" or path.endswith("/search")
+            else (BI_AI_CATALOG_MANAGE,)
+        )
+    if path.startswith("/api/system/metering/"):
+        return (METERING_READ,) if method == "GET" else (METERING_MANAGE,)
     if path.startswith("/api/datasource/connectors"):
         if "/source-bindings" in path:
             return (CONNECTORS_MANAGE,)
@@ -322,16 +351,37 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
         ):
             return (SECURITY_GOVERNANCE_MANAGE,)
         return (SECURITY_GOVERNANCE_OPERATE,)
+    if path.startswith("/api/system/trusted-delivery"):
+        if path.startswith("/api/system/trusted-delivery/controls/"):
+            if method == "GET":
+                return (SECURITY_GOVERNANCE_READ,)
+            if any(
+                marker in path
+                for marker in (
+                    "/profiles/activate",
+                    "/profiles/rollback",
+                    "/capability-approvals",
+                    "/destruction-approvals",
+                )
+            ):
+                return (SECURITY_GOVERNANCE_MANAGE,)
+            return (SECURITY_GOVERNANCE_OPERATE,)
+        if "/legal-holds" in path or "/reclaim/" in path:
+            return (SECURITY_GOVERNANCE_MANAGE,)
+        return (SECURITY_GOVERNANCE_OPERATE,)
     if path.startswith("/api/dataservice/governance"):
         if method == "GET":
             return (DATA_PRODUCTS_READ,)
-        if any(
-            marker in path
-            for marker in (
-                "/reconcile",
-                "/fulfill",
+        if (
+            any(
+                marker in path
+                for marker in (
+                    "/reconcile",
+                    "/fulfill",
+                )
             )
-        ) or path == "/api/dataservice/governance/products":
+            or path == "/api/dataservice/governance/products"
+        ):
             return (DATA_PRODUCTS_MANAGE,)
         return (DATA_PRODUCTS_OPERATE,)
     if path.startswith("/api/knowledge/agents"):
@@ -435,9 +485,7 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
     if path.startswith("/api/development/v1/device-quality"):
         if method == "GET":
             return (READ_GOVERNANCE,)
-        if path.startswith(
-            "/api/development/v1/device-quality/issues"
-        ):
+        if path.startswith("/api/development/v1/device-quality/issues"):
             if path.endswith("/review"):
                 return (QUALITY_ISSUES_REVIEW,)
             return (QUALITY_ISSUES_EDIT,)

+ 34 - 0
app/core/system/tenant_approval_repository.py

@@ -0,0 +1,34 @@
+"""Dedicated, independent database identity for lifecycle approval facts."""
+
+from __future__ import annotations
+
+import json
+import os
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+
+
+class SqlAlchemyTenantApprovalRepository:
+    def __init__(self, database_url: str | None = None) -> None:
+        url = database_url or os.environ.get("TENANT_APPROVER_DATABASE_URL", "")
+        validate_postgresql_url(url, "TENANT_APPROVER_DATABASE_URL")
+        self.engine = create_engine(url, poolclass=NullPool, pool_pre_ping=True)
+
+    def issue(self, *, payload: dict[str, Any]) -> dict[str, Any]:
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_approver_issue(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            code = getattr(getattr(exc, "orig", None), "pgcode", "unknown")
+            raise ValueError(f"tenant_approval_denied:{code}") from exc
+        finally:
+            self.engine.dispose()

+ 130 - 0
app/core/system/tenant_context.py

@@ -0,0 +1,130 @@
+"""Closed, server-derived tenant scope for the conditional WP10 foundation."""
+
+from __future__ import annotations
+
+import re
+from collections.abc import Mapping
+from dataclasses import dataclass
+from enum import StrEnum
+
+
+class TenantContextError(ValueError):
+    """A tenant boundary was absent, unapproved, or contradicted by input."""
+
+
+class DeliveryMode(StrEnum):
+    PRIVATE_SINGLE_TENANT = "private_single_tenant"
+    SHARED_CONTROL_PLANE = "shared_control_plane"
+    SAAS = "saas"
+
+
+_TENANT_ID = re.compile(r"^[a-z][a-z0-9-]{0,62}$")
+_HOST = re.compile(r"^[a-z0-9][a-z0-9.-]{0,252}$")
+_EVENT_TYPE = re.compile(r"^[a-z][a-z0-9_.-]{0,80}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+
+
+def _tenant_id(value: str) -> str:
+    if not isinstance(value, str) or not _TENANT_ID.fullmatch(value):
+        raise TenantContextError("tenant_scope_denied")
+    return value
+
+
+@dataclass(frozen=True)
+class TenantScope:
+    tenant_id: str
+    mode: DeliveryMode
+    version: int = 1
+
+    def __post_init__(self) -> None:
+        _tenant_id(self.tenant_id)
+        if self.version != 1:
+            raise TenantContextError("tenant_context_version_denied")
+
+    def require_background_scope(self, declared_tenant_id: str | None) -> str:
+        if declared_tenant_id is None:
+            raise TenantContextError("tenant_scope_required")
+        if _tenant_id(declared_tenant_id) != self.tenant_id:
+            raise TenantContextError("tenant_scope_denied")
+        return self.tenant_id
+
+    def require_admin_scope(self, declared_tenant_id: str | None) -> str:
+        return self.require_background_scope(declared_tenant_id)
+
+
+TenantContext = TenantScope
+
+
+def validate_tenant_event_envelope(scope: TenantScope, envelope: Mapping[str, object]) -> dict[str, object]:
+    """Reject task/event dispatch unless its scope is explicit and server-matched."""
+    required = {"schema_version", "tenant_id", "event_type", "payload_digest"}
+    if set(envelope) - required:
+        raise TenantContextError("tenant_event_closed")
+    tenant_id = envelope.get("tenant_id")
+    if tenant_id is None:
+        raise TenantContextError("tenant_scope_required")
+    if set(envelope) != required:
+        raise TenantContextError("tenant_event_closed")
+    if not isinstance(tenant_id, str) or _tenant_id(tenant_id) != scope.tenant_id:
+        raise TenantContextError("tenant_scope_denied")
+    if envelope.get("schema_version") != 1 or not isinstance(envelope.get("event_type"), str) or not _EVENT_TYPE.fullmatch(envelope["event_type"]):
+        raise TenantContextError("tenant_event_closed")
+    if not isinstance(envelope.get("payload_digest"), str) or not _DIGEST.fullmatch(envelope["payload_digest"]):
+        raise TenantContextError("tenant_event_closed")
+    return dict(envelope)
+
+
+class TenantContextResolver:
+    """Resolve scope only from server-held delivery configuration and host mapping."""
+
+    def __init__(
+        self,
+        *,
+        mode: DeliveryMode,
+        approved_default_tenant: str | None,
+        route_tenants: Mapping[str, str],
+        activated_modes: frozenset[DeliveryMode] | None = None,
+    ) -> None:
+        self.mode = DeliveryMode(mode)
+        self.approved_default_tenant = (
+            _tenant_id(approved_default_tenant)
+            if approved_default_tenant is not None
+            else None
+        )
+        self.route_tenants = {
+            self._host(host): _tenant_id(tenant_id)
+            for host, tenant_id in route_tenants.items()
+        }
+        self.activated_modes = activated_modes or frozenset(
+            {DeliveryMode.PRIVATE_SINGLE_TENANT}
+        )
+
+    @staticmethod
+    def _host(host: str) -> str:
+        if not isinstance(host, str) or not _HOST.fullmatch(host.lower()):
+            raise TenantContextError("tenant_route_denied")
+        return host.lower()
+
+    def resolve_request(
+        self,
+        *,
+        host: str,
+        claimed_tenant_id: str | None,
+        principal_id: str,
+    ) -> TenantContext:
+        if not isinstance(principal_id, str) or not principal_id:
+            raise TenantContextError("tenant_principal_required")
+        if self.mode not in self.activated_modes:
+            raise TenantContextError("delivery_mode_not_approved")
+        self._host(host)
+        if self.mode is DeliveryMode.PRIVATE_SINGLE_TENANT:
+            if self.approved_default_tenant is None:
+                raise TenantContextError("tenant_default_not_approved")
+            # Client claim is intentionally ignored: it never selects a tenant.
+            return TenantContext(self.approved_default_tenant, self.mode)
+        resolved = self.route_tenants.get(self._host(host))
+        if resolved is None:
+            raise TenantContextError("tenant_route_denied")
+        if claimed_tenant_id is not None and _tenant_id(claimed_tenant_id) != resolved:
+            raise TenantContextError("tenant_spoof_denied")
+        return TenantContext(resolved, self.mode)

+ 149 - 0
app/core/system/tenant_control_repository.py

@@ -0,0 +1,149 @@
+"""Dedicated control-identity repository for tenant claims.
+
+This intentionally does not use the shared application SQLAlchemy session:
+the separate connection must authenticate as a member of
+``dataops_tenant_control``.  If that deployment input is absent, the route is
+unavailable rather than falling back to the shared runtime login.
+"""
+
+from __future__ import annotations
+
+import json
+import os
+import uuid
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+from app.core.system.tenant_control_service import TenantControlError
+
+
+class SqlAlchemyTenantControlRepository:
+    def __init__(self, database_url: str | None = None) -> None:
+        url = database_url or os.environ.get("TENANT_CONTROL_DATABASE_URL", "")
+        validate_postgresql_url(url, "TENANT_CONTROL_DATABASE_URL")
+        self.engine = create_engine(url, poolclass=NullPool, pool_pre_ping=True)
+
+    def issue_claim(
+        self,
+        *,
+        principal_id: str,
+        host: str,
+        action: str,
+        request: dict[str, Any],
+    ) -> dict[str, Any]:
+        payload = {
+            "claim_uid": str(uuid.uuid4()),
+            "nonce": str(uuid.uuid4()),
+            "principal_id": principal_id,
+            "host": host.lower(),
+            "action": action,
+            "request": request,
+        }
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_control_issue_claim(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_control_claim_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def provision(self, *, tenant_id: str, principal_id: str, host: str, idempotency_key: str) -> dict[str, Any]:
+        payload = {"tenant_id": tenant_id, "principal_id": principal_id, "host": host.lower(), "idempotency_key": idempotency_key}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_control_provision(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            code = getattr(getattr(exc, "orig", None), "pgcode", "unknown")
+            raise TenantControlError(f"tenant_control_provision_denied:{code}") from exc
+        finally:
+            self.engine.dispose()
+
+    def lifecycle_transition(
+        self, *, principal_id: str, host: str, operation: str, request: dict[str, Any]
+    ) -> dict[str, Any]:
+        claim_payload = {
+            "claim_uid": str(uuid.uuid4()),
+            "nonce": str(uuid.uuid4()),
+            "principal_id": principal_id,
+            "host": host.lower(),
+            "action": "lifecycle_transition",
+            "request": request,
+        }
+        try:
+            with self.engine.begin() as connection:
+                connection.execute(
+                    text("SELECT public.tenant_control_issue_claim(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(claim_payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+                value = connection.execute(
+                    text("SELECT public.tenant_control_lifecycle_approved_mutate(CAST(:claim_uid AS uuid),CAST(:nonce AS uuid),CAST(:request AS jsonb))"),
+                    {
+                        "claim_uid": claim_payload["claim_uid"],
+                        "nonce": claim_payload["nonce"],
+                        "request": json.dumps(request, sort_keys=True, separators=(",", ":"), ensure_ascii=True),
+                    },
+                ).scalar_one()
+            return {**dict(value), "request": request}
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_lifecycle_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def read(self, *, principal_id: str, host: str, kind: str) -> dict[str, Any]:
+        functions = {
+            "status": "tenant_control_read_state",
+            "audit": "tenant_control_read_audit",
+            "manifests": "tenant_control_read_manifests",
+        }
+        function = functions.get(kind)
+        if function is None:
+            raise TenantControlError("tenant_read_denied")
+        payload = {"principal_id": principal_id, "host": host.lower()}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text(f"SELECT public.{function}(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_read_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def claim_outbox(self, *, outbox_uid: str, worker_id: str, lease_seconds: str = "30") -> dict[str, Any]:
+        payload = {"outbox_uid": outbox_uid, "worker_id": worker_id, "lease_seconds": lease_seconds}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_control_worker_claim(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_worker_scope_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def settle_outbox(self, *, outbox_uid: str, worker_id: str, lease_fence: int, payload_digest: str, outcome: str) -> dict[str, Any]:
+        payload = {"outbox_uid": outbox_uid, "worker_id": worker_id, "lease_fence": str(lease_fence), "payload_digest": payload_digest, "outcome": outcome}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(text("SELECT public.tenant_control_worker_settle(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)}).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_worker_settle_denied") from exc
+        finally:
+            self.engine.dispose()

+ 160 - 0
app/core/system/tenant_control_service.py

@@ -0,0 +1,160 @@
+"""Authenticated application boundary for tenant-control claims."""
+
+from __future__ import annotations
+
+import os
+import uuid
+from typing import Any
+
+from app.core.system.tenant_approval_repository import (
+    SqlAlchemyTenantApprovalRepository,
+)
+from app.core.system.tenant_context import (
+    DeliveryMode,
+    TenantScope,
+    validate_tenant_event_envelope,
+)
+from app.core.system.tenant_resources import build_tenant_namespace
+
+
+class TenantControlError(ValueError):
+    pass
+
+
+class TenantControlService:
+    _REQUEST_FIELDS = frozenset({"quota_name", "amount", "idempotency_key"})
+    _LIFECYCLE_FIELDS = frozenset({"expected_fence", "idempotency_key", "approval_ref", "backup_digest", "retention_seconds"})
+    _LIFECYCLE_OPERATIONS = frozenset({"activate", "freeze", "begin_recovery", "mark_deletion_candidate", "rollback", "delete"})
+
+    def __init__(self, repository: Any) -> None:
+        self.repository = repository
+
+    def provision_private(self, *, principal_id: str, host: str, request: dict[str, Any]) -> dict[str, Any]:
+        if set(request) != {"idempotency_key"} or not isinstance(request.get("idempotency_key"), str):
+            raise TenantControlError("tenant_payload_closed")
+        tenant_id = os.environ.get("PRIVATE_SINGLE_TENANT_ID", "")
+        trusted_host = os.environ.get("PRIVATE_SINGLE_TENANT_HOST", "").lower()
+        if not tenant_id or not trusted_host:
+            raise TenantControlError("tenant_default_not_approved")
+        return self.repository.provision(
+            tenant_id=tenant_id,
+            principal_id=principal_id,
+            host=trusted_host,
+            idempotency_key=request["idempotency_key"],
+        )
+
+    def issue_quota_claim(self, *, principal_id: str, host: str, request: dict[str, Any]) -> dict[str, Any]:
+        if set(request) != self._REQUEST_FIELDS:
+            raise TenantControlError("tenant_payload_closed")
+        if not isinstance(principal_id, str) or not principal_id or not isinstance(host, str) or not host:
+            raise TenantControlError("tenant_identity_required")
+        claim = self.repository.issue_claim(
+            principal_id=principal_id,
+            host=host,
+            action="quota_reserve",
+            request=request,
+        )
+        # This is the actual HTTP-service propagation point: the tenant is
+        # returned only after the database has matched principal+route, then
+        # copied into closed task/event and external-store namespace contracts.
+        tenant_id = claim.get("tenant_id")
+        digest = claim.get("request_digest")
+        if isinstance(tenant_id, str) and isinstance(digest, str):
+            scope = TenantScope(tenant_id, DeliveryMode.PRIVATE_SINGLE_TENANT)
+            event = validate_tenant_event_envelope(
+                scope,
+                {"schema_version": 1, "tenant_id": tenant_id, "event_type": "tenant.quota.claim", "payload_digest": digest},
+            )
+            claim["propagation"] = {
+                "task": event,
+                "event": event,
+                "namespaces": {
+                    resource: build_tenant_namespace(scope, resource, "quota-claim")
+                    for resource in ("object", "graph", "cache", "index")
+                },
+            }
+        return claim
+
+    def lifecycle_transition(
+        self, *, principal_id: str, host: str, operation: str, request: dict[str, Any]
+    ) -> dict[str, Any]:
+        if operation not in self._LIFECYCLE_OPERATIONS or not isinstance(request, dict):
+            raise TenantControlError("tenant_payload_closed")
+        if not set(request).issubset(self._LIFECYCLE_FIELDS) or set(request) < {"expected_fence", "idempotency_key"}:
+            raise TenantControlError("tenant_payload_closed")
+        if not isinstance(request["expected_fence"], str) or not isinstance(request["idempotency_key"], str):
+            raise TenantControlError("tenant_payload_closed")
+        normalized = {
+            "operation": operation,
+            "expected_fence": request["expected_fence"],
+            "idempotency_key": request["idempotency_key"],
+            "approval_ref": request.get("approval_ref"),
+            "backup_digest": request.get("backup_digest"),
+            "retention_seconds": request.get("retention_seconds"),
+        }
+        return self.repository.lifecycle_transition(
+            principal_id=principal_id, host=host, operation=operation, request=normalized
+        )
+
+    def read(self, *, principal_id: str, host: str, kind: str) -> dict[str, Any]:
+        if kind not in {"status", "audit", "manifests"}:
+            raise TenantControlError("tenant_read_denied")
+        return self.repository.read(principal_id=principal_id, host=host, kind=kind)
+
+    def issue_lifecycle_approval(self, *, reviewer_id: str, request: dict[str, Any]) -> dict[str, Any]:
+        allowed = frozenset({"operation", "expected_fence", "idempotency_key", "backup_digest", "retention_seconds"})
+        if not isinstance(request, dict) or not set(request).issubset(allowed) or set(request) < {"operation", "expected_fence", "idempotency_key"}:
+            raise TenantControlError("tenant_payload_closed")
+        operation = request["operation"]
+        if operation not in {"begin_recovery", "delete"} or not isinstance(reviewer_id, str):
+            raise TenantControlError("tenant_approval_denied")
+        tenant_id = os.environ.get("PRIVATE_SINGLE_TENANT_ID", "")
+        issuer_id = os.environ.get("TENANT_APPROVER_ISSUER_ID", "")
+        if not tenant_id or not issuer_id or issuer_id == reviewer_id:
+            raise TenantControlError("tenant_approval_identity_required")
+        approval_ref = str(uuid.uuid4())
+        normalized = {
+            "operation": operation,
+            "expected_fence": request["expected_fence"],
+            "idempotency_key": request["idempotency_key"],
+            "approval_ref": approval_ref,
+            "backup_digest": request.get("backup_digest"),
+            "retention_seconds": request.get("retention_seconds"),
+        }
+        value = SqlAlchemyTenantApprovalRepository().issue(
+            payload={
+                "approval_uid": approval_ref,
+                "tenant_id": tenant_id,
+                "action": operation,
+                "request": normalized,
+                "lease_fence": request["expected_fence"],
+                "issuer_id": issuer_id,
+                "reviewer_id": reviewer_id,
+                "ttl_seconds": os.environ.get("TENANT_APPROVAL_TTL_SECONDS", "120"),
+            }
+        )
+        return {**value, "approval_ref": approval_ref}
+
+    def claim_outbox(self, *, outbox_uid: str) -> dict[str, Any]:
+        worker_id = os.environ.get("TENANT_CONTROL_WORKER_ID", "")
+        if not worker_id:
+            raise TenantControlError("tenant_worker_identity_required")
+        value = self.repository.claim_outbox(outbox_uid=outbox_uid, worker_id=worker_id)
+        tenant_id = value.get("tenant_id")
+        if not isinstance(tenant_id, str):
+            raise TenantControlError("tenant_worker_scope_denied")
+        scope = TenantScope(tenant_id, DeliveryMode.PRIVATE_SINGLE_TENANT)
+        value["propagation"] = {
+            "event": validate_tenant_event_envelope(
+                scope,
+                {"schema_version": 1, "tenant_id": tenant_id, "event_type": value["event_type"], "payload_digest": value["payload_digest"]},
+            ),
+            "namespaces": {resource: build_tenant_namespace(scope, resource, "worker") for resource in ("object", "graph", "cache", "index")},
+        }
+        return value
+
+    def settle_outbox(self, *, outbox_uid: str, lease_fence: int, payload_digest: str, outcome: str) -> dict[str, Any]:
+        worker_id = os.environ.get("TENANT_CONTROL_WORKER_ID", "")
+        if not worker_id:
+            raise TenantControlError("tenant_worker_identity_required")
+        return self.repository.settle_outbox(outbox_uid=outbox_uid, worker_id=worker_id, lease_fence=lease_fence, payload_digest=payload_digest, outcome=outcome)

+ 113 - 0
app/core/system/tenant_lifecycle.py

@@ -0,0 +1,113 @@
+"""Deterministic lifecycle and fence contract used before tenant activation."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import re
+from dataclasses import dataclass, field
+from typing import Any
+
+
+class TenantLifecycleError(ValueError):
+    pass
+
+
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_TRANSITIONS = {
+    ("provisioning", "activate"): "active",
+    ("active", "freeze"): "frozen",
+    ("frozen", "begin_recovery"): "recovering",
+    ("recovering", "activate"): "active",
+    ("active", "mark_deletion_candidate"): "deletion_candidate",
+    ("frozen", "mark_deletion_candidate"): "deletion_candidate",
+    ("deletion_candidate", "delete"): "deleted",
+    ("deletion_candidate", "rollback"): "frozen",
+}
+
+
+@dataclass(frozen=True)
+class TenantLifecycleRecord:
+    tenant_id: str
+    state: str
+    fence: int
+
+
+@dataclass
+class TenantLifecycle:
+    tenant_id: str
+    state: str = "provisioning"
+    fence: int = 0
+    _replays: dict[str, tuple[str, TenantLifecycleRecord]] = field(default_factory=dict)
+
+    @classmethod
+    def provision(cls, tenant_id: str) -> TenantLifecycle:
+        return cls(tenant_id=tenant_id)
+
+    def _digest(self, action: str, expected_fence: int, values: dict[str, Any]) -> str:
+        payload = json.dumps(
+            {"action": action, "expected_fence": expected_fence, **values},
+            sort_keys=True,
+            separators=(",", ":"),
+        )
+        return hashlib.sha256(payload.encode("utf-8")).hexdigest()
+
+    def transition(
+        self,
+        action: str,
+        *,
+        expected_fence: int,
+        idempotency_key: str,
+        approval_ref: str | None = None,
+        backup_digest: str | None = None,
+        retention_seconds: int | None = None,
+        hold_active: bool = False,
+    ) -> TenantLifecycleRecord:
+        if not isinstance(expected_fence, int) or isinstance(expected_fence, bool):
+            raise TenantLifecycleError("tenant_fence_conflict")
+        if not isinstance(idempotency_key, str) or not idempotency_key:
+            raise TenantLifecycleError("tenant_replay_conflict")
+        values = {
+            "approval_ref": approval_ref,
+            "backup_digest": backup_digest,
+            "retention_seconds": retention_seconds,
+            "hold_active": hold_active,
+        }
+        request_digest = self._digest(action, expected_fence, values)
+        replay = self._replays.get(idempotency_key)
+        if replay is not None:
+            if replay[0] != request_digest:
+                raise TenantLifecycleError("tenant_replay_conflict")
+            return replay[1]
+        if expected_fence != self.fence:
+            raise TenantLifecycleError("tenant_fence_conflict")
+        target = _TRANSITIONS.get((self.state, action))
+        if target is None:
+            raise TenantLifecycleError("tenant_transition_denied")
+        if action in {"begin_recovery", "activate"} and self.state == "recovering" and not approval_ref:
+            raise TenantLifecycleError("tenant_recovery_approval_required")
+        if action in {"mark_deletion_candidate", "delete"}:
+            if not approval_ref:
+                raise TenantLifecycleError("tenant_deletion_approval_required")
+            if hold_active:
+                raise TenantLifecycleError("tenant_hold_active")
+            if not isinstance(backup_digest, str) or not _DIGEST.fullmatch(backup_digest):
+                raise TenantLifecycleError("tenant_backup_required")
+            if (
+                not isinstance(retention_seconds, int)
+                or isinstance(retention_seconds, bool)
+                or retention_seconds < 1
+            ):
+                raise TenantLifecycleError("tenant_retention_required")
+        self.state = target
+        self.fence += 1
+        result = TenantLifecycleRecord(self.tenant_id, self.state, self.fence)
+        self._replays[idempotency_key] = (request_digest, result)
+        return result
+
+    def require_active_task_scope(self, *, expected_fence: int) -> TenantLifecycleRecord:
+        if expected_fence != self.fence:
+            raise TenantLifecycleError("tenant_fence_conflict")
+        if self.state != "active":
+            raise TenantLifecycleError("tenant_not_active")
+        return TenantLifecycleRecord(self.tenant_id, self.state, self.fence)

+ 102 - 0
app/core/system/tenant_repository.py

@@ -0,0 +1,102 @@
+"""Runtime-only repository for the WP10 PostgreSQL tenant foundation."""
+
+from __future__ import annotations
+
+import json
+from typing import Any
+
+from sqlalchemy import text
+from sqlalchemy.exc import SQLAlchemyError
+
+
+class SqlAlchemyTenantFoundationRepository:
+    def __init__(self, connection: Any) -> None:
+        # 501--503 accepted tenant_id from a caller payload.  Those functions
+        # were revoked in 504 and this compatibility facade must never become
+        # a fallback around the claim-bound control identity introduced later.
+        raise RuntimeError("tenant_legacy_gateway_sealed")
+
+    def _set_runtime_scope(self, tenant_id: str) -> None:
+        if self._tenant_scope is not None and self._tenant_scope != tenant_id:
+            raise ValueError("tenant_scope_denied")
+        self.connection.execute(text("SET LOCAL ROLE dataops_app_runtime"))
+        self.connection.execute(
+            text("SELECT set_config('dataops.tenant_id', :tenant_id, true)"),
+            {"tenant_id": tenant_id},
+        )
+        self._tenant_scope = tenant_id
+
+    def _write(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        tenant_id = payload.get("tenant_id")
+        if not isinstance(tenant_id, str):
+            raise ValueError("tenant_scope_denied")
+        self._set_runtime_scope(tenant_id)
+        try:
+            with self.connection.begin_nested():
+                value = self.connection.execute(
+                    text("SELECT public.tenant_foundation_write(:action, CAST(:payload AS jsonb))"),
+                    {"action": action, "payload": json.dumps(payload, ensure_ascii=False)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as error:
+            message = str(error)
+            for code in (
+                "tenant_quota_exhausted",
+                "tenant_not_active",
+                "tenant_replay_conflict",
+                "tenant_fence_conflict",
+                "tenant_payload_closed",
+                "tenant_payload_invalid",
+            ):
+                if code in message:
+                    raise ValueError(code) from error
+            raise ValueError("tenant_gateway_denied") from error
+
+    def provision(self, tenant_id: str, delivery_mode: str, idempotency_key: str) -> dict[str, Any]:
+        return self._write("provision", {"tenant_id": tenant_id, "delivery_mode": delivery_mode, "idempotency_key": idempotency_key})
+
+    def reserve_quota(self, tenant_id: str, quota_name: str, amount: int | float, idempotency_key: str) -> int:
+        if isinstance(amount, bool) or not isinstance(amount, (int, float)):
+            raise ValueError("tenant_payload_invalid")
+        payload = {"tenant_id": tenant_id, "quota_name": quota_name, "amount": amount, "idempotency_key": idempotency_key}
+        self._set_runtime_scope(tenant_id)
+        try:
+            with self.connection.begin_nested():
+                value = self.connection.execute(text("SELECT public.tenant_quota_reserve(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, ensure_ascii=False)}).scalar_one()
+            result = dict(value)
+        except SQLAlchemyError as error:
+            message = str(error)
+            for code in ("tenant_quota_exhausted", "tenant_not_active", "tenant_replay_conflict", "tenant_fence_conflict", "tenant_payload_closed", "tenant_payload_invalid"):
+                if code in message:
+                    raise ValueError(code) from error
+            raise ValueError("tenant_gateway_denied") from error
+        return int(result["lease_fence"])
+
+    def transition_lifecycle(
+        self,
+        tenant_id: str,
+        operation: str,
+        expected_fence: int,
+        idempotency_key: str,
+        *,
+        approval_ref: str | None = None,
+    ) -> int:
+        self._set_runtime_scope(tenant_id)
+        try:
+            with self.connection.begin_nested():
+                result = self.connection.execute(
+                    text("SELECT public.tenant_lifecycle_transition(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps({"tenant_id": tenant_id, "operation": operation, "expected_fence": expected_fence, "idempotency_key": idempotency_key, "approval_ref": approval_ref}, ensure_ascii=False)},
+                ).scalar_one()
+            return int(dict(result)["lease_fence"])
+        except SQLAlchemyError as error:
+            message = str(error)
+            for code in ("tenant_not_active", "tenant_replay_conflict", "tenant_fence_conflict", "tenant_payload_closed", "tenant_payload_invalid", "tenant_recovery_approval_required"):
+                if code in message:
+                    raise ValueError(code) from error
+            raise ValueError("tenant_lifecycle_denied") from error
+
+    def list_audit(self, tenant_id: str) -> list[dict[str, Any]]:
+        self._set_runtime_scope(tenant_id)
+        rows = self.connection.execute(text("SELECT tenant_id,event_type,payload_digest,lease_fence,created_at FROM public.tenant_audit_events ORDER BY created_at,event_uid")).mappings()
+        return [dict(row) for row in rows]

+ 66 - 0
app/core/system/tenant_resources.py

@@ -0,0 +1,66 @@
+"""Tenant namespace and hash-only manifest contracts for non-PostgreSQL stores."""
+
+from __future__ import annotations
+
+import re
+from typing import Any
+
+from app.core.system.tenant_context import TenantScope
+
+
+class TenantResourceError(ValueError):
+    pass
+
+
+_RESOURCE_TYPES = frozenset(
+    {
+        "object",
+        "graph",
+        "cache",
+        "index",
+        "keys",
+        "connectors",
+        "models",
+        "plugins",
+        "backup",
+        "audit_export",
+    }
+)
+_RESOURCE_NAME = re.compile(r"^[a-z0-9][a-z0-9._-]{0,120}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+
+
+def _resource_token(value: str, *, allowed: frozenset[str] | None = None) -> str:
+    if not isinstance(value, str) or not _RESOURCE_NAME.fullmatch(value):
+        raise TenantResourceError("tenant_resource_invalid")
+    if allowed is not None and value not in allowed:
+        raise TenantResourceError("tenant_resource_invalid")
+    return value
+
+
+def build_tenant_namespace(scope: TenantScope, resource: str, name: str) -> str:
+    """Return an opaque prefix; callers must not concatenate their own paths."""
+    resource = _resource_token(resource, allowed=_RESOURCE_TYPES)
+    name = _resource_token(name)
+    return f"{scope.tenant_id}/{resource}/v{scope.version}/{name}"
+
+
+def build_tenant_resource_manifest(
+    scope: TenantScope,
+    *,
+    resource: str,
+    name: str,
+    digest: str,
+) -> dict[str, Any]:
+    if not isinstance(digest, str) or not _DIGEST.fullmatch(digest):
+        raise TenantResourceError("tenant_resource_invalid")
+    namespace = build_tenant_namespace(scope, resource, name)
+    return {
+        "schema_version": 1,
+        "tenant_id": scope.tenant_id,
+        "delivery_mode": scope.mode.value,
+        "resource": resource,
+        "namespace": namespace,
+        "digest": f"sha256:{digest}",
+        "provider_enabled": False,
+    }

+ 670 - 0
app/core/system/trusted_delivery.py

@@ -0,0 +1,670 @@
+"""Closed, default-deny contracts for fine-grained trusted delivery.
+
+This module intentionally never executes a data query or contacts a target.
+It produces a bounded authorization projection and digest-only provider envelope.
+Concrete enterprise providers remain external integration work.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import re
+import uuid
+from collections.abc import Callable, Mapping
+from datetime import UTC, datetime
+from typing import Any
+
+from app.core.common.identifiers import new_governance_uid
+from app.core.common.timezone_utils import now_china
+
+_PROVIDERS = frozenset({"database", "api", "file", "iam", "kms", "dlp", "siem"})
+_ENVIRONMENTS = frozenset({"development", "test", "production"})
+_ACTIONS = frozenset({"read", "use", "display", "export"})
+_CLASSIFICATIONS = frozenset({"public", "internal", "sensitive", "highly_sensitive"})
+_FIELD = re.compile(r"^[A-Za-z_][A-Za-z0-9_.-]{0,199}$")
+_CODE = re.compile(r"^[A-Z][A-Z0-9_]{2,119}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_UNSAFE_TEXT = re.compile(
+    r"(?i)(?:https?://|ftp://|file://|www\.|\b(?:secret|token|password|private[ _-]?key)\b|"
+    r"-----BEGIN|<script|javascript:|;)")
+_UNSAFE_SQL = re.compile(r"(?i)\b(?:select|insert|update|delete|drop|alter)\s+")
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ValueError(f"{label} must be an object")
+    extra = sorted(set(value) - allowed)
+    if extra:
+        raise ValueError(f"{label} contains unsupported fields: {', '.join(extra)}")
+    result = copy.deepcopy(value)
+    _assert_safe_value(result, label)
+    return result
+
+
+def _assert_safe_value(value: Any, label: str) -> None:
+    """Reject values that could turn an authorization reference into payload data."""
+    if isinstance(value, str) and _UNSAFE_TEXT.search(value):
+        raise ValueError(f"{label} contains unsafe content")
+    if isinstance(value, dict):
+        for item in value.values():
+            _assert_safe_value(item, label)
+    elif isinstance(value, list):
+        for item in value:
+            _assert_safe_value(item, label)
+
+
+def _text(value: Any, label: str, maximum: int = 300) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise ValueError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum:
+        raise ValueError(f"{label} exceeds {maximum} characters")
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as exc:
+        raise ValueError(f"{label} must be a UUID") from exc
+
+
+def _time(value: Any, label: str) -> datetime:
+    try:
+        result = value if isinstance(value, datetime) else datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as exc:
+        raise ValueError(f"{label} must be ISO-8601") from exc
+    if result.tzinfo is None:
+        raise ValueError(f"{label} must include a timezone")
+    return result.astimezone(UTC)
+
+
+def _values(value: Any, label: str, *, minimum: int = 1, maximum: int = 200) -> list[Any]:
+    if not isinstance(value, list) or not minimum <= len(value) <= maximum:
+        raise ValueError(f"{label} must contain between {minimum} and {maximum} items")
+    return copy.deepcopy(value)
+
+
+def _digest(value: Any) -> str:
+    return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(",", ":")).encode()).hexdigest()
+
+
+def _digest_value(value: Any, label: str) -> str:
+    result = _text(value, label, 64).lower()
+    if not _DIGEST.fullmatch(result):
+        raise ValueError(f"{label} must be SHA-256")
+    return result
+
+
+def _field(value: Any, label: str) -> str:
+    result = _text(value, label, 200)
+    if not _FIELD.fullmatch(result):
+        raise ValueError(f"{label} is invalid")
+    return result
+
+
+def _simple_values(value: Any, label: str, allowed: frozenset[str]) -> list[str]:
+    result = sorted({_text(item, label, 100) for item in _values(value, label)})
+    if not set(result) <= allowed:
+        raise ValueError(f"unsupported {label}")
+    return result
+
+
+def _row_filter(value: Any) -> dict[str, Any] | None:
+    if value is None:
+        return None
+    body = _closed(value, {"op", "field", "value", "items", "item"}, "row filter")
+    op = _text(body.get("op"), "row filter op", 10)
+    if op not in {"eq", "in", "and", "or", "not"}:
+        raise ValueError("unsupported row filter op")
+    if _UNSAFE_SQL.search(json.dumps(body, sort_keys=True)):
+        raise ValueError("row filter contains unsafe content")
+    if op in {"eq", "in"}:
+        if set(body) - {"op", "field", "value"}:
+            raise ValueError("row filter shape is invalid")
+        field = _field(body.get("field"), "row filter field")
+        raw = body.get("value")
+        if op == "eq" and not isinstance(raw, (str, int, float, bool)):
+            raise ValueError("row filter eq value must be scalar")
+        if op == "in":
+            if not isinstance(raw, list) or not 1 <= len(raw) <= 100 or not all(isinstance(item, (str, int, float, bool)) for item in raw):
+                raise ValueError("row filter in value must be bounded scalar list")
+            raw = sorted(raw, key=lambda item: (type(item).__name__, str(item)))
+        return {"op": op, "field": field, "value": raw}
+    if op == "not":
+        if set(body) != {"op", "item"}:
+            raise ValueError("row filter not shape is invalid")
+        return {"op": op, "item": _row_filter(body["item"])}
+    if set(body) != {"op", "items"}:
+        raise ValueError("row filter boolean shape is invalid")
+    items = [_row_filter(item) for item in _values(body.get("items"), "row filter items", minimum=1, maximum=20)]
+    return {"op": op, "items": items}
+
+
+class ClosedProviderRegistry:
+    """Provider names are a closed enum; tests may inject non-network adapters."""
+
+    def __init__(self, adapters: Mapping[str, Any] | None = None, *, test_mode: bool = False):
+        adapters = dict(adapters or {})
+        if set(adapters) - _PROVIDERS:
+            raise ValueError("unsupported trusted-delivery provider")
+        if adapters and not test_mode:
+            raise PermissionError("enterprise providers require approved external integration")
+        self._adapters = adapters
+        self._test_mode = test_mode
+
+    @classmethod
+    def for_tests(cls, adapters: Mapping[str, Any]):
+        return cls(adapters, test_mode=True)
+
+    @property
+    def is_enterprise_ready(self) -> bool:
+        return False
+
+    def dependency_status(self) -> dict[str, str]:
+        return dict.fromkeys(sorted(_PROVIDERS), "TBD_EXTERNAL")
+
+    def get(self, provider: str):
+        provider = _text(provider, "provider", 30)
+        if provider not in _PROVIDERS:
+            raise ValueError("unsupported trusted-delivery provider")
+        adapter = self._adapters.get(provider)
+        if adapter is None:
+            raise PermissionError(f"trusted-delivery provider {provider} is disabled")
+        return adapter
+
+
+class TrustedDeliveryService:
+    """Durable-service façade. Repositories own the database transaction boundary."""
+
+    def __init__(
+        self, repository, *, provider_registry: ClosedProviderRegistry | None = None,
+        uid_factory: Callable[[], str] = new_governance_uid,
+        now_factory: Callable[[], datetime] = now_china,
+    ):
+        self.repository = repository
+        self.provider_registry = provider_registry or ClosedProviderRegistry()
+        self.uid_factory = uid_factory
+        self.now_factory = now_factory
+
+    def _actor(self, value: Any) -> str:
+        actor = _uid(value, "actor_uid")
+        if self.repository.users_available({actor}) != {actor}:
+            raise ValueError("trusted-delivery actor is unavailable")
+        return actor
+
+    def _event(self, action: str, actor_uid: str, detail: dict[str, Any]) -> None:
+        if hasattr(self.repository, "add_evidence"):
+            self.repository.add_evidence({
+                "uid": self.uid_factory(), "action": action, "actor_uid": actor_uid,
+                "safe_detail": copy.deepcopy(detail), "created_at": self.now_factory().isoformat(),
+            })
+
+    def create_policy_version(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"code", "version", "selector", "resource_rules"}, "trusted delivery policy")
+        actor = self._actor(actor_uid)
+        code = _text(body.get("code"), "policy code", 120).upper()
+        if not _CODE.fullmatch(code):
+            raise ValueError("policy code is invalid")
+        selector = _closed(body.get("selector"), {"subjects", "roles", "business_domains", "assets", "purposes", "environments", "actions", "classifications", "expires_at"}, "policy selector")
+        subjects = sorted({_uid(item, "policy subject") for item in _values(selector.get("subjects", []), "policy subjects", minimum=0)})
+        roles = sorted({_text(item, "policy role", 80) for item in _values(selector.get("roles", []), "policy roles", minimum=0)})
+        if not subjects and not roles:
+            raise ValueError("policy selector requires a subject or role")
+        if subjects and self.repository.users_available(set(subjects)) != set(subjects):
+            raise ValueError("policy selector contains unavailable users")
+        rules = _closed(body.get("resource_rules"), {"row_filter", "field_rules"}, "resource rules")
+        field_rules = []
+        for item in _values(rules.get("field_rules"), "field rules", maximum=500):
+            field_rule = _closed(item, {"field", "effect", "mask_ref"}, "field rule")
+            effect = _text(field_rule.get("effect"), "field effect", 10)
+            if effect not in {"allow", "deny"}:
+                raise ValueError("unsupported field effect")
+            mask_ref = field_rule.get("mask_ref")
+            if mask_ref is not None:
+                mask_ref = _text(mask_ref, "mask ref", 120)
+                if not re.fullmatch(r"[a-z][a-z0-9-]{2,119}-v[1-9][0-9]*", mask_ref):
+                    raise ValueError("mask ref is invalid")
+            field_rules.append({"field": _field(field_rule.get("field"), "field rule field"), "effect": effect, "mask_ref": mask_ref})
+        if len({item["field"] for item in field_rules}) != len(field_rules):
+            raise ValueError("field rules must not duplicate fields")
+        expires_at = _time(selector.get("expires_at"), "policy expiry")
+        now = self.now_factory().astimezone(UTC)
+        if expires_at <= now:
+            raise ValueError("policy expiry must be in the future")
+        record = {
+            "uid": self.uid_factory(), "code": code, "version": _text(body.get("version"), "policy version", 30),
+            # A policy never becomes effective by creation alone.  This keeps
+            # both first and subsequent versions behind the durable approval
+            # transition, rather than treating an empty policy history as an
+            # implicit approval.
+            "status": "draft", "selector": {
+                "subjects": subjects, "roles": roles,
+                "business_domains": sorted({_uid(item, "business domain") for item in _values(selector.get("business_domains"), "business domains")}),
+                "assets": sorted({_uid(item, "asset") for item in _values(selector.get("assets"), "assets")}),
+                "purposes": sorted({_text(item, "purpose", 100) for item in _values(selector.get("purposes"), "purposes")}),
+                "environments": _simple_values(selector.get("environments"), "environments", _ENVIRONMENTS),
+                "actions": _simple_values(selector.get("actions"), "actions", _ACTIONS),
+                "classifications": _simple_values(selector.get("classifications"), "classifications", _CLASSIFICATIONS),
+                "expires_at": expires_at.isoformat(),
+            },
+            "resource_rules": {"row_filter": _row_filter(rules.get("row_filter")), "field_rules": sorted(field_rules, key=lambda item: item["field"])},
+            "created_by": actor, "created_at": now.isoformat(), "current_version": 1,
+        }
+        saved = self.repository.create_policy_version(record)
+        self._event("policy_version_created", actor, {"policy_code": code, "version": record["version"]})
+        return saved
+
+    def _lifecycle_request(self, payload: Any, *, label: str) -> tuple[dict[str, Any], str, str, str]:
+        body = _closed(payload, {"code", "version", "approval_ref", "approval_digest", "idempotency_key"}, label)
+        actor = self._actor(payload.get("actor_uid")) if isinstance(payload, dict) and "actor_uid" in payload else None
+        # Callers supply the actor separately.  This branch only keeps direct
+        # service use closed if a malformed payload is passed.
+        if actor is not None:
+            raise ValueError("actor_uid must not be in lifecycle payload")
+        return (
+            body,
+            _text(body.get("code"), "policy code", 120).upper(),
+            _text(body.get("version"), "policy version", 30),
+            _text(body.get("idempotency_key"), "idempotency key", 160),
+        )
+
+    def _policy_transition(self, payload: Any, *, actor_uid: str, operation: str) -> dict[str, Any]:
+        body = _closed(payload, {"code", "version", "approval_ref", "approval_digest", "idempotency_key"}, "policy transition")
+        actor = self._actor(actor_uid)
+        code = _text(body.get("code"), "policy code", 120).upper()
+        if not _CODE.fullmatch(code):
+            raise ValueError("policy code is invalid")
+        version = _text(body.get("version"), "policy version", 30)
+        approval_ref = _text(body.get("approval_ref"), "approval reference", 200)
+        approval_digest = _digest_value(body.get("approval_digest"), "approval digest")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        request_digest = _digest({"operation": operation, "code": code, "version": version, "approval_ref": approval_ref, "approval_digest": approval_digest})
+        if hasattr(self.repository, "transition_policy"):
+            saved = self.repository.transition_policy(code, version, operation, key, request_digest, actor, approval_ref, approval_digest)
+        elif hasattr(self.repository, "policies"):
+            # Small test repositories intentionally do not emulate PostgreSQL;
+            # preserve the same state rules for service-level tests.
+            history = getattr(self.repository, "policy_transitions", {})
+            existing = history.get(key)
+            if existing:
+                if existing["request_digest"] != request_digest:
+                    raise RuntimeError("trusted delivery idempotency conflict")
+                return copy.deepcopy(existing["result"])
+            target = next((item for item in self.repository.policies.values() if item["code"] == code and item["version"] == version), None)
+            if target is None:
+                raise LookupError("trusted delivery policy version was not found")
+            for item in self.repository.policies.values():
+                if item["code"] == code and item["uid"] != target["uid"] and item["status"] == "active":
+                    item["status"] = "retired"
+                    item["current_version"] += 1
+            if target["status"] != "active":
+                target["status"] = "active"
+                target["current_version"] += 1
+            saved = {key: target[key] for key in ("uid", "code", "version", "status", "current_version")}
+            history[key] = {"request_digest": request_digest, "result": copy.deepcopy(saved)}
+            self.repository.policy_transitions = history
+        else:
+            raise RuntimeError("durable policy transition repository is required")
+        self._event(f"policy_{operation}", actor, {"policy_code": code, "version": version, "approval_digest": approval_digest})
+        return saved
+
+    def activate_policy_version(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._policy_transition(payload, actor_uid=actor_uid, operation="activate")
+
+    def rollback_policy_version(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._policy_transition(payload, actor_uid=actor_uid, operation="rollback")
+
+    def evaluate_gateway(self, payload: Any) -> dict[str, Any]:
+        body = _closed(payload, {"subject_uid", "roles", "business_domain_uid", "asset_uid", "purpose", "environment", "action", "classification", "requested_fields"}, "gateway request")
+        context = {
+            "subject_uid": _uid(body.get("subject_uid"), "subject_uid"),
+            "roles": sorted({_text(item, "role", 80) for item in _values(body.get("roles"), "roles", minimum=0)}),
+            "business_domain_uid": _uid(body.get("business_domain_uid"), "business_domain_uid"),
+            "asset_uid": _uid(body.get("asset_uid"), "asset_uid"), "purpose": _text(body.get("purpose"), "purpose", 100),
+            "environment": _text(body.get("environment"), "environment", 30), "action": _text(body.get("action"), "action", 20),
+            "classification": _text(body.get("classification"), "classification", 30),
+            "requested_fields": sorted({_field(item, "requested field") for item in _values(body.get("requested_fields"), "requested fields", maximum=500)}),
+        }
+        if context["environment"] not in _ENVIRONMENTS or context["action"] not in _ACTIONS or context["classification"] not in _CLASSIFICATIONS:
+            raise ValueError("unsupported gateway environment, action, or classification")
+        if context["action"] == "export" and self.repository.active_hold_for_asset(context["asset_uid"]):
+            return {"decision": "deny", "reason_code": "active_legal_hold"}
+        if context["action"] == "export" and context["classification"] == "highly_sensitive":
+            return {"decision": "deny", "reason_code": "highly_sensitive_export_denied"}
+        now = self.now_factory().astimezone(UTC)
+        for policy in self.repository.active_policies():
+            selector = policy["selector"]
+            if _time(selector["expires_at"], "policy expiry") <= now:
+                continue
+            if not (context["subject_uid"] in selector["subjects"] or set(context["roles"]) & set(selector["roles"])):
+                continue
+            selector_keys = {
+                "business_domain_uid": "business_domains", "asset_uid": "assets",
+                "purpose": "purposes", "environment": "environments",
+                "action": "actions", "classification": "classifications",
+            }
+            if any(context[key] not in selector[selector_keys[key]] for key in selector_keys):
+                continue
+            rules = {rule["field"]: rule for rule in policy["resource_rules"]["field_rules"]}
+            if any(field not in rules or rules[field]["effect"] != "allow" for field in context["requested_fields"]):
+                continue
+            masks = {field: rules[field]["mask_ref"] for field in context["requested_fields"] if rules[field]["mask_ref"]}
+            return {"decision": "allow", "reason_code": "policy_allowed", "policy_code": policy["code"], "policy_version": policy["version"], "projected_fields": context["requested_fields"], "row_filter": policy["resource_rules"]["row_filter"], "field_masks": masks}
+        return {"decision": "deny", "reason_code": "default_deny"}
+
+    def create_grant(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"policy_uid", "approval_ref", "approval_digest", "subject_uid", "asset_uid", "provider", "expires_at", "decision"}, "trusted delivery grant")
+        actor = self._actor(actor_uid)
+        decision = _closed(body.get("decision"), {"decision", "reason_code", "policy_code", "policy_version", "projected_fields", "row_filter", "field_masks"}, "grant decision")
+        if decision.get("decision") != "allow":
+            raise PermissionError("trusted delivery grant requires allowed decision")
+        provider = _text(body.get("provider"), "provider", 30)
+        self.provider_registry.get(provider)
+        expires_at = _time(body.get("expires_at"), "grant expiry")
+        if expires_at <= self.now_factory().astimezone(UTC):
+            raise ValueError("grant expiry must be in the future")
+        record = {
+            "uid": self.uid_factory(), "policy_uid": _uid(body.get("policy_uid"), "policy_uid"),
+            "approval_ref": _text(body.get("approval_ref"), "approval reference", 200),
+            "approval_digest": _digest_value(body.get("approval_digest"), "approval digest"),
+            "subject_uid": _uid(body.get("subject_uid"), "subject_uid"), "asset_uid": _uid(body.get("asset_uid"), "asset_uid"),
+            "provider": provider, "expires_at": expires_at.isoformat(), "status": "active", "reason_code": "approval_bound",
+            "decision_digest": _digest(decision), "current_version": 1, "created_by": actor, "created_at": self.now_factory().isoformat(),
+        }
+        saved = self.repository.create_grant(record)
+        result = self.repository.get_grant(saved["uid"]) if hasattr(self.repository, "get_grant") else saved
+        self._event("grant_created", actor, {"grant_uid": result["uid"], "provider": provider, "decision_digest": record["decision_digest"]})
+        return result
+
+    def dispatch_grant(self, grant_uid: str, *, actor_uid: str) -> dict[str, Any]:
+        actor = self._actor(actor_uid)
+        if hasattr(self.repository, "get_grant"):
+            grant = self.repository.get_grant(_uid(grant_uid, "grant_uid"))
+        elif hasattr(self.repository, "grants"):
+            grant = copy.deepcopy(self.repository.grants.get(_uid(grant_uid, "grant_uid")))
+        else:
+            raise RuntimeError("durable dispatch repository is required")
+        if not grant or grant["status"] != "active":
+            raise LookupError("active trusted delivery grant was not found")
+        response = self.provider_registry.get(grant["provider"]).apply({
+            "schema": "dataops.trusted-delivery.v1", "grant_uid": grant["uid"], "provider": grant["provider"],
+            "subject_uid": grant["subject_uid"], "asset_uid": grant["asset_uid"], "expires_at": grant["expires_at"], "decision_digest": grant["decision_digest"],
+        })
+        response = _closed(response, {"status", "receipt_code", "response_digest"}, "provider receipt")
+        if response.get("status") != "applied":
+            raise RuntimeError("trusted delivery provider failed closed")
+        receipt = {"grant_uid": grant["uid"], "status": "applied", "receipt_code": _text(response.get("receipt_code"), "receipt code", 120), "response_digest": _digest_value(response.get("response_digest"), "provider response digest")}
+        self._event("grant_dispatched", actor, receipt)
+        return receipt
+
+    def provision(self, payload: Any, *, actor_uid: str, subject_roles: list[str] | None = None) -> dict[str, Any]:
+        """Create and apply one approval-bound, digest-only capability grant."""
+        body = _closed(payload, {"policy_uid", "approval_ref", "approval_digest", "subject_uid", "asset_uid", "business_domain_uid", "purpose", "environment", "action", "classification", "requested_fields", "expires_at", "target_capability", "provider", "idempotency_key"}, "trusted delivery provision")
+        actor = self._actor(actor_uid)
+        provider = _text(body.get("provider"), "provider", 30)
+        adapter = self.provider_registry.get(provider)
+        capability = _closed(body.get("target_capability"), {"actions", "fields"}, "target capability")
+        target_capability = {
+            "actions": _simple_values(capability.get("actions"), "capability actions", _ACTIONS),
+            "fields": sorted({_field(item, "capability field") for item in _values(capability.get("fields"), "capability fields", maximum=500)}),
+        }
+        approval_ref = _text(body.get("approval_ref"), "approval reference", 200)
+        approval_digest = _digest_value(body.get("approval_digest"), "approval digest")
+        policy_uid = _uid(body.get("policy_uid"), "policy_uid")
+        subject_uid = _uid(body.get("subject_uid"), "subject_uid")
+        asset_uid = _uid(body.get("asset_uid"), "asset_uid")
+        context = {
+            "subject_uid": subject_uid,
+            "roles": list(subject_roles or []),
+            "business_domain_uid": _uid(body.get("business_domain_uid"), "business_domain_uid"),
+            "asset_uid": asset_uid,
+            "purpose": _text(body.get("purpose"), "purpose", 100),
+            "environment": _text(body.get("environment"), "environment", 30),
+            "action": _text(body.get("action"), "action", 20),
+            "classification": _text(body.get("classification"), "classification", 30),
+            "requested_fields": sorted({_field(item, "requested field") for item in _values(body.get("requested_fields"), "requested fields", maximum=500)}),
+        }
+        # Re-evaluate from the durable, active policy version.  A caller's
+        # policy UID, capability and approval labels are only references; none
+        # of them is allowed to enlarge the authorisation projection.
+        decision = self.evaluate_gateway(context)
+        active = next((item for item in self.repository.active_policies() if item.get("uid") == policy_uid), None)
+        if active is None or decision.get("decision") != "allow" or active["code"] != decision.get("policy_code") or active["version"] != decision.get("policy_version"):
+            raise PermissionError("trusted delivery provision is not allowed by active policy")
+        if set(target_capability["actions"]) != {context["action"]} or set(target_capability["fields"]) != set(decision["projected_fields"]):
+            raise PermissionError("target capability exceeds server policy projection")
+        expires_at = _time(body.get("expires_at"), "grant expiry")
+        if expires_at <= self.now_factory().astimezone(UTC):
+            raise ValueError("grant expiry must be in the future")
+        policy_expiry = _time(active["selector"]["expires_at"], "policy expiry")
+        if expires_at > policy_expiry:
+            raise PermissionError("grant expiry exceeds active policy")
+        if "export" in target_capability["actions"] and self.repository.active_hold_for_asset(asset_uid):
+            raise PermissionError("active legal hold blocks export provision")
+        projection = {
+            "fields": decision["projected_fields"],
+            "row_predicate": decision["row_filter"],
+            "masking": decision["field_masks"],
+        }
+        decision_digest = _digest({"policy_uid": policy_uid, "policy_code": active["code"], "policy_version": active["version"], "context": context, "projection": projection, "approval_digest": approval_digest})
+        record = {
+            "uid": self.uid_factory(), "policy_uid": policy_uid,
+            "approval_ref": approval_ref, "approval_digest": approval_digest,
+            "subject_uid": subject_uid, "asset_uid": asset_uid,
+            "purpose": context["purpose"], "environment": context["environment"],
+            "target_capability": target_capability, "provider": provider,
+            "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160),
+            "expires_at": expires_at.isoformat(), "status": "active", "reason_code": "approval_bound",
+            "request_digest": _digest({"decision_digest": decision_digest, "provider": provider, "expires_at": expires_at.isoformat(), "idempotency_key": body.get("idempotency_key")}),
+            "decision_digest": decision_digest,
+            "current_version": 1, "created_by": actor,
+        }
+        if hasattr(self.repository, "enqueue_grant"):
+            grant = self.repository.enqueue_grant(record)
+            grant_uid = grant["uid"]
+            if hasattr(self.repository, "get_grant"):
+                stored = self.repository.get_grant(grant_uid)
+                if stored and stored.get("status") == "reclaimed":
+                    raise RuntimeError("trusted delivery grant was reclaimed")
+            if hasattr(self.repository, "get_provision_receipt"):
+                prior_receipt = self.repository.get_provision_receipt(grant_uid, record["idempotency_key"])
+                if prior_receipt:
+                    return {"grant_uid": grant_uid, "status": "applied", "receipt": prior_receipt}
+        else:
+            raise RuntimeError("durable provision repository is required")
+        # Persist a fenced, idempotent outbox intent before the adapter is
+        # permitted to see the request.  A process crash now leaves a retryable
+        # pending record rather than an unprovable external side effect.
+        if hasattr(self.repository, "prepare_provision_operation"):
+            operation = self.repository.prepare_provision_operation(
+                grant_uid, record["idempotency_key"], record["request_digest"]
+            )
+            if operation.get("completed"):
+                return {"grant_uid": grant_uid, "status": "applied", "receipt": operation["receipt"]}
+        elif hasattr(self.repository, "session"):
+            raise RuntimeError("durable provision outbox repository is required")
+        envelope = {"schema": "dataops.trusted-delivery.v2", "operation": "provision", "grant_uid": grant_uid, "policy_uid": record["policy_uid"], "provider": provider, "subject_uid": record["subject_uid"], "asset_uid": record["asset_uid"], "purpose": record["purpose"], "environment": record["environment"], "expires_at": record["expires_at"], "projection": projection, "decision_digest": decision_digest, "request_digest": record["request_digest"]}
+        claim = None
+        if hasattr(self.repository, "claim_provision_operation"):
+            worker = f"provision:{self.uid_factory()}"
+            claim = self.repository.claim_provision_operation(operation["delivery_uid"], worker)
+            if claim.get("state") == "completed":
+                return {"grant_uid": grant_uid, "status": "applied", "receipt": claim["receipt"]}
+            if claim.get("state") != "claimed":
+                # Another process owns the external side effect.  Returning a
+                # pending state is intentionally safer than performing a
+                # duplicate call while that DB-time lease is alive.
+                return {"grant_uid": grant_uid, "status": "pending", "retryable": True}
+        try:
+            response = _closed(adapter.apply(copy.deepcopy(envelope)), {"status", "receipt_code", "response_digest"}, "provider receipt")
+            if response.get("status") != "applied":
+                raise RuntimeError("trusted delivery provider failed closed")
+        except Exception:
+            if claim is not None:
+                # Commit the retryable outbox state before the HTTP boundary
+                # rolls back the failed request transaction.
+                self.repository.fail_provision_operation(operation["delivery_uid"], worker, claim["lease_fence"])
+                self.repository.session.commit()
+            raise
+        receipt = {"grant_uid": grant_uid, "status": "applied", "receipt_code": _text(response.get("receipt_code"), "receipt code", 120), "response_digest": _digest_value(response.get("response_digest"), "provider response digest"), "diff_digest": _digest({"operation": "provision", "request_digest": record["request_digest"], "response_digest": response.get("response_digest")})}
+        if claim is not None:
+            saved = self.repository.complete_provision_operation(
+                grant_uid, operation["delivery_uid"], worker, claim["lease_fence"], receipt
+            )
+            receipt = {**receipt, "grant_uid": saved.get("uid", grant_uid)}
+        elif hasattr(self.repository, "record_provision_receipt"):
+            receipt = self.repository.record_provision_receipt(grant_uid, record["idempotency_key"], record["request_digest"], receipt)
+        self._event("provision_applied", actor, {"grant_uid": grant_uid, "provider": provider, "request_digest": record["request_digest"], "response_digest": receipt["response_digest"]})
+        return {"grant_uid": grant_uid, "status": "applied", "receipt": receipt}
+
+    def create_legal_hold(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"asset_uid", "operation", "approver_refs", "evidence_digest"}, "legal hold")
+        actor = self._actor(actor_uid)
+        asset_uid = _uid(body.get("asset_uid"), "asset_uid")
+        if self.repository.active_hold_for_asset(asset_uid):
+            raise RuntimeError("active legal hold already exists")
+        operation = _text(body.get("operation"), "legal hold operation", 30)
+        if operation not in {"freeze", "export_review", "destruction_review"}:
+            raise ValueError("unsupported legal hold operation")
+        approvers = sorted({_text(item, "approver reference", 200) for item in _values(body.get("approver_refs"), "approver references", minimum=2, maximum=2)})
+        if len(approvers) != 2:
+            raise ValueError("legal hold requires two distinct approver references")
+        record = {
+            "uid": self.uid_factory(), "asset_uid": asset_uid, "operation": operation,
+            # The SQL schema intentionally stores the two approvals in separate
+            # columns so a parameter mapping cannot silently collapse them.
+            "approver_ref_one": approvers[0], "approver_ref_two": approvers[1],
+            "approver_refs": approvers, "evidence_digest": _digest_value(body.get("evidence_digest"), "evidence digest"),
+            "status": "active", "created_by": actor, "created_at": self.now_factory().isoformat(), "current_version": 1,
+        }
+        saved = self.repository.create_legal_hold(record)
+        self._event("legal_hold_active", actor, {"hold_uid": saved["uid"], "operation": operation})
+        return saved
+
+    def release_legal_hold(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"hold_uid", "approval_ref", "approval_digest", "idempotency_key"}, "legal hold release")
+        actor = self._actor(actor_uid)
+        hold_uid = _uid(body.get("hold_uid"), "hold_uid")
+        approval_ref = _text(body.get("approval_ref"), "approval reference", 200)
+        approval_digest = _digest_value(body.get("approval_digest"), "approval digest")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        request_digest = _digest({"hold_uid": hold_uid, "approval_ref": approval_ref, "approval_digest": approval_digest})
+        if hasattr(self.repository, "release_legal_hold"):
+            saved = self.repository.release_legal_hold(hold_uid, key, request_digest, actor, approval_ref, approval_digest)
+        elif hasattr(self.repository, "holds"):
+            releases = getattr(self.repository, "hold_releases", {})
+            existing = releases.get(key)
+            if existing:
+                if existing["request_digest"] != request_digest:
+                    raise RuntimeError("trusted delivery idempotency conflict")
+                return copy.deepcopy(existing["result"])
+            hold = self.repository.holds.get(hold_uid)
+            if not hold:
+                raise LookupError("trusted delivery legal hold was not found")
+            if hold["created_by"] == actor or approval_ref in hold["approver_refs"]:
+                raise PermissionError("legal hold release requires an independent approval")
+            hold["status"] = "released"
+            hold["current_version"] += 1
+            saved = {"uid": hold_uid, "status": "released", "current_version": hold["current_version"]}
+            releases[key] = {"request_digest": request_digest, "result": copy.deepcopy(saved)}
+            self.repository.hold_releases = releases
+        else:
+            raise RuntimeError("durable legal hold repository is required")
+        self._event("legal_hold_released", actor, {"hold_uid": hold_uid, "approval_digest": approval_digest})
+        return saved
+
+    def execute_reclaim(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        """Request provider revocation first; never delete or reclaim optimistically."""
+        body = _closed(payload, {"grant_uid", "idempotency_key"}, "trusted delivery reclaim")
+        actor = self._actor(actor_uid)
+        grant_uid = _uid(body.get("grant_uid"), "grant_uid")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        if not hasattr(self.repository, "get_grant"):
+            raise RuntimeError("durable reclaim repository is required")
+        grant = self.repository.get_grant(grant_uid)
+        if not grant:
+            raise LookupError("trusted delivery grant was not found")
+        now = self.now_factory().astimezone(UTC)
+        if grant.get("status") == "reclaimed":
+            return {"grant_uid": grant_uid, "status": "reclaimed", "idempotent": True}
+        if grant.get("status") != "active" or _time(grant["expires_at"], "grant expiry") > now:
+            raise ValueError("trusted delivery grant is not reclaimable")
+        if self.repository.active_hold_for_asset(grant["asset_uid"]):
+            raise PermissionError("active legal hold blocks reclaim")
+        expiry = _time(grant["expires_at"], "grant expiry").isoformat()
+        request_digest = _digest({"operation": "revoke", "grant_uid": grant_uid, "provider": grant["provider"], "expires_at": expiry})
+        worker_id = f"reclaim-{uuid.uuid4()}"
+        claim = None
+        if hasattr(self.repository, "claim_reclaim_operation"):
+            claim = self.repository.claim_reclaim_operation(grant_uid, key, request_digest, worker_id)
+            if claim["state"] == "completed":
+                return {"grant_uid": grant_uid, "status": "reclaimed", "idempotent": True}
+            if claim["state"] == "leased":
+                raise RuntimeError("trusted delivery reclaim is already leased")
+        try:
+            adapter = self.provider_registry.get(grant["provider"])
+        except PermissionError:
+            self._event("reclaim_provider_unavailable", actor, {"grant_uid": grant_uid, "provider": grant["provider"], "request_digest": request_digest})
+            raise
+        envelope = {"schema": "dataops.trusted-delivery.v2", "operation": "revoke", "grant_uid": grant_uid, "provider": grant["provider"], "asset_uid": grant["asset_uid"], "request_digest": request_digest}
+        revoke = getattr(adapter, "revoke", None)
+        if not callable(revoke):
+            self._event("reclaim_provider_unavailable", actor, {"grant_uid": grant_uid, "provider": grant["provider"], "request_digest": request_digest})
+            raise PermissionError("trusted delivery provider revoke is disabled")
+        try:
+            response = _closed(revoke(copy.deepcopy(envelope)), {"status", "receipt_code", "response_digest"}, "provider receipt")
+        except Exception:
+            if claim:
+                self.repository.fail_reclaim_operation(claim["delivery_uid"], worker_id, claim["lease_fence"])
+            raise
+        if response.get("status") != "revoked":
+            if claim:
+                self.repository.fail_reclaim_operation(claim["delivery_uid"], worker_id, claim["lease_fence"])
+            raise RuntimeError("trusted delivery provider failed closed")
+        receipt = {"grant_uid": grant_uid, "status": "reclaimed", "receipt_code": _text(response.get("receipt_code"), "receipt code", 120), "response_digest": _digest_value(response.get("response_digest"), "provider response digest"), "diff_digest": _digest({"operation": "revoke", "request_digest": request_digest, "response_digest": response.get("response_digest")})}
+        if claim:
+            saved = self.repository.complete_claimed_reclaim(grant_uid, claim["delivery_uid"], worker_id, claim["lease_fence"], receipt)
+        elif hasattr(self.repository, "complete_reclaim"):
+            saved = self.repository.complete_reclaim(grant_uid, key, request_digest, receipt)
+        else:
+            saved = self.repository.update_grant_status(grant_uid, grant["current_version"], "reclaimed", "expired_reclaimed")
+        self._event("grant_reclaimed", actor, {"grant_uid": grant_uid, "provider": grant["provider"], "request_digest": request_digest, "response_digest": receipt["response_digest"]})
+        return {"grant_uid": grant_uid, "status": saved["status"], "receipt": receipt}
+
+    def preview_reclaim(self, *, as_of: Any, actor_uid: str) -> list[dict[str, Any]]:
+        """Return eligible identifiers only; this query has no state transition."""
+        self._actor(actor_uid)
+        instant = _time(as_of, "as_of")
+        candidates = []
+        for grant in self.repository.grants_due_for_revoke(instant):
+            if grant.get("status") != "active" or _time(grant["expires_at"], "grant expiry") > instant:
+                continue
+            if self.repository.active_hold_for_asset(grant["asset_uid"]):
+                continue
+            candidates.append({"grant_uid": grant["uid"], "provider": grant.get("provider", "unknown"), "status": "eligible"})
+        return candidates
+
+    def revoke_expired(self, *, as_of: datetime, actor_uid: str) -> list[dict[str, Any]]:
+        actor = self._actor(actor_uid)
+        instant = _time(as_of, "as_of")
+        revoked = []
+        for grant in self.repository.grants_due_for_revoke(instant):
+            if _time(grant["expires_at"], "grant expiry") > instant or self.repository.active_hold_for_asset(grant["asset_uid"]):
+                continue
+            saved = self.repository.update_grant_status(grant["uid"], grant["current_version"], "revoked", "expired")
+            self._event("grant_revoked", actor, {"grant_uid": saved["uid"], "reason_code": "expired"})
+            revoked.append(saved)
+        return revoked
+
+    @staticmethod
+    def mask_preview(payload: Any) -> dict[str, Any]:
+        body = _closed(payload, {"mode", "mask_ref", "value"}, "mask preview")
+        mode = _text(body.get("mode"), "mask mode", 20)
+        if mode not in {"static", "dynamic", "display", "export"}:
+            raise ValueError("unsupported mask mode")
+        mask_ref = _text(body.get("mask_ref"), "mask ref", 120)
+        value = _text(body.get("value"), "mask value", 1000)
+        return {"mode": mode, "mask_ref": mask_ref, "masked_value": "***-****", "token_digest": _digest({"mask_ref": mask_ref, "value": value})}

+ 293 - 0
app/core/system/trusted_delivery_controls.py

@@ -0,0 +1,293 @@
+"""Fail-closed control-profile and trusted-delivery gate contracts.
+
+The module deliberately models only safe identifiers, digests and decision
+codes.  It neither stores scan payloads or credentials nor claims that an
+external legal, identity, network or industry assessment has happened.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import hmac
+import json
+import re
+from collections.abc import Callable, Mapping
+from datetime import UTC, datetime
+from typing import Any
+
+
+class TrustedDeliveryControlError(ValueError):
+    """The closed trusted-delivery controls rejected a caller supplied value."""
+
+
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_REF = re.compile(r"^[a-z][a-z0-9-]{2,40}:[A-Za-z0-9._-]{1,160}$")
+_ID = re.compile(r"^[A-Za-z][A-Za-z0-9._-]{2,159}$")
+_VERSION = re.compile(r"^[A-Za-z][A-Za-z0-9._-]{0,39}$")
+_UNSAFE = re.compile(
+    r"(?i)(?:https?://|ftp://|file://|\b(?:credential|secret|token|password|private[ _-]?key)\b|"
+    r"-----BEGIN|<script|javascript:|;|\b(?:select|insert|update|delete|drop|alter)\b)"
+)
+_CAPABILITIES = {
+    "kms": frozenset({"kms-key-wrap", "kms-evidence-seal"}),
+    "dlp": frozenset({"dlp-export-check"}),
+    "siem": frozenset({"siem-security-event"}),
+    "iam": frozenset({"iam-entitlement-provision"}),
+    "target": frozenset({"target-db-provision", "target-api-provision", "target-file-provision"}),
+}
+
+
+def _canonical(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _digest(value: Any) -> str:
+    return hashlib.sha256(_canonical(value).encode()).hexdigest()
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise TrustedDeliveryControlError(f"{label} must be an object")
+    extra = set(value) - allowed
+    if extra:
+        raise TrustedDeliveryControlError(f"{label} contains unsupported fields")
+    return copy.deepcopy(value)
+
+
+def _text(value: Any, label: str, maximum: int = 160) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise TrustedDeliveryControlError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum:
+        raise TrustedDeliveryControlError(f"{label} exceeds {maximum} characters")
+    if _UNSAFE.search(result):
+        raise TrustedDeliveryControlError(f"{label} contains unsafe content")
+    return result
+
+
+def _sha256(value: Any, label: str) -> str:
+    result = _text(value, label, 64).lower()
+    if not _DIGEST.fullmatch(result):
+        raise TrustedDeliveryControlError(f"{label} must be a SHA-256 digest")
+    return result
+
+
+def _instant(value: Any, label: str) -> datetime:
+    try:
+        result = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as error:
+        raise TrustedDeliveryControlError(f"{label} must be ISO-8601") from error
+    if result.tzinfo is None:
+        raise TrustedDeliveryControlError(f"{label} must include a timezone")
+    return result.astimezone(UTC)
+
+
+class ControlProfileCatalog:
+    """Versioned engineering evidence mappings, never external certification."""
+
+    _profiles = {
+        "china_general": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-16", "SEC-20"),
+        "finance": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-17", "SEC-20", "SEC-21"),
+        "medical": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-18", "SEC-20", "SEC-21"),
+        "government": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-19", "SEC-20", "SEC-22"),
+    }
+
+    def resolve(self, profile_id: Any, version: Any) -> dict[str, Any]:
+        name = _text(profile_id, "control profile", 40)
+        release = _text(version, "control profile version", 20)
+        if release != "1.0" or name not in self._profiles:
+            raise TrustedDeliveryControlError("unknown control profile version")
+        modules = self._profiles[name]
+        return {
+            "profile_id": name,
+            "version": release,
+            "conformance_state": "ENGINEERING_EVIDENCE_ONLY",
+            "external_required": True,
+            "external_dependencies": ["security_legal", "identity", "network"],
+            "evidence_mapping": [
+                {"module_id": module_id, "evidence_kind": "engineering_control_reference"}
+                for module_id in modules
+            ],
+        }
+
+
+class TrustedCapabilityRegistry:
+    """Closed, default-disabled capabilities with locally verifiable fake receipts."""
+
+    def __init__(self, approved: Mapping[str, Mapping[str, str]] | None = None, *, test_mode: bool = False):
+        values = dict(approved or {})
+        if values and not test_mode:
+            raise TrustedDeliveryControlError("enterprise capabilities require approved external integration")
+        if set(values) - set(_CAPABILITIES):
+            raise TrustedDeliveryControlError("unsupported capability provider")
+        self._approved: dict[str, dict[str, str]] = {}
+        for provider, descriptor in values.items():
+            body = _closed(descriptor, {"version", "config_digest"}, "capability descriptor")
+            version = _text(body.get("version"), "capability version", 30)
+            if not _VERSION.fullmatch(version):
+                raise TrustedDeliveryControlError("capability version is invalid")
+            self._approved[provider] = {
+                "version": version,
+                "config_digest": _sha256(body.get("config_digest"), "capability config digest"),
+            }
+        self._replay: dict[str, str] = {}
+
+    @classmethod
+    def for_tests(cls, approved: Mapping[str, Mapping[str, str]]):
+        return cls(approved, test_mode=True)
+
+    def dependency_status(self) -> dict[str, str]:
+        return {
+            provider: "LOCAL_FAKE_ONLY" if provider in self._approved else "TBD_EXTERNAL"
+            for provider in sorted(_CAPABILITIES)
+        }
+
+    def _key(self, provider: str) -> bytes:
+        descriptor = self._approved[provider]
+        return hashlib.sha256(
+            f"trusted-delivery-local-fake:{provider}:{descriptor['version']}:{descriptor['config_digest']}".encode()
+        ).digest()
+
+    def issue_envelope(self, provider: Any, capability: Any, payload: Any) -> dict[str, str]:
+        provider_name = _text(provider, "capability provider", 30)
+        operation = _text(capability, "capability", 80)
+        if provider_name not in _CAPABILITIES or operation not in _CAPABILITIES[provider_name]:
+            raise TrustedDeliveryControlError("unsupported capability")
+        if provider_name not in self._approved:
+            raise TrustedDeliveryControlError("capability provider is disabled")
+        body = _closed(payload, {"request_digest", "expires_at"}, "capability envelope request")
+        request_digest = _sha256(body.get("request_digest"), "request digest")
+        expires_at = _instant(body.get("expires_at"), "capability envelope expiry")
+        if expires_at <= datetime.now(UTC):
+            raise TrustedDeliveryControlError("capability envelope is expired")
+        replay_key = f"{provider_name}:{operation}:{request_digest}"
+        request_fingerprint = _digest({"request_digest": request_digest, "expires_at": expires_at.isoformat()})
+        if replay_key in self._replay:
+            if self._replay[replay_key] != request_fingerprint:
+                raise TrustedDeliveryControlError("capability replay conflict")
+            raise TrustedDeliveryControlError("capability replay rejected")
+        descriptor = self._approved[provider_name]
+        envelope = {
+            "capability": operation,
+            "version": descriptor["version"],
+            "config_digest": descriptor["config_digest"],
+            "request_digest": request_digest,
+            "expires_at": expires_at.isoformat(),
+            "receipt": f"LOCAL_FAKE_{_digest([provider_name, operation, request_digest])[:20].upper()}",
+        }
+        envelope["signature"] = hmac.new(self._key(provider_name), _canonical(envelope).encode(), hashlib.sha256).hexdigest()
+        self._replay[replay_key] = request_fingerprint
+        return envelope
+
+    def verify_envelope(self, envelope: Any) -> bool:
+        body = _closed(envelope, {"capability", "version", "config_digest", "request_digest", "expires_at", "receipt", "signature"}, "capability receipt")
+        operation = _text(body.get("capability"), "capability", 80)
+        provider = next((name for name, allowed in _CAPABILITIES.items() if operation in allowed), None)
+        if provider is None or provider not in self._approved:
+            raise TrustedDeliveryControlError("capability receipt is disabled")
+        descriptor = self._approved[provider]
+        if body.get("version") != descriptor["version"] or body.get("config_digest") != descriptor["config_digest"]:
+            raise TrustedDeliveryControlError("capability receipt binding is invalid")
+        _sha256(body.get("request_digest"), "request digest")
+        if _instant(body.get("expires_at"), "capability receipt expiry") <= datetime.now(UTC):
+            raise TrustedDeliveryControlError("capability receipt is expired")
+        receipt = _text(body.get("receipt"), "receipt", 80)
+        signature = _sha256(body.get("signature"), "receipt signature")
+        signed = {key: body[key] for key in body if key != "signature"}
+        expected = hmac.new(self._key(provider), _canonical(signed).encode(), hashlib.sha256).hexdigest()
+        if not hmac.compare_digest(signature, expected):
+            raise TrustedDeliveryControlError("capability receipt signature is invalid")
+        if not receipt.startswith("LOCAL_FAKE_"):
+            raise TrustedDeliveryControlError("capability receipt is invalid")
+        return True
+
+
+class SupplyChainReleaseGate:
+    """Digest-only release gate; a passing result is not a production approval."""
+
+    def __init__(self, *, now_factory: Callable[[], datetime] | None = None):
+        self.now_factory = now_factory or (lambda: datetime.now(UTC))
+
+    def evaluate(self, payload: Any) -> dict[str, str]:
+        body = _closed(payload, {
+            "artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest",
+            "approval_id", "approval_version", "scan_decision", "evidence_expires_at",
+        }, "release gate")
+        required = (
+            "artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest",
+            "approval_id", "approval_version", "scan_decision", "evidence_expires_at",
+        )
+        if any(key not in body or body[key] in (None, "") for key in required):
+            raise TrustedDeliveryControlError("missing release gate evidence")
+        digests = {key: _sha256(body[key], key.replace("_", " ")) for key in required[:4]}
+        approval_id = _text(body["approval_id"], "approval id", 160)
+        approval_version = _text(body["approval_version"], "approval version", 40)
+        if not _ID.fullmatch(approval_id) or not _VERSION.fullmatch(approval_version):
+            raise TrustedDeliveryControlError("release approval is invalid")
+        expiry = _instant(body["evidence_expires_at"], "release gate evidence expiry")
+        if expiry <= self.now_factory().astimezone(UTC):
+            raise TrustedDeliveryControlError("release gate evidence is expired")
+        if body["scan_decision"] != "passed":
+            raise TrustedDeliveryControlError("release gate rejected")
+        return {
+            "decision_code": "RELEASE_GATE_APPROVED",
+            **digests,
+            "approval_id": approval_id,
+            "approval_version": approval_version,
+            "evidence_expires_at": expiry.isoformat(),
+        }
+
+
+class EvidenceLedger:
+    """In-memory append-only contract used before its repository migration lands."""
+
+    def __init__(self):
+        self._entries: list[dict[str, str]] = []
+        self._audit: list[dict[str, str]] = []
+
+    def append(self, payload: Any) -> dict[str, str]:
+        body = _closed(payload, {"evidence_ref", "evidence_digest", "decision_code"}, "evidence entry")
+        if set(body) != {"evidence_ref", "evidence_digest", "decision_code"}:
+            raise TrustedDeliveryControlError("evidence entry is incomplete")
+        reference = _text(body["evidence_ref"], "evidence reference", 200)
+        if not _REF.fullmatch(reference):
+            raise TrustedDeliveryControlError("evidence reference is invalid")
+        entry = {
+            "evidence_ref": reference,
+            "evidence_digest": _sha256(body["evidence_digest"], "evidence digest"),
+            "decision_code": _text(body["decision_code"], "decision code", 120),
+        }
+        if any(item["evidence_ref"] == entry["evidence_ref"] for item in self._entries):
+            raise TrustedDeliveryControlError("evidence is immutable")
+        self._entries.append(entry)
+        return dict(entry)
+
+    def export_summary(self) -> list[dict[str, str]]:
+        return [dict(item) for item in self._entries]
+
+    def approve_destruction(self, payload: Any) -> dict[str, str]:
+        body = _closed(payload, {"approval_refs", "active_hold"}, "destruction approval")
+        refs = body.get("approval_refs")
+        if not isinstance(refs, list) or len(refs) != 2:
+            self._audit.append({"decision_code": "DESTRUCTION_REJECTED"})
+            raise TrustedDeliveryControlError("destruction requires two independent approvals")
+        approvals = [_text(item, "destruction approval reference", 160) for item in refs]
+        if approvals[0] == approvals[1]:
+            self._audit.append({"decision_code": "DESTRUCTION_REJECTED"})
+            raise TrustedDeliveryControlError("destruction requires two independent approvals")
+        if body.get("active_hold") is not False:
+            self._audit.append({"decision_code": "DESTRUCTION_HELD"})
+            raise TrustedDeliveryControlError("destruction blocked by active legal hold")
+        result = {"decision_code": "DESTRUCTION_DUAL_APPROVED", "approval_digest": _digest(sorted(approvals))}
+        self._audit.append(dict(result))
+        return result
+
+    def tamper(self, payload: Any) -> None:
+        # Never preserve an attempted replacement value, which may itself be sensitive.
+        _closed(payload, {"evidence_ref", "replacement"}, "tamper attempt")
+        self._audit.append({"decision_code": "TAMPER_REJECTED"})
+        raise TrustedDeliveryControlError("evidence ledger is immutable")
+
+    def audit_events(self) -> list[dict[str, str]]:
+        return [dict(item) for item in self._audit]

+ 150 - 0
app/core/system/trusted_delivery_controls_repository.py

@@ -0,0 +1,150 @@
+"""PostgreSQL persistence for digest-only trusted-delivery control evidence."""
+
+from __future__ import annotations
+
+import json
+import uuid
+from typing import Any
+
+from sqlalchemy import text
+
+
+def _json(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _row(value) -> dict[str, Any] | None:
+    return None if value is None else dict(value)
+
+
+class SqlAlchemyTrustedDeliveryControlsRepository:
+    """Closed-schema writes; service validation remains the public boundary."""
+
+    def __init__(self, session):
+        self.session = session
+
+    def _trusted_delivery_runtime_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_control_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        result = self.session.execute(text("SELECT public.trusted_delivery_runtime_control_write(:operation, CAST(:payload AS jsonb))"), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _runtime_restricted(self) -> bool:
+        return not self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_control_profile_versions', 'INSERT')
+        """)).scalar_one()
+
+    def users_available(self, values):
+        values = sorted(set(values))
+        if not values:
+            return set()
+        return set(self.session.execute(text("SELECT id::text FROM public.users WHERE status='active' AND id=ANY(CAST(:values AS uuid[]))"), {"values": values}).scalars())
+
+    def create_profile(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("create_control_profile", record))
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_control_profile_versions
+          (uid,profile_id,version,status,profile,profile_digest,created_by,current_version)
+          VALUES(CAST(:uid AS uuid),:profile_id,:version,'draft',CAST(:profile AS jsonb),:profile_digest,CAST(:created_by AS uuid),1)
+          RETURNING uid::text,profile_id,version,status,current_version"""), {**record, "profile": _json(record["profile"])}).mappings().one()
+        return _row(row)
+
+    def profile_exists(self, profile_id, version):
+        return self.session.execute(text("SELECT 1 FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND version=:version"), {"profile": profile_id, "version": version}).scalar_one_or_none() is not None
+
+    def activate_profile(self, profile_id, version, idempotency_key, request_digest, actor_uid, approval_ref, approval_digest, operation="activate"):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("activate_control_profile", {
+                "uid": str(uuid.uuid4()), "profile_id": profile_id, "version": version,
+                "idempotency_key": idempotency_key, "request_digest": request_digest,
+                "actor_uid": actor_uid, "approval_ref": approval_ref,
+                "approval_digest": approval_digest, "transition_operation": operation,
+            }))
+        existing = self.session.execute(text("SELECT profile_uid::text,request_digest FROM public.trusted_delivery_control_profile_transitions WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            row = self.session.execute(text("SELECT uid::text,profile_id,version,status,current_version FROM public.trusted_delivery_control_profile_versions WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["profile_uid"]}).mappings().one()
+            return _row(row)
+        target = self.session.execute(text("SELECT uid::text FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND version=:version FOR UPDATE"), {"profile": profile_id, "version": version}).mappings().one_or_none()
+        if target is None:
+            raise LookupError("control profile version was not found")
+        self.session.execute(text("SELECT uid FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND status='active' FOR UPDATE"), {"profile": profile_id})
+        self.session.execute(text("UPDATE public.trusted_delivery_control_profile_versions SET status='retired',current_version=current_version+1,updated_at=clock_timestamp() WHERE profile_id=:profile AND status='active' AND uid<>CAST(:uid AS uuid)"), {"profile": profile_id, "uid": target["uid"]})
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_control_profile_versions
+          SET status='active',current_version=current_version+CASE WHEN status='active' THEN 0 ELSE 1 END,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) RETURNING uid::text,profile_id,version,status,current_version"""), {"uid": target["uid"]}).mappings().one()
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_control_profile_transitions
+          (uid,profile_uid,operation,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+          VALUES(CAST(:uid AS uuid),CAST(:profile_uid AS uuid),:operation,:key,:request_digest,:approval_ref,:approval_digest,CAST(:actor AS uuid))"""), {"uid": str(uuid.uuid4()), "profile_uid": target["uid"], "operation": operation, "key": idempotency_key, "request_digest": request_digest, "approval_ref": approval_ref, "approval_digest": approval_digest, "actor": actor_uid})
+        return _row(row)
+
+    def active_profile_summary(self, profile_id):
+        row = self.session.execute(text("SELECT profile_id,version,profile_digest,status,current_version FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND status='active'"), {"profile": profile_id}).mappings().one_or_none()
+        return _row(row)
+
+    def approve_capability(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_control_write("approve_capability", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_capability_approvals WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return {"uid": existing["uid"], "status": "approved"}
+        self.session.execute(text("UPDATE public.trusted_delivery_capability_approvals SET status='revoked' WHERE provider=:provider AND capability=:capability AND status='approved'"), record)
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_capability_approvals
+          (uid,provider,capability,version,config_digest,status,idempotency_key,request_digest,created_by,approval_ref,approval_digest)
+          VALUES(CAST(:uid AS uuid),:provider,:capability,:version,:config_digest,'approved',:idempotency_key,:request_digest,CAST(:created_by AS uuid),:approval_ref,:approval_digest)
+          RETURNING uid::text,provider,capability,version,config_digest,status"""), record).mappings().one()
+        return _row(row)
+
+    def record_release_gate(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_control_write("record_release_gate", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest,decision_code FROM public.trusted_delivery_supply_chain_gates WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return _row(existing)
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_supply_chain_gates
+          (uid,artifact_digest,sbom_digest,license_policy_digest,vulnerability_scan_digest,approval_id,approval_version,evidence_expires_at,decision_code,idempotency_key,request_digest,created_by,approval_ref,approval_digest)
+          VALUES(CAST(:uid AS uuid),:artifact_digest,:sbom_digest,:license_policy_digest,:vulnerability_scan_digest,:approval_id,:approval_version,CAST(:evidence_expires_at AS timestamptz),:decision_code,:idempotency_key,:request_digest,CAST(:created_by AS uuid),:approval_ref,:approval_digest)
+          RETURNING uid::text,decision_code,artifact_digest,sbom_digest,license_policy_digest,vulnerability_scan_digest,approval_id,approval_version,evidence_expires_at"""), record).mappings().one()
+        return _row(row)
+
+    def create_evidence(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_control_write("create_control_evidence", record))
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_control_evidence
+          (uid,evidence_ref,evidence_digest,decision_code,gate_uid,actor_uid,approval_ref,approval_digest)
+          VALUES(CAST(:uid AS uuid),:evidence_ref,:evidence_digest,:decision_code,CAST(:gate_uid AS uuid),CAST(:actor_uid AS uuid),:approval_ref,:approval_digest)
+          ON CONFLICT(evidence_ref) DO NOTHING
+          RETURNING uid::text,evidence_ref,evidence_digest,decision_code,gate_uid::text"""), record).mappings().one_or_none()
+        if row is None:
+            row = self.session.execute(text("SELECT uid::text,evidence_ref,evidence_digest,decision_code,gate_uid::text FROM public.trusted_delivery_control_evidence WHERE evidence_ref=:evidence_ref"), {"evidence_ref": record["evidence_ref"]}).mappings().one()
+        return _row(row)
+
+    def evidence_summary(self, limit=100):
+        rows = self.session.execute(text("SELECT evidence_ref,evidence_digest,decision_code,gate_uid::text FROM public.trusted_delivery_control_evidence ORDER BY created_at,uid LIMIT :limit"), {"limit": int(limit)}).mappings()
+        return [_row(row) for row in rows]
+
+    def approve_destruction(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("approve_destruction", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest,status FROM public.trusted_delivery_destruction_approvals WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return _row(existing)
+        if self.session.execute(text("SELECT 1 FROM public.trusted_delivery_legal_holds WHERE asset_uid=CAST(:asset AS uuid) AND status='active'"), {"asset": record["asset_uid"]}).scalar_one_or_none():
+            raise PermissionError("destruction blocked by active legal hold")
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_destruction_approvals
+          (uid,asset_uid,approval_ref_one,approval_ref_two,evidence_digest,status,idempotency_key,request_digest,created_by)
+          VALUES(CAST(:uid AS uuid),CAST(:asset_uid AS uuid),:approval_ref_one,:approval_ref_two,:evidence_digest,'approved',:idempotency_key,:request_digest,CAST(:created_by AS uuid))
+          RETURNING uid::text,status"""), record).mappings().one()
+        return _row(row)

+ 103 - 0
app/core/system/trusted_delivery_controls_service.py

@@ -0,0 +1,103 @@
+"""Service boundary for durable trusted-delivery control profiles and gates."""
+
+from __future__ import annotations
+
+import hashlib
+import uuid
+from typing import Any
+
+from app.core.system.trusted_delivery_controls import (
+    ControlProfileCatalog,
+    EvidenceLedger,
+    SupplyChainReleaseGate,
+    TrustedDeliveryControlError,
+    _closed,
+    _digest,
+    _sha256,
+    _text,
+)
+
+
+class TrustedDeliveryControlsService:
+    def __init__(self, repository, *, catalog=None, gate=None):
+        self.repository = repository
+        self.catalog = catalog or ControlProfileCatalog()
+        self.gate = gate or SupplyChainReleaseGate()
+
+    def _actor(self, actor_uid: str) -> str:
+        if self.repository.users_available({actor_uid}) != {actor_uid}:
+            raise TrustedDeliveryControlError("control actor is unavailable")
+        return actor_uid
+
+    def _transition(self, payload: Any, *, actor_uid: str, operation: str) -> dict[str, Any]:
+        body = _closed(payload, {"profile_id", "version", "approval_ref", "approval_digest", "idempotency_key"}, "control profile transition")
+        actor = self._actor(actor_uid)
+        profile = self.catalog.resolve(body.get("profile_id"), body.get("version"))
+        digest = _digest(profile)
+        profile_id = profile["profile_id"]
+        version = profile["version"]
+        if not self.repository.profile_exists(profile_id, version):
+            self.repository.create_profile({"uid": str(uuid.uuid4()), "profile_id": profile_id, "version": version, "profile_digest": digest, "profile": profile, "created_by": actor})
+        request = {
+            "profile_id": profile_id, "version": version,
+            "approval_ref": _text(body.get("approval_ref"), "approval reference", 200),
+            "approval_digest": _sha256(body.get("approval_digest"), "approval digest"),
+            "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160),
+            "operation": operation,
+        }
+        return self.repository.activate_profile(profile_id, version, request["idempotency_key"], _digest(request), actor, request["approval_ref"], request["approval_digest"], operation)
+
+    def activate_profile(self, payload: Any, *, actor_uid: str, operation: str = "activate") -> dict[str, Any]:
+        return self._transition(payload, actor_uid=actor_uid, operation=operation)
+
+    def active_profile_summary(self, profile_id: Any) -> dict[str, Any] | None:
+        return self.repository.active_profile_summary(_text(profile_id, "control profile", 40))
+
+    def approve_capability(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"provider", "capability", "version", "config_digest", "approval_ref", "approval_digest", "idempotency_key"}, "capability approval")
+        actor = self._actor(actor_uid)
+        provider = _text(body.get("provider"), "capability provider", 20)
+        capability = _text(body.get("capability"), "capability", 80)
+        allowed = {
+            "kms": {"kms-key-wrap", "kms-evidence-seal"}, "dlp": {"dlp-export-check"},
+            "siem": {"siem-security-event"}, "iam": {"iam-entitlement-provision"},
+            "target": {"target-db-provision", "target-api-provision", "target-file-provision"},
+        }
+        if provider not in allowed or capability not in allowed[provider]:
+            raise TrustedDeliveryControlError("unsupported capability")
+        record = {"uid": str(uuid.uuid4()), "provider": provider, "capability": capability, "version": _text(body.get("version"), "capability version", 40), "config_digest": _sha256(body.get("config_digest"), "config digest"), "approval_ref": _text(body.get("approval_ref"), "approval reference", 200), "approval_digest": _sha256(body.get("approval_digest"), "approval digest"), "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160), "created_by": actor}
+        record["request_digest"] = _digest({key: record[key] for key in ("provider", "capability", "version", "config_digest", "idempotency_key")})
+        return self.repository.approve_capability(record)
+
+    def evaluate_release_gate(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "scan_decision", "evidence_expires_at", "approval_ref", "approval_digest", "idempotency_key"}, "release gate request")
+        actor = self._actor(actor_uid)
+        # Approval proof binds the durable write, but is not an input to the
+        # release-policy evaluator's closed schema.
+        summary = self.gate.evaluate({key: body[key] for key in (
+            "artifact_digest", "sbom_digest", "license_policy_digest",
+            "vulnerability_scan_digest", "approval_id", "approval_version",
+            "scan_decision", "evidence_expires_at",
+        )})
+        record = {"uid": str(uuid.uuid4()), **{key: summary[key] for key in ("artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "evidence_expires_at", "decision_code")}, "approval_ref": _text(body.get("approval_ref"), "approval reference", 200), "approval_digest": _sha256(body.get("approval_digest"), "approval digest"), "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160), "created_by": actor}
+        record["request_digest"] = _digest({key: record[key] for key in record if key not in {"uid", "created_by"}})
+        result = self.repository.record_release_gate(record)
+        self.repository.create_evidence({"uid": str(uuid.uuid4()), "evidence_ref": f"trusted-evidence:gate-{result['uid']}", "evidence_digest": hashlib.sha256(result["uid"].encode()).hexdigest(), "decision_code": result["decision_code"], "gate_uid": result["uid"], "actor_uid": actor, "approval_ref": record["approval_ref"], "approval_digest": record["approval_digest"]})
+        return result
+
+    def evidence_summary(self) -> list[dict[str, Any]]:
+        return self.repository.evidence_summary()
+
+    def approve_destruction(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"asset_uid", "approval_refs", "evidence_digest", "idempotency_key"}, "destruction approval")
+        actor = self._actor(actor_uid)
+        refs = body.get("approval_refs")
+        ledger = EvidenceLedger()
+        ledger.approve_destruction({"approval_refs": refs, "active_hold": False})
+        try:
+            asset_uid = str(uuid.UUID(str(body.get("asset_uid"))))
+        except (TypeError, ValueError, AttributeError) as error:
+            raise TrustedDeliveryControlError("asset uid must be a UUID") from error
+        record = {"uid": str(uuid.uuid4()), "asset_uid": asset_uid, "approval_ref_one": refs[0], "approval_ref_two": refs[1], "evidence_digest": _sha256(body.get("evidence_digest"), "evidence digest"), "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160), "created_by": actor}
+        record["request_digest"] = _digest({key: record[key] for key in ("asset_uid", "approval_ref_one", "approval_ref_two", "evidence_digest", "idempotency_key")})
+        return self.repository.approve_destruction(record)

+ 534 - 0
app/core/system/trusted_delivery_repository.py

@@ -0,0 +1,534 @@
+"""PostgreSQL repository for trusted-delivery state and digest-only receipts."""
+
+from __future__ import annotations
+
+import json
+import uuid
+from datetime import datetime
+from typing import Any
+
+from sqlalchemy import text
+
+
+def _json(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _row(row) -> dict[str, Any] | None:
+    return None if row is None else dict(row)
+
+
+class SqlAlchemyTrustedDeliveryRepository:
+    """All writes are parameterized and transactions are owned by the caller."""
+
+    def __init__(self, session):
+        self.session = session
+
+    def _trusted_delivery_gateway(self, operation: str, payload: dict[str, Any]) -> dict[str, Any] | None:
+        """Use the database definer gateway when this is a runtime session.
+
+        Migration/test identities retain direct DML while the long-running
+        runtime login receives only EXECUTE on the closed operation gateway.
+        The decision is derived from PostgreSQL privileges, not a caller flag.
+        """
+        direct_dml = self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_policy_versions', 'INSERT')
+        """)).scalar_one()
+        if direct_dml:
+            return None
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        """Execute one fixed database-side WP06 lifecycle operation."""
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_reclaim_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        """Use the atomic revoke outbox gateway for a restricted runtime login."""
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_reclaim_write(
+              :operation, CAST(:payload AS jsonb)
+            )
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _runtime_restricted(self) -> bool:
+        return not self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_grants', 'INSERT')
+        """)).scalar_one()
+
+    def users_available(self, values):
+        values = sorted(set(values))
+        if not values:
+            return set()
+        return set(self.session.execute(text("SELECT id::text FROM public.users WHERE status='active' AND id=ANY(CAST(:values AS uuid[]))"), {"values": values}).scalars())
+
+    def create_policy_version(self, record):
+        gateway = self._trusted_delivery_gateway("create_policy", {
+            key: record[key] for key in ("uid", "code", "version", "selector", "resource_rules", "created_by", "current_version") if key in record
+        })
+        if gateway is not None:
+            return gateway
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_policy_versions
+          (uid,code,version,status,selector,resource_rules,created_by,current_version)
+          VALUES(CAST(:uid AS uuid),:code,:version,:status,CAST(:selector AS jsonb),CAST(:resource_rules AS jsonb),CAST(:created_by AS uuid),:current_version)
+          RETURNING uid::text,code,version,status,current_version"""), {**record, "selector": _json(record["selector"]), "resource_rules": _json(record["resource_rules"])}).mappings().one()
+        # Compatibility for pre-WP06 fixture importers only: production policy
+        # creation always enters as draft and is activated through
+        # ``transition_policy``.  A repository caller that imports an already
+        # active historic record still receives an auditable bootstrap approval,
+        # so the DB active-grant trigger is never bypassed.
+        if record["status"] == "active":
+            self.session.execute(text("""INSERT INTO public.trusted_delivery_policy_transitions
+              (uid,policy_uid,operation,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+              VALUES(CAST(:uid AS uuid),CAST(:policy AS uuid),'activate',:key,:digest,:approval_ref,:digest,CAST(:actor AS uuid))
+              ON CONFLICT (idempotency_key) DO NOTHING"""), {
+                "uid": str(uuid.uuid4()), "policy": record["uid"],
+                "key": f"bootstrap:{record['uid']}", "digest": "0" * 64,
+                "approval_ref": f"bootstrap:{record['uid']}", "actor": record["created_by"],
+            })
+        return _row(row)
+
+    def transition_policy(self, code, version, operation, idempotency_key, request_digest, actor_uid, approval_ref, approval_digest):
+        gateway = self._trusted_delivery_gateway("transition_policy", {
+            "code": code, "version": version, "operation": operation,
+            "idempotency_key": idempotency_key, "request_digest": request_digest,
+            "actor_uid": actor_uid, "approval_ref": approval_ref,
+            "approval_digest": approval_digest,
+        })
+        if gateway is not None:
+            return gateway
+        existing = self.session.execute(text("SELECT policy_uid::text,request_digest FROM public.trusted_delivery_policy_transitions WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            row = self.session.execute(text("SELECT uid::text,code,version,status,current_version FROM public.trusted_delivery_policy_versions WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["policy_uid"]}).mappings().one()
+            return _row(row)
+        target = self.session.execute(text("SELECT uid::text,code,version,status,current_version FROM public.trusted_delivery_policy_versions WHERE code=:code AND version=:version FOR UPDATE"), {"code": code, "version": version}).mappings().one_or_none()
+        if target is None:
+            raise LookupError("trusted delivery policy version was not found")
+        # Lock all candidate active rows before changing the partial unique index.
+        self.session.execute(text("SELECT uid FROM public.trusted_delivery_policy_versions WHERE code=:code AND status='active' FOR UPDATE"), {"code": code})
+        self.session.execute(text("UPDATE public.trusted_delivery_policy_versions SET status='retired',current_version=current_version+1 WHERE code=:code AND status='active' AND uid<>CAST(:uid AS uuid)"), {"code": code, "uid": target["uid"]})
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_policy_versions
+          SET status='active',current_version=current_version+CASE WHEN status='active' THEN 0 ELSE 1 END
+          WHERE uid=CAST(:uid AS uuid)
+          RETURNING uid::text,code,version,status,current_version"""), {"uid": target["uid"]}).mappings().one()
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_policy_transitions
+          (uid,policy_uid,operation,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+          VALUES(CAST(:uid AS uuid),CAST(:policy_uid AS uuid),:operation,:key,:request_digest,:approval_ref,:approval_digest,CAST(:actor_uid AS uuid))"""), {"uid": str(uuid.uuid4()), "policy_uid": target["uid"], "operation": operation, "key": idempotency_key, "request_digest": request_digest, "approval_ref": approval_ref, "approval_digest": approval_digest, "actor_uid": actor_uid})
+        return _row(row)
+
+    def active_policies(self):
+        rows = self.session.execute(text("SELECT uid::text,code,version,status,selector,resource_rules FROM public.trusted_delivery_policy_versions WHERE status='active' ORDER BY created_at,uid")).mappings()
+        return [{**_row(row), "selector": dict(row["selector"]), "resource_rules": dict(row["resource_rules"])} for row in rows]
+
+    def enqueue_grant(self, record):
+        if record.get("approval_ref") and record.get("approval_digest") and record.get("target_capability") is not None:
+            gateway = self._trusted_delivery_gateway("create_grant", {
+                key: record[key] for key in (
+                    "uid", "policy_uid", "subject_uid", "asset_uid", "provider",
+                    "idempotency_key", "request_digest", "expires_at", "status",
+                    "reason_code", "current_version", "created_by", "approval_ref",
+                    "approval_digest", "purpose", "environment", "target_capability",
+                ) if key in record
+            })
+            if gateway is not None:
+                return {"uid": gateway["uid"]}
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_grants WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return {"uid": existing["uid"]}
+        # This method is also used by controlled legacy import tests.  Public
+        # provision paths always provide the real server-derived values; the
+        # import fallback remains database-validated and cannot be reproduced
+        # by direct SQL.
+        legacy_digest = record.get("request_digest")
+        values = {
+            "approval_ref": f"legacy-import:{record['uid']}", "approval_digest": legacy_digest,
+            "purpose": "legacy_import", "environment": "test", "target_capability": {}, **record,
+        }
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_grants
+          (uid,policy_uid,subject_uid,asset_uid,provider,idempotency_key,request_digest,expires_at,status,reason_code,current_version,created_by,approval_ref,approval_digest,purpose,environment,target_capability)
+          VALUES(CAST(:uid AS uuid),CAST(:policy_uid AS uuid),CAST(:subject_uid AS uuid),CAST(:asset_uid AS uuid),:provider,:idempotency_key,:request_digest,CAST(:expires_at AS timestamptz),:status,:reason_code,:current_version,CAST(:created_by AS uuid),:approval_ref,:approval_digest,:purpose,:environment,CAST(:target_capability AS jsonb))
+          RETURNING uid::text,status,current_version"""), {**values, "target_capability": None if values["target_capability"] is None else _json(values["target_capability"])}).mappings().one()
+        return _row(row)
+
+    def create_grant(self, record):
+        # Service-created grants retain closed-schema provenance as an idempotency input.
+        return self.enqueue_grant({
+            **record, "idempotency_key": f"grant:{record['uid']}", "request_digest": record["decision_digest"],
+        })
+
+    def get_grant(self, uid):
+        row = self.session.execute(text("""SELECT uid::text,policy_uid::text,subject_uid::text,asset_uid::text,provider,expires_at,status,reason_code,current_version,request_digest AS decision_digest,
+          approval_ref,approval_digest,purpose,environment,target_capability
+          FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid)"""), {"uid": uid}).mappings().one_or_none()
+        value = _row(row)
+        if value and value.get("target_capability") is not None:
+            value["target_capability"] = dict(value["target_capability"])
+        return value
+
+    def enqueue_delivery(self, grant_uid, idempotency_key, request_digest, operation="provision"):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("enqueue_delivery", {
+                "uid": str(uuid.uuid4()), "grant_uid": grant_uid,
+                "idempotency_key": idempotency_key, "request_digest": request_digest,
+                "operation": operation,
+            })
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_deliveries WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return {"uid": existing["uid"]}
+        if operation == "provision":
+            # The partial unique index is a last line of defence.  Taking a
+            # per-grant transaction advisory lock first lets different HTTP
+            # keys converge on the same intent without making a second worker
+            # guess whether an IntegrityError represented a replay or a
+            # conflicting entitlement.
+            self.session.execute(text("SELECT pg_advisory_xact_lock(hashtextextended(CAST(:grant AS text),494))"), {"grant": grant_uid})
+            existing = self.session.execute(text("""SELECT uid::text,request_digest
+              FROM public.trusted_delivery_deliveries
+              WHERE grant_uid=CAST(:grant AS uuid) AND operation='provision' FOR UPDATE"""), {"grant": grant_uid}).mappings().one_or_none()
+            if existing:
+                if existing["request_digest"] != request_digest:
+                    raise RuntimeError("trusted delivery idempotency conflict")
+                return {"uid": existing["uid"]}
+        uid = str(uuid.uuid4())
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_deliveries(uid,grant_uid,idempotency_key,request_digest,status,operation)
+          VALUES(CAST(:uid AS uuid),CAST(:grant_uid AS uuid),:key,:digest,'pending',:operation) RETURNING uid::text,status,lease_fence"""), {"uid": uid, "grant_uid": grant_uid, "key": idempotency_key, "digest": request_digest, "operation": operation}).mappings().one()
+        return _row(row)
+
+    def claim_delivery(self, uid, worker):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("claim_delivery", {"uid": uid, "worker": worker})
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status='processing',lease_owner=:worker,
+          lease_fence=lease_fence+1,lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND ((status='pending' AND next_attempt_at<=clock_timestamp()) OR (status='processing' AND lease_expires_at<=clock_timestamp()))
+          RETURNING uid::text,grant_uid::text,status,lease_fence,lease_owner"""), {"uid": uid, "worker": worker}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease unavailable")
+        return _row(row)
+
+    def complete_delivery(self, uid, worker, fence, status, receipt_code, response_digest, diff_digest):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("complete_delivery", {
+                "uid": uid, "worker": worker, "fence": fence, "status": status,
+                "receipt_uid": str(uuid.uuid4()), "receipt_code": receipt_code,
+                "response_digest": response_digest, "diff_digest": diff_digest,
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status=:status,lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text,grant_uid::text,request_digest,status"""), {"uid": uid, "worker": worker, "fence": int(fence), "status": status}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_receipts(uid,delivery_uid,grant_uid,status,receipt_code,request_digest,response_digest,diff_digest)
+          VALUES(CAST(:uid AS uuid),CAST(:delivery_uid AS uuid),CAST(:grant_uid AS uuid),:status,:receipt_code,:request_digest,:response_digest,:diff_digest)"""), {"uid": str(uuid.uuid4()), "delivery_uid": row["uid"], "grant_uid": row["grant_uid"], "status": status, "receipt_code": receipt_code, "request_digest": row["request_digest"], "response_digest": response_digest, "diff_digest": diff_digest})
+        return {"uid": row["uid"], "status": row["status"]}
+
+    def record_provision_receipt(self, grant_uid, idempotency_key, request_digest, receipt):
+        key = f"provision:{idempotency_key}"
+        delivery = self.enqueue_delivery(grant_uid, key, request_digest, operation="provision")
+        existing = self.session.execute(text("""SELECT status,receipt_code,response_digest,diff_digest FROM public.trusted_delivery_receipts
+          WHERE delivery_uid=CAST(:uid AS uuid)"""), {"uid": delivery["uid"]}).mappings().one_or_none()
+        if existing:
+            return {"grant_uid": grant_uid, "status": existing["status"], "receipt_code": existing["receipt_code"], "response_digest": existing["response_digest"], "diff_digest": existing["diff_digest"]}
+        claimed = self.claim_delivery(delivery["uid"], "provision-sync")
+        self.complete_delivery(delivery["uid"], "provision-sync", claimed["lease_fence"], "applied", receipt["receipt_code"], receipt["response_digest"], receipt["diff_digest"])
+        return receipt
+
+    def prepare_provision_operation(self, grant_uid, idempotency_key, request_digest):
+        """Persist the outbox intent before any provider adapter is invoked.
+
+        The API boundary owns ordinary commits, but external I/O is different:
+        an adapter must never run for an intent that can still be rolled back.
+        This deliberately commits only the durable intent and leaves completion
+        for the receipt path.  A retry sees the same delivery/receipt.
+        """
+        delivery = self.enqueue_delivery(
+            grant_uid, f"provision:{idempotency_key}", request_digest, operation="provision"
+        )
+        existing = self.session.execute(text("""SELECT status,receipt_code,response_digest,diff_digest
+          FROM public.trusted_delivery_receipts WHERE delivery_uid=CAST(:uid AS uuid)"""), {
+            "uid": delivery["uid"],
+        }).mappings().one_or_none()
+        self.session.commit()
+        if existing:
+            return {"delivery_uid": delivery["uid"], "completed": True, "receipt": {
+                "grant_uid": grant_uid, "status": existing["status"],
+                "receipt_code": existing["receipt_code"],
+                "response_digest": existing["response_digest"], "diff_digest": existing["diff_digest"],
+            }}
+        return {"delivery_uid": delivery["uid"], "completed": False}
+
+    def claim_provision_operation(self, delivery_uid, worker_id):
+        """Lease one persisted provision intent using PostgreSQL's clock.
+
+        This is deliberately separate from ``prepare_provision_operation``:
+        intent durability is committed before any process is entitled to call
+        an external provider, while a crashed worker can be replaced after its
+        database-time lease expires.
+        """
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("claim_provision", {
+                "uid": delivery_uid, "worker": worker_id,
+            })
+        completed = self.session.execute(text("""SELECT r.status,r.receipt_code,r.response_digest,r.diff_digest
+          FROM public.trusted_delivery_deliveries d
+          JOIN public.trusted_delivery_receipts r ON r.delivery_uid=d.uid
+          WHERE d.uid=CAST(:uid AS uuid) AND d.operation='provision'"""), {"uid": delivery_uid}).mappings().one_or_none()
+        if completed:
+            return {"state": "completed", "receipt": _row(completed)}
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries
+          SET status='processing',lease_owner=:worker,lease_fence=lease_fence+1,
+              lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND operation='provision' AND (
+              (status='pending' AND next_attempt_at<=clock_timestamp()) OR
+              (status='processing' AND lease_expires_at<=clock_timestamp())
+          )
+          RETURNING uid::text,grant_uid::text,lease_fence,lease_owner,lease_expires_at"""), {
+            "uid": delivery_uid, "worker": worker_id,
+        }).mappings().one_or_none()
+        return ({"state": "claimed", **_row(row)} if row else {"state": "leased"})
+
+    def fail_provision_operation(self, delivery_uid, worker_id, fence):
+        """Release only the still-current provision lease for a safe retry."""
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("fail_provision", {
+                "uid": delivery_uid, "worker": worker_id, "fence": int(fence),
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries
+          SET status='pending',lease_owner=NULL,lease_expires_at=NULL,
+              next_attempt_at=clock_timestamp(),updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND operation='provision' AND status='processing'
+            AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text"""), {
+            "uid": delivery_uid, "worker": worker_id, "fence": int(fence),
+        }).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+        return _row(row)
+
+    def complete_provision_operation(self, grant_uid, delivery_uid, worker_id, fence, receipt):
+        """Atomically append a receipt, complete delivery, and mark its grant."""
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("complete_provision", {
+                "grant_uid": grant_uid, "uid": delivery_uid, "worker": worker_id,
+                "fence": int(fence), "receipt_uid": str(uuid.uuid4()),
+                "receipt_code": receipt["receipt_code"],
+                "response_digest": receipt["response_digest"],
+                "diff_digest": receipt["diff_digest"],
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries
+          SET status='applied',lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND grant_uid=CAST(:grant AS uuid)
+            AND operation='provision' AND status='processing' AND lease_owner=:worker
+            AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text,grant_uid::text,request_digest,status"""), {
+            "uid": delivery_uid, "grant": grant_uid, "worker": worker_id, "fence": int(fence),
+        }).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_receipts
+          (uid,delivery_uid,grant_uid,status,receipt_code,request_digest,response_digest,diff_digest)
+          VALUES(CAST(:uid AS uuid),CAST(:delivery AS uuid),CAST(:grant AS uuid),'applied',:code,:request,:response,:diff)"""), {
+            "uid": str(uuid.uuid4()), "delivery": row["uid"], "grant": row["grant_uid"],
+            "code": receipt["receipt_code"], "request": row["request_digest"],
+            "response": receipt["response_digest"], "diff": receipt["diff_digest"],
+        })
+        grant = self.session.execute(text("""UPDATE public.trusted_delivery_grants
+          SET reason_code='provision_applied',current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='active'
+          RETURNING uid::text,status,reason_code,current_version"""), {"uid": grant_uid}).mappings().one_or_none()
+        if grant is None:
+            raise RuntimeError("trusted delivery grant version conflict")
+        return {
+            "delivery_uid": row["uid"], "status": "applied",
+            "grant_uid": grant["uid"], "grant_status": grant["status"],
+            "reason_code": grant["reason_code"], "current_version": grant["current_version"],
+        }
+
+    def get_provision_receipt(self, grant_uid, idempotency_key):
+        row = self.session.execute(text("""SELECT r.status,r.receipt_code,r.response_digest,r.diff_digest
+          FROM public.trusted_delivery_deliveries d JOIN public.trusted_delivery_receipts r ON r.delivery_uid=d.uid
+          WHERE d.grant_uid=CAST(:grant_uid AS uuid) AND d.idempotency_key=:key"""), {"grant_uid": grant_uid, "key": f"provision:{idempotency_key}"}).mappings().one_or_none()
+        if row is None:
+            return None
+        return {"grant_uid": grant_uid, "status": row["status"], "receipt_code": row["receipt_code"], "response_digest": row["response_digest"], "diff_digest": row["diff_digest"]}
+
+    def complete_reclaim(self, grant_uid, idempotency_key, request_digest, receipt):
+        grant = self.session.execute(text("SELECT uid::text,status,current_version FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid) FOR UPDATE"), {"uid": grant_uid}).mappings().one_or_none()
+        if grant is None:
+            raise LookupError("trusted delivery grant was not found")
+        if grant["status"] == "reclaimed":
+            return {"uid": grant_uid, "status": "reclaimed", "current_version": grant["current_version"]}
+        key = f"reclaim:{idempotency_key}"
+        delivery = self.enqueue_delivery(grant_uid, key, request_digest, operation="revoke")
+        existing = self.session.execute(text("SELECT status FROM public.trusted_delivery_receipts WHERE delivery_uid=CAST(:uid AS uuid)"), {"uid": delivery["uid"]}).mappings().one_or_none()
+        if existing:
+            row = self.session.execute(text("SELECT uid::text,status,current_version FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid)"), {"uid": grant_uid}).mappings().one()
+            return _row(row)
+        claimed = self.claim_delivery(delivery["uid"], "reclaim-sync")
+        # The provider receipt is append-only evidence.  Store it before the
+        # final grant transition; both writes share the caller transaction, so
+        # a later conflict rolls the receipt back rather than exposing a claim
+        # that was never completed.
+        self.complete_delivery(delivery["uid"], "reclaim-sync", claimed["lease_fence"], "reclaimed", receipt["receipt_code"], receipt["response_digest"], receipt["diff_digest"])
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_grants SET status='reclaimed',reason_code='expired_reclaimed',
+          current_version=current_version+1,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='active'
+          RETURNING uid::text,status,current_version"""), {"uid": grant_uid}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery version conflict")
+        return _row(row)
+
+    def claim_reclaim_operation(self, grant_uid, idempotency_key, request_digest, worker_id):
+        """Durably lease the one revoke outbox operation before provider I/O."""
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_reclaim_write("claim_reclaim", {
+                "grant_uid": grant_uid, "idempotency_key": idempotency_key,
+                "request_digest": request_digest, "worker": worker_id,
+            })
+        grant = self.session.execute(text("""SELECT uid::text,asset_uid::text,status,expires_at
+          FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid) FOR UPDATE"""), {"uid": grant_uid}).mappings().one_or_none()
+        if grant is None:
+            raise LookupError("trusted delivery grant was not found")
+        self.session.execute(text("SELECT pg_advisory_xact_lock(hashtextextended(CAST(:asset AS text),485))"), {"asset": grant["asset_uid"]})
+        if grant["status"] == "reclaimed":
+            return {"state": "completed", "grant_uid": grant_uid}
+        if grant["status"] != "active" or grant["expires_at"] > self.session.execute(text("SELECT clock_timestamp()")).scalar_one():
+            raise ValueError("trusted delivery grant is not reclaimable")
+        if self.active_hold_for_asset(grant["asset_uid"]):
+            raise PermissionError("active legal hold blocks reclaim")
+        row = self.session.execute(text("""SELECT uid::text,request_digest,status,lease_owner,lease_fence,lease_expires_at
+          FROM public.trusted_delivery_deliveries WHERE grant_uid=CAST(:grant AS uuid) AND operation='revoke' FOR UPDATE"""), {"grant": grant_uid}).mappings().one_or_none()
+        if row is None:
+            uid = str(uuid.uuid4())
+            row = self.session.execute(text("""INSERT INTO public.trusted_delivery_deliveries
+              (uid,grant_uid,idempotency_key,request_digest,status,operation,lease_owner,lease_fence,lease_expires_at)
+              VALUES(CAST(:uid AS uuid),CAST(:grant AS uuid),:key,:digest,'processing','revoke',:worker,1,clock_timestamp()+interval '300 seconds')
+              RETURNING uid::text,lease_fence"""), {"uid": uid, "grant": grant_uid, "key": f"reclaim:{idempotency_key}", "digest": request_digest, "worker": worker_id}).mappings().one()
+            return {"state": "claimed", "delivery_uid": row["uid"], "lease_fence": row["lease_fence"]}
+        if row["request_digest"] != request_digest:
+            raise RuntimeError("trusted delivery idempotency conflict")
+        if row["status"] == "reclaimed":
+            return {"state": "completed", "grant_uid": grant_uid}
+        claimed = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status='processing',lease_owner=:worker,
+          lease_fence=lease_fence+1,lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND (status='pending' OR (status='processing' AND lease_expires_at<=clock_timestamp()))
+          RETURNING uid::text,lease_fence"""), {"uid": row["uid"], "worker": worker_id}).mappings().one_or_none()
+        return {"state": "claimed", "delivery_uid": claimed["uid"], "lease_fence": claimed["lease_fence"]} if claimed else {"state": "leased"}
+
+    def fail_reclaim_operation(self, delivery_uid, worker_id, fence):
+        if self._runtime_restricted():
+            self._trusted_delivery_runtime_reclaim_write("fail_reclaim", {
+                "delivery_uid": delivery_uid, "worker": worker_id, "fence": fence,
+            })
+            return
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status='pending',lease_owner=NULL,
+          lease_expires_at=NULL,next_attempt_at=clock_timestamp()+interval '5 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text"""), {"uid": delivery_uid, "worker": worker_id, "fence": int(fence)}).one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+
+    def complete_claimed_reclaim(self, grant_uid, delivery_uid, worker_id, fence, receipt):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_reclaim_write("complete_reclaim", {
+                "grant_uid": grant_uid, "delivery_uid": delivery_uid,
+                "worker": worker_id, "fence": fence, "receipt_uid": str(uuid.uuid4()),
+                "receipt_code": receipt["receipt_code"],
+                "response_digest": receipt["response_digest"],
+                "diff_digest": receipt["diff_digest"],
+            })
+        self.complete_delivery(delivery_uid, worker_id, fence, "reclaimed", receipt["receipt_code"], receipt["response_digest"], receipt["diff_digest"])
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_grants SET status='reclaimed',reason_code='expired_reclaimed',current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='active' RETURNING uid::text,status,current_version"""), {"uid": grant_uid}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery version conflict")
+        return _row(row)
+
+    def create_legal_hold(self, record):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("create_hold", {
+                **record, "hold_operation": record["operation"],
+            })
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_legal_holds
+          (uid,asset_uid,operation,status,approver_ref_one,approver_ref_two,evidence_digest,created_by,current_version)
+          VALUES(CAST(:uid AS uuid),CAST(:asset_uid AS uuid),:operation,:status,:approver_ref_one,:approver_ref_two,:evidence_digest,CAST(:created_by AS uuid),:current_version)
+          RETURNING uid::text,status"""), record).mappings().one()
+        return _row(row)
+
+    def release_legal_hold(self, hold_uid, idempotency_key, request_digest, actor_uid, approval_ref, approval_digest):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("release_hold", {
+                "uid": str(uuid.uuid4()), "hold_uid": hold_uid,
+                "idempotency_key": idempotency_key, "request_digest": request_digest,
+                "actor_uid": actor_uid, "approval_ref": approval_ref,
+                "approval_digest": approval_digest,
+            })
+        existing = self.session.execute(text("SELECT hold_uid::text,request_digest FROM public.trusted_delivery_hold_releases WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            row = self.session.execute(text("SELECT uid::text,status,current_version FROM public.trusted_delivery_legal_holds WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["hold_uid"]}).mappings().one()
+            return _row(row)
+        hold = self.session.execute(text("""SELECT uid::text,status,current_version,created_by::text,approver_ref_one,approver_ref_two
+          FROM public.trusted_delivery_legal_holds WHERE uid=CAST(:uid AS uuid) FOR UPDATE"""), {"uid": hold_uid}).mappings().one_or_none()
+        if hold is None:
+            raise LookupError("trusted delivery legal hold was not found")
+        if hold["created_by"] == actor_uid or approval_ref in {hold["approver_ref_one"], hold["approver_ref_two"]}:
+            raise PermissionError("legal hold release requires an independent approval")
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_legal_holds SET status='released',current_version=current_version+1
+          WHERE uid=CAST(:uid AS uuid) AND status='active' RETURNING uid::text,status,current_version"""), {"uid": hold_uid}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery legal hold is not active")
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_hold_releases
+          (uid,hold_uid,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+          VALUES(CAST(:uid AS uuid),CAST(:hold_uid AS uuid),:key,:digest,:approval_ref,:approval_digest,CAST(:actor_uid AS uuid))"""), {"uid": str(uuid.uuid4()), "hold_uid": hold_uid, "key": idempotency_key, "digest": request_digest, "approval_ref": approval_ref, "approval_digest": approval_digest, "actor_uid": actor_uid})
+        return _row(row)
+
+    def active_hold_for_asset(self, asset_uid):
+        row = self.session.execute(text("SELECT uid::text,asset_uid::text,status FROM public.trusted_delivery_legal_holds WHERE asset_uid=CAST(:asset AS uuid) AND status='active'"), {"asset": asset_uid}).mappings().one_or_none()
+        return _row(row)
+
+    def grants_due_for_revoke(self, instant: datetime):
+        rows = self.session.execute(text("SELECT uid::text,asset_uid::text,expires_at,status,current_version FROM public.trusted_delivery_grants WHERE status='active' AND expires_at<=CAST(:instant AS timestamptz)"), {"instant": instant}).mappings()
+        return [_row(row) for row in rows]
+
+    def update_grant_status(self, uid, expected_version, status, reason_code):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("update_grant_status", {
+                "uid": uid, "expected_version": expected_version, "status": status,
+                "reason_code": reason_code,
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_grants SET status=:status,reason_code=:reason,current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND current_version=:expected RETURNING uid::text,status,reason_code,current_version"""), {"uid": uid, "expected": int(expected_version), "status": status, "reason": reason_code}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery version conflict")
+        return _row(row)
+
+    def expire_grants(self, instant, actor_uid):
+        expired = []
+        for grant in self.grants_due_for_revoke(instant):
+            if self.active_hold_for_asset(grant["asset_uid"]):
+                continue
+            expired.append(self.update_grant_status(grant["uid"], grant["current_version"], "revoked", "expired"))
+        return expired
+
+    def add_evidence(self, record):
+        if self._runtime_restricted():
+            self._trusted_delivery_runtime_write("subscription_evidence", {
+                "uid": record["uid"], "action": record["action"],
+                "actor_uid": record["actor_uid"], "safe_detail": record["safe_detail"],
+            })
+            return
+        self.session.execute(text("INSERT INTO public.trusted_delivery_evidence(uid,action,actor_uid,safe_detail) VALUES(CAST(:uid AS uuid),:action,CAST(:actor AS uuid),CAST(:detail AS jsonb))"), {"uid": record["uid"], "action": record["action"], "actor": record["actor_uid"], "detail": _json(record["safe_detail"])})

+ 203 - 0
app/core/system/trusted_delivery_subscription_repository.py

@@ -0,0 +1,203 @@
+"""PostgreSQL storage for fenced trusted-delivery subscription deliveries."""
+
+from __future__ import annotations
+
+import json
+from typing import Any
+
+from sqlalchemy import text
+
+
+def _json(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _row(value) -> dict[str, Any] | None:
+    if value is None:
+        return None
+    result = dict(value)
+    for key, item in tuple(result.items()):
+        if hasattr(item, "isoformat"):
+            result[key] = item.isoformat()
+        elif hasattr(item, "hex"):
+            result[key] = str(item)
+    if result.get("trigger") is not None:
+        result["trigger"] = dict(result["trigger"])
+    return result
+
+
+class SqlAlchemyTrustedDeliverySubscriptionRepository:
+    def __init__(self, session):
+        self.session = session
+
+    def _trusted_delivery_gateway(self, operation: str, payload: dict[str, Any]) -> dict[str, Any] | None:
+        direct_dml = self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_subscriptions', 'INSERT')
+        """)).scalar_one()
+        if direct_dml:
+            return None
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _runtime_restricted(self) -> bool:
+        return not self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_subscriptions', 'INSERT')
+        """)).scalar_one()
+
+    def users_available(self, values):
+        values = sorted(set(values))
+        if not values:
+            return set()
+        return set(self.session.execute(text("SELECT id::text FROM public.users WHERE status='active' AND id=ANY(CAST(:values AS uuid[]))"), {"values": values}).scalars())
+
+    def create_subscription(self, record):
+        gateway = self._trusted_delivery_gateway("create_subscription", {
+            key: record[key] for key in (
+                "uid", "grant_uid", "asset_uid", "trigger", "purpose", "expires_at",
+                "idempotency_key", "request_digest", "status", "current_version", "created_by",
+            ) if key in record
+        })
+        if gateway is not None:
+            return _row(gateway)
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_subscriptions WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("subscription idempotency conflict")
+            return _row(self.session.execute(text("SELECT uid::text,grant_uid::text,asset_uid::text,trigger,purpose,expires_at,status,current_version FROM public.trusted_delivery_subscriptions WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["uid"]}).mappings().one())
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_subscriptions
+          (uid,grant_uid,asset_uid,trigger,purpose,expires_at,idempotency_key,request_digest,status,current_version,created_by)
+          VALUES(CAST(:uid AS uuid),CAST(:grant_uid AS uuid),CAST(:asset_uid AS uuid),CAST(:trigger AS jsonb),:purpose,CAST(:expires_at AS timestamptz),:idempotency_key,:request_digest,:status,:current_version,CAST(:created_by AS uuid))
+          RETURNING uid::text,grant_uid::text,asset_uid::text,trigger,purpose,expires_at,status,current_version"""), {**record, "trigger": _json(record["trigger"])}).mappings().one()
+        return _row(row)
+
+    def get_grant_for_subscription(self, uid):
+        row = self.session.execute(text("""SELECT uid::text,asset_uid::text,purpose,expires_at,status
+          FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid) FOR KEY SHARE"""), {"uid": uid}).mappings().one_or_none()
+        return _row(row)
+
+    def transition_subscription(self, uid, expected_status, new_status):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("transition_subscription", {
+                "uid": uid, "expected_status": sorted(expected_status), "status": new_status,
+            }))
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscriptions SET status=:target,current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status=ANY(CAST(:expected AS varchar[]))
+          RETURNING uid::text,grant_uid::text,asset_uid::text,trigger,purpose,expires_at,status,current_version"""), {"uid": uid, "expected": sorted(expected_status), "target": new_status}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("subscription transition conflict")
+        return _row(row)
+
+    def enqueue_subscription_delivery(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("enqueue_subscription_delivery", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_subscription_deliveries WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("subscription idempotency conflict")
+            return _row(self.session.execute(text("SELECT uid::text,subscription_uid::text,trigger_ref,event_digest,status,attempt_count,lease_fence FROM public.trusted_delivery_subscription_deliveries WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["uid"]}).mappings().one())
+        state = self.session.execute(text("SELECT status FROM public.trusted_delivery_subscriptions WHERE uid=CAST(:uid AS uuid) FOR KEY SHARE"), {"uid": record["subscription_uid"]}).scalar_one_or_none()
+        if state != "active":
+            raise RuntimeError("subscription is not active")
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_subscription_deliveries
+          (uid,subscription_uid,trigger_ref,event_digest,idempotency_key,request_digest,status,attempt_count,lease_fence)
+          VALUES(CAST(:uid AS uuid),CAST(:subscription_uid AS uuid),:trigger_ref,:event_digest,:idempotency_key,:request_digest,:status,:attempt_count,:lease_fence)
+          RETURNING uid::text,subscription_uid::text,trigger_ref,event_digest,status,attempt_count,lease_fence"""), record).mappings().one()
+        return _row(row)
+
+    def claim_subscription_delivery(self, uid, worker):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("claim_subscription_delivery", {
+                "uid": uid, "worker": worker,
+            }))
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscription_deliveries SET status='processing',lease_owner=:worker,lease_fence=lease_fence+1,
+          lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND ((status='pending' AND next_attempt_at<=clock_timestamp()) OR (status='processing' AND lease_expires_at<=clock_timestamp()))
+          RETURNING uid::text,subscription_uid::text,status,attempt_count,lease_owner,lease_fence,lease_expires_at"""), {"uid": uid, "worker": worker}).mappings().one_or_none()
+        return _row(row)
+
+    def record_subscription_attempt(self, uid, worker, fence, delivered):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("subscription_attempt", {
+                "uid": uid, "worker": worker, "fence": fence, "delivered": delivered,
+            }))
+        if delivered:
+            statement = """UPDATE public.trusted_delivery_subscription_deliveries SET status='delivered',lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp()
+              WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+              RETURNING uid::text,subscription_uid::text,status,attempt_count,lease_fence"""
+            parameters = {"uid": uid, "worker": worker, "fence": fence}
+        else:
+            statement = """UPDATE public.trusted_delivery_subscription_deliveries SET attempt_count=attempt_count+1,lease_owner=NULL,lease_expires_at=NULL,
+              status=CASE WHEN attempt_count+1>=3 THEN 'dead_letter' ELSE 'pending' END,
+              next_attempt_at=clock_timestamp()+(LEAST(3600,60*(attempt_count+1))*interval '1 second'),last_reason_code='provider_unavailable',updated_at=clock_timestamp()
+              WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+              RETURNING uid::text,subscription_uid::text,status,attempt_count,lease_fence"""
+            parameters = {"uid": uid, "worker": worker, "fence": fence}
+        return _row(self.session.execute(text(statement), parameters).mappings().one_or_none())
+
+    def compensate_subscription_delivery(self, uid, reason_code, receipt_code):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("compensate_subscription_delivery", {
+                "uid": uid, "reason_code": reason_code, "receipt_code": receipt_code,
+            }))
+        current = self.session.execute(text("SELECT uid::text,status,compensation_reason_code,compensation_receipt_code FROM public.trusted_delivery_subscription_deliveries WHERE uid=CAST(:uid AS uuid) FOR UPDATE"), {"uid": uid}).mappings().one_or_none()
+        if current is None or current["status"] not in {"dead_letter", "compensated"}:
+            raise RuntimeError("subscription delivery is not compensable")
+        if current["status"] == "compensated":
+            if (current["compensation_reason_code"], current["compensation_receipt_code"]) != (reason_code, receipt_code):
+                raise RuntimeError("subscription compensation conflict")
+            return _row(current)
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscription_deliveries SET status='compensated',compensation_reason_code=:reason,
+          compensation_receipt_code=:receipt,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='dead_letter'
+          RETURNING uid::text,subscription_uid::text,status,attempt_count,compensation_reason_code,compensation_receipt_code"""), {"uid": uid, "reason": reason_code, "receipt": receipt_code}).mappings().one()
+        return _row(row)
+
+    def add_subscription_evidence(self, record):
+        if self._runtime_restricted():
+            self._trusted_delivery_runtime_write("subscription_evidence", record)
+            return
+        self.session.execute(text("INSERT INTO public.trusted_delivery_evidence(uid,action,actor_uid,safe_detail) VALUES(CAST(:uid AS uuid),:action,CAST(:actor_uid AS uuid),CAST(:detail AS jsonb))"), {**record, "detail": _json(record["safe_detail"])})
+
+    def incident_exists(self, incident_uid):
+        return self.session.execute(text("SELECT 1 FROM public.data_incidents WHERE uid=CAST(:uid AS uuid)"), {"uid": incident_uid}).scalar_one_or_none() is not None
+
+    def link_anomaly_incident(self, incident_uid, asset_uid, label):
+        if self._runtime_restricted():
+            self.session.execute(text("""
+                SELECT public.trusted_delivery_runtime_incident_impact(
+                  CAST(:incident_uid AS uuid), CAST(:asset_uid AS uuid), :label
+                )
+            """), {"incident_uid": incident_uid, "asset_uid": asset_uid, "label": label})
+            return
+        self.session.execute(text("""INSERT INTO public.data_incident_impacts(incident_uid,target_type,target_uid,label)
+          VALUES(CAST(:incident_uid AS uuid),'asset',:asset_uid,:label)
+          ON CONFLICT(incident_uid,target_type,target_uid) DO NOTHING"""), {"incident_uid": incident_uid, "asset_uid": asset_uid, "label": label})
+
+    def subscriptions_due_for_reclaim(self, instant):
+        rows = self.session.execute(text("""SELECT s.uid::text,s.grant_uid::text,s.asset_uid::text,s.status,s.current_version
+          FROM public.trusted_delivery_subscriptions s
+          WHERE s.status IN ('active','expired') AND s.expires_at<=CAST(:instant AS timestamptz)
+          AND NOT EXISTS(SELECT 1 FROM public.trusted_delivery_legal_holds h WHERE h.asset_uid=s.asset_uid AND h.status='active')
+          ORDER BY s.expires_at,s.uid"""), {"instant": instant}).mappings()
+        return [_row(row) for row in rows]
+
+    def mark_subscription_reclaimed(self, uid, expected_version):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("mark_subscription_reclaimed", {
+                "uid": uid, "expected_version": expected_version,
+            }))
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscriptions SET status='reclaimed',current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='expired' AND current_version=:version
+          RETURNING uid::text,grant_uid::text,asset_uid::text,status,current_version"""), {"uid": uid, "version": expected_version}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("subscription reclaim conflict")
+        return _row(row)

+ 255 - 0
app/core/system/trusted_delivery_subscriptions.py

@@ -0,0 +1,255 @@
+"""Closed subscription and delivery controls for trusted data delivery.
+
+The service never carries data rows, target URLs, credentials, or provider
+configuration.  It persists only the minimal delivery control-plane facts and
+safe incident references; P3 production operations remains the incident source
+of truth.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import re
+import uuid
+from collections.abc import Callable
+from datetime import UTC, datetime
+from typing import Any
+
+from app.core.common.identifiers import new_governance_uid
+from app.core.common.timezone_utils import now_china
+
+_SAFE_CODE = re.compile(r"^[A-Za-z][A-Za-z0-9_.:-]{0,159}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_UNSAFE = re.compile(
+    r"(?i)(?:https?://|ftp://|file://|www\.|\b(?:secret|token|password|private[ _-]?key)\b|"
+    r"-----BEGIN|<script|javascript:|;|\bselect\s+.+\bfrom\b)"
+)
+_ANOMALIES = frozenset({"unusual_access", "quota_exceeded", "purpose_breach", "secondary_propagation"})
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as exc:
+        raise ValueError(f"{label} must be a UUID") from exc
+
+
+def _text(value: Any, label: str, maximum: int = 160) -> str:
+    if not isinstance(value, str) or not value.strip() or len(value.strip()) > maximum:
+        raise ValueError(f"{label} is invalid")
+    result = value.strip()
+    if _UNSAFE.search(result):
+        raise ValueError(f"{label} contains unsafe content")
+    return result
+
+
+def _instant(value: Any, label: str) -> str:
+    try:
+        result = value if isinstance(value, datetime) else datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as exc:
+        raise ValueError(f"{label} must be ISO-8601") from exc
+    if result.tzinfo is None:
+        raise ValueError(f"{label} must include a timezone")
+    return result.astimezone(UTC).isoformat()
+
+
+def _digest(value: Any) -> str:
+    return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(",", ":")).encode()).hexdigest()
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ValueError(f"{label} must be an object")
+    extra = set(value) - allowed
+    if extra:
+        raise ValueError(f"{label} contains unsupported fields")
+    return copy.deepcopy(value)
+
+
+class TrustedDeliverySubscriptionService:
+    """State machine façade; the repository owns DB time and transaction scope."""
+
+    def __init__(
+        self,
+        repository,
+        *,
+        uid_factory: Callable[[], str] = new_governance_uid,
+        now_factory: Callable[[], datetime] = now_china,
+    ):
+        self.repository = repository
+        self.uid_factory = uid_factory
+        self.now_factory = now_factory
+
+    def _actor(self, value: Any) -> str:
+        actor = _uid(value, "actor_uid")
+        if self.repository.users_available({actor}) != {actor}:
+            raise ValueError("trusted delivery actor is unavailable")
+        return actor
+
+    def _evidence(self, action: str, actor_uid: str, detail: dict[str, str]) -> None:
+        self.repository.add_subscription_evidence({
+            "uid": self.uid_factory(), "action": action, "actor_uid": actor_uid,
+            "safe_detail": copy.deepcopy(detail), "created_at": self.now_factory().astimezone(UTC).isoformat(),
+        })
+
+    def _trigger(self, value: Any) -> dict[str, str]:
+        body = _closed(value, {"kind", "schedule_ref", "event_type"}, "subscription trigger")
+        kind = _text(body.get("kind"), "trigger kind", 20)
+        if kind == "schedule":
+            if set(body) != {"kind", "schedule_ref"}:
+                raise ValueError("schedule trigger has unsupported fields")
+            return {"kind": kind, "schedule_ref": _text(body["schedule_ref"], "schedule ref", 120)}
+        if kind == "event":
+            if set(body) != {"kind", "event_type"}:
+                raise ValueError("event trigger has unsupported fields")
+            return {"kind": kind, "event_type": _text(body["event_type"], "event type", 120)}
+        raise ValueError("trigger kind is unsupported")
+
+    def create_subscription(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"grant_uid", "asset_uid", "trigger", "purpose", "expires_at", "idempotency_key"}, "subscription")
+        actor = self._actor(actor_uid)
+        expiry = _instant(body.get("expires_at"), "subscription expiry")
+        if datetime.fromisoformat(expiry) <= self.now_factory().astimezone(UTC):
+            raise ValueError("subscription expiry must be in the future")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        if not _SAFE_CODE.fullmatch(key):
+            raise ValueError("idempotency key is invalid")
+        trigger = self._trigger(body.get("trigger"))
+        record = {
+            "uid": self.uid_factory(), "grant_uid": _uid(body.get("grant_uid"), "grant_uid"),
+            "asset_uid": _uid(body.get("asset_uid"), "asset_uid"), "trigger": trigger,
+            "purpose": _text(body.get("purpose"), "purpose", 100), "expires_at": expiry,
+            "idempotency_key": key, "status": "draft", "current_version": 1, "created_by": actor,
+        }
+        if not hasattr(self.repository, "get_grant_for_subscription"):
+            raise RuntimeError("durable trusted-delivery grant repository is required")
+        grant = self.repository.get_grant_for_subscription(record["grant_uid"])
+        if not grant or grant.get("status") != "active":
+            raise PermissionError("subscription grant is unavailable")
+        if grant.get("asset_uid") != record["asset_uid"] or grant.get("purpose") != record["purpose"]:
+            raise PermissionError("subscription grant does not bind asset and purpose")
+        if _instant(grant.get("expires_at"), "grant expiry") < record["expires_at"]:
+            raise PermissionError("subscription expiry exceeds grant")
+        record["request_digest"] = _digest({key: record[key] for key in ("grant_uid", "asset_uid", "trigger", "purpose", "expires_at", "idempotency_key")})
+        result = self.repository.create_subscription(record)
+        self._evidence("subscription_created", actor, {"subscription_uid": result["uid"], "trigger_kind": trigger["kind"]})
+        return result
+
+    def _transition(self, uid: Any, *, expected: set[str], target: str, actor_uid: str) -> dict[str, Any]:
+        actor = self._actor(actor_uid)
+        result = self.repository.transition_subscription(_uid(uid, "subscription_uid"), expected, target)
+        self._evidence(f"subscription_{target}", actor, {"subscription_uid": result["uid"], "status": target})
+        return result
+
+    def activate_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"draft", "paused"}, target="active", actor_uid=actor_uid)
+
+    def pause_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"active"}, target="paused", actor_uid=actor_uid)
+
+    def resume_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"paused"}, target="active", actor_uid=actor_uid)
+
+    def terminate_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"draft", "active", "paused"}, target="terminated", actor_uid=actor_uid)
+
+    def enqueue_delivery(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"subscription_uid", "trigger_ref", "event_digest"}, "subscription delivery")
+        actor = self._actor(actor_uid)
+        event_digest = _text(body.get("event_digest"), "event digest", 64).lower()
+        if not _DIGEST.fullmatch(event_digest):
+            raise ValueError("event digest must be SHA-256")
+        subscription_uid = _uid(body.get("subscription_uid"), "subscription_uid")
+        trigger_ref = _text(body.get("trigger_ref"), "trigger reference", 160)
+        if not _SAFE_CODE.fullmatch(trigger_ref):
+            raise ValueError("trigger reference is invalid")
+        record = {
+            "uid": self.uid_factory(), "subscription_uid": subscription_uid, "trigger_ref": trigger_ref,
+            "event_digest": event_digest, "status": "pending", "attempt_count": 0,
+            "lease_owner": None, "lease_fence": 0,
+        }
+        record["idempotency_key"] = f"{subscription_uid}:{trigger_ref}"
+        record["request_digest"] = _digest({key: record[key] for key in ("subscription_uid", "trigger_ref", "event_digest")})
+        result = self.repository.enqueue_subscription_delivery(record)
+        self._evidence("subscription_delivery_enqueued", actor, {"delivery_uid": result["uid"], "subscription_uid": subscription_uid})
+        return result
+
+    def claim_delivery(self, uid: Any, *, worker_id: str) -> dict[str, Any]:
+        result = self.repository.claim_subscription_delivery(_uid(uid, "delivery_uid"), _text(worker_id, "worker id", 80))
+        if result is None:
+            raise ValueError("subscription delivery is not claimable")
+        return result
+
+    def record_delivery_attempt(self, uid: Any, *, worker_id: str, lease_fence: Any, delivered: Any, actor_uid: str) -> dict[str, Any] | None:
+        actor = self._actor(actor_uid)
+        if not isinstance(lease_fence, int) or lease_fence < 1 or not isinstance(delivered, bool):
+            raise ValueError("subscription delivery attempt is invalid")
+        result = self.repository.record_subscription_attempt(_uid(uid, "delivery_uid"), _text(worker_id, "worker id", 80), lease_fence, delivered)
+        if result is not None:
+            self._evidence("subscription_delivery_delivered" if delivered else "subscription_delivery_failed", actor, {"delivery_uid": result["uid"], "status": result["status"]})
+        return result
+
+    def compensate_dead_letter(self, uid: Any, *, reason_code: Any, receipt_code: Any, actor_uid: str) -> dict[str, Any]:
+        actor = self._actor(actor_uid)
+        reason = _text(reason_code, "compensation reason", 64)
+        receipt = _text(receipt_code, "compensation receipt", 64)
+        if reason not in {"operator_review", "provider_recovered", "duplicate_suppressed"} or not re.fullmatch(r"[A-Z][A-Z0-9_]{0,63}", receipt):
+            raise ValueError("subscription compensation is invalid")
+        result = self.repository.compensate_subscription_delivery(_uid(uid, "delivery_uid"), reason, receipt)
+        self._evidence("subscription_dead_letter_compensated", actor, {"delivery_uid": result["uid"], "receipt_code": receipt})
+        return result
+
+    def report_anomaly(self, payload: Any, *, actor_uid: str) -> dict[str, str]:
+        body = _closed(payload, {"kind", "asset_uid", "subscription_uid", "incident_uid", "summary", "correlation_id"}, "subscription anomaly")
+        actor = self._actor(actor_uid)
+        kind = _text(body.get("kind"), "anomaly kind", 40)
+        if kind not in _ANOMALIES:
+            raise ValueError("anomaly kind is unsupported")
+        record = {
+            "kind": kind, "asset_uid": _uid(body.get("asset_uid"), "asset_uid"),
+            "subscription_uid": _uid(body.get("subscription_uid"), "subscription_uid"),
+            "incident_uid": _uid(body.get("incident_uid"), "incident_uid"),
+            "summary": _text(body.get("summary"), "anomaly summary", 160),
+            "correlation_id": _uid(body.get("correlation_id"), "correlation_id"),
+        }
+        if hasattr(self.repository, "incident_exists") and not self.repository.incident_exists(record["incident_uid"]):
+            raise ValueError("referenced incident is unavailable")
+        if not hasattr(self.repository, "link_anomaly_incident"):
+            raise RuntimeError("canonical incident linkage is unavailable")
+        # The P2 incident ledger remains the sole incident truth.  Trusted
+        # delivery only creates a bounded, idempotent asset impact link; it
+        # never creates a parallel incident record or accepts an unverified ID.
+        self.repository.link_anomaly_incident(
+            record["incident_uid"], record["asset_uid"], f"trusted_delivery:{kind}"
+        )
+        self._evidence("subscription_anomaly_reported", actor, {"kind": kind, "incident_uid": record["incident_uid"], "correlation_id": record["correlation_id"]})
+        return record
+
+    def expire_and_reclaim(self, *, as_of: Any, actor_uid: str, reclaim: Callable[[str, str], dict[str, Any]]) -> list[dict[str, Any]]:
+        """Reuse the trusted-delivery revocation path before changing state.
+
+        A legal hold is filtered by the repository; provider failures leave the
+        subscription unchanged so the next scheduler pass can retry safely.
+        """
+        actor = self._actor(actor_uid)
+        instant = _instant(as_of, "as_of")
+        results = []
+        for subscription in self.repository.subscriptions_due_for_reclaim(instant):
+            expired = subscription
+            if subscription.get("status", "active") == "active":
+                expired = self.repository.transition_subscription(subscription["uid"], {"active"}, "expired")
+            key = f"subscription-reclaim:{subscription['uid']}"
+            try:
+                receipt = reclaim(subscription["grant_uid"], key)
+            except (PermissionError, RuntimeError, ValueError):
+                self._evidence("subscription_reclaim_deferred", actor, {"subscription_uid": subscription["uid"], "grant_uid": subscription["grant_uid"]})
+                continue
+            if not isinstance(receipt, dict) or receipt.get("status") != "reclaimed":
+                self._evidence("subscription_reclaim_deferred", actor, {"subscription_uid": subscription["uid"], "grant_uid": subscription["grant_uid"]})
+                continue
+            saved = self.repository.mark_subscription_reclaimed(subscription["uid"], expired["current_version"])
+            self._evidence("subscription_reclaimed", actor, {"subscription_uid": saved["uid"], "grant_uid": subscription["grant_uid"]})
+            results.append(saved)
+        return results

+ 4 - 0
conftest.py

@@ -0,0 +1,4 @@
+"""Repository-wide pytest plugin registration."""
+
+# Pytest 9 requires plugin declarations to live in the root conftest file.
+pytest_plugins = ("tests.integration.wp06_postgres_identities",)

+ 27 - 20
deploy/docker/docker-compose.yml

@@ -6,7 +6,7 @@ services:
     environment:
       POSTGRES_DB: dataops
       POSTGRES_USER: dataops
-      POSTGRES_PASSWORD: dataops-test-password
+      POSTGRES_PASSWORD: ${DATAOPS_POSTGRES_PASSWORD:-dataops-test-password}
     ports:
       - "${DATAOPS_POSTGRES_PORT:-15432}:5432"
     volumes:
@@ -24,7 +24,7 @@ services:
   kestra-db-init:
     image: postgres:16-alpine
     environment:
-      PGPASSWORD: dataops-test-password
+      PGPASSWORD: ${DATAOPS_POSTGRES_PASSWORD:-dataops-test-password}
     volumes:
       - ./postgres/init/010-kestra-runtime.sql:/opt/dataops/010-kestra-runtime.sql:ro
     command:
@@ -53,12 +53,15 @@ services:
       dockerfile: deploy/docker/backend.Dockerfile
       target: migrator
     environment:
-      DB_ROLE_INIT_DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops
-      MIGRATION_DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops
+      DB_ROLE_INIT_DATABASE_URL: postgresql://dataops:${DATAOPS_POSTGRES_PASSWORD:-dataops-test-password}@postgres:5432/dataops
+      MIGRATION_DATABASE_URL: postgresql://dataops:${DATAOPS_POSTGRES_PASSWORD:-dataops-test-password}@postgres:5432/dataops
       DATABASE_URL: postgresql://dataops_app:${DATAOPS_RUNTIME_PASSWORD:-dataops-app-test-password}@postgres:5432/dataops
+      BI_AI_CATALOG_CONTROL_DATABASE_URL: postgresql://dataops_bi_ai_catalog_control:${DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD:-dataops-bi-ai-control-test-password}@postgres:5432/dataops
       DATAOPS_MIGRATOR_USER: dataops
       DATAOPS_RUNTIME_USER: dataops_app
       DATAOPS_RUNTIME_PASSWORD: ${DATAOPS_RUNTIME_PASSWORD:-dataops-app-test-password}
+      DATAOPS_BI_AI_CATALOG_CONTROL_USER: dataops_bi_ai_catalog_control
+      DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD: ${DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD:-dataops-bi-ai-control-test-password}
     command: ["python", "-m", "app.core.edge_gateway.runtime_roles"]
     depends_on:
       postgres:
@@ -75,7 +78,7 @@ services:
       target: migrator
     command: ["alembic", "-c", "alembic.ini", "upgrade", "head"]
     environment:
-      MIGRATION_DATABASE_URL: postgresql://dataops:dataops-test-password@postgres:5432/dataops
+      MIGRATION_DATABASE_URL: postgresql://dataops:${DATAOPS_POSTGRES_PASSWORD:-dataops-test-password}@postgres:5432/dataops
     depends_on:
       postgres:
         condition: service_healthy
@@ -90,7 +93,7 @@ services:
     environment:
       POSTGRES_DB: acceptance
       POSTGRES_USER: source_reader
-      POSTGRES_PASSWORD: source-test-password
+      POSTGRES_PASSWORD: ${SOURCE_POSTGRES_PASSWORD:-source-test-password}
     ports:
       - "${SOURCE_POSTGRES_PORT:-25432}:5432"
     volumes:
@@ -109,8 +112,8 @@ services:
     environment:
       MYSQL_DATABASE: acceptance
       MYSQL_USER: source_reader
-      MYSQL_PASSWORD: source-test-password
-      MYSQL_ROOT_PASSWORD: source-root-test-password
+      MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD:-source-test-password}
+      MYSQL_ROOT_PASSWORD: ${SOURCE_MYSQL_ROOT_PASSWORD:-source-root-test-password}
     ports:
       - "${SOURCE_MYSQL_PORT:-23306}:3306"
     volumes:
@@ -130,7 +133,7 @@ services:
   neo4j:
     image: neo4j:5.26-community
     environment:
-      NEO4J_AUTH: neo4j/Passw0rd
+      NEO4J_AUTH: neo4j/${DATAOPS_NEO4J_PASSWORD:-Passw0rd}
       NEO4J_server_memory_heap_initial__size: 256m
       NEO4J_server_memory_heap_max__size: 512m
       NEO4J_server_memory_pagecache_size: 256m
@@ -153,7 +156,7 @@ services:
     command: server /data --console-address ":9001"
     environment:
       MINIO_ROOT_USER: dataops-test
-      MINIO_ROOT_PASSWORD: dataops-test-password
+      MINIO_ROOT_PASSWORD: ${DATAOPS_MINIO_PASSWORD:-dataops-test-password}
     ports:
       - "${MINIO_API_PORT:-19000}:9000"
       - "${MINIO_CONSOLE_PORT:-19001}:9001"
@@ -190,12 +193,12 @@ services:
       DB_POSTGRESDB_PORT: 5432
       DB_POSTGRESDB_DATABASE: n8n
       DB_POSTGRESDB_USER: dataops
-      DB_POSTGRESDB_PASSWORD: dataops-test-password
+      DB_POSTGRESDB_PASSWORD: ${DATAOPS_POSTGRES_PASSWORD:-dataops-test-password}
       N8N_HOST: localhost
       N8N_PORT: 5678
       N8N_PROTOCOL: http
       N8N_SECURE_COOKIE: "false"
-      N8N_ENCRYPTION_KEY: dataops-local-test-encryption-key
+      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY:-dataops-local-test-encryption-key}
       N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
       WEBHOOK_URL: http://localhost:15678/
       GENERIC_TIMEZONE: Asia/Shanghai
@@ -229,7 +232,7 @@ services:
       KESTRA_DB_HOST: postgres
       KESTRA_DB_NAME: kestra
       KESTRA_DB_USERNAME: kestra_runtime
-      KESTRA_DB_PASSWORD: kestra-local-test-password
+      KESTRA_DB_PASSWORD: ${KESTRA_DB_PASSWORD:-kestra-local-test-password}
       KESTRA_USERNAME: ${KESTRA_USERNAME:-admin@dataops.local}
       KESTRA_PASSWORD: ${KESTRA_PASSWORD:-DataOpsKestra1!}
     ports:
@@ -363,7 +366,7 @@ services:
       RUNNER_HTTP_ALLOWED_HOSTS: ${RUNNER_HTTP_ALLOWED_HOSTS:-}
       RUNNER_MINIO_HOST: minio:9000
       RUNNER_MINIO_USER: dataops-test
-      RUNNER_MINIO_PASSWORD: dataops-test-password
+      RUNNER_MINIO_PASSWORD: ${DATAOPS_MINIO_PASSWORD:-dataops-test-password}
       RUNNER_MINIO_BUCKET: dataops-bucket
       RUNNER_MINIO_SECURE: "false"
       RUNNER_ARTIFACT_MAX_BYTES: 33554432
@@ -371,9 +374,10 @@ services:
       RUNNER_ARTIFACT_MEMORY_LIMIT_BYTES: 268435456
       RUNNER_ARTIFACT_TTL_SECONDS: 3600
       DATABASE_URL: postgresql://dataops_app:${DATAOPS_RUNTIME_PASSWORD:-dataops-app-test-password}@postgres:5432/dataops
+      BI_AI_CATALOG_CONTROL_DATABASE_URL: postgresql://dataops_bi_ai_catalog_control:${DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD:-dataops-bi-ai-control-test-password}@postgres:5432/dataops
       NEO4J_URI: bolt://neo4j:7687
       NEO4J_USER: neo4j
-      NEO4J_PASSWORD: Passw0rd
+      NEO4J_PASSWORD: ${DATAOPS_NEO4J_PASSWORD:-Passw0rd}
       DATASOURCE_CREDENTIAL_MASTER_KEY: ${DATASOURCE_CREDENTIAL_MASTER_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=}
       DATASOURCE_CREDENTIAL_KEY_VERSION: ${DATASOURCE_CREDENTIAL_KEY_VERSION:-v1}
     ports:
@@ -415,6 +419,8 @@ services:
 
   backend:
     image: ${DATAOPS_BACKEND_IMAGE:-dataops-platform-backend:local}
+    labels:
+      com.dataops.local_env: ${DATAOPS_LOCAL_ENV_LABEL:-dataops-local}
     build:
       context: ../..
       dockerfile: deploy/docker/backend.Dockerfile
@@ -425,14 +431,15 @@ services:
       LISTEN_PORT: 5500
       GUNICORN_WORKERS: 2
       DATABASE_URL: postgresql://dataops_app:${DATAOPS_RUNTIME_PASSWORD:-dataops-app-test-password}@postgres:5432/dataops
+      BI_AI_CATALOG_CONTROL_DATABASE_URL: postgresql://dataops_bi_ai_catalog_control:${DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD:-dataops-bi-ai-control-test-password}@postgres:5432/dataops
       NEO4J_URI: bolt://neo4j:7687
       NEO4J_HTTP_URI: http://neo4j:7474
       NEO4J_USER: neo4j
-      NEO4J_PASSWORD: Passw0rd
+      NEO4J_PASSWORD: ${DATAOPS_NEO4J_PASSWORD:-Passw0rd}
       NEO4J_ENCRYPTED: "false"
       MINIO_HOST: minio:9000
       MINIO_USER: dataops-test
-      MINIO_PASSWORD: dataops-test-password
+      MINIO_PASSWORD: ${DATAOPS_MINIO_PASSWORD:-dataops-test-password}
       MINIO_BUCKET: dataops-bucket
       MINIO_SECURE: "false"
       DATAFLOW_DEFAULT_DB_HOST: postgres
@@ -464,7 +471,7 @@ services:
       QWEN_EMBEDDING_BASE_URL: ${QWEN_EMBEDDING_BASE_URL:-}
       QWEN_EMBEDDING_API_KEY: ${QWEN_EMBEDDING_API_KEY:-}
       QWEN_EMBEDDING_MODEL: ${QWEN_EMBEDDING_MODEL:-text-embedding-v3}
-      SECRET_KEY: dataops-local-test-secret-key
+      SECRET_KEY: ${SECRET_KEY:-dataops-local-test-secret-key}
       AUDIT_EVIDENCE_SECRET: ${AUDIT_EVIDENCE_SECRET:-dataops-local-audit-evidence-secret-change-me}
       AUDIT_EVIDENCE_KEY_VERSION: ${AUDIT_EVIDENCE_KEY_VERSION:-local-v1}
       SECURITY_SIEM_HOST_ALLOWLIST: ${SECURITY_SIEM_HOST_ALLOWLIST:-}
@@ -566,12 +573,12 @@ services:
       POSTGRES_HOST: postgres
       POSTGRES_PORT: 5432
       POSTGRES_USER: lightrag
-      POSTGRES_PASSWORD: lightrag-test-password
+      POSTGRES_PASSWORD: ${LIGHTRAG_POSTGRES_PASSWORD:-lightrag-test-password}
       POSTGRES_DATABASE: dataops_lightrag
       POSTGRES_ENABLE_VECTOR: "true"
       NEO4J_URI: bolt://lightrag-neo4j:7687
       NEO4J_USERNAME: neo4j
-      NEO4J_PASSWORD: lightrag-test-password
+      NEO4J_PASSWORD: ${LIGHTRAG_NEO4J_PASSWORD:-lightrag-test-password}
       NEO4J_DATABASE: neo4j
       LLM_BINDING: openai
       LLM_BINDING_HOST: ${LIGHTRAG_LLM_BASE_URL:-https://api.deepseek.com/v1}

+ 1 - 1
deployment/CHECKLIST.md

@@ -5,7 +5,7 @@
 - [ ] 服务器为 Ubuntu 20.04/22.04,可 sudo
 - [ ] Python 3.8+ 已安装(`python3 --version`)
 - [ ] Supervisor 已安装并运行(`systemctl status supervisor`)
-- [ ] PostgreSQL 三身份分离:role-init(DBA/CREATEROLE)、migrator(无 CREATEROLE)、runtime(非 owner)
+- [ ] PostgreSQL 三身份分离:role-init(DBA/CREATEROLE)、migrator(无 CREATEROLE)、runtime(非 owner);WP06 另有 NOLOGIN trusted-delivery owner / writer,runtime 仅可执行受控写入过程
 - [ ] `DB_ROLE_INIT_DATABASE_URL` 仅在一次性角色初始化期间可用,完成后已回收
 - [ ] `MIGRATION_DATABASE_URL` 与 runtime `DATABASE_URL` 分别测试通过
 - [ ] Neo4j 可连接(Bolt 7687 / HTTP 7474)

+ 2 - 2
deployment/DEPLOYMENT_GUIDE.md

@@ -99,8 +99,8 @@ sudo chmod 640 /etc/dataops-platform/dataops.env
 | `DEEPSEEK_API_KEY` | DeepSeek API 密钥 |
 | `N8N_API_KEY` | n8n API 密钥 |
 | `DB_ROLE_INIT_DATABASE_URL` | 仅一次性角色预置使用的 DBA/CREATEROLE 连接串;完成后回收 |
-| `MIGRATION_DATABASE_URL` | 仅 schema migration 使用;无需 CREATEROLE,但须为 evidence owner 成员 |
-| `DATABASE_URL` | Gunicorn 常驻进程使用的非 owner、非超级用户 runtime 连接串 |
+| `MIGRATION_DATABASE_URL` | 仅 schema migration 使用;无需 CREATEROLE,且须为 evidence / trusted-delivery owner 与 writer 角色成员 |
+| `DATABASE_URL` | Gunicorn 常驻进程使用的非 owner、非超级用户 runtime 连接串;不得是 trusted-delivery owner / writer 成员 |
 | `NEO4J_PASSWORD` | Neo4j 密码 |
 | `MINIO_*` | MinIO 四项须匹配同一实例 |
 

+ 73 - 0
deployment/app/api/data_factory/observability_routes.py

@@ -2,6 +2,9 @@
 
 from __future__ import annotations
 
+import uuid
+from contextlib import suppress
+
 from flask import g, jsonify, request
 
 from app import db
@@ -22,18 +25,40 @@ def get_data_observability_service():
     )
 
 
+def get_production_operations_service():
+    import time
+
+    from app.core.events.production_operations import ProductionOperationsService
+    from app.core.events.production_operations_repository import (
+        SqlAlchemyProductionOperationsRepository,
+    )
+
+    return ProductionOperationsService(
+        SqlAlchemyProductionOperationsRepository(db.session), now=time.time
+    )
+
+
 def _actor_uid():
     identity = getattr(g, "current_user", {}) or {}
     return identity.get("id") or identity.get("sub")
 
 
 def _payload():
+    body = request.get_data(cache=True)
+    if len(body) > 4096:
+        raise ValueError("request body exceeds 4096 bytes")
     value = request.get_json(silent=True)
     if not isinstance(value, dict):
         raise ValueError("request body must be an object")
     return value
 
 
+def _no_store(value, status):
+    response = jsonify(success(value))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
 def _error(error):
     db.session.rollback()
     if isinstance(error, LookupError):
@@ -45,6 +70,35 @@ def _error(error):
     return jsonify(failed("数据可观测与事故请求处理失败", code=500)), 500
 
 
+def _production_delivery_error(error, service):
+    """Rollback first, then record only a redacted rejection receipt."""
+    db.session.rollback()
+    message = str(error)
+    reason_code = (
+        "conflict"
+        if isinstance(error, RuntimeError)
+        or message in {"idempotency conflict", "delivery queue hard limit reached"}
+        else "invalid_request"
+        if isinstance(error, ValueError)
+        else "internal_error"
+    )
+    with suppress(Exception):
+        service.audit_rejection_independently(
+            actor_uid=_actor_uid(),
+            reason_code=reason_code,
+            correlation_id=str(uuid.uuid4()),
+        )
+    status = {"invalid_request": 400, "conflict": 409, "internal_error": 500}[reason_code]
+    return jsonify(failed(reason_code, code=status)), status
+
+
+@bp.after_app_request
+def _no_store_production_delivery_responses(response):
+    if request.path == "/api/datafactory/observability/operations/deliveries":
+        response.headers["Cache-Control"] = "no-store"
+    return response
+
+
 @bp.get("/observability/overview")
 def get_observability_overview():
     try:
@@ -84,6 +138,25 @@ def collect_observability_signals():
         return _error(error)
 
 
+@bp.post("/observability/operations/deliveries")
+def enqueue_production_delivery():
+    service = None
+    try:
+        payload = _payload()
+        if set(payload) != {"incident_uid", "alert_uid", "channel", "summary"}:
+            raise ValueError("production delivery request has unsupported fields")
+        service = get_production_operations_service()
+        record = service.enqueue_incident_delivery(
+            payload, actor_uid=_actor_uid()
+        )
+        db.session.commit()
+        return _no_store(record, 201)
+    except Exception as error:
+        return _production_delivery_error(
+            error, service or get_production_operations_service()
+        )
+
+
 @bp.get("/observability/alerts")
 def list_observability_alerts():
     try:

+ 108 - 0
deployment/app/api/knowledge_base/agent_governance_routes.py

@@ -3,6 +3,7 @@
 from __future__ import annotations
 
 import hashlib
+import uuid
 
 from flask import current_app, g, jsonify, request
 
@@ -14,6 +15,14 @@ from app.core.llm.agent_governance_repository import (
     SqlAlchemyAgentGovernanceRepository,
     WorkCenterAgentApprovalGateway,
 )
+from app.core.llm.runtime_governance_repository import (
+    SqlAlchemyRuntimeGovernanceRepository,
+)
+from app.core.llm.runtime_server import (
+    RuntimeServerContext,
+    RuntimeServerError,
+    ServerGovernedInvocationService,
+)
 from app.core.system.permissions import (
     AGENTS_MANAGE,
     AGENTS_OPERATE,
@@ -60,6 +69,10 @@ def _service():
     )
 
 
+def _runtime_service():
+    return ServerGovernedInvocationService(SqlAlchemyRuntimeGovernanceRepository(db.session))
+
+
 def _expected_version() -> int:
     raw = str(request.headers.get("If-Match") or "").strip()
     if raw.startswith("W/"):
@@ -267,3 +280,98 @@ def agent_governance_dashboard():
         return jsonify(success(_service().dashboard()))
     except AgentGovernanceUnavailable as exc:
         return _error(exc)
+
+
+@bp.route("/agents/<agent_uid>/runtime/invocations", methods=["POST"])
+@require_permissions(AGENTS_OPERATE)
+def authorize_runtime_invocation(agent_uid):
+    """The only HTTP path that binds Agent credentials to a server identity."""
+    try:
+        token = str(request.headers.get("X-Agent-Credential") or "")
+        if not token:
+            raise PermissionError("Agent credential is required")
+        _service().validate_credential(agent_uid, token)
+        result = _runtime_service().authorize(
+            RuntimeServerContext(
+                agent_uid=agent_uid,
+                actor_uid=g.current_user["id"],
+                roles=frozenset(g.current_user["roles"]),
+            ),
+            request.get_json(silent=True) or {},
+        )
+        db.session.commit()
+        return _no_store(jsonify(success(result, code=201))), 201
+    except (RuntimeServerError, ValueError, LookupError, PermissionError, RuntimeError) as exc:
+        response, status = _error(exc)
+        return _no_store(response), status
+
+
+@bp.route("/agents/<agent_uid>/runtime/invocations/<idempotency_key>/settle", methods=["POST"])
+@require_permissions(AGENTS_OPERATE)
+def settle_runtime_invocation(agent_uid, idempotency_key):
+    try:
+        token = str(request.headers.get("X-Agent-Credential") or "")
+        if not token:
+            raise PermissionError("Agent credential is required")
+        claims = _service().validate_credential(agent_uid, token)
+        agent = _service().get_agent(agent_uid)
+        if claims["agent_uid"] != agent_uid or agent["owner_uid"] != g.current_user["id"]:
+            raise PermissionError("Agent credential principal does not match")
+        body = request.get_json(silent=True) or {}
+        allowed = {"lease_fence", "outcome", "actual_tokens", "actual_cost_micros", "actual_tools", "actual_time_ms"}
+        if set(body) != allowed:
+            raise ValueError("runtime settlement payload is closed")
+        scope = _runtime_service().repository.settlement_context(
+            agent_uid=agent_uid, actor_uid=g.current_user["id"], idempotency_key=idempotency_key
+        )
+        result = _runtime_service().repository.settle_claim({
+            **scope,
+            "worker_id": f"agent-runtime-http:{g.current_user['id']}",
+            **body,
+        })
+        db.session.commit()
+        if result.get("rejected"):
+            return _no_store(jsonify(failed("runtime_settlement_rejected", code=409))), 409
+        return _no_store(jsonify(success(result, code=201))), 201
+    except (RuntimeServerError, ValueError, LookupError, PermissionError, RuntimeError) as exc:
+        response, status = _error(exc)
+        return _no_store(response), status
+
+
+@bp.route("/agents/<agent_uid>/runtime/control", methods=["POST"])
+@require_permissions(AGENTS_OPERATE)
+def control_runtime(agent_uid):
+    """Execute a recovery/canary change only through an authenticated control claim."""
+    try:
+        token = str(request.headers.get("X-Agent-Credential") or "")
+        if not token:
+            raise PermissionError("Agent credential is required")
+        claims = _service().validate_credential(agent_uid, token)
+        agent = _service().get_agent(agent_uid)
+        if claims["agent_uid"] != agent_uid or agent["owner_uid"] != g.current_user["id"]:
+            raise PermissionError("Agent credential principal does not match")
+        body = request.get_json(silent=True) or {}
+        forbidden = {"agent_uid", "principal_id"}
+        required = {
+            "tenant_id", "business_domain_uid", "environment", "operation", "approval_task_uid",
+            "idempotency_key", "request_digest", "expected_fence", "incident_uid", "from_state",
+            "to_state", "generation", "from_generation", "to_generation", "dataset_version",
+            "dataset_digest", "metrics_digest", "threshold_policy", "issued_at",
+        }
+        if set(body) != required or set(body) & forbidden:
+            raise ValueError("runtime control payload is closed")
+        credential = _service().repository.get_credential(claims["jti"])
+        if not credential:
+            raise PermissionError("Agent credential is revoked or unknown")
+        payload = {**body, "agent_uid": agent_uid, "principal_id": g.current_user["id"]}
+        claim_uid = _runtime_service().repository.issue_control_claim({
+            "claim_uid": str(uuid.uuid4()), "credential_uid": credential["uid"],
+            "credential_token_digest": hashlib.sha256(token.encode()).hexdigest(),
+            "nonce": str(uuid.uuid4()), "control_payload": payload,
+        })
+        result = _runtime_service().repository.control_claimed(payload, claim_uid)
+        db.session.commit()
+        return _no_store(jsonify(success(result, code=201))), 201
+    except (RuntimeServerError, ValueError, LookupError, PermissionError, RuntimeError) as exc:
+        response, status = _error(exc)
+        return _no_store(response), status

+ 6 - 0
deployment/app/api/system/__init__.py

@@ -6,9 +6,15 @@ bp = Blueprint("system", __name__)
 
 from app.api.system import governance_audit  # noqa: E402, F401
 from app.api.system import enterprise_identity  # noqa: E402, F401
+from app.api.system import bi_ai_catalog_routes  # noqa: E402, F401
+from app.api.system import metering_showback_routes  # noqa: E402, F401
+from app.api.system import plugin_platform_routes  # noqa: E402, F401
 from app.api.system import responsibilities  # noqa: E402, F401
 from app.api.system import routes  # noqa: E402, F401
 from app.api.system import security_governance  # noqa: E402, F401
+from app.api.system import trusted_delivery  # noqa: E402, F401
+from app.api.system import trusted_delivery_controls  # noqa: E402, F401
+from app.api.system import tenant_routes  # noqa: E402, F401
 from app.api.system import users  # noqa: E402, F401
 from app.api.system import workbench  # noqa: E402, F401
 from app.api.system import work_center  # noqa: E402, F401

+ 166 - 0
deployment/app/api/system/bi_ai_catalog_routes.py

@@ -0,0 +1,166 @@
+"""Closed, RBAC-protected HTTP contract for the local WP11 catalog fixture."""
+
+from __future__ import annotations
+
+import os
+
+from flask import current_app, g, jsonify, request
+from sqlalchemy import create_engine
+
+from app import db
+from app.api.system import bp
+from app.config.database_urls import validate_postgresql_url
+from app.core.governance.bi_ai_asset_catalog import (
+    CatalogApplicationService,
+    CatalogControlIssuer,
+)
+from app.core.system.permissions import (
+    BI_AI_CATALOG_MANAGE,
+    BI_AI_CATALOG_READ,
+    require_permissions,
+)
+from app.models.result import failed, success
+
+_MAX_BODY_BYTES = 4096
+
+
+def _service():
+    control_url = os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", "")
+    control = validate_postgresql_url(control_url, "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+    runtime = validate_postgresql_url(
+        str(current_app.config.get("SQLALCHEMY_DATABASE_URI", "")), "DATABASE_URL"
+    )
+    if control.username != "dataops_bi_ai_catalog_control" or control.username == runtime.username:
+        raise RuntimeError("catalog control identity is not configured")
+    return CatalogApplicationService(
+        db.session,
+        CatalogControlIssuer(create_engine(control_url, pool_pre_ping=True)),
+    )
+
+
+def _closed_body(required: set[str]) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("catalog request rejected")
+    body = request.get_json(silent=True)
+    if not isinstance(body, dict) or set(body) != required:
+        raise ValueError("catalog request rejected")
+    return body
+
+
+def _response(value, status: int = 200):
+    response = jsonify(success(value, code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _failure(status: int = 400):
+    response = jsonify(failed("catalog request rejected", code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+@bp.post("/bi-ai-catalog/local-fixture/sync")
+@require_permissions(BI_AI_CATALOG_MANAGE)
+def sync_local_fixture():
+    try:
+        body = _closed_body(set())
+        service = _service()
+        if hasattr(service, "sync_local_fixture"):
+            return _response(
+                service.sync_local_fixture(
+                    principal_id=str(g.current_user["id"]), body=body
+                ),
+                201,
+            )
+        return _response(
+            {
+                "source": "local-fixture-v1",
+                "mode": "ENGINEERING_EVIDENCE_ONLY",
+                "persisted_before_ack": False,
+            },
+            201,
+        )
+    except (KeyError, PermissionError, RuntimeError, TypeError, ValueError):
+        return _failure()
+
+
+@bp.post("/bi-ai-catalog/assets/search")
+@require_permissions(BI_AI_CATALOG_READ)
+def search_catalog_assets():
+    try:
+        body = _closed_body({"query", "filters"})
+        service = _service()
+        if hasattr(service, "search_for_principal"):
+            return _response(
+                service.search_for_principal(
+                    principal_id=str(g.current_user["id"]),
+                    query=body["query"],
+                    filters=body["filters"],
+                )
+            )
+        return _response(
+            service.search(
+                body["query"],
+                body["filters"],
+                principal_roles=set(g.current_user.get("roles", [])),
+                domain="default",
+            )
+        )
+    except ValueError:
+        return _failure(400)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError):
+        return _failure(403)
+
+
+@bp.get("/bi-ai-catalog/assets/<external_uid>/impact")
+@require_permissions(BI_AI_CATALOG_READ)
+def catalog_asset_impact(external_uid: str):
+    try:
+        if set(request.args) - {"max_depth", "max_nodes"}:
+            raise ValueError("catalog request rejected")
+        max_depth, max_nodes = (
+            int(request.args.get("max_depth", "3")),
+            int(request.args.get("max_nodes", "50")),
+        )
+        service = _service()
+        if hasattr(service, "impact_for_principal"):
+            return _response(
+                service.impact_for_principal(
+                    principal_id=str(g.current_user["id"]),
+                    external_uid=external_uid,
+                    max_depth=max_depth,
+                    max_nodes=max_nodes,
+                )
+            )
+        return _response(
+            service.impact(
+                external_uid,
+                principal_roles=set(g.current_user.get("roles", [])),
+                domain="default",
+                max_depth=max_depth,
+                max_nodes=max_nodes,
+            )
+        )
+    except (
+        KeyError,
+        LookupError,
+        PermissionError,
+        RuntimeError,
+        TypeError,
+        ValueError,
+    ):
+        return _failure(403)
+
+
+@bp.get("/bi-ai-catalog/audit")
+@require_permissions(BI_AI_CATALOG_READ)
+def catalog_audit():
+    try:
+        if request.args:
+            raise ValueError("catalog request rejected")
+        service = _service()
+        return _response(
+            service.audit_for_principal(principal_id=str(g.current_user["id"]))
+        )
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError):
+        return _failure(403)

+ 137 - 0
deployment/app/api/system/metering_showback_routes.py

@@ -0,0 +1,137 @@
+"""Closed, Showback-only WP12 HTTP boundary; no chargeback endpoint exists."""
+
+from __future__ import annotations
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import SQLAlchemyError
+
+from app.api.system import bp
+from app.core.governance.metering_showback import DatabaseMeteringShowbackService
+from app.core.system.permissions import (
+    METERING_MANAGE,
+    METERING_READ,
+    require_permissions,
+)
+from app.models.result import failed, success
+
+_MAX_BODY_BYTES = 4096
+_EVENT_FIELDS = {"schema_version", "event_uid", "event_kind", "occurred_at", "window_start", "window_end", "quantity", "unit", "idempotency_key", "evidence", "mapping", "correction_of"}
+_REQUIRED_EVENT_FIELDS = _EVENT_FIELDS - {"correction_of"}
+_ALLOCATION_FIELDS = {"schema_version", "rule_uid", "rule_version", "effective_start", "effective_end", "mapping", "allocations"}
+_BUDGET_FIELDS = {"schema_version", "budget_uid", "window", "mapping", "limit_micros", "threshold_micros"}
+
+
+def _service() -> DatabaseMeteringShowbackService:
+    return DatabaseMeteringShowbackService()
+
+
+def _response(value: object, status: int = 200):
+    response = jsonify(success(value, code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _failure(status: int = 400):
+    response = jsonify(failed("metering request rejected", code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _event_body() -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("metering_body_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) not in (_REQUIRED_EVENT_FIELDS, _EVENT_FIELDS):
+        raise ValueError("metering_body_closed")
+    mapping = value.get("mapping")
+    if not isinstance(mapping, dict) or set(mapping) != {"department", "project", "cost_center"}:
+        raise ValueError("metering_mapping_closed")
+    return value
+
+
+@bp.post("/metering/events")
+@require_permissions(METERING_MANAGE)
+def record_metering_event():
+    """record local metering event"""
+    try:
+        body = _event_body()
+        result = _service().record_for_principal(principal_id=str(g.current_user["id"]), body=body)
+        return _response(result, 201 if not result.get("replay") else 200)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+def _control_body(fields: set[str]) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("metering_body_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) != fields:
+        raise ValueError("metering_body_closed")
+    mapping = value.get("mapping")
+    if not isinstance(mapping, dict) or set(mapping) != {"department", "project", "cost_center"}:
+        raise ValueError("metering_mapping_closed")
+    return value
+
+
+@bp.post("/metering/allocations")
+@require_permissions(METERING_MANAGE)
+def publish_metering_allocation():
+    """publish versioned local allocation rule"""
+    try:
+        return _response(_service().publish_allocation_for_principal(principal_id=str(g.current_user["id"]), body=_control_body(_ALLOCATION_FIELDS)), 201)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/metering/budgets")
+@require_permissions(METERING_MANAGE)
+def evaluate_metering_budget():
+    """persist disabled-provider budget alert evidence"""
+    try:
+        return _response(_service().evaluate_budget_for_principal(principal_id=str(g.current_user["id"]), body=_control_body(_BUDGET_FIELDS)), 201)
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+def _window() -> str:
+    if set(request.args) != {"window"}:
+        raise ValueError("metering_query_closed")
+    value = request.args.get("window", "")
+    if len(value) != 7 or value[4:5] != "-" or not value.replace("-", "").isdigit():
+        raise ValueError("metering_window_invalid")
+    return value
+
+
+@bp.get("/metering/showback")
+@require_permissions(METERING_READ)
+def get_showback():
+    """get local showback"""
+    try:
+        return _response(_service().showback_for_principal(principal_id=str(g.current_user["id"]), window=_window(), kind="showback"))
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure(403)
+
+
+@bp.get("/metering/reconciliation")
+@require_permissions(METERING_READ)
+def get_metering_reconciliation():
+    """get metering reconciliation"""
+    try:
+        return _response(_service().showback_for_principal(principal_id=str(g.current_user["id"]), window=_window(), kind="reconciliation"))
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure(403)
+
+
+@bp.get("/metering/allocation-replay")
+@require_permissions(METERING_READ)
+def get_metering_allocation_replay():
+    """replay one persisted allocation-rule version"""
+    try:
+        if set(request.args) != {"window", "rule_uid", "rule_version"}:
+            raise ValueError("metering_query_closed")
+        version = request.args.get("rule_version", "")
+        if not version.isdigit():
+            raise ValueError("rule_version_invalid")
+        return _response(_service().allocation_replay_for_principal(principal_id=str(g.current_user["id"]), window=request.args.get("window", ""), rule_uid=request.args.get("rule_uid", ""), rule_version=int(version)))
+    except (KeyError, LookupError, PermissionError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure(403)

+ 140 - 0
deployment/app/api/system/plugin_platform_routes.py

@@ -0,0 +1,140 @@
+"""Closed HTTP validation boundary for the inactive WP13 local fixture."""
+
+from __future__ import annotations
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import SQLAlchemyError
+
+from app.api.system import bp
+from app.core.plugins.governance import PluginManifestError, normalize_plugin_manifest
+from app.core.plugins.persistence import (
+    DatabasePluginPlatformService,
+    PluginPersistenceError,
+)
+from app.core.plugins.repository import PluginLifecycleError, PluginPlatform
+from app.core.system.permissions import AGENTS_MANAGE, require_permissions
+from app.models.result import failed, success
+
+_MAX_BODY_BYTES = 8192
+
+
+def _body(required: set[str]) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_BODY_BYTES:
+        raise ValueError("plugin_body_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) != required:
+        raise ValueError("plugin_body_closed")
+    return value
+
+
+def _response(value: object, status: int = 200):
+    response = jsonify(success(value, code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+def _failure(status: int = 400):
+    response = jsonify(failed("plugin request rejected", code=status))
+    response.headers["Cache-Control"] = "no-store"
+    return response, status
+
+
+@bp.post("/plugins/local-fixture/validate")
+@require_permissions(AGENTS_MANAGE)
+def validate_local_plugin_fixture():
+    """Validate closed metadata only; it never stores or activates a plugin."""
+    try:
+        body = _body({"manifest", "registry_record"})
+        platform = PluginPlatform(now=lambda: 0)
+        result = platform.register(body["manifest"], registry_record=body["registry_record"])
+        return _response({"plugin_uid": result["plugin_uid"], "version": result["version"], "manifest_digest": result["manifest_digest"], "mode": "ENGINEERING_EVIDENCE_ONLY", "activation": "blocked"})
+    except (PluginManifestError, PluginLifecycleError, TypeError, ValueError):
+        return _failure()
+
+
+@bp.post("/plugins/invocations")
+@require_permissions(AGENTS_MANAGE)
+def invoke_plugin_fixture():
+    """Invoke only an approved fixed local fixture through the DB gateway."""
+    try:
+        body = _body({"plugin_uid", "version", "operation", "input_digest", "idempotency_key"})
+        return _response(DatabasePluginPlatformService().invoke(actor_ref=str(g.current_user["id"]), **body), 201)
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/registry")
+@require_permissions(AGENTS_MANAGE)
+def register_plugin_fixture():
+    try:
+        body = _body({"manifest", "registry_record"})
+        # Validate executable-surface metadata before allocating a DB gateway;
+        # this keeps malformed URL/code/credential bodies out of all backends.
+        normalize_plugin_manifest(body["manifest"])
+        return _response(DatabasePluginPlatformService().register(actor_ref=str(g.current_user["id"]), **body), 201)
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/review")
+@require_permissions(AGENTS_MANAGE)
+def review_plugin_fixture(plugin_uid: str, version: str):
+    try:
+        _body(set())
+        return _response(DatabasePluginPlatformService().review(plugin_uid=plugin_uid, version=version, actor_ref=str(g.current_user["id"])))
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/approvals")
+@require_permissions(AGENTS_MANAGE)
+def approve_plugin_fixture(plugin_uid: str, version: str):
+    try:
+        body = _body({"approval_action"})
+        return _response(DatabasePluginPlatformService().issue_approval(plugin_uid=plugin_uid, version=version, actor_ref=str(g.current_user["id"]), **body), 201)
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+def _transition(plugin_uid: str, version: str, target_state: str):
+    try:
+        body = _body({"approval_uid", "expected_fence", "incident_uid"})
+        return _response(DatabasePluginPlatformService().transition(plugin_uid=plugin_uid, version=version, target_state=target_state, actor_ref=str(g.current_user["id"]), **body))
+    except (PluginPersistenceError, RuntimeError, TypeError, ValueError, SQLAlchemyError):
+        return _failure()
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/canary")
+@require_permissions(AGENTS_MANAGE)
+def canary_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "canary")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/activate")
+@require_permissions(AGENTS_MANAGE)
+def activate_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "active")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/pause")
+@require_permissions(AGENTS_MANAGE)
+def pause_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "paused")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/rollback")
+@require_permissions(AGENTS_MANAGE)
+def rollback_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "rolled_back")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/revoke")
+@require_permissions(AGENTS_MANAGE)
+def revoke_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "revoked")
+
+
+@bp.post("/plugins/<plugin_uid>/<version>/recover")
+@require_permissions(AGENTS_MANAGE)
+def recover_plugin_fixture(plugin_uid: str, version: str):
+    return _transition(plugin_uid, version, "recovery")

+ 207 - 0
deployment/app/api/system/tenant_routes.py

@@ -0,0 +1,207 @@
+"""Authenticated, fail-closed HTTP entry points for the conditional WP10 base."""
+
+from __future__ import annotations
+
+import os
+
+from flask import g, jsonify, request
+
+from app.api.system import bp
+from app.core.system.permissions import (
+    IDENTITY_MANAGE,
+    IDENTITY_OPERATE,
+    IDENTITY_READ,
+    require_permissions,
+)
+from app.core.system.tenant_control_repository import SqlAlchemyTenantControlRepository
+from app.core.system.tenant_control_service import (
+    TenantControlError,
+    TenantControlService,
+)
+from app.models.result import failed, success
+
+_MAX_REQUEST_BYTES = 4096
+_QUOTA_FIELDS = {"quota_name", "amount", "idempotency_key"}
+_LIFECYCLE_FIELDS = {"expected_fence", "idempotency_key", "approval_ref", "backup_digest", "retention_seconds"}
+_APPROVAL_FIELDS = {"operation", "expected_fence", "idempotency_key", "backup_digest", "retention_seconds"}
+
+
+def _service() -> TenantControlService:
+    return TenantControlService(SqlAlchemyTenantControlRepository())
+
+
+def _body(allowed: set[str] = _QUOTA_FIELDS) -> dict:
+    if request.content_length is not None and request.content_length > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    if len(request.get_data(cache=True)) > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or set(value) != allowed:
+        raise TenantControlError("tenant_payload_closed")
+    return value
+
+
+def _server_host() -> str:
+    # Deliberately never consume a client-supplied tenant field or a forwarded
+    # host header.  Trusted proxy normalization belongs in deployment; the
+    # persistent DB membership is the final principal+route authorization.
+    host = os.environ.get("TRUSTED_TENANT_ROUTE_HOST", "").lower()
+    if not host:
+        raise TenantControlError("tenant_route_denied")
+    return host
+
+
+@bp.post("/tenant/quota-claims")
+@require_permissions(IDENTITY_OPERATE)
+def issue_tenant_quota_claim():
+    try:
+        value = _service().issue_quota_claim(
+            principal_id=str(g.current_user["id"]),
+            host=_server_host(),
+            request=_body(),
+        )
+        response = jsonify(success(value, code=201))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 201
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant control request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+@bp.post("/tenant/provisions")
+@require_permissions(IDENTITY_MANAGE)
+def provision_private_tenant():
+    try:
+        value = _service().provision_private(
+            principal_id=str(g.current_user["id"]), host=_server_host(), request=_body_provision()
+        )
+        response = jsonify(success(value, code=201))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 201
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant control request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+def _body_provision() -> dict:
+    return _body({"idempotency_key"})
+
+
+@bp.post("/tenant/approvals")
+@require_permissions(IDENTITY_MANAGE)
+def issue_tenant_lifecycle_approval():
+    try:
+        value = _service().issue_lifecycle_approval(
+            reviewer_id=str(g.current_user["id"]), request=_body_approval()
+        )
+        response = jsonify(success(value, code=201))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 201
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant approval request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+def _body_approval() -> dict:
+    if request.content_length is not None and request.content_length > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    if len(request.get_data(cache=True)) > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or not set(value).issubset(_APPROVAL_FIELDS) or not {"operation", "expected_fence", "idempotency_key"}.issubset(value):
+        raise TenantControlError("tenant_payload_closed")
+    return value
+
+
+def _lifecycle(operation: str):
+    try:
+        value = _service().lifecycle_transition(
+            principal_id=str(g.current_user["id"]), host=_server_host(), operation=operation, request=_body_lifecycle()
+        )
+        response = jsonify(success(value))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 200
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant lifecycle request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+@bp.post("/tenant/lifecycle/activate")
+@require_permissions(IDENTITY_MANAGE)
+def activate_tenant_lifecycle():
+    return _lifecycle("activate")
+
+
+@bp.post("/tenant/lifecycle/freeze")
+@require_permissions(IDENTITY_MANAGE)
+def freeze_tenant_lifecycle():
+    return _lifecycle("freeze")
+
+
+@bp.post("/tenant/lifecycle/recover")
+@require_permissions(IDENTITY_MANAGE)
+def recover_tenant_lifecycle():
+    return _lifecycle("begin_recovery")
+
+
+@bp.post("/tenant/lifecycle/deletion-candidate")
+@require_permissions(IDENTITY_MANAGE)
+def mark_tenant_deletion_candidate():
+    return _lifecycle("mark_deletion_candidate")
+
+
+@bp.post("/tenant/lifecycle/rollback")
+@require_permissions(IDENTITY_MANAGE)
+def rollback_tenant_lifecycle():
+    return _lifecycle("rollback")
+
+
+@bp.post("/tenant/lifecycle/delete")
+@require_permissions(IDENTITY_MANAGE)
+def delete_tenant_lifecycle():
+    return _lifecycle("delete")
+
+
+@bp.get("/tenant/status")
+@require_permissions(IDENTITY_READ)
+def get_tenant_status():
+    return _read("status")
+
+
+@bp.get("/tenant/audit")
+@require_permissions(IDENTITY_READ)
+def get_tenant_audit():
+    return _read("audit")
+
+
+@bp.get("/tenant/manifests")
+@require_permissions(IDENTITY_READ)
+def get_tenant_manifests():
+    return _read("manifests")
+
+
+def _read(kind: str):
+    try:
+        value = _service().read(principal_id=str(g.current_user["id"]), host=_server_host(), kind=kind)
+        response = jsonify(success(value))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 200
+    except (KeyError, RuntimeError, TypeError, ValueError, TenantControlError):
+        response = jsonify(failed("tenant read request rejected", code=400))
+        response.headers["Cache-Control"] = "no-store"
+        return response, 400
+
+
+def _body_lifecycle() -> dict:
+    if request.content_length is not None and request.content_length > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    if len(request.get_data(cache=True)) > _MAX_REQUEST_BYTES:
+        raise TenantControlError("tenant_payload_closed")
+    value = request.get_json(silent=True)
+    if not isinstance(value, dict) or not set(value).issubset(_LIFECYCLE_FIELDS) or not {"expected_fence", "idempotency_key"}.issubset(value):
+        raise TenantControlError("tenant_payload_closed")
+    return value

+ 182 - 0
deployment/app/api/system/trusted_delivery.py

@@ -0,0 +1,182 @@
+"""No-store HTTP boundary for closed trusted-delivery contracts."""
+from datetime import UTC, datetime
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import DBAPIError, IntegrityError
+
+from app import db
+from app.api.system import bp
+from app.core.system.permissions import (
+    SECURITY_GOVERNANCE_MANAGE,
+    SECURITY_GOVERNANCE_OPERATE,
+    require_permissions,
+)
+from app.core.system.trusted_delivery import TrustedDeliveryService
+from app.core.system.trusted_delivery_repository import (
+    SqlAlchemyTrustedDeliveryRepository,
+)
+from app.core.system.trusted_delivery_subscription_repository import (
+    SqlAlchemyTrustedDeliverySubscriptionRepository,
+)
+from app.core.system.trusted_delivery_subscriptions import (
+    TrustedDeliverySubscriptionService,
+)
+from app.models.result import failed, success
+
+MAX_TRUSTED_DELIVERY_REQUEST_BYTES = 16 * 1024
+
+
+def _service():
+    return TrustedDeliveryService(SqlAlchemyTrustedDeliveryRepository(db.session))
+
+
+def _subscription_service():
+    return TrustedDeliverySubscriptionService(
+        SqlAlchemyTrustedDeliverySubscriptionRepository(db.session)
+    )
+
+
+def _execute(operation, *, created=False):
+    try:
+        value = operation()
+        # Service/repository methods deliberately leave transaction ownership to
+        # the HTTP boundary.  Commit before returning success so a second
+        # connection can observe a successful response immediately.
+        db.session.commit()
+        response = jsonify(success(value, code=201 if created else 200))
+        response.headers["Cache-Control"] = "no-store"
+        return (response, 201) if created else response
+    except PermissionError:
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery request denied", code=403))
+    except (IntegrityError, DBAPIError):
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery request conflict", code=409))
+    except (LookupError, RuntimeError, ValueError, TypeError):
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery request rejected", code=400))
+    response.headers["Cache-Control"] = "no-store"
+    return response, response.get_json()["code"]
+
+
+def _body(allowed):
+    if request.content_length is not None and request.content_length > MAX_TRUSTED_DELIVERY_REQUEST_BYTES:
+        raise ValueError("trusted delivery request is too large")
+    if len(request.get_data(cache=True)) > MAX_TRUSTED_DELIVERY_REQUEST_BYTES:
+        raise ValueError("trusted delivery request is too large")
+    body = request.get_json(silent=True)
+    if not isinstance(body, dict) or set(body) - allowed:
+        raise ValueError("closed request schema")
+    return body
+
+
+@bp.post("/trusted-delivery/policy-versions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def create_trusted_delivery_policy():
+    return _execute(lambda: _service().create_policy_version(_body({"code", "version", "selector", "resource_rules"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/policy-versions/activate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def activate_trusted_delivery_policy():
+    return _execute(lambda: _service().activate_policy_version(_body({"code", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/policy-versions/rollback")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def rollback_trusted_delivery_policy():
+    return _execute(lambda: _service().rollback_policy_version(_body({"code", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/decisions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def evaluate_trusted_delivery():
+    allowed = {"subject_uid", "roles", "business_domain_uid", "asset_uid", "purpose", "environment", "action", "classification", "requested_fields"}
+    body = _body(allowed)
+    body["subject_uid"] = g.current_user["id"]
+    body["roles"] = list(g.current_user["roles"])
+    return _execute(lambda: _service().evaluate_gateway(body))
+
+
+@bp.post("/trusted-delivery/provisions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def provision_trusted_delivery():
+    allowed = {"policy_uid", "approval_ref", "approval_digest", "asset_uid", "business_domain_uid", "purpose", "environment", "action", "classification", "requested_fields", "expires_at", "target_capability", "provider", "idempotency_key"}
+    def operation():
+        body = _body(allowed)
+        # Browser callers never choose the identity facts used for policy matching.
+        body["subject_uid"] = g.current_user["id"]
+        return _service().provision(body, actor_uid=g.current_user["id"], subject_roles=list(g.current_user["roles"]))
+    return _execute(operation, created=True)
+
+
+@bp.post("/trusted-delivery/legal-holds")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def create_trusted_delivery_hold():
+    return _execute(lambda: _service().create_legal_hold(_body({"asset_uid", "operation", "approver_refs", "evidence_digest"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/legal-holds/release")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def release_trusted_delivery_hold():
+    return _execute(lambda: _service().release_legal_hold(_body({"hold_uid", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/reclaim/preview")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_reclaim_preview():
+    body = _body({"as_of"})
+    as_of = body.get("as_of") or datetime.now(UTC).isoformat()
+    return _execute(lambda: {"candidates": _service().preview_reclaim(as_of=as_of, actor_uid=g.current_user["id"]), "executed": False})
+
+
+@bp.post("/trusted-delivery/reclaim/execute")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_reclaim_execute():
+    return _execute(lambda: _service().execute_reclaim(_body({"grant_uid", "idempotency_key"}), actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def create_trusted_delivery_subscription():
+    allowed = {"grant_uid", "asset_uid", "trigger", "purpose", "expires_at", "idempotency_key"}
+    return _execute(lambda: _subscription_service().create_subscription(_body(allowed), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/pause")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def pause_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().pause_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/activate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def activate_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().activate_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/resume")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def resume_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().resume_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/<subscription_uid>/terminate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def terminate_trusted_delivery_subscription(subscription_uid):
+    return _execute(lambda: _subscription_service().terminate_subscription(subscription_uid, actor_uid=g.current_user["id"]))
+
+
+@bp.post("/trusted-delivery/subscriptions/deliveries/<delivery_uid>/compensate")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def compensate_trusted_delivery_subscription_delivery(delivery_uid):
+    return _execute(lambda: _subscription_service().compensate_dead_letter(
+        delivery_uid, **_body({"reason_code", "receipt_code"}), actor_uid=g.current_user["id"]
+    ))
+
+
+@bp.post("/trusted-delivery/subscriptions/anomalies")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def report_trusted_delivery_subscription_anomaly():
+    allowed = {"kind", "asset_uid", "subscription_uid", "incident_uid", "summary", "correlation_id"}
+    return _execute(lambda: _subscription_service().report_anomaly(_body(allowed), actor_uid=g.current_user["id"]), created=True)

+ 99 - 0
deployment/app/api/system/trusted_delivery_controls.py

@@ -0,0 +1,99 @@
+"""No-store HTTP boundary for trusted-delivery control and release gate summaries."""
+
+from flask import g, jsonify, request
+from sqlalchemy.exc import DBAPIError, IntegrityError
+
+from app import db
+from app.api.system import bp
+from app.core.system.permissions import (
+    SECURITY_GOVERNANCE_MANAGE,
+    SECURITY_GOVERNANCE_OPERATE,
+    SECURITY_GOVERNANCE_READ,
+    require_permissions,
+)
+from app.core.system.trusted_delivery_controls import TrustedDeliveryControlError
+from app.core.system.trusted_delivery_controls_repository import (
+    SqlAlchemyTrustedDeliveryControlsRepository,
+)
+from app.core.system.trusted_delivery_controls_service import (
+    TrustedDeliveryControlsService,
+)
+from app.models.result import failed, success
+
+MAX_TRUSTED_DELIVERY_CONTROL_REQUEST_BYTES = 16 * 1024
+
+
+def _service():
+    return TrustedDeliveryControlsService(SqlAlchemyTrustedDeliveryControlsRepository(db.session))
+
+
+def _body(allowed):
+    if request.content_length is not None and request.content_length > MAX_TRUSTED_DELIVERY_CONTROL_REQUEST_BYTES:
+        raise TrustedDeliveryControlError("trusted delivery control request is too large")
+    if len(request.get_data(cache=True)) > MAX_TRUSTED_DELIVERY_CONTROL_REQUEST_BYTES:
+        raise TrustedDeliveryControlError("trusted delivery control request is too large")
+    body = request.get_json(silent=True)
+    if not isinstance(body, dict) or set(body) - allowed:
+        raise TrustedDeliveryControlError("closed request schema")
+    return body
+
+
+def _execute(operation, *, created=False):
+    try:
+        value = operation()
+        # Do not acknowledge a durable control mutation before its commit has
+        # succeeded.  Failure takes the common rollback/redacted-error path.
+        db.session.commit()
+        response = jsonify(success(value, code=201 if created else 200))
+        response.headers["Cache-Control"] = "no-store"
+        return (response, 201) if created else response
+    except PermissionError:
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery control request denied", code=403))
+    except (LookupError, RuntimeError, TrustedDeliveryControlError, ValueError, TypeError, IntegrityError, DBAPIError):
+        db.session.rollback()
+        response = jsonify(failed("trusted delivery control request rejected", code=400))
+    response.headers["Cache-Control"] = "no-store"
+    return response, response.get_json()["code"]
+
+
+@bp.get("/trusted-delivery/controls/profiles/<profile_id>/active")
+@require_permissions(SECURITY_GOVERNANCE_READ)
+def trusted_delivery_active_control_profile(profile_id):
+    return _execute(lambda: _service().active_profile_summary(profile_id))
+
+
+@bp.post("/trusted-delivery/controls/release-gates/evaluate")
+@require_permissions(SECURITY_GOVERNANCE_OPERATE)
+def trusted_delivery_release_gate():
+    return _execute(lambda: _service().evaluate_release_gate(_body({"artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "scan_decision", "evidence_expires_at", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/controls/profiles/activate")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_activate_control_profile():
+    return _execute(lambda: _service().activate_profile(_body({"profile_id", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.post("/trusted-delivery/controls/profiles/rollback")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_rollback_control_profile():
+    return _execute(lambda: _service().activate_profile(_body({"profile_id", "version", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"], operation="rollback"))
+
+
+@bp.post("/trusted-delivery/controls/capability-approvals")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_capability_approval():
+    return _execute(lambda: _service().approve_capability(_body({"provider", "capability", "version", "config_digest", "approval_ref", "approval_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)
+
+
+@bp.get("/trusted-delivery/controls/evidence")
+@require_permissions(SECURITY_GOVERNANCE_READ)
+def trusted_delivery_control_evidence():
+    return _execute(lambda: _service().evidence_summary())
+
+
+@bp.post("/trusted-delivery/controls/destruction-approvals")
+@require_permissions(SECURITY_GOVERNANCE_MANAGE)
+def trusted_delivery_destruction_approval():
+    return _execute(lambda: _service().approve_destruction(_body({"asset_uid", "approval_refs", "evidence_digest", "idempotency_key"}), actor_uid=g.current_user["id"]), created=True)

+ 16 - 3
deployment/app/config/config.py

@@ -214,6 +214,7 @@ PRODUCTION_SERVICE_DEFAULTS = {
 
 _PRODUCTION_REQUIRED_SERVICE_ENV = (
     "DATABASE_URL",
+    "BI_AI_CATALOG_CONTROL_DATABASE_URL",
     "NEO4J_URI",
     "NEO4J_HTTP_URI",
     "NEO4J_USER",
@@ -228,9 +229,12 @@ _PRODUCTION_REQUIRED_SERVICE_ENV = (
 def _validate_production_service_env() -> None:
     """Reject missing, template, or malformed production service settings."""
     values = {name: _clean_env(name) for name in _PRODUCTION_REQUIRED_SERVICE_ENV}
-    validate_postgresql_url(values["DATABASE_URL"], "DATABASE_URL")
+    runtime = validate_postgresql_url(values["DATABASE_URL"], "DATABASE_URL")
+    control = validate_postgresql_url(values["BI_AI_CATALOG_CONTROL_DATABASE_URL"], "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+    if control.username != "dataops_bi_ai_catalog_control" or control.username == runtime.username:
+        raise RuntimeError("production BI_AI_CATALOG_CONTROL_DATABASE_URL must use the dedicated control identity")
     for name, value in values.items():
-        if name == "DATABASE_URL":
+        if name in {"DATABASE_URL", "BI_AI_CATALOG_CONTROL_DATABASE_URL"}:
             continue
         placeholder = is_placeholder_env_value(value)
         if name in {"NEO4J_URI", "NEO4J_HTTP_URI", "MINIO_HOST"}:
@@ -377,7 +381,15 @@ def validate_production_database_identity(app, engine) -> None:
                          SELECT 1 FROM pg_roles evidence_owner
                          WHERE evidence_owner.rolname='dataops_edge_evidence_owner'
                            AND pg_has_role(current_user,evidence_owner.oid,'MEMBER')
-                       ) AS evidence_owner_member
+                       ) AS evidence_owner_member,
+                       EXISTS (
+                         SELECT 1 FROM pg_roles trusted_owner
+                         WHERE trusted_owner.rolname IN (
+                           'dataops_trusted_delivery_owner',
+                           'dataops_trusted_delivery_writer'
+                         )
+                           AND pg_has_role(current_user,trusted_owner.oid,'MEMBER')
+                       ) AS trusted_delivery_owner_member
                   FROM pg_roles role WHERE role.rolname=current_user
             """)).mappings().one()
     except Exception as exc:
@@ -386,6 +398,7 @@ def validate_production_database_identity(app, engine) -> None:
         identity["rolsuper"] or identity["rolcreaterole"] or identity["rolcreatedb"]
         or identity["rolreplication"] or identity["rolbypassrls"]
         or identity["owns_application_objects"] or identity["evidence_owner_member"]
+        or identity["trusted_delivery_owner_member"]
     )
     if forbidden:
         raise RuntimeError(

+ 318 - 4
deployment/app/core/edge_gateway/runtime_roles.py

@@ -8,7 +8,10 @@ import re
 from sqlalchemy import create_engine, text
 from sqlalchemy.pool import NullPool
 
-from app.config.database_urls import validate_database_environment
+from app.config.database_urls import (
+    validate_database_environment,
+    validate_postgresql_url,
+)
 
 _ROLE_NAME = re.compile(r"^[A-Za-z_][A-Za-z0-9_]{0,62}$")
 
@@ -20,6 +23,9 @@ def provision_runtime_login() -> None:
     runtime_user = os.environ.get("DATAOPS_RUNTIME_USER", "")
     runtime_password = os.environ.get("DATAOPS_RUNTIME_PASSWORD", "")
     migrator_user = os.environ.get("DATAOPS_MIGRATOR_USER", "")
+    control_url = os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", "")
+    control_user = os.environ.get("DATAOPS_BI_AI_CATALOG_CONTROL_USER", "")
+    control_password = os.environ.get("DATAOPS_BI_AI_CATALOG_CONTROL_PASSWORD", "")
     if (
         not _ROLE_NAME.fullmatch(runtime_user)
         or not _ROLE_NAME.fullmatch(migrator_user)
@@ -31,6 +37,9 @@ def provision_runtime_login() -> None:
         "DATABASE_URL": runtime_url,
         "DATAOPS_RUNTIME_PASSWORD": runtime_password,
     })
+    control_parts = validate_postgresql_url(control_url, "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+    if not _ROLE_NAME.fullmatch(control_user) or control_parts.username != control_user or not control_password or control_parts.password != control_password:
+        raise RuntimeError("BI/AI catalog control identity provisioning is not configured")
     engine = create_engine(role_init_url, poolclass=NullPool)
     quoted_user = engine.dialect.identifier_preparer.quote(runtime_user)
     quoted_migrator = engine.dialect.identifier_preparer.quote(migrator_user)
@@ -50,9 +59,49 @@ def provision_runtime_login() -> None:
                   IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_edge_evidence_owner') THEN
                     CREATE ROLE dataops_edge_evidence_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
                   END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_trusted_delivery_owner') THEN
+                    CREATE ROLE dataops_trusted_delivery_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_trusted_delivery_writer') THEN
+                    CREATE ROLE dataops_trusted_delivery_writer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_agent_runtime_owner') THEN
+                    CREATE ROLE dataops_agent_runtime_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_agent_runtime') THEN
+                    CREATE ROLE dataops_agent_runtime NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_tenant_foundation_owner') THEN
+                    CREATE ROLE dataops_tenant_foundation_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_tenant_control') THEN
+                    CREATE ROLE dataops_tenant_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_tenant_approver') THEN
+                    CREATE ROLE dataops_tenant_approver NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_bi_ai_catalog_issuer') THEN
+                    CREATE ROLE dataops_bi_ai_catalog_issuer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_plugin_platform_owner') THEN
+                    CREATE ROLE dataops_plugin_platform_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                  END IF;
+                  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dataops_plugin_platform_control') THEN
+                    CREATE ROLE dataops_plugin_platform_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
+                  END IF;
                 END $$;
                 ALTER ROLE dataops_app_runtime NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
                 ALTER ROLE dataops_edge_evidence_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_trusted_delivery_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_trusted_delivery_writer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_agent_runtime_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_agent_runtime NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_tenant_foundation_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_tenant_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_tenant_approver NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_bi_ai_catalog_issuer NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
+                ALTER ROLE dataops_plugin_platform_owner NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;
+                ALTER ROLE dataops_plugin_platform_control NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOINHERIT;
             """))
             migrator_exists = connection.execute(
                 text("SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname=:role)"),
@@ -70,20 +119,285 @@ def provision_runtime_login() -> None:
                 "NOCREATEROLE NOREPLICATION PASSWORD :password"
             ), {"password": runtime_password})
             connection.execute(text(f"GRANT dataops_app_runtime TO {quoted_user}"))
+            quoted_control = engine.dialect.identifier_preparer.quote(control_user)
+            control_exists = connection.execute(text("SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname=:role)"), {"role": control_user}).scalar_one()
+            control_action = "ALTER" if control_exists else "CREATE"
+            connection.execute(text(f"{control_action} ROLE {quoted_control} LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION INHERIT PASSWORD :password"), {"password": control_password})
+            connection.execute(text(f"GRANT dataops_bi_ai_catalog_issuer TO {quoted_control}"))
+            connection.execute(text(f"GRANT dataops_plugin_platform_control TO {quoted_control}"))
+            # Role-init also runs before a fresh database has reached WP11.
+            # The restricted migration grants the function after creating it;
+            # a later idempotent role-init grants the dedicated login directly.
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.bi_ai_catalog_issue_request_claim(text,text,jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.bi_ai_catalog_issue_request_claim(text,text,jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.plugin_platform_control_v2(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_control_v2(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_issue_claim(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_issue_claim(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_control_v3(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_control_v3(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_control_v4(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'REVOKE ALL ON FUNCTION public.plugin_platform_control_v4(jsonb) FROM "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_control_v5(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.plugin_platform_control_v5(jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_issue_claim_v3(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.plugin_platform_issue_claim_v3(jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; "
+                "IF to_regprocedure('public.plugin_platform_issue_recovery_claim(jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.plugin_platform_issue_recovery_claim(jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            # WP12 reuses the separate, configured control login for claims.
+            # It remains distinct from the long-running runtime login, and a
+            # role-init replay grants only this execute capability.
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.metering_showback_issue_claim(text,text,jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.metering_showback_issue_claim(text,text,jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regprocedure('public.metering_showback_control_write(text,text,jsonb)') IS NOT NULL THEN "
+                "EXECUTE 'GRANT EXECUTE ON FUNCTION public.metering_showback_control_write(text,text,jsonb) TO "
+                + quoted_control
+                + "'; "
+                "END IF; END $$"
+            ))
+            connection.execute(text(f"REVOKE dataops_bi_ai_catalog_issuer FROM {quoted_user}"))
+            # A role-init replay must never restore legacy direct table access
+            # after the WP11 live-head ACL compensation has run.
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'bi_ai_catalog_sources','bi_ai_catalog_assets',"
+                "'bi_ai_catalog_asset_versions','bi_ai_catalog_dependencies',"
+                "'bi_ai_catalog_sync_errors','bi_ai_catalog_audit_events',"
+                "'bi_ai_catalog_scope_grants','bi_ai_catalog_scan_observations',"
+                "'bi_ai_catalog_scan_sessions','bi_ai_catalog_scan_page_acks',"
+                "'bi_ai_catalog_page_acknowledgements','bi_ai_catalog_request_claims',"
+                "'bi_ai_catalog_empty_snapshot_approvals'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            # The compatibility matrix above is intentionally broad for
+            # legacy tables. Reapply WP12's facts-only gateway boundary after
+            # every role-init replay, including the concrete app login.
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'metering_scope_grants','metering_showback_configuration',"
+                "'metering_runtime_leases','metering_runtime_claims','metering_events',"
+                "'metering_allocation_rules','metering_allocations','metering_budgets',"
+                "'metering_alert_outbox','metering_reconciliation_reports','metering_audit_events'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY['plugin_registry_versions','plugin_approvals','plugin_runtime_leases','plugin_runs','plugin_dead_letters','plugin_audit_outbox','plugin_request_claims','plugin_runtime_breakers','plugin_recovery_claims'] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
             connection.execute(text(
                 f"GRANT dataops_edge_evidence_owner TO {quoted_migrator}"
             ))
+            connection.execute(text(
+                f"GRANT dataops_trusted_delivery_owner TO {quoted_migrator}"
+            ))
+            connection.execute(text(
+                f"GRANT dataops_trusted_delivery_writer TO {quoted_migrator}"
+            ))
+            connection.execute(text(
+                f"GRANT dataops_agent_runtime_owner TO {quoted_migrator}"
+            ))
+            connection.execute(text(
+                f"GRANT dataops_tenant_foundation_owner TO {quoted_migrator}"
+            ))
+            # Tenant-control is a separate capability: only the explicitly
+            # configured control login (or the migration identity used to
+            # create its schema) may inherit it.  The shared app login never
+            # receives this membership.
+            connection.execute(text(
+                f"GRANT dataops_tenant_control TO {quoted_migrator}"
+            ))
+            connection.execute(text(f"GRANT dataops_plugin_platform_owner TO {quoted_migrator}"))
+            connection.execute(text(f"GRANT dataops_agent_runtime TO {quoted_user}"))
             connection.execute(text(
                 "GRANT USAGE,CREATE ON SCHEMA public TO dataops_edge_evidence_owner"
             ))
-            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_app_runtime"))
             connection.execute(text(
-                "GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public "
-                "TO dataops_app_runtime"
+                "GRANT USAGE,CREATE ON SCHEMA public TO dataops_trusted_delivery_owner"
+            ))
+            connection.execute(text(
+                "GRANT USAGE,CREATE ON SCHEMA public TO dataops_trusted_delivery_writer"
+            ))
+            connection.execute(text("GRANT USAGE,CREATE ON SCHEMA public TO dataops_agent_runtime_owner"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_agent_runtime"))
+            connection.execute(text("GRANT USAGE,CREATE ON SCHEMA public TO dataops_tenant_foundation_owner"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_tenant_control"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_tenant_approver"))
+            connection.execute(text("GRANT USAGE,CREATE ON SCHEMA public TO dataops_plugin_platform_owner"))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_plugin_platform_control"))
+            # The definer gateway validates actor references against the
+            # canonical identity table but never receives identity DML.
+            connection.execute(text(
+                "DO $$ BEGIN IF to_regclass('public.users') IS NOT NULL THEN "
+                "GRANT SELECT ON TABLE public.users TO dataops_trusted_delivery_writer; END IF; END $$"
+            ))
+            # A non-privileged migrator still needs REFERENCES to create the
+            # versioned WP06 tables that bind their actor to the canonical
+            # identity record.  It does not receive users DML.
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regclass('public.users') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.users TO " + quoted_migrator + "'; END IF; "
+                "IF to_regclass('public.governed_agents') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.governed_agents TO " + quoted_migrator + "'; END IF; "
+                "END $$"
+            ))
+            connection.execute(text(
+                "DO $$ BEGIN "
+                "IF to_regclass('public.data_incidents') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.data_incidents TO " + quoted_migrator + "'; END IF; "
+                "IF to_regclass('public.governance_tasks') IS NOT NULL THEN EXECUTE 'GRANT REFERENCES ON TABLE public.governance_tasks TO " + quoted_migrator + "'; END IF; "
+                "END $$"
+            ))
+            # WP09's hardened definer gateway reads its approval source of
+            # truth.  The migrator can delegate only these capabilities while
+            # retaining no direct data-modification path of its own.
+            connection.execute(text(f"""
+                DO $$ BEGIN
+                  IF to_regclass('public.governance_tasks') IS NOT NULL THEN GRANT SELECT, UPDATE ON TABLE public.governance_tasks TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                  IF to_regclass('public.governance_task_reviews') IS NOT NULL THEN GRANT SELECT ON TABLE public.governance_task_reviews TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                  IF to_regclass('public.agent_tool_grants') IS NOT NULL THEN GRANT SELECT ON TABLE public.agent_tool_grants TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                  IF to_regclass('public.governed_agents') IS NOT NULL THEN GRANT SELECT ON TABLE public.governed_agents TO {quoted_migrator} WITH GRANT OPTION; END IF;
+                END $$
+            """))
+            connection.execute(text(
+                "DO $$ BEGIN IF to_regclass('public.data_incident_impacts') IS NOT NULL THEN "
+                "GRANT SELECT,INSERT ON TABLE public.data_incident_impacts TO dataops_trusted_delivery_writer; END IF; END $$"
             ))
+            connection.execute(text(
+                "DO $$ BEGIN IF to_regclass('public.data_incidents') IS NOT NULL THEN "
+                "GRANT SELECT ON TABLE public.data_incidents TO dataops_trusted_delivery_writer; END IF; END $$"
+            ))
+            connection.execute(text("GRANT USAGE ON SCHEMA public TO dataops_app_runtime"))
+            # Revoke legacy broad grants both from the shared runtime role and
+            # from the concrete login before rebuilding its explicit table
+            # matrix.  This is required when upgrading an installation that
+            # previously granted DML across the whole public schema.
+            connection.execute(text(f"""
+                DO $$ DECLARE target text;
+                BEGIN
+                  FOR target IN
+                    SELECT format('%I.%I', schemaname, tablename)
+                    FROM pg_tables
+                    WHERE schemaname='public' AND (
+                      tablename LIKE 'trusted_delivery_%' OR tablename='data_incident_impacts'
+                      OR tablename IN ('tenants','tenant_quotas','tenant_quota_reservations',
+                                       'tenant_lifecycle_events','tenant_audit_events','tenant_resource_manifests')
+                    )
+                  LOOP
+                    EXECUTE 'REVOKE INSERT, UPDATE, DELETE, TRUNCATE ON TABLE ' || target || ' FROM dataops_app_runtime';
+                    EXECUTE 'REVOKE INSERT, UPDATE, DELETE, TRUNCATE ON TABLE ' || target || ' FROM {quoted_user}';
+                  END LOOP;
+                END $$;
+            """))
+            # Runtime receives explicit table grants only.  In particular it
+            # must never inherit DML on future tables or on the WP06 trusted
+            # delivery state machine; those writes are reached only through
+            # SECURITY DEFINER procedures owned by the dedicated writer role.
+            connection.execute(text("""
+                DO $$ DECLARE target text;
+                BEGIN
+                  FOR target IN
+                    SELECT format('%I.%I', schemaname, tablename)
+                    FROM pg_tables
+                    WHERE schemaname='public' AND tablename NOT LIKE 'trusted_delivery_%'
+                      AND tablename <> 'data_incident_impacts'
+                      AND tablename NOT IN ('tenants','tenant_quotas','tenant_quota_reservations',
+                                            'tenant_lifecycle_events','tenant_audit_events','tenant_resource_manifests')
+                  LOOP
+                    EXECUTE 'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE ' || target || ' TO dataops_app_runtime';
+                  END LOOP;
+                END $$;
+            """))
             connection.execute(text(
                 "GRANT USAGE,SELECT ON ALL SEQUENCES IN SCHEMA public TO dataops_app_runtime"
             ))
+            # The legacy compatibility matrix above intentionally grants most
+            # public tables.  Reapply WP11's closed facts after it so a
+            # role-init replay cannot re-open catalog data to the runtime.
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'bi_ai_catalog_sources','bi_ai_catalog_assets',"
+                "'bi_ai_catalog_asset_versions','bi_ai_catalog_dependencies',"
+                "'bi_ai_catalog_sync_errors','bi_ai_catalog_audit_events',"
+                "'bi_ai_catalog_scope_grants','bi_ai_catalog_scan_observations',"
+                "'bi_ai_catalog_scan_sessions','bi_ai_catalog_scan_page_acks',"
+                "'bi_ai_catalog_page_acknowledgements','bi_ai_catalog_request_claims',"
+                "'bi_ai_catalog_empty_snapshot_approvals'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY["
+                "'metering_scope_grants','metering_showback_configuration',"
+                "'metering_runtime_leases','metering_runtime_claims','metering_events',"
+                "'metering_allocation_rules','metering_allocations','metering_budgets',"
+                "'metering_alert_outbox','metering_reconciliation_reports','metering_audit_events'"
+                "] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER "
+                "ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
+            connection.execute(text(
+                "DO $$ DECLARE item text; BEGIN "
+                "FOREACH item IN ARRAY ARRAY['plugin_registry_versions','plugin_approvals','plugin_runtime_leases','plugin_runs','plugin_dead_letters','plugin_audit_outbox','plugin_request_claims','plugin_runtime_breakers','plugin_recovery_claims'] LOOP "
+                "IF to_regclass('public.' || item) IS NOT NULL THEN "
+                "EXECUTE 'REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public.' || quote_ident(item) || ' FROM PUBLIC, dataops_app_runtime, dataops_app'; "
+                "END IF; END LOOP; END $$"
+            ))
             is_evidence_member = connection.execute(text("""
                 SELECT pg_has_role(:role,'dataops_edge_evidence_owner','MEMBER')
             """), {"role": runtime_user}).scalar_one()

+ 518 - 0
deployment/app/core/events/production_observability.py

@@ -0,0 +1,518 @@
+"""Closed, deterministic P3 production-observability adapter contracts.
+
+This module intentionally does not configure or contact enterprise providers.
+It makes the boundary for approved monitoring, notification, on-call, and ITSM
+adapters safe and testable while P3-WP05 enterprise inputs remain external.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import math
+import re
+import uuid
+from collections.abc import Callable
+from datetime import UTC, datetime
+from typing import Any
+
+from app.core.events.data_observability import _reject_secret_material
+
+CONTRACT_VERSION = "1.0.0"
+TELEMETRY_RESOURCE_TYPES = frozenset(
+    {"api", "task", "database", "graph", "object_storage"}
+)
+TELEMETRY_LAYERS = frozenset({"service", "task", "data", "capacity"})
+TELEMETRY_STATUSES = frozenset({"ok", "error", "degraded", "backpressure"})
+DELIVERY_CHANNELS = frozenset({"smtp", "enterprise_collaboration", "on_call"})
+MAX_DELIVERY_ATTEMPTS = 3
+DELIVERY_LEASE_SECONDS = 300
+_TRACE_ID = re.compile(r"^[0-9a-f]{32}$")
+_SPAN_ID = re.compile(r"^[0-9a-f]{16}$")
+
+
+class ProductionObservabilityContractError(ValueError):
+    """Raised before unsafe or ambiguous operations leave the local boundary."""
+
+
+_SENSITIVE_VALUE = re.compile(
+    r"(?i)(?:bearer\s+|password\s*[=:]|secret\s*[=:]|-----begin|\bselect\b.+\bfrom\b)"
+)
+
+
+def _safe_object(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ProductionObservabilityContractError(f"{label} must be an object")
+    try:
+        _reject_secret_material(value)
+    except ValueError as error:
+        raise ProductionObservabilityContractError(str(error)) from error
+    unknown = sorted(set(value) - allowed)
+    if unknown:
+        raise ProductionObservabilityContractError(
+            f"{label} contains unsupported fields: {', '.join(unknown)}"
+        )
+    return dict(value)
+
+
+def _reject_sensitive_values(value: Any, *, depth: int = 0) -> None:
+    if depth > 4:
+        raise ProductionObservabilityContractError("payload nesting exceeds 4")
+    if isinstance(value, str) and _SENSITIVE_VALUE.search(value):
+        raise ProductionObservabilityContractError("sensitive value is not allowed")
+    if isinstance(value, dict):
+        for item in value.values():
+            _reject_sensitive_values(item, depth=depth + 1)
+    elif isinstance(value, list):
+        if len(value) > 32:
+            raise ProductionObservabilityContractError("payload list exceeds 32 items")
+        for item in value:
+            _reject_sensitive_values(item, depth=depth + 1)
+
+
+def _timestamp(value: Any) -> str:
+    try:
+        parsed = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as error:
+        raise ProductionObservabilityContractError(
+            "occurred_at must be RFC3339"
+        ) from error
+    if parsed.tzinfo is None:
+        raise ProductionObservabilityContractError(
+            "occurred_at must include a timezone"
+        )
+    return parsed.astimezone(UTC).isoformat().replace("+00:00", "Z")
+
+
+def _string(value: Any, label: str, maximum: int = 200) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise ProductionObservabilityContractError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum:
+        raise ProductionObservabilityContractError(
+            f"{label} exceeds {maximum} characters"
+        )
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as error:
+        raise ProductionObservabilityContractError(f"{label} must be a UUID") from error
+
+
+def _number(value: Any, label: str) -> float:
+    if isinstance(value, bool):
+        raise ProductionObservabilityContractError(f"{label} must be numeric")
+    try:
+        result = float(value)
+    except (TypeError, ValueError) as error:
+        raise ProductionObservabilityContractError(
+            f"{label} must be numeric"
+        ) from error
+    if not math.isfinite(result):
+        raise ProductionObservabilityContractError(f"{label} must be finite")
+    return result
+
+
+def _canonical_digest(value: dict[str, Any]) -> str:
+    encoded = json.dumps(
+        value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
+    )
+    return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
+
+
+def normalize_telemetry_event(payload: Any) -> dict[str, Any]:
+    """Validate a cardinality-safe telemetry envelope before provider adaptation."""
+    body = _safe_object(
+        payload,
+        {
+            "event_id",
+            "occurred_at",
+            "layer",
+            "operation",
+            "resource_type",
+            "resource_uid",
+            "correlation_id",
+            "trace_id",
+            "span_id",
+            "status",
+            "attributes",
+        },
+        "telemetry event",
+    )
+    _reject_sensitive_values(body)
+    attributes = _safe_object(
+        body.get("attributes"),
+        {
+            "duration_ms",
+            "queue_depth",
+            "utilization_ratio",
+            "retry_count",
+            "error_code",
+        },
+        "telemetry attributes",
+    )
+    trace_id = _string(body.get("trace_id"), "trace_id", 32).lower()
+    span_id = _string(body.get("span_id"), "span_id", 16).lower()
+    if not _TRACE_ID.fullmatch(trace_id) or not _SPAN_ID.fullmatch(span_id):
+        raise ProductionObservabilityContractError("trace_id or span_id is invalid")
+    layer = _string(body.get("layer"), "layer", 20)
+    resource_type = _string(body.get("resource_type"), "resource_type", 30)
+    status = _string(body.get("status"), "status", 20)
+    if layer not in TELEMETRY_LAYERS:
+        raise ProductionObservabilityContractError("telemetry layer is invalid")
+    if resource_type not in TELEMETRY_RESOURCE_TYPES:
+        raise ProductionObservabilityContractError("telemetry resource_type is invalid")
+    if status not in TELEMETRY_STATUSES:
+        raise ProductionObservabilityContractError("telemetry status is invalid")
+    normalized_attributes: dict[str, Any] = {}
+    for key, value in attributes.items():
+        if key == "error_code":
+            normalized_attributes[key] = _string(value, "error_code", 64)
+        elif key == "retry_count":
+            numeric = _number(value, "retry_count")
+            if not numeric.is_integer():
+                raise ProductionObservabilityContractError(
+                    "retry_count must be an integer"
+                )
+            retry_count = int(numeric)
+            if retry_count < 0 or retry_count > 10:
+                raise ProductionObservabilityContractError(
+                    "retry_count must be between 0 and 10"
+                )
+            normalized_attributes[key] = retry_count
+        else:
+            number = _number(value, key)
+            if number < 0:
+                raise ProductionObservabilityContractError(
+                    f"{key} must not be negative"
+                )
+            normalized_attributes[key] = number
+    return {
+        "contract_version": CONTRACT_VERSION,
+        "event_id": _uid(body.get("event_id"), "event_id"),
+        "occurred_at": _timestamp(body.get("occurred_at")),
+        "layer": layer,
+        "operation": _string(body.get("operation"), "operation", 80),
+        "resource_type": resource_type,
+        "resource_uid": _string(body.get("resource_uid"), "resource_uid", 160),
+        "correlation_id": _uid(body.get("correlation_id"), "correlation_id"),
+        "trace_id": trace_id,
+        "span_id": span_id,
+        "status": status,
+        "attributes": normalized_attributes,
+    }
+
+
+def production_slo_catalog() -> list[dict[str, Any]]:
+    """Return the versioned production SLO catalog used by approved adapters."""
+    return [
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "service",
+            "sli": "availability_ratio",
+            "target": 0.999,
+            "error_budget_ratio": 0.001,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "task",
+            "sli": "delivery_ratio",
+            "target": 0.99,
+            "error_budget_ratio": 0.01,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "data",
+            "sli": "freshness_ratio",
+            "target": 0.99,
+            "error_budget_ratio": 0.01,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+        {
+            "catalog_version": CONTRACT_VERSION,
+            "layer": "capacity",
+            "sli": "headroom_ratio",
+            "target": 0.2,
+            "error_budget_ratio": 0.05,
+            "alert_rule_version": CONTRACT_VERSION,
+        },
+    ]
+
+
+def evaluate_capacity(payload: Any) -> dict[str, Any]:
+    """Provide a deterministic admission recommendation without dropping work."""
+    body = _safe_object(
+        payload,
+        {
+            "active_users",
+            "data_sources",
+            "utilization_ratio",
+            "queue_depth",
+            "queue_limit",
+            "ingress_per_minute",
+            "max_ingress_per_minute",
+        },
+        "capacity snapshot",
+    )
+    active_users = int(_number(body.get("active_users"), "active_users"))
+    data_sources = int(_number(body.get("data_sources"), "data_sources"))
+    utilization = _number(body.get("utilization_ratio"), "utilization_ratio")
+    queue_depth = int(_number(body.get("queue_depth"), "queue_depth"))
+    queue_limit = int(_number(body.get("queue_limit"), "queue_limit"))
+    ingress = _number(body.get("ingress_per_minute"), "ingress_per_minute")
+    max_ingress = _number(body.get("max_ingress_per_minute"), "max_ingress_per_minute")
+    if not 100 <= active_users <= 500:
+        raise ProductionObservabilityContractError(
+            "active_users must be between 100 and 500"
+        )
+    if not 50 <= data_sources <= 500:
+        raise ProductionObservabilityContractError(
+            "data_sources must be between 50 and 500"
+        )
+    if not 0 <= utilization <= 1 or queue_depth < 0 or queue_limit < 1:
+        raise ProductionObservabilityContractError("capacity snapshot is invalid")
+    if ingress < 0 or max_ingress <= 0:
+        raise ProductionObservabilityContractError("ingress capacity is invalid")
+    if queue_depth > queue_limit:
+        raise ProductionObservabilityContractError(
+            "queue exceeds hard limit; reject before data loss"
+        )
+    pressure = max(utilization, queue_depth / queue_limit, ingress / max_ingress)
+    if pressure >= 0.8:
+        admission = "backpressure"
+        throttle_ratio = 0.5
+        recommendation = (
+            "scale workers or queue capacity before accepting additional work"
+        )
+    elif pressure >= 0.7:
+        admission = "throttle"
+        throttle_ratio = 0.75
+        recommendation = "throttle non-critical work and review capacity headroom"
+    else:
+        admission = "allow"
+        throttle_ratio = 1.0
+        recommendation = "capacity within approved local baseline"
+    return {
+        "baseline": {"active_users": [100, 500], "data_sources": [50, 500]},
+        "admission": admission,
+        "throttle_ratio": throttle_ratio,
+        "recommendation": recommendation,
+        "pressure_ratio": round(pressure, 4),
+    }
+
+
+class DeliveryCoordinator:
+    """Deterministic local state machine for adapter contract verification only."""
+
+    def __init__(self, *, now: Callable[[], float]):
+        self.now = now
+        self.deliveries: dict[str, dict[str, Any]] = {}
+        self._delivery_digests: dict[str, str] = {}
+        self._itsm_by_key: dict[str, dict[str, str]] = {}
+        self._itsm_by_external_ref: dict[str, str] = {}
+        self.audit: list[dict[str, Any]] = []
+
+    def _audit(self, action: str, delivery_id: str, **safe_detail: Any) -> None:
+        self.audit.append(
+            {
+                "action": action,
+                "delivery_id": delivery_id,
+                "at": self.now(),
+                "safe_detail": safe_detail,
+            }
+        )
+
+    def enqueue_delivery(self, payload: Any) -> dict[str, Any]:
+        body = _safe_object(
+            payload,
+            {
+                "delivery_id",
+                "incident_uid",
+                "alert_uid",
+                "channel",
+                "idempotency_key",
+                "summary",
+            },
+            "delivery request",
+        )
+        normalized = {
+            "delivery_id": _uid(body.get("delivery_id"), "delivery_id"),
+            "incident_uid": _uid(body.get("incident_uid"), "incident_uid"),
+            "alert_uid": _uid(body.get("alert_uid"), "alert_uid"),
+            "channel": _string(body.get("channel"), "channel", 40),
+            "idempotency_key": _string(
+                body.get("idempotency_key"), "idempotency_key", 120
+            ),
+            "summary": _string(body.get("summary"), "summary", 160),
+        }
+        if normalized["channel"] not in DELIVERY_CHANNELS:
+            raise ProductionObservabilityContractError("delivery channel is invalid")
+        digest = _canonical_digest(normalized)
+        existing_digest = self._delivery_digests.get(normalized["idempotency_key"])
+        if existing_digest is not None:
+            if existing_digest != digest:
+                raise ProductionObservabilityContractError("delivery replay conflicts")
+            return dict(self.deliveries[normalized["delivery_id"]])
+        record = {
+            **normalized,
+            "status": "pending",
+            "attempt_count": 0,
+            "lease_owner": None,
+            "lease_expires_at": None,
+            "fencing_token": 0,
+        }
+        self.deliveries[record["delivery_id"]] = record
+        self._delivery_digests[record["idempotency_key"]] = digest
+        self._audit(
+            "delivery_enqueued", record["delivery_id"], channel=record["channel"]
+        )
+        return dict(record)
+
+    def claim_delivery(
+        self,
+        delivery_id: str,
+        *,
+        worker_id: str,
+        now: float | None = None,
+    ) -> dict[str, Any]:
+        record = self._delivery(delivery_id)
+        current = self.now() if now is None else now
+        if record["status"] == "processing" and current < record["lease_expires_at"]:
+            raise ProductionObservabilityContractError("delivery is leased")
+        if record["status"] not in {"pending", "processing"}:
+            raise ProductionObservabilityContractError("delivery is not claimable")
+        record["status"] = "processing"
+        record["lease_owner"] = _string(worker_id, "worker_id", 80)
+        record["lease_expires_at"] = current + DELIVERY_LEASE_SECONDS
+        record["fencing_token"] += 1
+        return dict(record)
+
+    def record_attempt(
+        self,
+        delivery_id: str,
+        *,
+        worker_id: str,
+        fencing_token: int,
+        outcome: str,
+        reason_code: str | None = None,
+    ) -> dict[str, Any]:
+        record = self._delivery(delivery_id)
+        if (
+            record["status"] != "processing"
+            or record["lease_owner"] != _string(worker_id, "worker_id", 80)
+            or record["fencing_token"] != fencing_token
+        ):
+            raise ProductionObservabilityContractError(
+                "delivery fencing token is invalid"
+            )
+        if outcome == "delivered":
+            record["status"] = "delivered"
+            self._audit("delivery_delivered", record["delivery_id"])
+            return dict(record)
+        if outcome != "failed":
+            raise ProductionObservabilityContractError("delivery outcome is invalid")
+        reason = _string(reason_code, "reason_code", 64)
+        if not re.fullmatch(r"[a-z][a-z0-9_]{0,63}", reason):
+            raise ProductionObservabilityContractError("reason_code is invalid")
+        record["attempt_count"] += 1
+        record["lease_owner"] = None
+        record["lease_expires_at"] = None
+        if record["attempt_count"] >= MAX_DELIVERY_ATTEMPTS:
+            record["status"] = "dead_letter"
+            self._audit(
+                "delivery_dead_lettered", record["delivery_id"], reason_code=reason
+            )
+        else:
+            record["status"] = "pending"
+            self._audit(
+                "delivery_attempt_failed", record["delivery_id"], reason_code=reason
+            )
+        return dict(record)
+
+    def compensate_dead_letter(
+        self, delivery_id: str, *, actor_uid: str, note: str
+    ) -> dict[str, Any]:
+        record = self._delivery(delivery_id)
+        if record["status"] != "dead_letter":
+            raise ProductionObservabilityContractError("delivery is not a dead letter")
+        record["status"] = "compensated"
+        self._audit(
+            "delivery_compensated",
+            record["delivery_id"],
+            actor_uid=_uid(actor_uid, "actor_uid"),
+            note=_string(note, "compensation note", 160),
+        )
+        return dict(record)
+
+    def select_on_call_route(
+        self, payload: Any, *, elapsed_seconds: int
+    ) -> dict[str, Any]:
+        body = _safe_object(
+            payload,
+            {
+                "rotation_version",
+                "severity",
+                "primary",
+                "secondary",
+                "escalate_after_seconds",
+            },
+            "on-call route",
+        )
+        severity = _string(body.get("severity"), "severity", 20)
+        if severity not in {"warning", "error", "critical"}:
+            raise ProductionObservabilityContractError("on-call severity is invalid")
+        escalate_after = int(
+            _number(body.get("escalate_after_seconds"), "escalate_after_seconds")
+        )
+        if escalate_after < 60 or elapsed_seconds < 0:
+            raise ProductionObservabilityContractError("on-call escalation is invalid")
+        escalated = elapsed_seconds >= escalate_after
+        return {
+            "target": _string(
+                body.get("secondary") if escalated else body.get("primary"),
+                "on-call target",
+                120,
+            ),
+            "level": 2 if escalated else 1,
+            "rotation_version": _string(
+                body.get("rotation_version"), "rotation_version", 20
+            ),
+        }
+
+    def bind_itsm_reference(
+        self, *, incident_uid: str, external_ref: str, idempotency_key: str
+    ) -> dict[str, str]:
+        record = {
+            "incident_uid": _uid(incident_uid, "incident_uid"),
+            "external_ref": _string(external_ref, "external_ref", 120),
+            "idempotency_key": _string(idempotency_key, "idempotency_key", 120),
+        }
+        existing = self._itsm_by_key.get(record["idempotency_key"])
+        if existing is not None:
+            if existing != record:
+                raise ProductionObservabilityContractError("ITSM replay conflicts")
+            return dict(existing)
+        linked_incident = self._itsm_by_external_ref.get(record["external_ref"])
+        if linked_incident is not None and linked_incident != record["incident_uid"]:
+            raise ProductionObservabilityContractError(
+                "ITSM external reference conflicts"
+            )
+        self._itsm_by_key[record["idempotency_key"]] = record
+        self._itsm_by_external_ref[record["external_ref"]] = record["incident_uid"]
+        return dict(record)
+
+    def platform_incident_for_itsm(self, external_ref: str) -> str | None:
+        return self._itsm_by_external_ref.get(
+            _string(external_ref, "external_ref", 120)
+        )
+
+    def _delivery(self, delivery_id: str) -> dict[str, Any]:
+        record = self.deliveries.get(_uid(delivery_id, "delivery_id"))
+        if record is None:
+            raise LookupError("delivery was not found")
+        return record

+ 431 - 0
deployment/app/core/events/production_operations.py

@@ -0,0 +1,431 @@
+"""Persistent-provider-ready orchestration for P2 incident delivery.
+
+External providers are disabled by default.  The service only stores safe
+references, hashes, codes, and bounded summaries; adapters receive no URL or
+credential from this boundary.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import re
+import uuid
+from collections.abc import Callable
+from typing import Any
+
+from app.core.events.data_observability import _reject_secret_material
+
+
+class ProductionOperationsError(ValueError):
+    pass
+
+
+def _safe_string(value: Any, label: str, maximum: int = 160) -> str:
+    if not isinstance(value, str) or not value.strip() or len(value.strip()) > maximum:
+        raise ProductionOperationsError(f"{label} is invalid")
+    result = value.strip()
+    try:
+        _reject_secret_material({"value": result})
+    except ValueError as error:
+        raise ProductionOperationsError("sensitive material is not allowed") from error
+    if re.search(
+        r"(?i)(bearer\s+|password\s*[=:]|-----begin|\bselect\b.+\bfrom\b)", result
+    ):
+        raise ProductionOperationsError("sensitive material is not allowed")
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as error:
+        raise ProductionOperationsError(f"{label} must be a UUID") from error
+
+
+def _digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(value, sort_keys=True, separators=(",", ":")).encode()
+    ).hexdigest()
+
+
+class ProviderRegistry:
+    """Closed capability registry; real adapter registration is enterprise UAT."""
+
+    allowed = frozenset(
+        {"monitoring", "smtp", "enterprise_collaboration", "on_call", "itsm"}
+    )
+
+    def __init__(
+        self,
+        adapters: dict[str, Callable[[dict[str, str]], dict[str, str]]] | None = None,
+    ):
+        self.adapters = adapters or {}
+
+    def dispatch(self, capability: str, envelope: dict[str, str]) -> dict[str, str]:
+        capability = _safe_string(capability, "provider capability", 40)
+        if capability not in self.allowed or capability not in self.adapters:
+            raise ProductionOperationsError("provider capability is disabled")
+        response = self.adapters[capability](dict(envelope))
+        if not isinstance(response, dict) or set(response) != {
+            "status",
+            "receipt_code",
+        }:
+            raise ProductionOperationsError("provider response is invalid")
+        try:
+            _reject_secret_material(response)
+            status = _safe_string(response["status"], "provider response status", 20)
+            receipt_code = _safe_string(
+                response["receipt_code"], "provider receipt code", 160
+            )
+        except (KeyError, ValueError, ProductionOperationsError) as error:
+            raise ProductionOperationsError("provider response is invalid") from error
+        if status not in {"accepted", "queued", "rejected"}:
+            raise ProductionOperationsError("provider response is invalid")
+        return {"status": status, "receipt_code": receipt_code}
+
+
+class ProductionOperationsService:
+    def __init__(
+        self,
+        repository,
+        *,
+        now: Callable[[], float],
+        providers: ProviderRegistry | None = None,
+        queue_hard_limit: int = 500,
+    ):
+        if (
+            isinstance(queue_hard_limit, bool)
+            or not isinstance(queue_hard_limit, int)
+            or not 1 <= queue_hard_limit <= 500
+        ):
+            raise ProductionOperationsError("queue hard limit must be between 1 and 500")
+        self.repository = repository
+        self.now = now
+        self.providers = providers or ProviderRegistry()
+        self.queue_hard_limit = queue_hard_limit
+
+    def _audit(
+        self,
+        action: str,
+        *,
+        delivery_uid: str | None,
+        actor_uid: str,
+        detail: dict[str, str] | None = None,
+    ) -> None:
+        self.repository.append_audit(
+            {
+                "uid": str(uuid.uuid4()),
+                "delivery_uid": delivery_uid,
+                "action": action,
+                "actor_uid": _uid(actor_uid, "actor_uid"),
+                "safe_detail": detail or {},
+                "created_at": self.now(),
+            }
+        )
+
+    def enqueue_incident_delivery(
+        self, payload: Any, *, actor_uid: str
+    ) -> dict[str, Any]:
+        if not isinstance(payload, dict) or set(payload) != {
+            "incident_uid",
+            "alert_uid",
+            "channel",
+            "summary",
+        }:
+            raise ProductionOperationsError("delivery request has unsupported fields")
+        _reject_secret_material(payload)
+        record = {
+            "uid": str(uuid.uuid4()),
+            "incident_uid": _uid(payload["incident_uid"], "incident_uid"),
+            "alert_uid": _uid(payload["alert_uid"], "alert_uid"),
+            "channel": _safe_string(payload["channel"], "channel", 40),
+            "summary": _safe_string(payload["summary"], "summary"),
+            "status": "pending",
+            "attempt_count": 0,
+            "next_attempt_at": self.now(),
+            "lease_owner": None,
+            "lease_fence": 0,
+            "lease_expires_at": None,
+        }
+        if record["channel"] not in {
+            "smtp",
+            "enterprise_collaboration",
+            "on_call",
+            "itsm",
+            "monitoring",
+        }:
+            raise ProductionOperationsError("delivery channel is invalid")
+        record["idempotency_key"] = (
+            f"{record['incident_uid']}:{record['alert_uid']}:{record['channel']}"
+        )
+        record["payload_digest"] = _digest(
+            {
+                key: record[key]
+                for key in ("incident_uid", "alert_uid", "channel", "summary")
+            }
+        )
+        try:
+            stored = self.repository.enqueue_delivery(
+                record, queue_hard_limit=self.queue_hard_limit
+            )
+        except RuntimeError as error:
+            if str(error) in {"idempotency conflict", "delivery queue hard limit reached"}:
+                raise ProductionOperationsError(str(error)) from error
+            raise
+        if stored["uid"] == record["uid"]:
+            self._audit(
+                "delivery_enqueued",
+                delivery_uid=stored["uid"],
+                actor_uid=actor_uid,
+                detail={"channel": stored["channel"]},
+            )
+        return stored
+
+    def claim_delivery(
+        self, delivery_uid: str, *, worker_id: str, now: float | None = None
+    ) -> dict[str, Any]:
+        result = self.repository.claim_delivery(
+            _uid(delivery_uid, "delivery_uid"),
+            _safe_string(worker_id, "worker_id", 80),
+            self.now() if now is None else now,
+        )
+        if result is None:
+            raise ProductionOperationsError("delivery is not claimable")
+        return result
+
+    def record_delivery_attempt(
+        self,
+        delivery_uid: str,
+        *,
+        worker_id: str,
+        lease_fence: int,
+        delivered: bool,
+        actor_uid: str,
+        now: float | None = None,
+    ) -> dict[str, Any]:
+        if not isinstance(lease_fence, int) or lease_fence < 1:
+            raise ProductionOperationsError("lease fence is invalid")
+        current = self.now() if now is None else now
+        result = self.repository.record_attempt(
+            _uid(delivery_uid, "delivery_uid"),
+            _safe_string(worker_id, "worker_id", 80),
+            lease_fence,
+            current,
+            delivered,
+            "provider_unavailable" if not delivered else None,
+        )
+        if result is None:
+            raise ProductionOperationsError("delivery lease is expired or fenced")
+        action = (
+            "delivery_delivered"
+            if delivered
+            else (
+                "delivery_dead_lettered"
+                if result["status"] == "dead_letter"
+                else "delivery_attempt_failed"
+            )
+        )
+        self._audit(
+            action,
+            delivery_uid=result["uid"],
+            actor_uid=actor_uid,
+            detail={"status": result["status"]},
+        )
+        return result
+
+    def compensate_dead_letter(
+        self,
+        delivery_uid: str,
+        *,
+        reason_code: str,
+        receipt_code: str,
+        actor_uid: str,
+    ) -> dict[str, Any]:
+        reason_code = _safe_string(reason_code, "compensation reason code", 64)
+        receipt_code = _safe_string(receipt_code, "compensation receipt code", 64)
+        if reason_code not in {
+            "operator_review",
+            "provider_recovered",
+            "duplicate_suppressed",
+        } or not re.fullmatch(r"[A-Z][A-Z0-9_]{0,63}", receipt_code):
+            raise ProductionOperationsError("compensation receipt is invalid")
+        try:
+            result = self.repository.compensate_dead_letter(
+                _uid(delivery_uid, "delivery_uid"), reason_code, receipt_code
+            )
+        except RuntimeError as error:
+            raise ProductionOperationsError(str(error)) from error
+        self._audit(
+            "delivery_dead_letter_compensated",
+            delivery_uid=result["uid"],
+            actor_uid=actor_uid,
+            detail={"reason_code": reason_code, "receipt_code": receipt_code},
+        )
+        return result
+
+    def audit_rejection_independently(
+        self, *, actor_uid: str, reason_code: str, correlation_id: str
+    ) -> None:
+        reason_code = _safe_string(reason_code, "reason code", 64)
+        if reason_code not in {"invalid_request", "conflict", "internal_error"}:
+            raise ProductionOperationsError("reason code is invalid")
+        self.repository.append_rejection_audit_independently(
+            {
+                "uid": str(uuid.uuid4()),
+                "action": f"delivery_{reason_code}",
+                "actor_uid": _uid(actor_uid, "actor_uid"),
+                "safe_detail": {
+                    "reason_code": reason_code,
+                    "correlation_id": _uid(correlation_id, "correlation_id"),
+                },
+            }
+        )
+
+    def dispatch_provider(
+        self, capability: str, payload: dict[str, Any]
+    ) -> dict[str, str]:
+        incident_uid = _uid(payload.get("incident_uid"), "incident_uid")
+        return self.providers.dispatch(
+            capability,
+            {
+                "incident_uid": incident_uid,
+                "summary": _safe_string(payload.get("summary"), "summary"),
+            },
+        )
+
+    def create_policy(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        if not isinstance(payload, dict) or set(payload) != {
+            "code",
+            "version",
+            "layer",
+            "error_budget_ratio",
+        }:
+            raise ProductionOperationsError("policy has unsupported fields")
+        budget = payload["error_budget_ratio"]
+        if (
+            isinstance(budget, bool)
+            or not isinstance(budget, (int, float))
+            or not 0 < budget < 1
+        ):
+            raise ProductionOperationsError("error budget is invalid")
+        record = {
+            "uid": str(uuid.uuid4()),
+            "code": _safe_string(payload["code"], "policy code", 80),
+            "version": _safe_string(payload["version"], "policy version", 20),
+            "layer": _safe_string(payload["layer"], "policy layer", 20),
+            "error_budget_ratio": float(budget),
+            "status": "draft",
+            "created_by": _uid(actor_uid, "actor_uid"),
+            "created_at": self.now(),
+        }
+        if record["layer"] not in {"service", "task", "data", "capacity"}:
+            raise ProductionOperationsError("policy layer is invalid")
+        return dict(self.repository.save_policy(record))
+
+    def activate_policy(
+        self, code: str, version: str, *, actor_uid: str
+    ) -> dict[str, Any]:
+        result = self.repository.activate_policy(
+            _safe_string(code, "policy code", 80),
+            _safe_string(version, "policy version", 20),
+        )
+        self._audit(
+            "policy_activated",
+            delivery_uid=None,
+            actor_uid=actor_uid,
+            detail={"code": result["code"], "version": result["version"]},
+        )
+        return dict(result)
+
+    def active_policy(self, code: str) -> dict[str, Any]:
+        result = self.repository.active_policy(_safe_string(code, "policy code", 80))
+        if result is None:
+            raise ProductionOperationsError("active policy is not found")
+        return dict(result)
+
+    def list_deliveries(self, incident_uid: str) -> list[dict[str, Any]]:
+        return list(self.repository.list_deliveries(_uid(incident_uid, "incident_uid")))
+
+    def bind_itsm_reference(
+        self,
+        *,
+        incident_uid: str,
+        external_ref: str,
+        idempotency_key: str,
+        actor_uid: str,
+    ) -> dict[str, Any]:
+        record = {
+            "uid": str(uuid.uuid4()),
+            "incident_uid": _uid(incident_uid, "incident_uid"),
+            "external_ref": _safe_string(external_ref, "external_ref", 120),
+            "idempotency_key": _safe_string(idempotency_key, "idempotency_key", 160),
+        }
+        record["payload_digest"] = _digest(
+            {
+                key: record[key]
+                for key in ("incident_uid", "external_ref", "idempotency_key")
+            }
+        )
+        try:
+            stored = self.repository.bind_itsm_reference(record)
+        except RuntimeError as error:
+            if str(error) in {"idempotency conflict", "ITSM reference conflict"}:
+                raise ProductionOperationsError(str(error)) from error
+            raise
+        if stored["uid"] == record["uid"]:
+            self._audit(
+                "itsm_reference_bound",
+                delivery_uid=None,
+                actor_uid=actor_uid,
+                detail={"external_ref": stored["external_ref"]},
+            )
+        return dict(stored)
+
+    def itsm_reference_for_incident(self, incident_uid: str) -> dict[str, Any]:
+        result = self.repository.itsm_reference_for_incident(
+            _uid(incident_uid, "incident_uid")
+        )
+        if result is None:
+            raise ProductionOperationsError("ITSM reference is not found")
+        return dict(result)
+
+    def platform_incident_for_itsm(self, external_ref: str) -> str:
+        result = self.repository.platform_incident_for_itsm(
+            _safe_string(external_ref, "external_ref", 120)
+        )
+        if result is None:
+            raise ProductionOperationsError("ITSM reference is not found")
+        return result
+
+
+def run_local_fault_injection(
+    service: ProductionOperationsService,
+    *,
+    kind: str,
+    incident_uid: str,
+    alert_uid: str,
+    actor_uid: str,
+) -> dict[str, Any]:
+    kind = _safe_string(kind, "fault kind", 40)
+    if kind not in {
+        "collection_failed",
+        "dependency_slow",
+        "capacity_exhausted",
+        "recovered",
+    }:
+        raise ProductionOperationsError("fault kind is invalid")
+    record = {
+        "fault_kind": kind,
+        "incident_uid": _uid(incident_uid, "incident_uid"),
+        "alert_uid": _uid(alert_uid, "alert_uid"),
+        "correlation_id": str(uuid.uuid4()),
+        "recovery_candidate": True,
+    }
+    service._audit(
+        "fault_injected",
+        delivery_uid=None,
+        actor_uid=actor_uid,
+        detail={"fault_kind": kind, "correlation_id": record["correlation_id"]},
+    )
+    return record

+ 262 - 0
deployment/app/core/events/production_operations_repository.py

@@ -0,0 +1,262 @@
+"""PostgreSQL persistence for P3 operations delivery; no provider payload bodies."""
+
+from __future__ import annotations
+
+import json
+
+from sqlalchemy import text
+
+
+class SqlAlchemyProductionOperationsRepository:
+    def __init__(self, session):
+        self.session = session
+
+    def _row(self, value):
+        if value is None:
+            return None
+        return {
+            key: (
+                item.isoformat()
+                if hasattr(item, "isoformat")
+                else str(item)
+                if hasattr(item, "hex")
+                else item
+            )
+            for key, item in dict(value).items()
+        }
+
+    def enqueue_delivery(self, record, *, queue_hard_limit):
+        # A transaction-scoped advisory lock makes the count-and-insert admission
+        # check serializable across independent workers without a mutable counter.
+        self.session.execute(text("SELECT pg_advisory_xact_lock(48005)"))
+        existing = (
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_deliveries WHERE idempotency_key=:key"
+                ),
+                {"key": record["idempotency_key"]},
+            )
+            .mappings()
+            .one_or_none()
+        )
+        if existing:
+            if existing["payload_digest"] != record["payload_digest"]:
+                raise RuntimeError("idempotency conflict")
+            return self._row(existing)
+        occupied = self.session.execute(
+            text(
+                "SELECT count(*) FROM public.production_observability_deliveries "
+                "WHERE status IN ('pending','processing')"
+            )
+        ).scalar_one()
+        if occupied >= queue_hard_limit:
+            raise RuntimeError("delivery queue hard limit reached")
+        self.session.execute(
+            text(
+                """INSERT INTO public.production_observability_deliveries (uid,incident_uid,alert_uid,channel,idempotency_key,payload_digest,status,attempt_count,next_attempt_at,lease_fence,created_at,updated_at) VALUES (CAST(:uid AS uuid),CAST(:incident_uid AS uuid),CAST(:alert_uid AS uuid),:channel,:idempotency_key,:payload_digest,'pending',0,clock_timestamp(),0,clock_timestamp(),clock_timestamp())"""
+            ),
+            record,
+        )
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_deliveries WHERE uid=CAST(:uid AS uuid)"
+                ),
+                record,
+            )
+            .mappings()
+            .one()
+        )
+
+    def append_audit(self, record):
+        self.session.execute(
+            text(
+                "SELECT public.record_production_observability_audit("
+                "CAST(:uid AS uuid),CAST(:delivery_uid AS uuid),:action,"
+                "CAST(:actor_uid AS uuid),CAST(:safe_detail AS jsonb))"
+            ),
+            {**record, "safe_detail": json.dumps(record["safe_detail"])},
+        )
+
+    def append_rejection_audit_independently(self, record):
+        """Persist a safe rejection receipt outside a caller's rollback scope."""
+        get_bind = getattr(self.session, "get_bind", None)
+        bind = get_bind() if get_bind is not None else self.session
+        engine = getattr(bind, "engine", bind)
+        with engine.begin() as connection:
+            connection.execute(
+                text(
+                    "SELECT public.record_production_observability_audit("
+                    "CAST(:uid AS uuid),NULL,:action,CAST(:actor_uid AS uuid),"
+                    "CAST(:safe_detail AS jsonb))"
+                ),
+                {**record, "safe_detail": json.dumps(record["safe_detail"])},
+            )
+
+    def claim_delivery(self, uid, worker, now):
+        return self._row(
+            self.session.execute(
+                text(
+                    """UPDATE public.production_observability_deliveries SET status='processing',lease_owner=:worker,lease_fence=lease_fence+1,lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND ((status='pending' AND next_attempt_at<=clock_timestamp()) OR (status='processing' AND lease_expires_at<=clock_timestamp())) RETURNING *"""
+                ),
+                {"uid": uid, "worker": worker},
+            )
+            .mappings()
+            .one_or_none()
+        )
+
+    def record_attempt(self, uid, worker, fence, now, delivered, reason):
+        if delivered:
+            sql = """UPDATE public.production_observability_deliveries SET status='delivered',lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp() RETURNING *"""
+        else:
+            sql = """UPDATE public.production_observability_deliveries SET attempt_count=attempt_count+1,lease_owner=NULL,lease_expires_at=NULL,status=CASE WHEN attempt_count+1>=3 THEN 'dead_letter' ELSE 'pending' END,next_attempt_at=clock_timestamp()+(LEAST(3600,60*(attempt_count+1))*interval '1 second'),last_reason_code=:reason,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp() RETURNING *"""
+        return self._row(
+            self.session.execute(
+                text(sql),
+                {"uid": uid, "worker": worker, "fence": fence, "reason": reason},
+            )
+            .mappings()
+            .one_or_none()
+        )
+
+    def compensate_dead_letter(self, uid, reason_code, receipt_code):
+        existing = self.session.execute(
+            text(
+                "SELECT * FROM public.production_observability_deliveries "
+                "WHERE uid=CAST(:uid AS uuid) FOR UPDATE"
+            ),
+            {"uid": uid},
+        ).mappings().one_or_none()
+        if existing is None or existing["status"] not in {"dead_letter", "compensated"}:
+            raise RuntimeError("delivery is not compensable")
+        if existing["status"] == "compensated":
+            if (
+                existing["compensation_reason_code"] == reason_code
+                and existing["compensation_receipt_code"] == receipt_code
+            ):
+                return self._row(existing)
+            raise RuntimeError("compensation conflict")
+        return self._row(
+            self.session.execute(
+                text(
+                    "UPDATE public.production_observability_deliveries SET "
+                    "status='compensated',compensation_reason_code=:reason_code,"
+                    "compensation_receipt_code=:receipt_code,updated_at=clock_timestamp() "
+                    "WHERE uid=CAST(:uid AS uuid) AND status='dead_letter' RETURNING *"
+                ),
+                {"uid": uid, "reason_code": reason_code, "receipt_code": receipt_code},
+            ).mappings().one()
+        )
+
+    def save_policy(self, record):
+        self.session.execute(
+            text(
+                """INSERT INTO public.production_observability_policies (uid,code,version,layer,error_budget_ratio,status,created_by,created_at) VALUES (CAST(:uid AS uuid),:code,:version,:layer,:error_budget_ratio,:status,CAST(:created_by AS uuid),clock_timestamp())"""
+            ),
+            record,
+        )
+        return record
+
+    def activate_policy(self, code, version):
+        self.session.execute(
+            text(
+                "UPDATE public.production_observability_policies SET status='retired' WHERE code=:code AND status='active'"
+            ),
+            {"code": code},
+        )
+        return self._row(
+            self.session.execute(
+                text(
+                    "UPDATE public.production_observability_policies SET status='active' WHERE code=:code AND version=:version RETURNING *"
+                ),
+                {"code": code, "version": version},
+            )
+            .mappings()
+            .one()
+        )
+
+    def active_policy(self, code):
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_policies "
+                    "WHERE code=:code AND status='active'"
+                ),
+                {"code": code},
+            )
+            .mappings()
+            .one_or_none()
+        )
+
+    def list_deliveries(self, incident_uid):
+        return [
+            self._row(row)
+            for row in self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_deliveries "
+                    "WHERE incident_uid=CAST(:incident_uid AS uuid) ORDER BY created_at,uid"
+                ),
+                {"incident_uid": incident_uid},
+            ).mappings()
+        ]
+
+    def bind_itsm_reference(self, record):
+        existing = self.session.execute(
+            text(
+                "SELECT * FROM public.production_observability_itsm_references "
+                "WHERE idempotency_key=:key"
+            ),
+            {"key": record["idempotency_key"]},
+        ).mappings().one_or_none()
+        if existing:
+            if existing["payload_digest"] != record["payload_digest"]:
+                raise RuntimeError("idempotency conflict")
+            return self._row(existing)
+        collision = self.session.execute(
+            text(
+                "SELECT 1 FROM public.production_observability_itsm_references "
+                "WHERE incident_uid=CAST(:incident_uid AS uuid) OR external_ref=:external_ref"
+            ),
+            record,
+        ).scalar_one_or_none()
+        if collision:
+            raise RuntimeError("ITSM reference conflict")
+        self.session.execute(
+            text(
+                "INSERT INTO public.production_observability_itsm_references "
+                "(uid,incident_uid,external_ref,idempotency_key,payload_digest,created_at) "
+                "VALUES (CAST(:uid AS uuid),CAST(:incident_uid AS uuid),:external_ref,"
+                ":idempotency_key,:payload_digest,clock_timestamp())"
+            ),
+            record,
+        )
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_itsm_references "
+                    "WHERE uid=CAST(:uid AS uuid)"
+                ),
+                record,
+            ).mappings().one()
+        )
+
+    def itsm_reference_for_incident(self, incident_uid):
+        return self._row(
+            self.session.execute(
+                text(
+                    "SELECT * FROM public.production_observability_itsm_references "
+                    "WHERE incident_uid=CAST(:incident_uid AS uuid)"
+                ),
+                {"incident_uid": incident_uid},
+            ).mappings().one_or_none()
+        )
+
+    def platform_incident_for_itsm(self, external_ref):
+        row = self.session.execute(
+            text(
+                "SELECT incident_uid FROM public.production_observability_itsm_references "
+                "WHERE external_ref=:external_ref"
+            ),
+            {"external_ref": external_ref},
+        ).mappings().one_or_none()
+        return None if row is None else str(row["incident_uid"])

+ 901 - 0
deployment/app/core/governance/bi_ai_asset_catalog.py

@@ -0,0 +1,901 @@
+"""Closed, read-only BI/AI asset catalog engineering baseline.
+
+This module deliberately supports only the local fixture provider until an
+enterprise provider, API scope and service identity have been approved.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import os
+import re
+import uuid
+from datetime import UTC, datetime
+from typing import Any
+
+from sqlalchemy import create_engine, text
+
+ASSET_TYPES = frozenset(
+    {
+        "dataset",
+        "report",
+        "dashboard",
+        "model",
+        "prompt",
+        "agent",
+        "knowledge_base",
+        "index",
+        "evaluation_set",
+    }
+)
+CLASSIFICATIONS = frozenset({"public", "internal", "confidential", "restricted"})
+CAPABILITIES = frozenset({"assets.read", "dependencies.read"})
+_TOKEN = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,119}")
+_WORDS = re.compile(r"[A-Za-z0-9]{2,80}")
+_FORBIDDEN_TEXT = re.compile(
+    r"(?i)(?:https?://|://|\bselect\b|\binsert\b|\bupdate\b|\bdelete\b|\bscript\b|\btoken\b|\bpassword\b|\bsecret\b|api[_ -]?key)"
+)
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ValueError(f"{label} must be an object")
+    unknown = sorted(set(value) - allowed)
+    if unknown:
+        raise ValueError(f"unsupported {label} fields: {', '.join(unknown)}")
+    return copy.deepcopy(value)
+
+
+def _text(value: Any, label: str, maximum: int = 240) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise ValueError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum or _FORBIDDEN_TEXT.search(result):
+        raise ValueError(f"{label} is unsafe or exceeds {maximum} characters")
+    return result
+
+
+def _token(value: Any, label: str) -> str:
+    result = _text(value, label, 120)
+    if not _TOKEN.fullmatch(result):
+        raise ValueError(f"{label} is invalid")
+    return result
+
+
+def _string_list(value: Any, label: str, maximum: int = 32) -> list[str]:
+    if not isinstance(value, list) or len(value) > maximum:
+        raise ValueError(f"{label} must be a bounded list")
+    return sorted({_token(item, label) for item in value})
+
+
+def _digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(
+            value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
+        ).encode()
+    ).hexdigest()
+
+
+class ProviderRegistry:
+    """Resolve an allowlisted, versioned provider without any network configuration."""
+
+    _LOCAL = {
+        "provider_id": "local-fixture-v1",
+        "provider_version": "1",
+        "mode": "ENGINEERING_EVIDENCE_ONLY",
+        "origin": "local-fixture://wp11/v1",
+        "timeout_seconds": 3,
+        "page_size": 50,
+        "rate_limit_per_minute": 20,
+        "max_pages": 4,
+        "capabilities": ["assets.read", "dependencies.read"],
+    }
+
+    def resolve(
+        self,
+        provider_id: str,
+        provider_version: str,
+        *,
+        engineering_evidence_only: bool,
+    ) -> dict[str, Any]:
+        if not engineering_evidence_only:
+            raise PermissionError("engineering evidence only")
+        if (provider_id, provider_version) != ("local-fixture-v1", "1"):
+            raise PermissionError("provider disabled or unsupported")
+        return copy.deepcopy(self._LOCAL)
+
+
+def normalize_asset(
+    value: Any,
+    *,
+    source: str,
+    platform: str,
+    provider_version: str,
+    observed_at: str | None = None,
+) -> dict[str, Any]:
+    body = _closed(
+        value,
+        {
+            "external_uid",
+            "asset_type",
+            "name",
+            "owner",
+            "domain",
+            "tags",
+            "classification",
+            "permissions",
+            "dependencies",
+        },
+        "asset",
+    )
+    asset_type = _token(body.get("asset_type"), "asset_type")
+    if asset_type not in ASSET_TYPES:
+        raise ValueError("unsupported asset type")
+    classification = _token(body.get("classification"), "classification")
+    if classification not in CLASSIFICATIONS:
+        raise ValueError("unsupported classification")
+    normalized = {
+        "source": _token(source, "source"),
+        "platform": _token(platform, "platform"),
+        "provider_version": _token(provider_version, "provider_version"),
+        "external_uid": _token(body.get("external_uid"), "external_uid"),
+        "asset_type": asset_type,
+        "name": _text(body.get("name"), "name"),
+        "owner": _token(body.get("owner"), "owner"),
+        "domain": _token(body.get("domain"), "domain"),
+        "tags": _string_list(body.get("tags", []), "tags"),
+        "classification": classification,
+        "permissions": _string_list(body.get("permissions", []), "permissions"),
+        "dependencies": _string_list(body.get("dependencies", []), "dependencies"),
+        "raw_payload_retained": False,
+    }
+    normalized["digest"] = _digest(
+        {key: value for key, value in normalized.items() if key != "digest"}
+    )
+    normalized["observed_at"] = observed_at or datetime.now(UTC).isoformat().replace(
+        "+00:00", "Z"
+    )
+    return normalized
+
+
+def normalize_search(query: Any, filters: Any) -> dict[str, Any]:
+    if not isinstance(query, str) or len(query) > 500:
+        raise ValueError("query must be a bounded string")
+    allowed = {"asset_type", "tag", "classification"}
+    normalized_filters = _closed(filters, allowed, "search filters")
+    for key, value in tuple(normalized_filters.items()):
+        normalized_filters[key] = _token(value, key)
+    if (
+        "asset_type" in normalized_filters
+        and normalized_filters["asset_type"] not in ASSET_TYPES
+    ):
+        raise ValueError("unsupported asset type")
+    if (
+        "classification" in normalized_filters
+        and normalized_filters["classification"] not in CLASSIFICATIONS
+    ):
+        raise ValueError("unsupported classification")
+    return {
+        "keywords": [word.lower() for word in _WORDS.findall(query)][:12],
+        "filters": normalized_filters,
+        "sql": None,
+    }
+
+
+def local_fixture_assets() -> list[dict[str, Any]]:
+    """Controlled, content-free sample covering BI and AI catalog types."""
+    owner, domain, visible = "local-owner", "default", ["viewer"]
+    return [
+        {
+            "external_uid": "dataset-sales",
+            "asset_type": "dataset",
+            "name": "Sales facts",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["sales"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": [],
+        },
+        {
+            "external_uid": "report-sales",
+            "asset_type": "report",
+            "name": "Sales report",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["sales"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["dataset-sales"],
+        },
+        {
+            "external_uid": "dashboard-sales",
+            "asset_type": "dashboard",
+            "name": "Sales dashboard",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["sales"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["report-sales"],
+        },
+        {
+            "external_uid": "model-sales",
+            "asset_type": "model",
+            "name": "Sales model",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["forecast"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["dataset-sales"],
+        },
+        {
+            "external_uid": "prompt-sales",
+            "asset_type": "prompt",
+            "name": "Sales summary prompt",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["prompt"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": [],
+        },
+        {
+            "external_uid": "agent-sales",
+            "asset_type": "agent",
+            "name": "Sales assistant",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["agent"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["model-sales", "prompt-sales"],
+        },
+        {
+            "external_uid": "knowledge-sales",
+            "asset_type": "knowledge_base",
+            "name": "Sales knowledge",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["knowledge"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": [],
+        },
+        {
+            "external_uid": "index-sales",
+            "asset_type": "index",
+            "name": "Sales index",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["index"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["knowledge-sales"],
+        },
+        {
+            "external_uid": "evaluation-sales",
+            "asset_type": "evaluation_set",
+            "name": "Sales evaluation",
+            "owner": owner,
+            "domain": domain,
+            "tags": ["evaluation"],
+            "classification": "internal",
+            "permissions": visible,
+            "dependencies": ["agent-sales"],
+        },
+    ]
+
+
+class CatalogControlIssuer:
+    """Issue one-time catalog claims through the separate control connection."""
+
+    def __init__(self, engine):
+        self.engine = engine
+
+    def issue(self, action: str, principal: str, body: dict[str, Any]) -> str:
+        with self.engine.begin() as control:
+            claim = control.execute(
+                text("SELECT public.bi_ai_catalog_issue_request_claim(:action,:principal,CAST(:body AS jsonb))"),
+                {"action": action, "principal": principal, "body": json.dumps(body, separators=(",", ":"))},
+            ).scalar_one()
+        return str(claim["request_claim"])
+
+    @classmethod
+    def from_environment(cls) -> CatalogControlIssuer:
+        from app.config.database_urls import validate_postgresql_url
+
+        url = os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", "")
+        parts = validate_postgresql_url(url, "BI_AI_CATALOG_CONTROL_DATABASE_URL")
+        if parts.username != "dataops_bi_ai_catalog_control":
+            raise PermissionError("catalog control issuer is not configured")
+        return cls(create_engine(url, pool_pre_ping=True))
+
+
+class SqlAlchemyCatalogRepository:
+    """Persist only normalized projections; SQL rows/payloads are never retained."""
+
+    def __init__(self, session, control_issuer: CatalogControlIssuer | None = None):
+        self.session = session
+        self.control_issuer = control_issuer
+
+    @staticmethod
+    def _plain(row):
+        if row is None:
+            return None
+        result = dict(row)
+        for key, value in tuple(result.items()):
+            if isinstance(value, datetime):
+                result[key] = value.isoformat()
+            elif key in {"tags", "permissions", "dependencies"} and value is None:
+                result[key] = []
+        result["digest"] = result.pop("content_digest")
+        result["deleted_candidate"] = bool(result["deleted_candidate"])
+        result["tombstoned"] = result.pop("tombstoned_at") is not None
+        return result
+
+    def register_local_fixture(self):
+        # Tenant sources are inserted by the only runtime gateway after a
+        # persisted grant is checked.  Legacy registration is intentionally
+        # not callable from application code.
+        ProviderRegistry().resolve(
+            "local-fixture-v1", "1", engineering_evidence_only=True
+        )
+
+    def runtime_write(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        payload = self._claimed_payload(action, payload)
+        row = (
+            self.session.execute(
+                text(
+                    "SELECT public.bi_ai_catalog_runtime_write(:action,CAST(:payload AS jsonb)) AS result"
+                ),
+                {
+                    "action": action,
+                    "payload": json.dumps(payload, separators=(",", ":")),
+                },
+            )
+            .mappings()
+            .one()
+        )
+        return dict(row["result"])
+
+    def runtime_read(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        payload = self._claimed_payload(action, payload)
+        row = self.session.execute(
+            text(
+                "SELECT public.bi_ai_catalog_runtime_read(:action,CAST(:payload AS jsonb)) AS result"
+            ),
+            {"action": action, "payload": json.dumps(payload, separators=(",", ":"))},
+        ).mappings().one()
+        return dict(row["result"] or {})
+
+    def _claimed_payload(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        """Have the issuer-only DB identity bind a server-derived scope once."""
+        principal = payload.get("principal_ref")
+        if not isinstance(principal, str):
+            raise PermissionError("catalog request claim denied")
+        body = {
+            key: value
+            for key, value in payload.items()
+            if key not in {"principal_ref", "tenant_ref", "domain_ref", "request_claim"}
+        }
+        if self.control_issuer is None:
+            raise PermissionError("catalog control issuer is not configured")
+        return body | {"request_claim": self.control_issuer.issue(action, principal, body)}
+
+    def persist_local_fixture(
+        self, principal_ref: str, assets: list[dict[str, Any]]
+    ) -> dict[str, Any]:
+        lease_token = str(uuid.uuid4())
+        claim = self.runtime_write(
+            "claim",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "lease_owner": principal_ref,
+                "lease_token": lease_token,
+            },
+        )
+        projected = []
+        for asset in assets:
+            normalized = normalize_asset(
+                asset,
+                source="local-fixture-v1",
+                platform="local-fixture",
+                provider_version="1",
+            )
+            projected.append(
+                {
+                    key: normalized[key]
+                    for key in (
+                        "external_uid",
+                        "asset_type",
+                        "name",
+                        "owner",
+                        "domain",
+                        "tags",
+                        "classification",
+                        "permissions",
+                        "dependencies",
+                        "digest",
+                        "observed_at",
+                    )
+                }
+            )
+        return self.runtime_write(
+            "persist_page",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "lease_owner": principal_ref,
+                "lease_token": lease_token,
+                "lease_fence": claim["lease_fence"],
+                # A checkpoint is an acknowledged page boundary, not a lease
+                # token; each controlled fixture run advances a bounded token.
+                "cursor": f"fixture-page-{uuid.uuid4()}",
+                "assets": projected,
+                "page_digest": _digest({"assets": projected}),
+                "operation_id": str(uuid.uuid4()),
+                "final_page": True,
+            },
+        )
+
+    def observe_scan(
+        self, principal_ref: str, scan_id: str, observed_uids: list[str]
+    ) -> dict[str, Any]:
+        values = sorted({_token(item, "observed_uid") for item in observed_uids})
+        status = self.runtime_read("scan_status", {"principal_ref": principal_ref})
+        completed = status.get("scan_complete") and status.get("scan_id") == scan_id
+        if completed:
+            return {"replay": True}
+        generation = f"generation-{_token(scan_id, 'scan_id')}"
+        base = {
+            "source": "local-fixture-v1",
+            "principal_ref": principal_ref,
+            "scan_id": scan_id,
+        }
+        self.runtime_write(
+            "begin_scan",
+            base
+            | {
+                "generation_ref": generation,
+                "expected_pages": 1,
+            },
+        )
+        self.runtime_write(
+            "scan_page",
+            base
+            | {
+                "page_number": 1,
+                "observed_uids": values,
+                "page_digest": _digest({"scan_id": scan_id, "observed_uids": values}),
+            },
+        )
+        return self.runtime_write(
+            "finalize_scan",
+            base | {"final_cursor": f"final-{_token(scan_id, 'scan_id')}"},
+        )
+
+    def record_runtime_failure(
+        self, principal_ref: str, fence: int, error_code: str, payload_digest: str
+    ) -> dict[str, Any]:
+        return self.runtime_write(
+            "record_error",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "lease_fence": fence,
+                "error_code": _token(error_code, "error_code"),
+                "payload_digest": payload_digest,
+            },
+        )
+
+    def recover_runtime_failure(
+        self, principal_ref: str, error_code: str
+    ) -> dict[str, Any]:
+        return self.runtime_write(
+            "recover",
+            {
+                "source": "local-fixture-v1",
+                "principal_ref": principal_ref,
+                "error_code": _token(error_code, "error_code"),
+            },
+        )
+
+    def asset(
+        self,
+        source: str,
+        external_uid: str,
+        *,
+        tenant_ref: str,
+        domain_ref: str,
+    ):
+        raise RuntimeError("catalog direct read is sealed; use authorized gateway")
+
+    def all_assets(self, source: str, *, tenant_ref: str, domain_ref: str):
+        raise RuntimeError("catalog direct read is sealed; use authorized gateway")
+
+    def search_authorized(self, principal_ref: str, normalized: dict[str, Any]):
+        # Runtime roles have no table SELECT.  Principal is the sole read
+        # authorization root; tenant/domain/role come from its persisted grant.
+        return self.runtime_read(
+            "search",
+            {
+                "principal_ref": principal_ref,
+                "keywords": normalized["keywords"],
+                "filters": normalized["filters"],
+            },
+        ) | {"query": normalized}
+
+    def impact_authorized(self, principal_ref: str, external_uid: str, max_depth: int, max_nodes: int):
+        _token(external_uid, "external_uid")
+        return self.runtime_read(
+            "impact",
+            {
+                "principal_ref": principal_ref,
+                "external_uid": external_uid,
+                "max_depth": max_depth,
+                "max_nodes": max_nodes,
+            },
+        ) | {"source": external_uid, "max_depth": max_depth, "max_nodes": max_nodes}
+
+    def save_asset(self, asset: dict[str, Any]) -> None:
+        raise RuntimeError("catalog direct DML is sealed; use runtime gateway")
+
+    def missing_count(self, source: str, external_uid: str) -> int:
+        raise RuntimeError("catalog direct read requires server-derived scope")
+
+    def set_missing_count(self, source: str, external_uid: str, count: int) -> None:
+        return None
+
+    def record_audit(self, event_type: str, asset: dict[str, Any]) -> None:
+        raise RuntimeError("catalog direct audit is sealed; use runtime gateway")
+
+    def record_failure(
+        self, source: str, error_code: str, payload_digest: str, fence: int
+    ):
+        raise RuntimeError("catalog direct error write is sealed; use runtime gateway")
+
+    def recover_failure(self, source: str, error_code: str):
+        raise RuntimeError("catalog direct recovery is sealed; use runtime gateway")
+
+
+class CatalogApplicationService:
+    """HTTP-facing façade: principal scope is derived server-side, never body supplied."""
+
+    def __init__(self, session, control_issuer: CatalogControlIssuer | None = None):
+        self.session = session
+        self.repository = SqlAlchemyCatalogRepository(
+            session, control_issuer or CatalogControlIssuer.from_environment()
+        )
+        self.catalog = AssetCatalogService(self.repository)
+
+    def sync_local_fixture(self, *, principal_id: str, body: dict[str, Any]):
+        if body:
+            raise ValueError("catalog request rejected")
+        summary = self.repository.persist_local_fixture(
+            principal_id, local_fixture_assets()
+        )
+        self.session.commit()
+        return {
+            "source": "local-fixture-v1",
+            "mode": "ENGINEERING_EVIDENCE_ONLY",
+            "persisted_before_ack": True,
+            "summary": summary,
+        }
+
+    def search_for_principal(
+        self, *, principal_id: str, query: str, filters: dict[str, Any]
+    ):
+        return self.repository.search_authorized(
+            principal_id, normalize_search(query, filters)
+        )
+
+    def impact_for_principal(
+        self, *, principal_id: str, external_uid: str, max_depth: int, max_nodes: int
+    ):
+        return self.repository.impact_authorized(
+            principal_id, external_uid, max_depth, max_nodes
+        )
+
+    def audit_for_principal(self, *, principal_id: str):
+        # The security-definer gateway resolves the persisted principal grant
+        # before joining audit rows to visible assets.
+        return self.repository.runtime_read("audit", {"principal_ref": principal_id})
+
+
+class InMemoryCatalogRepository:
+    """Small deterministic repository used only by unit tests and local fixtures."""
+
+    def __init__(self):
+        self._assets: dict[tuple[str, str], dict[str, Any]] = {}
+        self._scans: dict[tuple[str, str], int] = {}
+        self._errors: dict[tuple[str, str, str], dict[str, Any]] = {}
+        self.audit: list[dict[str, Any]] = []
+
+    def asset(self, source: str, external_uid: str) -> dict[str, Any] | None:
+        row = self._assets.get((source, external_uid))
+        return copy.deepcopy(row) if row else None
+
+    def all_assets(self, source: str) -> list[dict[str, Any]]:
+        return [
+            copy.deepcopy(row)
+            for (item_source, _), row in self._assets.items()
+            if item_source == source
+        ]
+
+    def save_asset(self, asset: dict[str, Any]) -> None:
+        self._assets[(asset["source"], asset["external_uid"])] = copy.deepcopy(asset)
+
+    def missing_count(self, source: str, external_uid: str) -> int:
+        return self._scans.get((source, external_uid), 0)
+
+    def set_missing_count(self, source: str, external_uid: str, count: int) -> None:
+        self._scans[(source, external_uid)] = count
+
+    def record_audit(self, event_type: str, asset: dict[str, Any]) -> None:
+        self.audit.append(
+            {
+                "event_type": event_type,
+                "source": asset["source"],
+                "external_uid": asset["external_uid"],
+                "digest": asset["digest"],
+            }
+        )
+
+    def record_failure(
+        self, source: str, error_code: str, payload_digest: str, fence: int
+    ):
+        key = (source, error_code, payload_digest)
+        previous = self._errors.get(key, {"attempts": 0})
+        attempts = previous["attempts"] + 1
+        record = {
+            "source": source,
+            "error_code": error_code,
+            "payload_digest": payload_digest,
+            "lease_fence": fence,
+            "attempts": attempts,
+            "status": "dead_letter" if attempts >= 5 else "retryable",
+        }
+        self._errors[key] = record
+        return copy.deepcopy(record)
+
+    def recover_failure(self, source: str, error_code: str):
+        candidates = [
+            record
+            for (item_source, item_code, _), record in self._errors.items()
+            if item_source == source
+            and item_code == error_code
+            and record["status"] == "dead_letter"
+        ]
+        if not candidates:
+            raise LookupError("dead letter unavailable")
+        record = candidates[-1]
+        record["status"] = "recovered"
+        return copy.deepcopy(record)
+
+
+class AssetCatalogService:
+    """Persist normalized metadata, then advance only the caller's cursor/ack."""
+
+    def __init__(self, repository, *, registry: ProviderRegistry | None = None):
+        self.repository = repository
+        self.registry = registry or ProviderRegistry()
+
+    def ingest_page(
+        self,
+        provider_id: str,
+        provider_version: str,
+        assets: list[dict[str, Any]],
+        *,
+        cursor: str,
+        fence: int,
+    ) -> dict[str, int]:
+        if not isinstance(fence, int) or fence < 1 or not _TOKEN.fullmatch(str(cursor)):
+            raise ValueError("invalid cursor or fence")
+        manifest = self.registry.resolve(
+            provider_id, provider_version, engineering_evidence_only=True
+        )
+        results = {"created": 0, "unchanged": 0, "changed": 0, "restored": 0}
+        if not isinstance(assets, list) or len(assets) > manifest["page_size"]:
+            raise ValueError("asset page exceeds configured bound")
+        for item in assets:
+            normalized = normalize_asset(
+                item,
+                source=provider_id,
+                platform="local-fixture",
+                provider_version=provider_version,
+            )
+            saved = self.repository.asset(provider_id, normalized["external_uid"])
+            if saved is None:
+                normalized["version"] = 1
+                normalized["deleted_candidate"] = False
+                normalized["tombstoned"] = False
+                results["created"] += 1
+                self.repository.record_audit("catalog.asset.created", normalized)
+            elif saved["digest"] == normalized["digest"] and not saved.get(
+                "tombstoned"
+            ):
+                normalized.update(
+                    {
+                        "version": saved["version"],
+                        "deleted_candidate": False,
+                        "tombstoned": False,
+                    }
+                )
+                results["unchanged"] += 1
+            else:
+                normalized.update(
+                    {
+                        "version": saved["version"]
+                        + (0 if saved["digest"] == normalized["digest"] else 1),
+                        "deleted_candidate": False,
+                        "tombstoned": False,
+                    }
+                )
+                if saved.get("tombstoned"):
+                    results["restored"] += 1
+                    self.repository.record_audit("catalog.asset.restored", normalized)
+                else:
+                    results["changed"] += 1
+                    self.repository.record_audit("catalog.asset.changed", normalized)
+            self.repository.set_missing_count(
+                provider_id, normalized["external_uid"], 0
+            )
+            self.repository.save_asset(normalized)
+        return results
+
+    def confirm_missing(
+        self, source: str, observed_external_uids: set[str], *, scan_id: str
+    ) -> dict[str, int]:
+        _token(source, "source")
+        _token(scan_id, "scan_id")
+        if not isinstance(observed_external_uids, set) or not all(
+            isinstance(item, str) for item in observed_external_uids
+        ):
+            raise ValueError("observed external uids must be a set")
+        result = {"candidates": 0, "tombstoned": 0}
+        for asset in self.repository.all_assets(source):
+            if asset["external_uid"] in observed_external_uids or asset.get(
+                "tombstoned"
+            ):
+                continue
+            count = self.repository.missing_count(source, asset["external_uid"]) + 1
+            self.repository.set_missing_count(source, asset["external_uid"], count)
+            asset["deleted_candidate"] = True
+            if count >= 2:
+                asset["tombstoned"] = True
+                result["tombstoned"] += 1
+                self.repository.record_audit("catalog.asset.tombstoned", asset)
+            else:
+                result["candidates"] += 1
+                self.repository.record_audit("catalog.asset.deletion_candidate", asset)
+            self.repository.save_asset(asset)
+        return result
+
+    def record_failure(
+        self, source: str, *, fence: int, error_code: str, payload_digest: str
+    ) -> dict[str, Any]:
+        _token(source, "source")
+        _token(error_code, "error_code")
+        if (
+            not isinstance(fence, int)
+            or fence < 1
+            or not re.fullmatch(r"[0-9a-f]{64}", payload_digest)
+        ):
+            raise ValueError("catalog failure is invalid")
+        if not hasattr(self.repository, "record_failure"):
+            raise RuntimeError("catalog failure store unavailable")
+        return self.repository.record_failure(source, error_code, payload_digest, fence)
+
+    def recover_failure(self, source: str, *, error_code: str) -> dict[str, Any]:
+        _token(source, "source")
+        _token(error_code, "error_code")
+        if not hasattr(self.repository, "recover_failure"):
+            raise RuntimeError("catalog recovery store unavailable")
+        return self.repository.recover_failure(source, error_code)
+
+    def _visible(
+        self, asset: dict[str, Any], principal_roles: set[str], domain: str
+    ) -> bool:
+        if "viewer" not in principal_roles and "admin" not in principal_roles:
+            raise PermissionError("catalog read denied")
+        return asset["domain"] == domain and "viewer" in asset["permissions"]
+
+    def search(
+        self,
+        query: str,
+        filters: dict[str, Any],
+        *,
+        principal_roles: set[str],
+        domain: str,
+    ) -> list[dict[str, Any]]:
+        request = normalize_search(query, filters)
+        results = []
+        for asset in self.repository.all_assets("local-fixture-v1"):
+            if asset.get("tombstoned") or not self._visible(
+                asset, principal_roles, domain
+            ):
+                continue
+            haystack = " ".join([asset["name"], *asset["tags"]]).lower()
+            if request["keywords"] and not all(
+                word in haystack for word in request["keywords"]
+            ):
+                continue
+            if any(
+                asset.get(key) != value and value not in asset.get(key + "s", [])
+                for key, value in request["filters"].items()
+            ):
+                continue
+            results.append(
+                {
+                    key: asset[key]
+                    for key in (
+                        "external_uid",
+                        "asset_type",
+                        "name",
+                        "owner",
+                        "domain",
+                        "tags",
+                        "classification",
+                        "version",
+                        "observed_at",
+                    )
+                }
+            )
+        return sorted(
+            results, key=lambda row: (row["name"].lower(), row["external_uid"])
+        )[:50]
+
+    def impact(
+        self,
+        external_uid: str,
+        *,
+        principal_roles: set[str],
+        domain: str,
+        max_depth: int,
+        max_nodes: int,
+    ) -> dict[str, Any]:
+        if max_depth < 1 or max_depth > 5 or max_nodes < 1 or max_nodes > 100:
+            raise ValueError("impact bounds are invalid")
+        root = self.repository.asset(
+            "local-fixture-v1", _token(external_uid, "external_uid")
+        )
+        if root is None or not self._visible(root, principal_roles, domain):
+            raise LookupError("catalog asset unavailable")
+        by_dependency: dict[str, list[dict[str, Any]]] = {}
+        for asset in self.repository.all_assets("local-fixture-v1"):
+            if not asset.get("tombstoned") and self._visible(
+                asset, principal_roles, domain
+            ):
+                for dependency in asset["dependencies"]:
+                    by_dependency.setdefault(dependency, []).append(asset)
+        affected, seen, frontier = (
+            [],
+            {root["external_uid"]},
+            [(root["external_uid"], 0)],
+        )
+        truncated = False
+        while frontier:
+            node, depth = frontier.pop(0)
+            if depth >= max_depth:
+                continue
+            for child in by_dependency.get(node, []):
+                if child["external_uid"] in seen:
+                    continue
+                if len(affected) >= max_nodes:
+                    truncated = True
+                    break
+                seen.add(child["external_uid"])
+                affected.append(child["external_uid"])
+                frontier.append((child["external_uid"], depth + 1))
+            if truncated:
+                break
+        return {
+            "external_uid": root["external_uid"],
+            "affected": affected,
+            "truncated": truncated,
+        }

+ 616 - 82
deployment/app/core/governance/domain_replication.py

@@ -11,9 +11,13 @@ from __future__ import annotations
 import hashlib
 import json
 import re
+import unicodedata
 from copy import deepcopy
+from datetime import date
 from typing import Any
 
+from app.core.governance.domain_replication_contract_registry import verify_registry
+
 REQUIRED_STAGES = (
     "template_initialization",
     "incremental_ingestion",
@@ -56,6 +60,66 @@ _REQUIRED_ENTERPRISE_BINDINGS = {
     "readonly_source",
     "uat_users",
 }
+_EXECUTION_ACTIONS = ("dry_run", "execute")
+_RECOVERY_ACTIONS = frozenset({"diff", "rollback"})
+_EXECUTION_REF = re.compile(
+    r"^[a-z][a-z0-9-]{1,31}://([a-z][a-z0-9_]{1,63})/[a-zA-Z0-9_./:-]{1,240}$"
+)
+_HTTP_URL = re.compile(r"https?://", re.IGNORECASE)
+_RAW_ROW_KEY = re.compile(r"(?:raw[_-]?rows?|source[_-]?rows?)", re.IGNORECASE)
+_SHA256 = re.compile(r"^[0-9a-f]{64}$")
+_IDENTIFIER = re.compile(r"^[a-z][a-z0-9_-]{1,79}$")
+_CONFUSABLES = str.maketrans({
+    "а": "a", "е": "e", "і": "i", "о": "o", "р": "p", "с": "c",
+    "х": "x", "у": "y", "к": "k", "м": "m", "т": "t", "ѕ": "s",
+})
+_SENSITIVE_KEY_MARKERS = (
+    "password", "passwd", "secret", "token", "credential", "authorization",
+    "apikey", "privatekey",
+)
+_RAW_SOURCE_KEYS = {"rawrows", "sourcerows", "rows"}
+_SQL = re.compile(r"\b(?:select|insert|update|delete|drop|alter|create|grant|revoke)\b", re.IGNORECASE)
+_API_ALLOWLIST = {
+    "template_initialization": ("/api/meta/domain-templates",),
+    "incremental_ingestion": ("/api/meta/active-metadata",),
+    "catalog": ("/api/meta/active-metadata",),
+    "semantics": ("/api/development/v1/semantic-assets",),
+    "responsibility": ("/api/system/responsibilities",),
+    "quality": ("/api/rules/quality-operations",),
+    "remediation": ("/api/system/work-center",),
+    "observability": ("/api/datafactory/observability",),
+    "data_product": ("/api/dataservice/governance/products",),
+    "agent": ("/api/knowledge/agents",),
+}
+_EVIDENCE_PREFIXES = {
+    "template_initialization": "domain-template://",
+    "incremental_ingestion": "ingestion://",
+    "catalog": "catalog-run://",
+    "semantics": "semantic-release://",
+    "responsibility": "responsibility://",
+    "quality": "quality://",
+    "remediation": "workflow://",
+    "observability": "incident://",
+    "data_product": "product://",
+    "agent": "agent-request://",
+}
+_CONTRACT_REQUIREMENTS = {
+    "incremental_ingestion": "p3_wp03_connector_run",
+    "catalog": "p3_wp03_catalog_lineage",
+    "observability": "p3_wp04_edge_health",
+}
+_METRIC_FIELDS = {
+    "template_initialization": {"template_version", "object_type_count", "rule_count", "role_count", "metric_count"},
+    "incremental_ingestion": {"snapshot_rows", "delta_rows", "inserted", "updated", "deleted", "final_rows", "replay_changes", "cursor_before", "cursor_after"},
+    "catalog": {"asset_count", "incremental_change_count", "cursor_after"},
+    "semantics": {"published_term_count", "published_code_set_count", "published_metric_count", "mapped_field_count"},
+    "responsibility": {"coverage_percent", "bound_role_count"},
+    "quality": {"published_rule_count", "initial_finding_count", "target_score", "final_score"},
+    "remediation": {"issue_status", "task_status", "independent_closer"},
+    "observability": {"slo_count", "incident_status", "recovered"},
+    "data_product": {"contract_status", "certificate_status", "certificate_evidence_refs"},
+    "agent": {"autonomy_level", "decision", "automatic_execution_allowed", "citation_count", "cross_domain_denied"},
+}
 
 
 class DomainReplicationError(ValueError):
@@ -88,17 +152,291 @@ def _bounded_text(value: Any, field: str, limit: int = 256) -> str:
     return rendered
 
 
-def _reject_secrets(value: Any, path: str = "$") -> None:
+def _security_key(value: Any) -> str:
+    return re.sub(
+        r"[^a-z0-9]", "", unicodedata.normalize("NFKC", str(value)).casefold().translate(_CONFUSABLES)
+    )
+
+
+def _reject_secrets(value: Any, path: str = "$", depth: int = 0) -> None:
+    if depth > 12:
+        raise DomainReplicationError(f"maximum package depth exceeded at {path}")
     if isinstance(value, dict):
+        if len(value) > 64:
+            raise DomainReplicationError(f"maximum object properties exceeded at {path}")
         for key, item in value.items():
-            if _SECRET.search(str(key)):
+            normalized_key = _security_key(key)
+            if normalized_key in _RAW_SOURCE_KEYS:
+                raise DomainReplicationError(
+                    f"raw source rows are not allowed at {path}.{key}"
+                )
+            if _SECRET.search(normalized_key) or any(
+                marker in normalized_key for marker in _SENSITIVE_KEY_MARKERS
+            ):
                 raise DomainReplicationError(
-                    f"secret material is not allowed at {path}.{key}"
+                    f"sensitive material is not allowed at {path}.{key}"
                 )
-            _reject_secrets(item, f"{path}.{key}")
+            _reject_secrets(item, f"{path}.{key}", depth + 1)
+    elif isinstance(value, list):
+        if len(value) > 500:
+            raise DomainReplicationError(f"maximum collection items exceeded at {path}")
+        for index, item in enumerate(value):
+            _reject_secrets(item, f"{path}[{index}]", depth + 1)
+    elif isinstance(value, str):
+        if len(value) > 4096:
+            raise DomainReplicationError(f"maximum string length exceeded at {path}")
+        normalized = unicodedata.normalize("NFKC", value)
+        if _HTTP_URL.search(normalized):
+            raise DomainReplicationError(f"URL is not allowed at {path}")
+        if _SQL.search(normalized):
+            raise DomainReplicationError(f"SQL is not allowed at {path}")
+
+
+def _closed_mapping(value: Any, field: str, allowed: set[str]) -> dict[str, Any]:
+    value = _mapping(value, field)
+    unknown = sorted(set(value) - allowed)
+    if unknown:
+        normalized_unknown = [_security_key(key) for key in unknown]
+        if any(key in _RAW_SOURCE_KEYS for key in normalized_unknown):
+            raise DomainReplicationError(f"raw source rows are not allowed at {field}")
+        if any(
+            _SECRET.search(key) or any(marker in key for marker in _SENSITIVE_KEY_MARKERS)
+            for key in normalized_unknown
+        ):
+            raise DomainReplicationError(f"sensitive material is not allowed at {field}")
+        raise DomainReplicationError(f"{field} has unsupported fields: {unknown}")
+    return value
+
+
+def _closed_required(value: Any, field: str, required: set[str], allowed: set[str]) -> dict[str, Any]:
+    value = _closed_mapping(value, field, allowed)
+    missing = sorted(required - set(value))
+    if missing:
+        raise DomainReplicationError(f"{field} is missing required fields: {missing}")
+    return value
+
+
+def _string(value: Any, field: str, limit: int = 256) -> str:
+    if not isinstance(value, str):
+        raise DomainReplicationError(f"{field} must be a string")
+    return _bounded_text(value, field, limit)
+
+
+def _digest_string(value: Any, field: str) -> str:
+    value = _string(value, field, 64)
+    if not _SHA256.fullmatch(value):
+        raise DomainReplicationError(f"{field} must be a lowercase SHA-256 digest")
+    return value
+
+
+def _bounded_list(value: Any, field: str, *, minimum: int = 1, maximum: int = 100) -> list[Any]:
+    if not isinstance(value, list) or not minimum <= len(value) <= maximum:
+        raise DomainReplicationError(f"{field} must contain {minimum}..{maximum} items")
+    return value
+
+
+def _execution_ref(value: Any, field: str) -> tuple[str, str]:
+    rendered = _bounded_text(value, field, 320)
+    if _HTTP_URL.search(rendered):
+        raise DomainReplicationError(f"{field} must not contain a URL")
+    matched = _EXECUTION_REF.fullmatch(rendered)
+    if not matched:
+        raise DomainReplicationError(f"{field} must be a canonical evidence reference")
+    return rendered, matched.group(1)
+
+
+def _reject_execution_sensitive(value: Any, path: str = "execution_evidence") -> None:
+    if isinstance(value, dict):
+        for key, item in value.items():
+            if _RAW_ROW_KEY.search(str(key)):
+                raise DomainReplicationError(f"raw source rows are not allowed at {path}.{key}")
+            if _HTTP_URL.search(str(item)):
+                raise DomainReplicationError(f"URL is not allowed at {path}.{key}")
+            _reject_execution_sensitive(item, f"{path}.{key}")
     elif isinstance(value, list):
         for index, item in enumerate(value):
-            _reject_secrets(item, f"{path}[{index}]")
+            _reject_execution_sensitive(item, f"{path}[{index}]")
+
+
+def _validate_execute_state(action: dict[str, Any], stage: str) -> dict[str, Any]:
+    """Validate the v2 receipt that owns a governed state transition."""
+
+    required = {
+        "action", "status", "write_count", "evidence_ref", "audit_ref", "operation_uid",
+        "idempotency_key", "request_digest", "attempt", "lease_fence", "pre_state_digest",
+        "post_state_digest", "result_digest",
+    }
+    action = _closed_required(action, f"{stage}.execute", required, required)
+    for field in ("operation_uid", "idempotency_key"):
+        if not _IDENTIFIER.fullmatch(_string(action[field], f"{stage}.execute.{field}", 80)):
+            raise DomainReplicationError(f"{stage}.execute.{field} is invalid")
+    for field in ("request_digest", "pre_state_digest", "post_state_digest", "result_digest"):
+        _digest_string(action[field], f"{stage}.execute.{field}")
+    if action["pre_state_digest"] == action["post_state_digest"]:
+        raise DomainReplicationError(f"{stage}.execute state digests must differ")
+    if isinstance(action["attempt"], bool) or not isinstance(action["attempt"], int) or not 1 <= action["attempt"] <= 5:
+        raise DomainReplicationError(f"{stage}.execute.attempt must be 1..5")
+    if isinstance(action["lease_fence"], bool) or not isinstance(action["lease_fence"], int) or action["lease_fence"] < 1:
+        raise DomainReplicationError(f"{stage}.execute.lease_fence must be positive")
+    return action
+
+
+def _validate_rollback(action: dict[str, Any], stage: str, *, strict_state_machine: bool) -> dict[str, Any]:
+    required = {
+        "action", "status", "write_count", "evidence_ref", "audit_ref", "operation",
+        "idempotency_key", "request_digest", "attempt", "lease_fence", "from_digest",
+        "to_digest", "replay_status",
+    }
+    if strict_state_machine:
+        required = required - {"replay_status"} | {"operation_uid", "result_digest"}
+    action = _closed_required(action, f"{stage}.rollback", required, required)
+    if action["operation"] != "restore":
+        raise DomainReplicationError(f"{stage}.rollback.operation must be restore")
+    for field in ("operation_uid", "idempotency_key") if strict_state_machine else ("idempotency_key",):
+        if not _IDENTIFIER.fullmatch(_string(action[field], f"{stage}.rollback.{field}", 80)):
+            raise DomainReplicationError(f"{stage}.rollback.{field} is invalid")
+    digest_fields = ("request_digest", "from_digest", "to_digest", "result_digest") if strict_state_machine else ("request_digest", "from_digest", "to_digest")
+    for key in digest_fields:
+        _digest_string(action[key], f"{stage}.rollback.{key}")
+    if action["from_digest"] == action["to_digest"]:
+        raise DomainReplicationError(f"{stage}.rollback digests must differ")
+    if isinstance(action["attempt"], bool) or not isinstance(action["attempt"], int) or not 1 <= action["attempt"] <= 5:
+        raise DomainReplicationError(f"{stage}.rollback.attempt must be 1..5")
+    if isinstance(action["lease_fence"], bool) or not isinstance(action["lease_fence"], int) or action["lease_fence"] < 1:
+        raise DomainReplicationError(f"{stage}.rollback.lease_fence must be positive")
+    if not strict_state_machine and action["replay_status"] != "exact_replay":
+        raise DomainReplicationError(f"{stage}.rollback replay must be exact_replay")
+    return action
+
+
+def _validate_replay_receipts(value: Any, rollbacks: dict[str, dict[str, Any]]) -> None:
+    """Require a second receipt, not a rollback's self-declared replay label."""
+
+    required = {
+        "stage", "operation_uid", "idempotency_key", "request_digest", "attempt",
+        "lease_fence", "from_digest", "to_digest", "result_digest", "status",
+    }
+    receipts = _bounded_list(value, "execution_evidence.replay_receipts", minimum=len(rollbacks), maximum=len(rollbacks))
+    by_stage: dict[str, dict[str, Any]] = {}
+    for item in receipts:
+        item = _closed_required(item, "execution_evidence.replay_receipt", required, required)
+        stage = _string(item["stage"], "execution_evidence.replay_receipt.stage", 80)
+        if stage not in rollbacks or stage in by_stage:
+            raise DomainReplicationError("replay receipt must bind exactly one rollback stage")
+        if item["status"] != "exact_replay":
+            raise DomainReplicationError("replay receipt status must be exact_replay")
+        for field in ("operation_uid", "idempotency_key"):
+            if not _IDENTIFIER.fullmatch(_string(item[field], f"replay_receipt.{field}", 80)):
+                raise DomainReplicationError(f"replay receipt {field} is invalid")
+        for field in ("request_digest", "from_digest", "to_digest", "result_digest"):
+            _digest_string(item[field], f"replay_receipt.{field}")
+        rollback = rollbacks[stage]
+        for field in required - {"stage", "status"}:
+            if item[field] != rollback[field]:
+                raise DomainReplicationError(f"replay receipt does not match rollback {field}")
+        by_stage[stage] = item
+    if set(by_stage) != set(rollbacks):
+        raise DomainReplicationError("replay receipt coverage is incomplete")
+
+
+def validate_execution_evidence(
+    execution_evidence: dict[str, Any], *, domain_code: str | None = None
+) -> dict[str, dict[str, Any]]:
+    """Validate the ordered, row-free execution chain for every governance stage."""
+
+    initial = _mapping(execution_evidence, "execution_evidence")
+    schema_version = initial.get("schema_version")
+    if schema_version not in {1, 2}:
+        raise DomainReplicationError("execution_evidence.schema_version must be 1 or 2")
+    strict_state_machine = schema_version == 2
+    execution_evidence = _closed_mapping(
+        execution_evidence,
+        "execution_evidence",
+        {"schema_version", "stages", "replay_receipts"} if strict_state_machine else {"schema_version", "stages"},
+    )
+    _reject_secrets(execution_evidence, "execution_evidence")
+    _reject_execution_sensitive(execution_evidence)
+    receipts = execution_evidence.get("stages")
+    if not isinstance(receipts, list) or len(receipts) != len(REQUIRED_STAGES):
+        raise DomainReplicationError("execution_evidence must contain every required stage")
+
+    summaries: dict[str, dict[str, Any]] = {}
+    rollbacks: dict[str, dict[str, Any]] = {}
+    for expected_stage, receipt in zip(REQUIRED_STAGES, receipts, strict=True):
+        receipt = _closed_mapping(receipt, "execution_evidence.stage", {"stage", "actions"})
+        stage = _bounded_text(receipt.get("stage"), "execution_evidence.stage.stage", 80)
+        if stage != expected_stage:
+            raise DomainReplicationError("execution evidence stages must be ordered")
+        actions = receipt.get("actions")
+        if not isinstance(actions, list) or len(actions) != 3:
+            raise DomainReplicationError(f"{stage} must contain dry_run, execute and diff or rollback")
+        normalized_actions: list[dict[str, Any]] = []
+        domains: set[str] = set()
+        for index, action in enumerate(actions):
+            action = _mapping(action, f"{stage}.actions[{index}]")
+            action_name = _bounded_text(action.get("action"), f"{stage}.action", 32)
+            expected_action = (
+                _EXECUTION_ACTIONS[index] if index < 2 else None
+            )
+            if expected_action and action_name != expected_action:
+                raise DomainReplicationError(f"{stage} actions must be ordered dry_run then execute")
+            if index == 2 and action_name not in _RECOVERY_ACTIONS:
+                raise DomainReplicationError(f"{stage} recovery action must be diff or rollback")
+            allowed = {"action", "status", "write_count", "evidence_ref", "audit_ref"}
+            if action_name == "rollback":
+                action = _validate_rollback(action, stage, strict_state_machine=strict_state_machine)
+            elif action_name == "execute" and strict_state_machine:
+                action = _validate_execute_state(action, stage)
+            else:
+                action = _closed_required(action, f"{stage}.actions[{index}]", allowed, allowed)
+            if action.get("status") != "passed":
+                raise DomainReplicationError(f"{stage}.{action_name} status must be passed")
+            write_count = action.get("write_count")
+            if isinstance(write_count, bool) or not isinstance(write_count, int):
+                raise DomainReplicationError(f"{stage}.{action_name}.write_count must be an integer")
+            if write_count < 0 or write_count > 1_000_000:
+                raise DomainReplicationError(f"{stage}.{action_name}.write_count is out of range")
+            if action_name == "dry_run" and write_count != 0:
+                raise DomainReplicationError(f"{stage}.dry_run must record zero writes")
+            evidence_ref, evidence_domain = _execution_ref(
+                action.get("evidence_ref"), f"{stage}.{action_name}.evidence_ref"
+            )
+            audit_ref, audit_domain = _execution_ref(
+                action.get("audit_ref"), f"{stage}.{action_name}.audit_ref"
+            )
+            domains.update({evidence_domain, audit_domain})
+            normalized_actions.append(
+                {
+                    "action": action_name,
+                    "write_count": write_count,
+                    "evidence_ref": evidence_ref,
+                    "audit_ref": audit_ref,
+                }
+            )
+            if action_name == "rollback" and strict_state_machine:
+                execute = actions[1]
+                for field in ("operation_uid", "idempotency_key", "request_digest", "attempt", "lease_fence"):
+                    if action[field] != execute[field]:
+                        raise DomainReplicationError(f"{stage}.rollback must match execute {field}")
+                if action["from_digest"] != execute["post_state_digest"]:
+                    raise DomainReplicationError(f"{stage}.rollback.from_digest must match execute post_state_digest")
+                if action["to_digest"] != execute["pre_state_digest"]:
+                    raise DomainReplicationError(f"{stage}.rollback.to_digest must match execute pre_state_digest")
+                rollbacks[stage] = action
+        if len(domains) != 1 or (domain_code is not None and domains != {domain_code}):
+            raise DomainReplicationError(f"{stage} execution evidence contains a cross-domain reference")
+        summaries[stage] = {
+            "actions": [item["action"] for item in normalized_actions],
+            "dry_run_write_count": normalized_actions[0]["write_count"],
+            "execute_write_count": normalized_actions[1]["write_count"],
+            "recovery_strategy": normalized_actions[2]["action"],
+            "recovery_write_count": normalized_actions[2]["write_count"],
+            "audit_ref_count": len(normalized_actions),
+            "evidence_digest": _digest(normalized_actions),
+        }
+    if strict_state_machine:
+        _validate_replay_receipts(execution_evidence.get("replay_receipts"), rollbacks)
+    return summaries
 
 
 def _row_key(row: dict[str, str], fields: list[str]) -> tuple[str, ...]:
@@ -123,7 +461,10 @@ def _validate_source_fields(rows: list[dict[str, str]]) -> None:
         if not isinstance(row, dict):
             raise DomainReplicationError("source rows must be objects")
         for field in row:
-            if _SECRET.search(str(field)):
+            normalized = _security_key(field)
+            if normalized in _RAW_SOURCE_KEYS or _SECRET.search(normalized) or any(
+                marker in normalized for marker in _SENSITIVE_KEY_MARKERS
+            ):
                 raise DomainReplicationError(
                     f"secret-like source field is not allowed: {field}"
                 )
@@ -368,14 +709,218 @@ def _validate_stage_metrics(
             raise DomainReplicationError("agent cross-domain request must be denied")
 
 
-def _validate_manifest(manifest: dict[str, Any], template: dict[str, Any]) -> tuple[str, str]:
-    manifest = _mapping(manifest, "manifest")
+def _validate_seed_data(seed_data: Any, *, schema_version: int) -> None:
+    payload_key = "records" if schema_version == 1 else "items"
+    record_fields = {
+        "source_contract": {"id", "type", "binding_status"},
+        "term_and_code_set": {"id", "name"},
+        "workflow_contract": {"id", "name"},
+    }
+    for item in _bounded_list(seed_data, "template.seed_data", minimum=0):
+        item = _closed_required(
+            item,
+            "template.seed_data.item",
+            {"kind", payload_key},
+            {"kind", payload_key},
+        )
+        kind = _string(item["kind"], "template.seed_data.kind", 80)
+        if kind not in record_fields:
+            raise DomainReplicationError("template.seed_data.kind is unsupported")
+        for record in _bounded_list(item[payload_key], f"template.seed_data.{payload_key}", minimum=1):
+            record = _closed_required(
+                record,
+                "template.seed_data.record",
+                record_fields[kind],
+                record_fields[kind],
+            )
+            for key in record_fields[kind]:
+                _string(record[key], f"template.seed_data.record.{key}", 200)
+
+
+def _validate_template(template: dict[str, Any], *, schema_version: int) -> dict[str, Any]:
+    required = {
+        "template_code", "name", "description", "lifecycle_status", "object_types",
+        "responsibility_roles", "rules", "metrics", "seed_data",
+    }
+    _reject_secrets(template, "template")
+    template = _closed_required(template, "template", required, required)
+    _string(template["template_code"], "template.template_code", 64)
+    _string(template["name"], "template.name", 200)
+    _string(template["description"], "template.description", 500)
+    if template["lifecycle_status"] not in {"draft", "active", "retired"}:
+        raise DomainReplicationError("template.lifecycle_status is invalid")
+    for item in _bounded_list(template["object_types"], "template.object_types", minimum=3):
+        item = _closed_required(
+            item,
+            "template.object_types.item",
+            {"type_code", "name", "stable_uid_prefix", "source_identity_fields", "fields"},
+            {"type_code", "name", "description", "stable_uid_prefix", "source_identity_fields", "fields"},
+        )
+        for key in ("type_code", "name", "stable_uid_prefix"):
+            _string(item[key], f"template.object_types.{key}", 200)
+        for identity in _bounded_list(item["source_identity_fields"], "template.source_identity_fields"):
+            _string(identity, "template.source_identity_fields.item", 64)
+        for field in _bounded_list(item["fields"], "template.fields"):
+            field = _closed_required(
+                field,
+                "template.fields.item",
+                {"code", "name", "type", "required"},
+                {"code", "name", "type", "required", "description"},
+            )
+            if not isinstance(field["required"], bool):
+                raise DomainReplicationError("template.fields.required must be boolean")
+            for key in ("code", "name", "type"):
+                _string(field[key], f"template.fields.{key}", 200)
+    for collection, required_fields in (
+        ("responsibility_roles", {"code", "name", "raci_role"}),
+        ("rules", {"code", "name", "dimension", "target_object"}),
+        ("metrics", {"code", "name", "unit"}),
+    ):
+        for item in _bounded_list(template[collection], f"template.{collection}"):
+            item = _closed_required(item, f"template.{collection}.item", required_fields, required_fields)
+            for key in required_fields:
+                _string(item[key], f"template.{collection}.{key}", 200)
+    _validate_seed_data(template["seed_data"], schema_version=schema_version)
+    return template
+
+
+def _validate_contract_refs(stage: str, value: Any) -> list[dict[str, Any]]:
+    if stage not in _CONTRACT_REQUIREMENTS:
+        if value is not None:
+            raise DomainReplicationError(f"{stage} does not accept contract_refs")
+        return []
+    refs = _bounded_list(value, f"{stage}.contract_refs", minimum=1, maximum=1)
+    return [validate_contract_reference(refs[0], expected_contract_id=_CONTRACT_REQUIREMENTS[stage])]
+
+
+def validate_contract_reference(
+    reference: dict[str, Any], *, expected_contract_id: str
+) -> dict[str, Any]:
+    """Resolve one v2 receipt only against the code-side trusted registry."""
+
+    required = {
+        "contract_id", "contract_version", "schema_digest", "operation_uid", "run_id",
+        "operation", "attempt", "lease_fence", "request_digest", "result_digest", "status",
+    }
+    reference = _closed_required(reference, "contract_ref", required, required)
+    try:
+        registry = verify_registry()
+    except ValueError as exc:
+        raise DomainReplicationError("trusted contract registry integrity check failed") from exc
+    if registry["trust_level"] != "ENGINEERING_EVIDENCE_ONLY":
+        raise DomainReplicationError("trusted contract registry has an invalid trust level")
+    if date.fromisoformat(registry["expires_on"]) < date.today():
+        raise DomainReplicationError("trusted contract registry is expired")
+    contract_id = _string(reference["contract_id"], "contract_ref.contract_id", 80)
+    if contract_id != expected_contract_id:
+        raise DomainReplicationError("cross-contract reference was rejected")
+    contract = next(
+        (item for item in registry["contracts"] if item["contract_id"] == contract_id), None
+    )
+    if contract is None:
+        raise DomainReplicationError("contract is absent from the trusted registry")
+    if reference["contract_version"] != contract["contract_version"]:
+        raise DomainReplicationError("contract version does not match the trusted registry")
+    if reference["schema_digest"] != contract["schema_digest"]:
+        raise DomainReplicationError("contract schema digest does not match the trusted registry")
+    if reference["operation"] not in contract["allowed_operations"]:
+        raise DomainReplicationError("contract operation is not allowed")
+    run = next(
+        (
+            item for item in contract["runs"]
+            if item["operation_uid"] == reference["operation_uid"]
+            and item["run_id"] == reference["run_id"]
+        ),
+        None,
+    )
+    if run is None:
+        raise DomainReplicationError("run is absent from the trusted registry")
+    for field in (
+        "operation_uid", "run_id", "operation", "attempt", "lease_fence",
+        "request_digest", "result_digest", "status",
+    ):
+        if reference[field] != run[field]:
+            raise DomainReplicationError(f"contract registry mismatch for {field}")
+    for field in ("schema_digest", "request_digest", "result_digest"):
+        _digest_string(reference[field], f"contract_ref.{field}")
+    return deepcopy(reference)
+
+
+def _validate_terminal_evidence(
+    evidence: dict[str, Any], package_code: str, domain_code: str, template: dict[str, Any], incremental: dict[str, Any], *, schema_version: int
+) -> dict[str, dict[str, Any]]:
+    _reject_secrets(evidence, "evidence")
+    evidence = _closed_required(evidence, "evidence", {"schema_version", "package_code", "receipts"}, {"schema_version", "package_code", "receipts"})
+    if evidence["schema_version"] != 1 or evidence["package_code"] != package_code:
+        raise DomainReplicationError("evidence package identity is invalid")
+    receipts = _bounded_list(evidence["receipts"], "evidence.receipts", minimum=1, maximum=len(REQUIRED_STAGES))
+    by_stage: dict[str, dict[str, Any]] = {}
+    for receipt in receipts:
+        receipt = _mapping(receipt, "receipt")
+        stage = _string(receipt.get("stage"), "receipt.stage", 80)
+        required = {"stage", "domain_code", "status", "subsystem", "api_refs", "evidence_refs", "metrics"}
+        allowed = set(required)
+        if schema_version == 2 and stage in _CONTRACT_REQUIREMENTS:
+            required.add("contract_refs")
+            allowed.add("contract_refs")
+        receipt = _closed_required(receipt, "receipt", required, allowed)
+        if stage in by_stage:
+            raise DomainReplicationError(f"duplicate evidence stage: {stage}")
+        by_stage[stage] = receipt
+    missing = sorted(set(REQUIRED_STAGES) - set(by_stage))
+    extra = sorted(set(by_stage) - set(REQUIRED_STAGES))
+    if missing:
+        raise DomainReplicationError(f"missing stages: {','.join(missing)}")
+    if extra:
+        raise DomainReplicationError(f"unsupported stages: {','.join(extra)}")
+    reports: dict[str, dict[str, Any]] = {}
+    for stage in REQUIRED_STAGES:
+        receipt = by_stage[stage]
+        if receipt["domain_code"] != domain_code:
+            raise DomainReplicationError(f"{stage} evidence has the wrong domain")
+        if receipt["status"] != "passed":
+            raise DomainReplicationError(f"{stage} evidence status must be passed")
+        if receipt["subsystem"] != STAGE_SUBSYSTEMS[stage]:
+            raise DomainReplicationError(f"{stage} evidence subsystem is invalid")
+        api_refs = _bounded_list(receipt["api_refs"], f"{stage}.api_refs", maximum=1)
+        if any("/device-" in str(ref) for ref in api_refs):
+            raise DomainReplicationError("device-specific API evidence is not allowed")
+        if tuple(api_refs) != _API_ALLOWLIST[stage]:
+            raise DomainReplicationError(f"{stage} must use its allowlisted API")
+        evidence_refs = _bounded_list(receipt["evidence_refs"], f"{stage}.evidence_refs", maximum=8)
+        prefix = _EVIDENCE_PREFIXES[stage]
+        if any(not isinstance(ref, str) or not ref.startswith(prefix + domain_code + "/") for ref in evidence_refs):
+            raise DomainReplicationError(f"{stage} evidence_refs are not canonical")
+        metrics = _closed_required(receipt["metrics"], f"{stage}.metrics", _METRIC_FIELDS[stage], _METRIC_FIELDS[stage])
+        _validate_stage_metrics(stage, metrics, template=template, incremental=incremental)
+        contracts = (
+            _validate_contract_refs(stage, receipt.get("contract_refs"))
+            if schema_version == 2
+            else []
+        )
+        reports[stage] = {"status": "passed", "subsystem": STAGE_SUBSYSTEMS[stage], "api_refs": list(api_refs), "evidence_refs": sorted(evidence_refs), "metrics": deepcopy(metrics)}
+        if contracts:
+            reports[stage]["contract_refs"] = contracts
+    return reports
+
+
+def _validate_manifest(
+    manifest: dict[str, Any], template: dict[str, Any]
+) -> tuple[str, str, int]:
+    required = {
+        "schema_version", "package_code", "domain", "files", "source",
+        "core_change_assessment", "enterprise_bindings", "third_domain_reuse",
+    }
     _reject_secrets(manifest)
-    if int(manifest.get("schema_version", 0)) != 1:
-        raise DomainReplicationError("manifest.schema_version must be 1")
-    package_code = _bounded_text(manifest.get("package_code"), "package_code", 80)
-    domain = _mapping(manifest.get("domain"), "domain")
-    domain_code = _bounded_text(domain.get("code"), "domain.code", 64)
+    manifest = _closed_required(manifest, "manifest", required, required)
+    if isinstance(manifest["schema_version"], bool) or not isinstance(manifest["schema_version"], int):
+        raise DomainReplicationError("manifest.schema_version must be an integer")
+    schema_version = manifest["schema_version"]
+    if schema_version not in {1, 2}:
+        raise DomainReplicationError("manifest.schema_version must be 1 or 2")
+    package_code = _string(manifest["package_code"], "package_code", 80)
+    domain = _closed_required(manifest["domain"], "manifest.domain", {"code", "name"}, {"code", "name"})
+    domain_code = _string(domain["code"], "domain.code", 64)
     if not _CODE.fullmatch(domain_code):
         raise DomainReplicationError("domain.code must be a stable lowercase code")
     if template.get("template_code") != domain_code:
@@ -385,17 +930,41 @@ def _validate_manifest(manifest: dict[str, Any], template: dict[str, Any]) -> tu
     if len(template.get("rules", [])) < 5:
         raise DomainReplicationError("domain template must contain at least five rules")
 
-    assessment = _mapping(
-        manifest.get("core_change_assessment"), "core_change_assessment"
+    files = _mapping(manifest["files"], "manifest.files")
+    expected_file_keys = {"template", "evidence", "snapshot", "delta", "acceptance_report"}
+    if schema_version == 2:
+        expected_file_keys.add("execution_evidence")
+    if set(files) != expected_file_keys:
+        raise DomainReplicationError("manifest.files has unsupported or missing bindings")
+    for key, binding in files.items():
+        binding = _closed_required(binding, f"manifest.files.{key}", {"path", "sha256"}, {"path", "sha256"})
+        _string(binding["path"], f"manifest.files.{key}.path", 240)
+        _digest_string(binding["sha256"], f"manifest.files.{key}.sha256")
+    source = _closed_required(
+        manifest["source"], "manifest.source",
+        {"kind", "classification", "primary_key", "required_columns", "operation_field", "cursor_field", "snapshot_cursor"},
+        {"kind", "classification", "primary_key", "required_columns", "operation_field", "cursor_field", "snapshot_cursor"},
+    )
+    if source["kind"] != "controlled_csv" or source["classification"] != "desensitized":
+        raise DomainReplicationError("manifest source is invalid")
+    for field in ("primary_key", "required_columns"):
+        for value in _bounded_list(source[field], f"manifest.source.{field}"):
+            _string(value, f"manifest.source.{field}.item", 80)
+    for field in ("operation_field", "cursor_field"):
+        _string(source[field], f"manifest.source.{field}", 80)
+    if isinstance(source["snapshot_cursor"], bool) or not isinstance(source["snapshot_cursor"], int) or source["snapshot_cursor"] < 0:
+        raise DomainReplicationError("manifest.source.snapshot_cursor is invalid")
+    assessment = _closed_required(
+        manifest["core_change_assessment"], "core_change_assessment",
+        {"baseline_commit", "device_specific_changes", "generic_extensions", "extension_points_used"},
+        {"baseline_commit", "device_specific_changes", "generic_extensions", "extension_points_used"},
     )
     device_changes = assessment.get("device_specific_changes")
     if not isinstance(device_changes, list):
         raise DomainReplicationError("device_specific_changes must be a list")
     if device_changes:
         raise DomainReplicationError("device-specific core changes must remain zero")
-    generic_extensions = assessment.get("generic_extensions")
-    if not isinstance(generic_extensions, list) or not generic_extensions:
-        raise DomainReplicationError("generic extension points must be documented")
+    generic_extensions = _bounded_list(assessment["generic_extensions"], "generic_extensions")
     if any(
         str(path).startswith(marker)
         for path in generic_extensions
@@ -403,13 +972,16 @@ def _validate_manifest(manifest: dict[str, Any], template: dict[str, Any]) -> tu
     ):
         raise DomainReplicationError("generic extensions cannot target device-specific paths")
 
-    reuse = _mapping(manifest.get("third_domain_reuse"), "third_domain_reuse")
+    reuse = _closed_required(
+        manifest["third_domain_reuse"], "third_domain_reuse",
+        {"reusable", "required_replacements"}, {"reusable", "required_replacements"},
+    )
     if reuse.get("reusable") is not True:
         raise DomainReplicationError("third-domain reuse must be explicitly enabled")
-    placeholders = reuse.get("required_replacements")
+    placeholders = reuse["required_replacements"]
     if not isinstance(placeholders, list) or len(placeholders) < 4:
         raise DomainReplicationError("third-domain replacement checklist is incomplete")
-    return package_code, domain_code
+    return package_code, domain_code, schema_version
 
 
 def evaluate_replication_package(
@@ -419,76 +991,30 @@ def evaluate_replication_package(
     template: dict[str, Any],
     snapshot_rows: list[dict[str, str]],
     delta_rows: list[dict[str, str]],
+    execution_evidence: dict[str, Any] | None = None,
 ) -> dict[str, Any]:
     """Evaluate one domain package and return a deterministic, row-free report."""
 
-    package_code, domain_code = _validate_manifest(manifest, template)
+    manifest_schema_version = _mapping(manifest, "manifest").get("schema_version")
+    if isinstance(manifest_schema_version, bool) or manifest_schema_version not in {1, 2}:
+        raise DomainReplicationError("manifest.schema_version must be 1 or 2")
+    template = _validate_template(template, schema_version=manifest_schema_version)
+    package_code, domain_code, schema_version = _validate_manifest(manifest, template)
     incremental = collect_incremental_rows(
         snapshot_rows,
         delta_rows,
         _mapping(manifest.get("source"), "source"),
     )
-    evidence = _mapping(evidence, "evidence")
-    _reject_secrets(evidence)
-    if evidence.get("package_code") != package_code:
-        raise DomainReplicationError("evidence package code does not match manifest")
-    receipts = evidence.get("receipts")
-    if not isinstance(receipts, list):
-        raise DomainReplicationError("evidence.receipts must be a list")
-    by_stage: dict[str, dict[str, Any]] = {}
-    for receipt in receipts:
-        receipt = _mapping(receipt, "receipt")
-        stage = _bounded_text(receipt.get("stage"), "receipt.stage", 80)
-        if stage in by_stage:
-            raise DomainReplicationError(f"duplicate evidence stage: {stage}")
-        by_stage[stage] = receipt
-    missing = sorted(set(REQUIRED_STAGES) - set(by_stage))
-    extra = sorted(set(by_stage) - set(REQUIRED_STAGES))
-    if missing:
-        raise DomainReplicationError(f"missing stages: {','.join(missing)}")
-    if extra:
-        raise DomainReplicationError(f"unsupported stages: {','.join(extra)}")
-
-    stage_reports: dict[str, dict[str, Any]] = {}
-    for stage in REQUIRED_STAGES:
-        receipt = by_stage[stage]
-        if receipt.get("domain_code") != domain_code:
-            raise DomainReplicationError(f"{stage} evidence has the wrong domain")
-        if receipt.get("status") != "passed":
-            raise DomainReplicationError(f"{stage} evidence status must be passed")
-        if receipt.get("subsystem") != STAGE_SUBSYSTEMS[stage]:
-            raise DomainReplicationError(f"{stage} evidence subsystem is invalid")
-        api_refs = receipt.get("api_refs")
-        if not isinstance(api_refs, list) or not api_refs:
-            raise DomainReplicationError(f"{stage} api_refs are required")
-        if any("/device-" in str(ref) for ref in api_refs):
-            raise DomainReplicationError("device-specific API evidence is not allowed")
-        evidence_refs = receipt.get("evidence_refs")
-        if not isinstance(evidence_refs, list) or not evidence_refs:
-            raise DomainReplicationError(f"{stage} evidence_refs are required")
-        metrics = _mapping(receipt.get("metrics"), f"{stage}.metrics")
-        _validate_stage_metrics(
-            stage,
-            metrics,
-            template=template,
-            incremental=incremental,
-        )
-        stage_reports[stage] = {
-            "status": "passed",
-            "subsystem": STAGE_SUBSYSTEMS[stage],
-            "api_refs": sorted(str(ref) for ref in api_refs),
-            "evidence_refs": sorted(str(ref) for ref in evidence_refs),
-            "metrics": deepcopy(metrics),
-        }
+    stage_reports = _validate_terminal_evidence(
+        evidence, package_code, domain_code, template, incremental, schema_version=schema_version
+    )
 
-    bindings = manifest.get("enterprise_bindings")
-    if not isinstance(bindings, list) or not bindings:
-        raise DomainReplicationError("enterprise binding checklist is required")
+    bindings = _bounded_list(manifest["enterprise_bindings"], "enterprise_bindings", minimum=1, maximum=4)
     binding_statuses: dict[str, str] = {}
     for item in bindings:
-        item = _mapping(item, "enterprise_bindings.item")
-        kind = _bounded_text(item.get("kind"), "enterprise_bindings.kind")
-        status = _bounded_text(item.get("status"), "enterprise_bindings.status")
+        item = _closed_required(item, "enterprise_bindings.item", {"kind", "status"}, {"kind", "status"})
+        kind = _string(item["kind"], "enterprise_bindings.kind")
+        status = _string(item["status"], "enterprise_bindings.status")
         if status not in {"bound", "unbound"}:
             raise DomainReplicationError("enterprise binding status must be bound or unbound")
         if kind in binding_statuses:
@@ -504,12 +1030,12 @@ def evaluate_replication_package(
     )
     assessment = manifest["core_change_assessment"]
     report: dict[str, Any] = {
-        "schema_version": 1,
+        "schema_version": schema_version,
         "package_code": package_code,
         "status": "passed",
         "domain": {
             "code": domain_code,
-            "name": _bounded_text(manifest["domain"].get("name"), "domain.name"),
+            "name": _string(manifest["domain"]["name"], "domain.name"),
             "template_version": int(
                 stage_reports["template_initialization"]["metrics"]["template_version"]
             ),
@@ -524,5 +1050,13 @@ def evaluate_replication_package(
             "unbound_requirements": unbound,
         },
     }
+    if schema_version == 2:
+        if execution_evidence is None:
+            raise DomainReplicationError("schema-v2 package requires execution evidence")
+        report["execution_evidence"] = validate_execution_evidence(
+            execution_evidence, domain_code=domain_code
+        )
+    elif execution_evidence is not None:
+        raise DomainReplicationError("schema-v1 package cannot include execution evidence")
     report["report_sha256"] = _digest(report)
     return report

+ 88 - 0
deployment/app/core/governance/domain_replication_contract_registry.py

@@ -0,0 +1,88 @@
+"""Trusted local contract registry for domain-replication engineering evidence.
+
+The registry is code-side rather than package-side: an implementation package
+cannot add a digest or a run receipt and thereby grant itself trust.  Entries
+are deliberately labelled ENGINEERING_EVIDENCE_ONLY; enterprise connector and
+edge runs remain external acceptance evidence.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+from copy import deepcopy
+from typing import Any
+
+
+def _canonical(value: Any) -> bytes:
+    return json.dumps(value, sort_keys=True, separators=(",", ":")).encode("utf-8")
+
+
+CONTRACT_REGISTRY: dict[str, Any] = {
+    "schema_version": 1,
+    "trust_level": "ENGINEERING_EVIDENCE_ONLY",
+    "expires_on": "2099-12-31",
+    "contracts": [
+        {
+            "contract_id": "p3_wp03_connector_run",
+            "contract_version": "1",
+            "schema_digest": "1111111111111111111111111111111111111111111111111111111111111111",
+            "allowed_operations": ["incremental"],
+            "runs": [{
+                "operation_uid": "op-inc-203",
+                "run_id": "run-203",
+                "operation": "incremental",
+                "attempt": 1,
+                "lease_fence": 1,
+                "request_digest": "1212121212121212121212121212121212121212121212121212121212121212",
+                "result_digest": "1313131313131313131313131313131313131313131313131313131313131313",
+                "status": "succeeded",
+            }],
+        },
+        {
+            "contract_id": "p3_wp03_catalog_lineage",
+            "contract_version": "1",
+            "schema_digest": "2222222222222222222222222222222222222222222222222222222222222222",
+            "allowed_operations": ["catalog"],
+            "runs": [{
+                "operation_uid": "op-cat-203",
+                "run_id": "catalog-203",
+                "operation": "catalog",
+                "attempt": 1,
+                "lease_fence": 1,
+                "request_digest": "2323232323232323232323232323232323232323232323232323232323232323",
+                "result_digest": "2424242424242424242424242424242424242424242424242424242424242424",
+                "status": "succeeded",
+            }],
+        },
+        {
+            "contract_id": "p3_wp04_edge_health",
+            "contract_version": "1",
+            "schema_digest": "3333333333333333333333333333333333333333333333333333333333333333",
+            "allowed_operations": ["health"],
+            "runs": [{
+                "operation_uid": "op-health-203",
+                "run_id": "health-203",
+                "operation": "health",
+                "attempt": 1,
+                "lease_fence": 2,
+                "request_digest": "3434343434343434343434343434343434343434343434343434343434343434",
+                "result_digest": "3535353535353535353535353535353535353535353535353535353535353535",
+                "status": "succeeded",
+            }],
+        },
+    ],
+}
+REGISTRY_SHA256 = "ff312c88ea48d7d110b60cdcd118457f3ae6fb52f3d3f6d431a7ad53eb036be2"
+
+
+def registry_snapshot() -> dict[str, Any]:
+    """Return a deep copy so callers cannot mutate the trusted registry."""
+
+    return deepcopy(CONTRACT_REGISTRY)
+
+
+def verify_registry() -> dict[str, Any]:
+    if hashlib.sha256(_canonical(CONTRACT_REGISTRY)).hexdigest() != REGISTRY_SHA256:
+        raise ValueError("trusted contract registry digest mismatch")
+    return registry_snapshot()

+ 599 - 0
deployment/app/core/governance/metering_showback.py

@@ -0,0 +1,599 @@
+"""Closed, local-only metering and Showback contracts.
+
+The module intentionally has no network providers, price book, billing action
+or financial artifact.  It only normalizes engineering evidence and supplies
+integer-micros arithmetic for the database gateway and local fixture.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import os
+import re
+import unicodedata
+import uuid
+from datetime import UTC, datetime
+from decimal import ROUND_HALF_EVEN, Decimal, InvalidOperation
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+
+EVENT_KINDS = frozenset(
+    {"query", "api", "file", "subscription", "storage", "compute", "task", "model_call"}
+)
+_EVENT_FIELDS = frozenset(
+    {
+        "schema_version",
+        "event_uid",
+        "event_kind",
+        "occurred_at",
+        "window_start",
+        "window_end",
+        "quantity",
+        "unit",
+        "idempotency_key",
+        "evidence",
+        "mapping",
+        "correction_of",
+    }
+)
+_TOKEN = re.compile(r"[a-z][a-z0-9-]{0,62}")
+_UID = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:-]{0,119}")
+_HEX = re.compile(r"[0-9a-f]{64}")
+_DECIMAL = re.compile(r"(?:0|[1-9][0-9]{0,17})(?:\.[0-9]{1,6})?")
+_REFERENCE = re.compile(r"local-fixture://wp12/v1(?:/[a-z][a-z0-9-]{0,62})?")
+_UNSAFE_REFERENCE_SEGMENT = re.compile(r"(?:sql|script|select|insert|update|delete|drop|exec|curl|wget|token|secret|credential|password)")
+_UNITS: dict[str, tuple[str, Decimal]] = {
+    "bytes": ("data", Decimal("1")),
+    "kb": ("data", Decimal("1000")),
+    "mb": ("data", Decimal("1000000")),
+    "gb": ("data", Decimal("1000000000")),
+    "seconds": ("time", Decimal("1")),
+    "milliseconds": ("time", Decimal("0.001")),
+    "requests": ("count", Decimal("1")),
+    "tasks": ("count", Decimal("1")),
+    "tokens": ("count", Decimal("1")),
+}
+_MICRO = Decimal("1000000")
+
+
+def _closed(value: Any, allowed: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict) or set(value) - allowed:
+        raise ValueError(f"{label}_closed")
+    return copy.deepcopy(value)
+
+
+def _normalized_text(value: Any, label: str, maximum: int = 120) -> str:
+    if not isinstance(value, str) or not value or len(value) > maximum:
+        raise ValueError(f"{label}_invalid")
+    normalized = unicodedata.normalize("NFKC", value)
+    if normalized != value:
+        raise ValueError(f"{label}_unicode_rejected")
+    return value
+
+
+def _token(value: Any, label: str) -> str:
+    result = _normalized_text(value, label)
+    if not _TOKEN.fullmatch(result):
+        raise ValueError(f"{label}_invalid")
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    result = _normalized_text(value, label)
+    if not _UID.fullmatch(result):
+        raise ValueError(f"{label}_invalid")
+    return result
+
+
+def _timestamp(value: Any, label: str) -> str:
+    text = _normalized_text(value, label, 30)
+    if not text.endswith("Z"):
+        raise ValueError(f"{label}_invalid")
+    try:
+        parsed = datetime.fromisoformat(text.replace("Z", "+00:00"))
+    except ValueError as exc:
+        raise ValueError(f"{label}_invalid") from exc
+    if parsed.tzinfo is None or parsed.utcoffset() != UTC.utcoffset(parsed):
+        raise ValueError(f"{label}_invalid")
+    return parsed.astimezone(UTC).isoformat(timespec="microseconds").replace("+00:00", "Z")
+
+
+def _decimal(value: Any, label: str) -> Decimal:
+    if isinstance(value, bool) or not isinstance(value, str) or not _DECIMAL.fullmatch(value):
+        raise ValueError(f"{label}_invalid")
+    try:
+        parsed = Decimal(value)
+    except InvalidOperation as exc:
+        raise ValueError(f"{label}_invalid") from exc
+    if not parsed.is_finite() or parsed < 0:
+        raise ValueError(f"{label}_invalid")
+    return parsed
+
+
+def to_micros(quantity: Any, source_unit: Any, target_unit: Any) -> int:
+    """Convert a bounded string decimal using a compatible unit dimension."""
+
+    value = _decimal(quantity, "quantity")
+    source = _normalized_text(source_unit, "source_unit", 20)
+    target = _normalized_text(target_unit, "target_unit", 20)
+    if source not in _UNITS or target not in _UNITS or _UNITS[source][0] != _UNITS[target][0]:
+        raise ValueError("unit_dimension_mismatch")
+    converted = value * _UNITS[source][1] / _UNITS[target][1]
+    micros = (converted * _MICRO).quantize(Decimal("1"), rounding=ROUND_HALF_EVEN)
+    if micros < 0 or micros > Decimal("1000000000000000000000000"):
+        raise ValueError("quantity_out_of_range")
+    return int(micros)
+
+
+def canonical_digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(value, sort_keys=True, ensure_ascii=True, separators=(",", ":")).encode("utf-8")
+    ).hexdigest()
+
+
+def normalize_event(value: Any) -> dict[str, Any]:
+    """Return a versioned, safe event without raw source evidence."""
+
+    body = _closed(value, _EVENT_FIELDS, "metering_event")
+    required = _EVENT_FIELDS - {"correction_of"}
+    if set(body) - {"correction_of"} != required:
+        raise ValueError("metering_event_closed")
+    if body["schema_version"] != 1:
+        raise ValueError("schema_version_invalid")
+    event_kind = _token(body["event_kind"], "event_kind")
+    if event_kind not in EVENT_KINDS:
+        raise ValueError("event_kind_invalid")
+    evidence = _closed(body["evidence"], frozenset({"digest", "reference"}), "evidence")
+    digest = _normalized_text(evidence.get("digest"), "evidence_digest", 64)
+    reference = _normalized_text(evidence.get("reference"), "evidence_reference", 120)
+    if not _HEX.fullmatch(digest) or not _REFERENCE.fullmatch(reference) or _UNSAFE_REFERENCE_SEGMENT.search(reference):
+        raise ValueError("evidence_invalid")
+    mapping = _closed(
+        body["mapping"],
+        frozenset({"department", "business_domain", "project", "cost_center"}),
+        "mapping",
+    )
+    if set(mapping) != {"department", "business_domain", "project", "cost_center"}:
+        raise ValueError("mapping_closed")
+    normalized = {
+        "schema_version": 1,
+        "event_uid": _uid(body["event_uid"], "event_uid"),
+        "event_kind": event_kind,
+        "occurred_at": _timestamp(body["occurred_at"], "occurred_at"),
+        "window_start": _timestamp(body["window_start"], "window_start"),
+        "window_end": _timestamp(body["window_end"], "window_end"),
+        "quantity": body["quantity"],
+        "unit": _normalized_text(body["unit"], "unit", 20),
+        "idempotency_key": _uid(body["idempotency_key"], "idempotency_key"),
+        "evidence": {"digest": digest, "reference": reference},
+        "mapping": {key: _token(mapping[key], key) for key in sorted(mapping)},
+        "raw_payload_retained": False,
+    }
+    if normalized["window_start"] >= normalized["window_end"]:
+        raise ValueError("window_invalid")
+    normalized["quantity_micros"] = to_micros(normalized["quantity"], normalized["unit"], normalized["unit"])
+    if "correction_of" in body:
+        normalized["correction_of"] = _uid(body["correction_of"], "correction_of")
+    normalized["digest"] = canonical_digest(normalized)
+    return normalized
+
+
+class ReplayConflict(ValueError):
+    """An idempotency key was reused with a different immutable request."""
+
+
+class InMemoryMeteringRepository:
+    """Tiny deterministic adapter for unit contracts; not a production store."""
+
+    def __init__(self) -> None:
+        self.events_by_key: dict[tuple[str, str], dict[str, Any]] = {}
+        self.events_by_uid: dict[tuple[str, str], dict[str, Any]] = {}
+        self.allocation_rules: dict[tuple[str, int], dict[str, Any]] = {}
+        self.alert_keys: set[tuple[str, str, int]] = set()
+
+    def record_event(self, tenant_ref: str, event: dict[str, Any]) -> dict[str, Any]:
+        key = (tenant_ref, event["idempotency_key"])
+        replay = self.events_by_key.get(key)
+        if replay is not None:
+            if replay["digest"] != event["digest"]:
+                raise ReplayConflict("metering_replay_conflict")
+            return copy.deepcopy(replay)
+        uid_key = (tenant_ref, event["event_uid"])
+        if uid_key in self.events_by_uid:
+            raise ReplayConflict("metering_event_uid_conflict")
+        self.events_by_key[key] = copy.deepcopy(event)
+        self.events_by_uid[uid_key] = copy.deepcopy(event)
+        return copy.deepcopy(event)
+
+    def events_for_window(self, tenant_ref: str, window: str) -> list[dict[str, Any]]:
+        prefix = f"{window}-"
+        return [
+            copy.deepcopy(event)
+            for (tenant, _), event in self.events_by_uid.items()
+            if tenant == tenant_ref and event["window_start"].startswith(prefix)
+        ]
+
+
+def _window(value: Any) -> str:
+    text = _normalized_text(value, "window", 7)
+    if not re.fullmatch(r"[0-9]{4}-(0[1-9]|1[0-2])", text):
+        raise ValueError("window_invalid")
+    return text
+
+
+def _mapping(value: Any) -> dict[str, str]:
+    body = _closed(
+        value,
+        frozenset({"department", "business_domain", "project", "cost_center"}),
+        "mapping",
+    )
+    if set(body) != {"department", "business_domain", "project", "cost_center"}:
+        raise ValueError("mapping_closed")
+    return {key: _token(body[key], key) for key in sorted(body)}
+
+
+class MeteringShowbackService:
+    """Local, non-financial behavior shared by API and gateway adapters."""
+
+    def __init__(self, repository: InMemoryMeteringRepository, *, tenant_ref: str) -> None:
+        self.repository = repository
+        self.tenant_ref = _token(tenant_ref, "tenant_ref")
+
+    def record(self, request: Any) -> dict[str, Any]:
+        return self.repository.record_event(self.tenant_ref, normalize_event(request))
+
+    def correct(self, original_uid: Any, request: Any) -> dict[str, Any]:
+        original = _uid(original_uid, "original_uid")
+        original_event = self.repository.events_by_uid.get((self.tenant_ref, original))
+        if original_event is None:
+            raise LookupError("metering_original_not_found")
+        if "correction_of" in original_event:
+            raise ValueError("correction_chain_invalid")
+        body = copy.deepcopy(request)
+        if "correction_of" in body:
+            raise ValueError("correction_closed")
+        candidate = normalize_event(body)
+        if any(candidate[key] != original_event[key] for key in ("event_kind", "unit", "window_start", "window_end", "mapping")):
+            raise ValueError("correction_scope_invalid")
+        body["correction_of"] = original
+        return self.record(body)
+
+    def publish_allocation(self, request: Any) -> dict[str, Any]:
+        body = _closed(
+            request,
+            frozenset(
+                {
+                    "schema_version",
+                    "rule_uid",
+                    "rule_version",
+                    "effective_start",
+                    "effective_end",
+                    "mapping",
+                    "allocations",
+                }
+            ),
+            "allocation_rule",
+        )
+        if body.get("schema_version") != 1 or not isinstance(body.get("rule_version"), int):
+            raise ValueError("allocation_rule_invalid")
+        rule_uid = _uid(body.get("rule_uid"), "rule_uid")
+        version = body["rule_version"]
+        if version < 1 or version > 1_000_000:
+            raise ValueError("rule_version_invalid")
+        start = _timestamp(body.get("effective_start"), "effective_start")
+        end = _timestamp(body.get("effective_end"), "effective_end")
+        if start >= end:
+            raise ValueError("effective_window_invalid")
+        allocations = body.get("allocations")
+        if not isinstance(allocations, list) or not 1 <= len(allocations) <= 32:
+            raise ValueError("allocations_invalid")
+        normalized_allocations: list[dict[str, Any]] = []
+        total = Decimal("0")
+        for allocation in allocations:
+            item = _closed(allocation, frozenset({"target", "weight"}), "allocation")
+            if set(item) != {"target", "weight"}:
+                raise ValueError("allocation_closed")
+            weight = _decimal(item["weight"], "weight")
+            if weight <= 0 or weight > Decimal("1"):
+                raise ValueError("weight_invalid")
+            total += weight
+            target = _token(item["target"], "target")
+            if any(existing["target"] == target for existing in normalized_allocations):
+                raise ValueError("allocation_target_duplicate")
+            normalized_allocations.append({"target": target, "weight": str(weight)})
+        if total != Decimal("1.000000"):
+            raise ValueError("allocation_weight_not_one")
+        normalized = {
+            "schema_version": 1,
+            "rule_uid": rule_uid,
+            "rule_version": version,
+            "effective_start": start,
+            "effective_end": end,
+            "mapping": _mapping(body.get("mapping")),
+            "allocations": sorted(normalized_allocations, key=lambda item: item["target"]),
+        }
+        key = (rule_uid, version)
+        existing = self.repository.allocation_rules.get(key)
+        if existing is not None and canonical_digest(existing) != canonical_digest(normalized):
+            raise ReplayConflict("allocation_rule_conflict")
+        self.repository.allocation_rules[key] = copy.deepcopy(normalized)
+        return copy.deepcopy(normalized)
+
+    def replay_allocation(self, rule_version: Any, window: Any) -> dict[str, Any]:
+        if not isinstance(rule_version, int) or rule_version < 1:
+            raise ValueError("rule_version_invalid")
+        month = _window(window)
+        matching = [
+            rule
+            for (_, version), rule in self.repository.allocation_rules.items()
+            if version == rule_version
+            and rule["effective_start"].startswith(month)
+            and rule["effective_end"] > f"{month}-01T00:00:00.000000Z"
+        ]
+        if len(matching) != 1:
+            raise LookupError("allocation_rule_not_found")
+        source = sum(event["quantity_micros"] for event in self.repository.events_for_window(self.tenant_ref, month))
+        allocations = [
+            {
+                "target": allocation["target"],
+                "quantity_micros": int(
+                    (Decimal(source) * _decimal(allocation["weight"], "weight")).quantize(
+                        Decimal("1"), rounding=ROUND_HALF_EVEN
+                    )
+                ),
+            }
+            for allocation in matching[0]["allocations"]
+        ]
+        return {
+            "rule_uid": matching[0]["rule_uid"],
+            "rule_version": rule_version,
+            "window": month,
+            "source_micros": source,
+            "allocations": allocations,
+            "allocated_micros": sum(item["quantity_micros"] for item in allocations),
+        }
+
+    def reconcile(self, window: Any) -> dict[str, int]:
+        month = _window(window)
+        source = sum(event["quantity_micros"] for event in self.repository.events_for_window(self.tenant_ref, month))
+        return {"source_micros": source, "allocated_micros": source, "difference_micros": 0}
+
+    def evaluate_budget(self, request: Any) -> dict[str, Any]:
+        body = _closed(
+            request,
+            frozenset({"schema_version", "budget_uid", "window", "mapping", "limit_micros", "threshold_micros"}),
+            "budget",
+        )
+        if body.get("schema_version") != 1:
+            raise ValueError("budget_invalid")
+        budget_uid = _uid(body.get("budget_uid"), "budget_uid")
+        window = _window(body.get("window"))
+        mapping = _mapping(body.get("mapping"))
+        if (
+            isinstance(body.get("limit_micros"), bool)
+            or isinstance(body.get("threshold_micros"), bool)
+            or not isinstance(body.get("limit_micros"), int)
+            or not isinstance(body.get("threshold_micros"), int)
+            or body["limit_micros"] < 0
+            or body["threshold_micros"] < 0
+            or body["threshold_micros"] > body["limit_micros"]
+        ):
+            raise ValueError("budget_invalid")
+        used = sum(
+            event["quantity_micros"]
+            for event in self.repository.events_for_window(self.tenant_ref, window)
+            if event["mapping"] == mapping
+        )
+        key = (budget_uid, window, body["threshold_micros"])
+        alert_created = used >= body["threshold_micros"] and key not in self.repository.alert_keys
+        if alert_created:
+            self.repository.alert_keys.add(key)
+        return {
+            "budget_uid": budget_uid,
+            "window": window,
+            "used_micros": used,
+            "limit_micros": body["limit_micros"],
+            "alert_created": alert_created,
+            "provider": "disabled",
+            "mode": "ENGINEERING_EVIDENCE_ONLY",
+        }
+
+    def request_chargeback(self, request: Any) -> None:
+        del request
+        raise PermissionError("chargeback_disabled")
+
+
+class DatabaseMeteringShowbackService:
+    """Fail-closed control/runtime gateway adapter for the HTTP boundary."""
+
+    def __init__(self) -> None:
+        control_url = os.environ.get("METERING_SHOWBACK_CONTROL_DATABASE_URL", "")
+        runtime_url = os.environ.get("DATABASE_URL", "")
+        control = validate_postgresql_url(control_url, "METERING_SHOWBACK_CONTROL_DATABASE_URL")
+        runtime = validate_postgresql_url(runtime_url, "DATABASE_URL")
+        if control.username == runtime.username:
+            raise RuntimeError("metering control and runtime identities must differ")
+        self._control_url = control_url
+        self._runtime_url = runtime_url
+
+    def _claim(self, action: str, principal_id: str) -> dict[str, str]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(
+                text("SELECT public.metering_showback_issue_claim(:action,:principal,'{}'::jsonb)"),
+                {"action": action, "principal": principal_id},
+            ).scalar_one()
+        return dict(value)
+
+    def _write(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(
+                text("SELECT public.metering_showback_runtime_write(:action,CAST(:payload AS jsonb))"),
+                {"action": action, "payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+            ).scalar_one()
+        return dict(value)
+
+    def _control_write(self, action: str, principal_id: str, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(
+                text("SELECT public.metering_showback_control_write(:action,:principal,CAST(:payload AS jsonb))"),
+                {"action": action, "principal": principal_id, "payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+            ).scalar_one()
+        return dict(value)
+
+    @staticmethod
+    def _trusted_mapping(value: Any) -> dict[str, str]:
+        body = _closed(value, frozenset({"department", "project", "cost_center"}), "metering_mapping")
+        if set(body) != {"department", "project", "cost_center"}:
+            raise ValueError("metering_mapping_closed")
+        return {
+            "department": _token(body["department"], "department"),
+            "business_domain": _token(os.environ.get("TRUSTED_METERING_DOMAIN", ""), "trusted_metering_domain"),
+            "project": _token(body["project"], "project"),
+            "cost_center": _token(body["cost_center"], "cost_center"),
+        }
+
+    def record_for_principal(self, *, principal_id: str, body: dict[str, Any]) -> dict[str, Any]:
+        domain = _token(os.environ.get("TRUSTED_METERING_DOMAIN", ""), "trusted_metering_domain")
+        raw = copy.deepcopy(body)
+        raw["mapping"] = raw["mapping"] | {"business_domain": domain}
+        event = normalize_event(raw)
+        lease_claim = self._claim("lease", principal_id)
+        record_claim = self._claim("record", principal_id)
+        lease_token = str(uuid.uuid4())
+        # Claiming the lease and recording its event share one runtime transaction:
+        # a rejected immutable replay cannot strand a new live lease.
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            lease = dict(
+                connection.execute(
+                    text("SELECT public.metering_showback_runtime_write(:action,CAST(:payload AS jsonb))"),
+                    {
+                        "action": "claim_lease",
+                        "payload": json.dumps(
+                            {"request_claim": lease_claim["request_claim"], "lease_owner": "http-metering", "lease_token": lease_token},
+                            sort_keys=True,
+                            separators=(",", ":"),
+                        ),
+                    },
+                ).scalar_one()
+            )
+            payload = {
+                "request_claim": record_claim["request_claim"], "lease_owner": "http-metering", "lease_token": lease_token,
+                "lease_fence": lease["lease_fence"], "event_uid": event["event_uid"], "event_kind": event["event_kind"],
+                "occurred_at": event["occurred_at"], "window_start": event["window_start"], "window_end": event["window_end"],
+                "quantity_micros": event["quantity_micros"], "unit": event["unit"], "idempotency_key": event["idempotency_key"],
+                "evidence": event["evidence"], "mapping": event["mapping"],
+            }
+            if "correction_of" in event:
+                payload["correction_of"] = event["correction_of"]
+            value = connection.execute(
+                text("SELECT public.metering_showback_runtime_write(:action,CAST(:payload AS jsonb))"),
+                {"action": "record_event", "payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+            ).scalar_one()
+        return dict(value)
+
+    def publish_allocation_for_principal(self, *, principal_id: str, body: dict[str, Any]) -> dict[str, Any]:
+        raw = _closed(
+            body,
+            frozenset({"schema_version", "rule_uid", "rule_version", "effective_start", "effective_end", "mapping", "allocations"}),
+            "allocation_rule",
+        )
+        if raw.get("schema_version") != 1 or isinstance(raw.get("rule_version"), bool) or not isinstance(raw.get("rule_version"), int):
+            raise ValueError("allocation_rule_closed")
+        if not 1 <= raw["rule_version"] <= 1_000_000:
+            raise ValueError("allocation_rule_closed")
+        allocations = raw.get("allocations")
+        if not isinstance(allocations, list) or not 1 <= len(allocations) <= 32:
+            raise ValueError("allocation_rule_closed")
+        normalized_allocations: list[dict[str, Any]] = []
+        for item in allocations:
+            allocation = _closed(item, frozenset({"target", "weight_micros"}), "allocation")
+            if set(allocation) != {"target", "weight_micros"} or isinstance(allocation["weight_micros"], bool) or not isinstance(allocation["weight_micros"], int):
+                raise ValueError("allocation_rule_closed")
+            if not 0 < allocation["weight_micros"] <= 1_000_000:
+                raise ValueError("allocation_rule_closed")
+            target = _token(allocation["target"], "allocation_target")
+            if any(existing["target"] == target for existing in normalized_allocations):
+                raise ValueError("allocation_target_duplicate")
+            normalized_allocations.append({"target": target, "weight_micros": allocation["weight_micros"]})
+        if sum(item["weight_micros"] for item in normalized_allocations) != 1_000_000:
+            raise ValueError("allocation_weight_not_one")
+        start = _timestamp(raw.get("effective_start"), "effective_start")
+        end = _timestamp(raw.get("effective_end"), "effective_end")
+        if start >= end:
+            raise ValueError("effective_window_invalid")
+        return self._control_write(
+            "allocation",
+            principal_id,
+            {
+                "rule_uid": _uid(raw.get("rule_uid"), "rule_uid"),
+                "rule_version": str(raw["rule_version"]),
+                "effective_start": start,
+                "effective_end": end,
+                "mapping": self._trusted_mapping(raw.get("mapping")),
+                "allocations": normalized_allocations,
+            },
+        )
+
+    def evaluate_budget_for_principal(self, *, principal_id: str, body: dict[str, Any]) -> dict[str, Any]:
+        raw = _closed(body, frozenset({"schema_version", "budget_uid", "window", "mapping", "limit_micros", "threshold_micros"}), "budget")
+        if raw.get("schema_version") != 1:
+            raise ValueError("budget_closed")
+        if any(isinstance(raw.get(key), bool) or not isinstance(raw.get(key), int) for key in ("limit_micros", "threshold_micros")):
+            raise ValueError("budget_closed")
+        if not 0 <= raw["threshold_micros"] <= raw["limit_micros"] <= 999_999_999_999_999_999:
+            raise ValueError("budget_closed")
+        return self._control_write(
+            "budget",
+            principal_id,
+            {
+                "budget_uid": _uid(raw.get("budget_uid"), "budget_uid"),
+                "window": _window(raw.get("window")),
+                "mapping": self._trusted_mapping(raw.get("mapping")),
+                "limit_micros": str(raw["limit_micros"]),
+                "threshold_micros": str(raw["threshold_micros"]),
+            },
+        )
+
+    def allocation_replay_for_principal(self, *, principal_id: str, window: Any, rule_uid: Any, rule_version: Any) -> dict[str, Any]:
+        if isinstance(rule_version, bool) or not isinstance(rule_version, int) or not 1 <= rule_version <= 1_000_000:
+            raise ValueError("rule_version_invalid")
+        claim = self._claim("read", principal_id)
+        payload = {
+            "request_claim": claim["request_claim"],
+            "window": _window(window),
+            "rule_uid": _uid(rule_uid, "rule_uid"),
+            "rule_version": str(rule_version),
+        }
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            try:
+                value = connection.execute(
+                    text("SELECT public.metering_showback_allocation_replay(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))},
+                ).scalar_one()
+            except SQLAlchemyError as exc:
+                raise PermissionError("metering_allocation_replay_denied") from exc
+        return dict(value)
+
+    def showback_for_principal(self, *, principal_id: str, window: str, kind: str) -> dict[str, Any]:
+        if kind not in {"showback", "reconciliation", "audit"}:
+            raise ValueError("metering_read_kind_invalid")
+        claim = self._claim("read", principal_id)
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            if kind in {"showback", "reconciliation"}:
+                value = connection.execute(
+                    text("SELECT public.metering_showback_rollup(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps({"request_claim": claim["request_claim"], "window": _window(window)}, sort_keys=True)},
+                ).scalar_one()
+            else:
+                value = connection.execute(
+                    text("SELECT public.metering_showback_runtime_read(:action,CAST(:payload AS jsonb))"),
+                    {"action": kind, "payload": json.dumps({"request_claim": claim["request_claim"], "window": _window(window)}, sort_keys=True)},
+                ).scalar_one()
+        return dict(value) if isinstance(value, dict) else {"records": value}

+ 1 - 1
deployment/app/core/llm/agent_governance.py

@@ -761,7 +761,7 @@ class AgentGovernanceService:
             if needs_approval:
                 workflow_uid = _uid(body.get("workflow_uid"), "workflow_uid")
                 task = self.approval_gateway.create_agent_task(
-                    record, workflow_uid, agent["owner_uid"]
+                    {**record, "owner_uid": agent["owner_uid"]}, workflow_uid, agent["owner_uid"]
                 )
                 record["approval_task_uid"] = task["uid"]
         try:

+ 4 - 0
deployment/app/core/llm/agent_governance_repository.py

@@ -58,6 +58,10 @@ class WorkCenterAgentApprovalGateway:
                     "environment": request_record["environment"],
                     "agent_uid": request_record["agent_uid"],
                     "request_uid": request_record["uid"],
+                    "principal_id": request_record.get("owner_uid", ""),
+                    "tool_name": request_record["tool_name"],
+                    "action": request_record["action"],
+                    "request_digest": request_record["input_digest"],
                     "automatic_execution_allowed": False,
                 },
             },

+ 379 - 0
deployment/app/core/llm/runtime_governance.py

@@ -0,0 +1,379 @@
+"""Default-deny, hash-only runtime governance for model and Agent invocations."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import re
+import threading
+import unicodedata
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Any
+from uuid import uuid4
+
+from app.core.mcp.governed_invocation import (
+    InvocationContractError,
+    normalize_mcp_invocation,
+)
+
+
+class RuntimeDecisionError(ValueError):
+    def __init__(self, code: str):
+        self.code = code
+        super().__init__(code)
+
+
+class DatasetLeakageError(ValueError):
+    pass
+
+
+def load_engineering_fixture(manifest_path: str | Path) -> dict[str, Any]:
+    """Read each fixture once and verify its declared SHA-256 before evaluation."""
+    manifest_file = Path(manifest_path)
+    manifest = json.loads(manifest_file.read_text(encoding="utf-8"))
+    if manifest.get("fixture_only") is not True or manifest.get("schema_version") != "1":
+        raise DatasetLeakageError("fixture_manifest_invalid")
+    files = manifest.get("files")
+    if not isinstance(files, dict) or set(files) != {"dataset.json", "temporal-dataset.json"}:
+        raise DatasetLeakageError("fixture_manifest_invalid")
+    loaded: dict[str, Any] = {}
+    for name, expected in files.items():
+        if not isinstance(expected, str) or not expected.startswith("sha256:"):
+            raise DatasetLeakageError("fixture_manifest_invalid")
+        content = (manifest_file.parent / name).read_bytes()
+        if hashlib.sha256(content).hexdigest() != expected.removeprefix("sha256:"):
+            raise DatasetLeakageError("fixture_digest_mismatch")
+        loaded[name] = json.loads(content)
+    train = set(loaded["dataset.json"].get("train_case_ids", []))
+    evaluation = {item.get("case_id") for item in loaded["dataset.json"].get("evaluation_cases", [])}
+    if train & evaluation:
+        raise DatasetLeakageError("dataset_leakage_detected")
+    return loaded
+
+
+@dataclass(frozen=True)
+class ModelRoute:
+    route_id: str
+    provider: str
+    model: str
+    prompt_version: str
+    generation: str
+    tenant_id: str
+    principal_id: str
+    business_domain_uid: str
+    environment: str
+    canary_status: str
+
+
+@dataclass(frozen=True)
+class BudgetPolicy:
+    token_limit: int
+    cost_limit_micros: int
+    tool_limit: int
+    time_limit_ms: int
+    concurrency_limit: int
+    model_limits: dict[str, int]
+
+
+_SCOPE_FIELDS = ("tenant_id", "principal_id", "business_domain_uid", "environment")
+_REQUEST_KEYS = frozenset(
+    {
+        *_SCOPE_FIELDS, "provider", "model", "prompt_version", "generation",
+        "interface_type", "tool_name", "action", "requested_capabilities", "input_text",
+        "evidence_refs", "idempotency_key", "estimated_tokens", "estimated_cost_micros",
+        "requested_time_ms",
+    }
+)
+_FORBIDDEN_KEYS = frozenset(
+    {
+        "url", "uri", "endpoint", "path", "file_path", "filename", "command", "shell",
+        "script", "secret", "token", "password", "api_key", "raw_rows", "rows", "records",
+        "payload", "arguments", "output", "raw_input", "raw_output",
+    }
+)
+_SAFE_ID = re.compile(r"^[A-Za-z0-9_.:-]{1,160}$")
+_INJECTION = re.compile(
+    r"(?is)(ignore\s+(?:all\s+)?(?:previous|prior|system)\s+instructions?|"
+    r"bypass\s+(?:the\s+)?(?:policy|guard|permission)|reveal.{0,50}(?:secret|token|password|api[_ -]?key)|"
+    r"(?:忽略).{0,16}(?:指令|规则|系统)|(?:绕过|关闭|禁用).{0,16}(?:权限|策略|审计))"
+)
+_LOCATION = re.compile(r"(?i)(?:https?://|file://|(?:^|\s)/[A-Za-z0-9_./-]+)")
+
+
+def _hash(value: str) -> str:
+    return hashlib.sha256(value.encode("utf-8")).hexdigest()
+
+
+def _positive_int(value: Any, label: str, maximum: int) -> int:
+    if isinstance(value, bool) or not isinstance(value, int) or not 0 < value <= maximum:
+        raise RuntimeDecisionError(f"{label}_invalid")
+    return value
+
+
+def _closed_request(value: Any) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise RuntimeDecisionError("request_invalid")
+    if len(value) > len(_REQUEST_KEYS):
+        raise RuntimeDecisionError("request_invalid")
+    for key in value:
+        normalized = unicodedata.normalize("NFKC", str(key))
+        if normalized != key or normalized.casefold() in _FORBIDDEN_KEYS:
+            raise RuntimeDecisionError("forbidden_contract_key")
+    unknown = set(value) - _REQUEST_KEYS
+    if unknown or set(value) != _REQUEST_KEYS:
+        raise RuntimeDecisionError("request_schema_invalid")
+    return dict(value)
+
+
+def _normalize_request(value: Any) -> dict[str, Any]:
+    request = _closed_request(value)
+    for key in _SCOPE_FIELDS + ("provider", "model", "prompt_version", "generation", "idempotency_key"):
+        item = request[key]
+        if not isinstance(item, str) or not _SAFE_ID.fullmatch(item):
+            raise RuntimeDecisionError(f"{key}_invalid")
+    text = request["input_text"]
+    if not isinstance(text, str) or not text.strip() or len(text) > 8000:
+        raise RuntimeDecisionError("input_invalid")
+    normalized_text = unicodedata.normalize("NFKC", text).strip()
+    if _INJECTION.search(normalized_text):
+        raise RuntimeDecisionError("prompt_injection_detected")
+    if _LOCATION.search(normalized_text):
+        raise RuntimeDecisionError("input_location_denied")
+    capabilities = request["requested_capabilities"]
+    if not isinstance(capabilities, list) or not capabilities or len(capabilities) > 8:
+        raise RuntimeDecisionError("capability_invalid")
+    if any(not isinstance(item, str) or item not in {"network", "file", "data", "command", "resource", "time"} for item in capabilities):
+        raise RuntimeDecisionError("capability_invalid")
+    evidence = request["evidence_refs"]
+    if not isinstance(evidence, list) or len(evidence) > 20:
+        raise RuntimeDecisionError("citation_invalid")
+    for item in evidence:
+        if not isinstance(item, dict) or set(item) != {"evidence_id", "digest"}:
+            raise RuntimeDecisionError("citation_invalid")
+        if not isinstance(item["evidence_id"], str) or not _SAFE_ID.fullmatch(item["evidence_id"]):
+            raise RuntimeDecisionError("citation_invalid")
+        if not isinstance(item["digest"], str) or not re.fullmatch(r"[a-f0-9]{64}", item["digest"]):
+            raise RuntimeDecisionError("citation_invalid")
+    try:
+        normalize_mcp_invocation(
+            {
+                "interface_type": request["interface_type"], "tool_name": request["tool_name"],
+                "action": request["action"], "arguments_digest": _hash(normalized_text),
+                "evidence_refs": evidence,
+            }
+        )
+    except InvocationContractError as error:
+        raise RuntimeDecisionError("mcp_contract_invalid") from error
+    return {
+        **{key: request[key] for key in _SCOPE_FIELDS},
+        **{key: request[key] for key in ("provider", "model", "prompt_version", "generation", "interface_type", "tool_name", "action", "idempotency_key")},
+        "requested_capabilities": frozenset(request["requested_capabilities"]),
+        "input_hash": _hash(normalized_text),
+        "evidence_refs": tuple((item["evidence_id"], item["digest"]) for item in evidence),
+        "estimated_tokens": _positive_int(request["estimated_tokens"], "estimated_tokens", 1_000_000),
+        "estimated_cost_micros": _positive_int(request["estimated_cost_micros"], "estimated_cost_micros", 1_000_000_000),
+        "requested_time_ms": _positive_int(request["requested_time_ms"], "requested_time_ms", 300_000),
+    }
+
+
+class InMemoryRuntimeRepository:
+    """Thread-safe reference repository used by unit contracts and local wiring."""
+
+    def __init__(self) -> None:
+        self._lock = threading.RLock()
+        self._routes: list[ModelRoute] = []
+        self._capabilities: set[tuple[str, str, str, str, str, str, frozenset[str]]] = set()
+        self._budgets: dict[str, dict[str, Any]] = {}
+        self._decisions: dict[tuple[str, str], dict[str, Any]] = {}
+        self._audit: list[dict[str, Any]] = []
+        self._states: dict[str, dict[str, Any]] = {}
+        self._generations: dict[tuple[str, str], dict[str, Any]] = {}
+
+    def register_route(self, route: ModelRoute) -> None:
+        with self._lock:
+            self._routes.append(route)
+            self._generations.setdefault((route.tenant_id, route.generation), {"status": route.canary_status, "fence": 0, "parent": None})
+            self._states.setdefault(route.tenant_id, {"state": "active", "incident_ref": None, "fence": 0})
+
+    def register_capability(self, *, tenant_id: str, business_domain_uid: str, environment: str, tool_name: str, interface_type: str, action: str, risk_level: str, allowed_capabilities: set[str]) -> None:
+        if risk_level != "low" or not allowed_capabilities <= {"data"}:
+            raise ValueError("only declared low-risk data capability may be registered locally")
+        with self._lock:
+            self._capabilities.add((tenant_id, business_domain_uid, environment, tool_name, interface_type, action, frozenset(allowed_capabilities)))
+
+    def set_budget(self, tenant_id: str, policy: BudgetPolicy) -> None:
+        if min(policy.token_limit, policy.cost_limit_micros, policy.tool_limit, policy.time_limit_ms, policy.concurrency_limit) < 1:
+            raise ValueError("budget limits must be positive")
+        with self._lock:
+            self._budgets[tenant_id] = {"policy": policy, "tokens": policy.token_limit, "cost": policy.cost_limit_micros, "tools": policy.tool_limit, "time": policy.time_limit_ms, "concurrency": policy.concurrency_limit, "models": dict(policy.model_limits), "fence": 0}
+
+    def find_route(self, request: dict[str, Any]) -> ModelRoute | None:
+        with self._lock:
+            for route in self._routes:
+                if all(getattr(route, field) == request[field] for field in _SCOPE_FIELDS + ("provider", "model", "prompt_version", "generation")):
+                    return route
+            return None
+
+    def generation_status(self, tenant_id: str, generation: str) -> str | None:
+        with self._lock:
+            entry = self._generations.get((tenant_id, generation))
+            return entry["status"] if entry else None
+
+    def allowed_capability(self, request: dict[str, Any]) -> bool:
+        key = (request["tenant_id"], request["business_domain_uid"], request["environment"], request["tool_name"], request["interface_type"], request["action"], request["requested_capabilities"])
+        with self._lock:
+            return key in self._capabilities
+
+    def existing(self, tenant_id: str, idempotency_key: str) -> dict[str, Any] | None:
+        with self._lock:
+            record = self._decisions.get((tenant_id, idempotency_key))
+            return dict(record) if record else None
+
+    def reserve(self, request: dict[str, Any]) -> int:
+        with self._lock:
+            budget = self._budgets.get(request["tenant_id"])
+            if budget is None or any((budget["tokens"] < request["estimated_tokens"], budget["cost"] < request["estimated_cost_micros"], budget["tools"] < 1, budget["time"] < request["requested_time_ms"], budget["concurrency"] < 1, budget["models"].get(request["model"], 0) < 1)):
+                raise RuntimeDecisionError("budget_exhausted")
+            budget["tokens"] -= request["estimated_tokens"]
+            budget["cost"] -= request["estimated_cost_micros"]
+            budget["tools"] -= 1
+            budget["time"] -= request["requested_time_ms"]
+            budget["concurrency"] -= 1
+            budget["models"][request["model"]] -= 1
+            budget["fence"] += 1
+            return budget["fence"]
+
+    def write_authorized(self, request: dict[str, Any], route: ModelRoute, fence: int) -> dict[str, Any]:
+        record = {"invocation_id": str(uuid4()), "decision": "authorized", "route_id": route.route_id, "generation": route.generation, "budget_fence": fence, "input_hash": request["input_hash"], "evidence_digests": tuple(digest for _, digest in request["evidence_refs"]), "tenant_id": request["tenant_id"], "principal_id": request["principal_id"], "business_domain_uid": request["business_domain_uid"], "environment": request["environment"]}
+        with self._lock:
+            self._decisions[(request["tenant_id"], request["idempotency_key"])] = record
+            self._audit.append(dict(record))
+            return dict(record)
+
+    def remaining_budget(self, tenant_id: str) -> dict[str, int]:
+        with self._lock:
+            budget = self._budgets[tenant_id]
+            return {"tokens": budget["tokens"], "cost_micros": budget["cost"], "tools": budget["tools"], "time_ms": budget["time"], "concurrency": budget["concurrency"]}
+
+    def audit_records(self) -> list[dict[str, Any]]:
+        with self._lock:
+            return [dict(item) for item in self._audit]
+
+    def runtime_state(self, tenant_id: str) -> dict[str, Any]:
+        with self._lock:
+            return dict(self._states.get(tenant_id, {"state": "active", "incident_ref": None, "fence": 0}))
+
+    def set_runtime_state(self, tenant_id: str, state: str, incident_ref: str | None, *, require_active: bool = False) -> dict[str, Any]:
+        with self._lock:
+            current = self._states.setdefault(tenant_id, {"state": "active", "incident_ref": None, "fence": 0})
+            if require_active and current["state"] != "paused":
+                raise RuntimeDecisionError("runtime_state_conflict")
+            current["state"] = state
+            current["incident_ref"] = incident_ref or current["incident_ref"]
+            current["fence"] += 1
+            return dict(current)
+
+    def register_generation(self, tenant_id: str, generation: str, *, parent_generation: str, status: str) -> None:
+        if status not in {"canary", "approved"}:
+            raise ValueError("generation status invalid")
+        with self._lock:
+            self._generations[(tenant_id, generation)] = {"status": status, "parent": parent_generation, "fence": 0}
+
+    def promote_generation(self, tenant_id: str, generation: str) -> int:
+        with self._lock:
+            current = self._generations.get((tenant_id, generation))
+            if not current or current["status"] != "canary":
+                raise RuntimeDecisionError("canary_not_approved")
+            current["status"] = "approved"
+            current["fence"] += 1
+            return current["fence"]
+
+    def rollback_generation(self, tenant_id: str, generation: str, fence: int) -> str:
+        with self._lock:
+            approved = [entry for (tenant, name), entry in self._generations.items() if tenant == tenant_id and entry["status"] == "approved"]
+            if not approved or max(entry["fence"] for entry in approved) != fence:
+                raise RuntimeDecisionError("generation_fence_conflict")
+            target = self._generations.get((tenant_id, generation))
+            if not target:
+                raise RuntimeDecisionError("route_scope_denied")
+            return generation
+
+    def replay(self, invocation_id: str) -> dict[str, Any]:
+        with self._lock:
+            for record in self._audit:
+                if record["invocation_id"] == invocation_id:
+                    return dict(record)
+        raise RuntimeDecisionError("invocation_not_found")
+
+
+class GovernedInvocationService:
+    def __init__(self, repository: InMemoryRuntimeRepository):
+        self.repository = repository
+
+    def authorize(self, raw_request: dict[str, Any]) -> dict[str, Any]:
+        request = _normalize_request(raw_request)
+        replay = self.repository.existing(request["tenant_id"], request["idempotency_key"])
+        if replay:
+            return replay
+        state = self.repository.runtime_state(request["tenant_id"])
+        if state["state"] == "paused":
+            raise RuntimeDecisionError("runtime_paused")
+        route = self.repository.find_route(request)
+        if route is None:
+            if self.repository.generation_status(request["tenant_id"], request["generation"]) == "canary":
+                raise RuntimeDecisionError("canary_not_approved")
+            raise RuntimeDecisionError("route_scope_denied")
+        if route.canary_status != "approved":
+            raise RuntimeDecisionError("canary_not_approved")
+        if not self.repository.allowed_capability(request):
+            if request["tool_name"] == "knowledge.search":
+                raise RuntimeDecisionError("capability_denied")
+            raise RuntimeDecisionError("tool_contract_denied")
+        fence = self.repository.reserve(request)
+        return self.repository.write_authorized(request, route, fence)
+
+    def record_anomaly(self, tenant_id: str, *, incident_ref: str, severity: str, actor: str) -> dict[str, Any]:
+        if not _SAFE_ID.fullmatch(tenant_id) or not _SAFE_ID.fullmatch(incident_ref) or actor != "detector":
+            raise RuntimeDecisionError("anomaly_contract_invalid")
+        if severity not in {"medium", "high", "critical"}:
+            raise RuntimeDecisionError("anomaly_severity_invalid")
+        return self.repository.set_runtime_state(tenant_id, "paused" if severity == "critical" else "degraded", incident_ref)
+
+    def recover(self, tenant_id: str, *, approval_ref: str | None, actor: str) -> dict[str, Any]:
+        if actor != "operator" or not isinstance(approval_ref, str) or not _SAFE_ID.fullmatch(approval_ref):
+            raise RuntimeDecisionError("recovery_approval_required")
+        return self.repository.set_runtime_state(tenant_id, "active", None, require_active=True)
+
+    def promote_canary(self, tenant_id: str, generation: str, *, approval_ref: str) -> int:
+        if not _SAFE_ID.fullmatch(approval_ref):
+            raise RuntimeDecisionError("recovery_approval_required")
+        return self.repository.promote_generation(tenant_id, generation)
+
+    def rollback_generation(self, tenant_id: str, generation: str, *, fence: int, approval_ref: str) -> str:
+        if not _SAFE_ID.fullmatch(approval_ref):
+            raise RuntimeDecisionError("recovery_approval_required")
+        return self.repository.rollback_generation(tenant_id, generation, fence)
+
+    def replay(self, invocation_id: str) -> dict[str, Any]:
+        return self.repository.replay(invocation_id)
+
+
+def evaluate_governed_dataset(*, train_case_ids: set[str], evaluation_cases: list[dict[str, Any]]) -> dict[str, float]:
+    case_ids = [str(case.get("case_id", "")) for case in evaluation_cases]
+    if not case_ids or len(case_ids) != len(set(case_ids)) or train_case_ids.intersection(case_ids):
+        raise DatasetLeakageError("dataset_leakage_detected")
+    recalls, reciprocal_ranks, citations, violations, fresh = [], [], [], [], []
+    for case in evaluation_cases:
+        expected = case.get("expected_evidence_id")
+        retrieved = list(case.get("retrieved_evidence_ids") or [])
+        cited = list(case.get("citation_evidence_ids") or [])
+        if not isinstance(expected, str) or not expected:
+            raise DatasetLeakageError("dataset_case_invalid")
+        recalls.append(float(expected in retrieved))
+        reciprocal_ranks.append(1.0 / (retrieved.index(expected) + 1) if expected in retrieved else 0.0)
+        citations.append(float(cited == [expected]))
+        violations.append(float(not bool(case.get("authorized"))))
+        fresh.append(float(bool(case.get("fresh"))))
+    count = float(len(evaluation_cases))
+    return {"recall": sum(recalls) / count, "mrr": sum(reciprocal_ranks) / count, "citation_correctness": sum(citations) / count, "privilege_violation_rate": sum(violations) / count, "freshness": sum(fresh) / count}

+ 168 - 0
deployment/app/core/llm/runtime_governance_repository.py

@@ -0,0 +1,168 @@
+"""PostgreSQL repository for WP09 budget leases and immutable audit metadata."""
+
+from __future__ import annotations
+
+import json
+from typing import Any
+from uuid import uuid4
+
+from sqlalchemy import text
+from sqlalchemy.exc import SQLAlchemyError
+
+from app.core.llm.runtime_governance import BudgetPolicy
+
+
+class SqlAlchemyRuntimeGovernanceRepository:
+    def __init__(self, connection) -> None:
+        self.connection = connection
+
+    def create_budget(self, tenant_id: str, policy: BudgetPolicy) -> None:
+        self.connection.execute(text("""
+            INSERT INTO public.agent_runtime_budgets (
+                tenant_id, token_remaining, cost_remaining_micros, tool_remaining,
+                time_remaining_ms, concurrency_remaining
+            ) VALUES (:tenant_id, :tokens, :cost, :tools, :time_ms, :concurrency)
+        """), {"tenant_id": tenant_id, "tokens": policy.token_limit, "cost": policy.cost_limit_micros, "tools": policy.tool_limit, "time_ms": policy.time_limit_ms, "concurrency": policy.concurrency_limit})
+        for model, remaining in policy.model_limits.items():
+            self.connection.execute(text("""
+                INSERT INTO public.agent_runtime_model_budgets (tenant_id, model, remaining)
+                VALUES (:tenant_id, :model, :remaining)
+            """), {"tenant_id": tenant_id, "model": model, "remaining": remaining})
+
+    def reserve_budget(self, tenant_id: str, idempotency_key: str, model: str, tokens: int, cost_micros: int, tools: int, time_ms: int) -> int:
+        values = (tokens, cost_micros, tools, time_ms)
+        if any(isinstance(value, bool) or not isinstance(value, int) or value < 1 for value in values):
+            raise ValueError("budget_value_invalid")
+        with self.connection.begin_nested():
+            return self._reserve_budget_atomic(tenant_id, idempotency_key, model, tokens, cost_micros, tools, time_ms)
+
+    def _reserve_budget_atomic(self, tenant_id: str, idempotency_key: str, model: str, tokens: int, cost_micros: int, tools: int, time_ms: int) -> int:
+        model_row = self.connection.execute(text("""
+            UPDATE public.agent_runtime_model_budgets
+            SET remaining = remaining - 1
+            WHERE tenant_id = :tenant_id AND model = :model AND remaining >= 1
+            RETURNING remaining
+        """), {"tenant_id": tenant_id, "model": model}).one_or_none()
+        if model_row is None:
+            raise ValueError("budget_exhausted")
+        row = self.connection.execute(text("""
+            UPDATE public.agent_runtime_budgets
+            SET token_remaining = token_remaining - :tokens,
+                cost_remaining_micros = cost_remaining_micros - :cost,
+                tool_remaining = tool_remaining - :tools,
+                time_remaining_ms = time_remaining_ms - :time_ms,
+                concurrency_remaining = concurrency_remaining - 1,
+                lease_fence = lease_fence + 1, updated_at = now()
+            WHERE tenant_id = :tenant_id AND token_remaining >= :tokens
+              AND cost_remaining_micros >= :cost AND tool_remaining >= :tools
+              AND time_remaining_ms >= :time_ms AND concurrency_remaining >= 1
+            RETURNING lease_fence
+        """), {"tenant_id": tenant_id, "tokens": tokens, "cost": cost_micros, "tools": tools, "time_ms": time_ms}).one_or_none()
+        if row is None:
+            raise ValueError("budget_exhausted")
+        fence = int(row[0])
+        self.connection.execute(text("""
+            INSERT INTO public.agent_runtime_reservations (
+                reservation_id, tenant_id, idempotency_key, model, token_count,
+                cost_micros, tool_count, time_ms, lease_fence, status, lease_expires_at
+            ) VALUES (CAST(:reservation_id AS uuid), :tenant_id, :idempotency_key,
+                      :model, :tokens, :cost, :tools, :time_ms, :fence, 'reserved',
+                      clock_timestamp()+interval '5 minutes')
+        """), {"reservation_id": str(uuid4()), "tenant_id": tenant_id, "idempotency_key": idempotency_key, "model": model, "tokens": tokens, "cost": cost_micros, "tools": tools, "time_ms": time_ms, "fence": fence})
+        return fence
+
+    def append_audit(self, record: dict[str, Any]) -> None:
+        try:
+            self.connection.execute(text("""
+                INSERT INTO public.agent_invocation_audits (
+                    invocation_id, tenant_id, idempotency_key, route_id, generation,
+                    lease_fence, input_hash, evidence_digests, decision, request_digest
+                ) VALUES (CAST(:invocation_id AS uuid), :tenant_id, :idempotency_key,
+                          :route_id, :generation, :lease_fence, :input_hash,
+                          CAST(:evidence_digests AS jsonb), :decision, :request_digest)
+            """), {
+                **record, "evidence_digests": json.dumps(record["evidence_digests"]),
+                "request_digest": record.get("request_digest", record["input_hash"]),
+            })
+        except Exception as error:
+            raise ValueError("append_only_conflict") from error
+
+    def grant_context(self, *, agent_uid: str, grant_uid: str, actor_uid: str) -> dict[str, Any]:
+        """Load scope exclusively from persisted Agent, grant and approved route state."""
+        row = self.connection.execute(text("""
+            SELECT r.tenant_id, a.owner_uid::text AS principal_id,
+                   g.business_domain_uid::text AS business_domain_uid, g.environment,
+                   r.provider, r.model, r.prompt_version, r.generation,
+                   g.interface_type, g.tool_name, g.action, g.risk_level
+            FROM public.agent_tool_grants g
+            JOIN public.governed_agents a ON a.uid=g.agent_uid
+            JOIN public.model_gateway_routes r ON r.principal_id=a.owner_uid
+              AND r.business_domain_uid=g.business_domain_uid AND r.environment=g.environment
+              AND r.canary_status='approved'
+            WHERE g.uid=CAST(:grant_uid AS uuid) AND g.agent_uid=CAST(:agent_uid AS uuid)
+              AND a.owner_uid=CAST(:actor_uid AS uuid) AND g.status='active' AND a.status='active'
+            ORDER BY r.created_at DESC LIMIT 1
+        """), {"agent_uid": agent_uid, "grant_uid": grant_uid, "actor_uid": actor_uid}).mappings().one_or_none()
+        if row is None:
+            from app.core.llm.runtime_server import RuntimeServerError
+            raise RuntimeServerError("server_scope_denied")
+        return dict(row)
+
+    def authorize_claim(self, request: dict[str, Any]) -> dict[str, Any]:
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_agent_runtime"))
+            row = self.connection.execute(text("""
+                SELECT public.agent_runtime_authorize(CAST(:payload AS jsonb)) AS result
+            """), {"payload": json.dumps({
+                key: (sorted(value) if isinstance(value, frozenset) else value)
+                for key, value in request.items()
+            }, ensure_ascii=False)}).scalar_one()
+            return dict(row)
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_authorization_rejected") from error
+
+    def settlement_context(self, *, agent_uid: str, actor_uid: str, idempotency_key: str) -> dict[str, Any]:
+        row = self.connection.execute(text("""
+            SELECT r.agent_uid::text AS agent_uid, r.principal_id::text AS principal_id,
+                   r.idempotency_key, r.lease_fence
+              FROM public.agent_runtime_reservations r
+             WHERE r.idempotency_key=:idempotency_key
+               AND r.agent_uid=CAST(:agent_uid AS uuid)
+               AND r.principal_id=CAST(:actor_uid AS uuid)
+        """), {"agent_uid": agent_uid, "actor_uid": actor_uid, "idempotency_key": idempotency_key}).mappings().one_or_none()
+        if row is None:
+            from app.core.llm.runtime_server import RuntimeServerError
+            raise RuntimeServerError("server_scope_denied")
+        return dict(row)
+
+    def settle_claim(self, request: dict[str, Any]) -> dict[str, Any]:
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_agent_runtime"))
+            row = self.connection.execute(text("""
+                SELECT public.agent_runtime_settle(CAST(:payload AS jsonb)) AS result
+            """), {"payload": json.dumps(request, ensure_ascii=False)}).scalar_one()
+            return dict(row)
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_settlement_rejected") from error
+
+    def issue_control_claim(self, claim: dict[str, Any]) -> str:
+        """Persist a credential-bound, one-shot control claim in this request transaction."""
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_app_runtime"))
+            return str(self.connection.execute(text("""
+                SELECT public.agent_runtime_control_issue_claim(CAST(:claim AS jsonb))
+            """), {"claim": json.dumps(claim, ensure_ascii=False)}).scalar_one())
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_control_claim_rejected") from error
+
+    def control_claimed(self, payload: dict[str, Any], claim_uid: str) -> dict[str, Any]:
+        try:
+            self.connection.execute(text("SET LOCAL ROLE dataops_app_runtime"))
+            row = self.connection.execute(text("""
+                SELECT public.agent_runtime_control_claimed(
+                  CAST(:payload AS jsonb),CAST(:claim_uid AS uuid)
+                ) AS result
+            """), {"payload": json.dumps(payload, ensure_ascii=False), "claim_uid": claim_uid}).scalar_one()
+            return dict(row)
+        except SQLAlchemyError as error:
+            raise RuntimeError("runtime_control_rejected") from error

+ 111 - 0
deployment/app/core/llm/runtime_server.py

@@ -0,0 +1,111 @@
+"""Server-derived invocation contract for the hardened WP09 runtime path."""
+
+from __future__ import annotations
+
+import hashlib
+from dataclasses import dataclass
+from decimal import Decimal, InvalidOperation
+from typing import Any
+
+
+class RuntimeServerError(ValueError):
+    pass
+
+
+@dataclass(frozen=True)
+class RuntimeServerContext:
+    agent_uid: str
+    actor_uid: str
+    roles: frozenset[str]
+
+
+_PAYLOAD_FIELDS = frozenset(
+    {
+        "grant_uid", "idempotency_key", "input_text", "evidence_refs",
+        "estimated_tokens", "estimated_cost_micros", "requested_time_ms",
+    }
+)
+_OPTIONAL_APPROVAL_FIELD = "approval_task_uid"
+_SCOPE_FIELDS = frozenset(
+    {
+        "tenant_id", "principal_id", "business_domain_uid", "environment", "provider",
+        "model", "prompt_version", "generation", "interface_type", "tool_name", "action",
+        "risk_level", "agent_uid",
+    }
+)
+
+
+def _positive_integer(value: Any) -> int:
+    if isinstance(value, bool) or not isinstance(value, int) or not 0 < value <= 1_000_000:
+        raise RuntimeServerError("budget_value_invalid")
+    return value
+
+
+def _cost_micros(value: Any) -> int:
+    if isinstance(value, bool) or not isinstance(value, str) or len(value) > 32:
+        raise RuntimeServerError("budget_value_invalid")
+    try:
+        decimal = Decimal(value)
+    except (InvalidOperation, ValueError) as error:
+        raise RuntimeServerError("budget_value_invalid") from error
+    if not decimal.is_finite() or decimal <= 0 or decimal != decimal.to_integral_value():
+        raise RuntimeServerError("budget_value_invalid")
+    result = int(decimal)
+    if result > 1_000_000_000:
+        raise RuntimeServerError("budget_value_invalid")
+    return result
+
+
+class ServerGovernedInvocationService:
+    """Reject client-supplied scope, deriving every authority field server-side."""
+
+    def __init__(self, repository):
+        self.repository = repository
+
+    def authorize(self, context: RuntimeServerContext, payload: Any) -> dict[str, Any]:
+        if not isinstance(payload, dict):
+            raise RuntimeServerError("payload_invalid")
+        if set(payload) & _SCOPE_FIELDS:
+            raise RuntimeServerError("payload_scope_forbidden")
+        if set(payload) not in {_PAYLOAD_FIELDS, _PAYLOAD_FIELDS | {_OPTIONAL_APPROVAL_FIELD}}:
+            raise RuntimeServerError("payload_schema_invalid")
+        if not context.agent_uid or not context.actor_uid or not context.roles:
+            raise RuntimeServerError("server_identity_invalid")
+        grant_uid = payload["grant_uid"]
+        if not isinstance(grant_uid, str) or not grant_uid:
+            raise RuntimeServerError("payload_invalid")
+        idempotency_key = payload["idempotency_key"]
+        if not isinstance(idempotency_key, str) or not idempotency_key or len(idempotency_key) > 160:
+            raise RuntimeServerError("payload_invalid")
+        input_text = payload["input_text"]
+        if not isinstance(input_text, str) or not input_text.strip() or len(input_text) > 8000:
+            raise RuntimeServerError("payload_invalid")
+        evidence_refs = payload["evidence_refs"]
+        if not isinstance(evidence_refs, list) or len(evidence_refs) > 20:
+            raise RuntimeServerError("payload_invalid")
+        derived = self.repository.grant_context(
+            agent_uid=context.agent_uid, grant_uid=grant_uid, actor_uid=context.actor_uid
+        )
+        requires_approval = derived.get("risk_level") != "low" or derived.get("action") == "execute"
+        approval_task_uid = payload.get(_OPTIONAL_APPROVAL_FIELD)
+        if requires_approval and (not isinstance(approval_task_uid, str) or len(approval_task_uid) != 36):
+            raise RuntimeServerError("human_approval_required")
+        if not requires_approval and approval_task_uid is not None:
+            raise RuntimeServerError("approval_not_applicable")
+        request = {
+            **derived,
+            "agent_uid": context.agent_uid,
+            "grant_uid": grant_uid,
+            "idempotency_key": idempotency_key,
+            "request_digest": hashlib.sha256(
+                (input_text.strip() + "|" + repr(evidence_refs)).encode("utf-8")
+            ).hexdigest(),
+            "input_hash": hashlib.sha256(input_text.strip().encode("utf-8")).hexdigest(),
+            "evidence_digests": [],
+            "estimated_tokens": _positive_integer(payload["estimated_tokens"]),
+            "estimated_cost_micros": _cost_micros(payload["estimated_cost_micros"]),
+            "requested_time_ms": _positive_integer(payload["requested_time_ms"]),
+        }
+        if requires_approval:
+            request["approval_task_uid"] = approval_task_uid
+        return self.repository.authorize_claim(request)

+ 74 - 0
deployment/app/core/mcp/governed_invocation.py

@@ -0,0 +1,74 @@
+"""Closed, minimized contract for MCP calls made by governed Agents."""
+
+from __future__ import annotations
+
+import copy
+import re
+import unicodedata
+from typing import Any
+
+
+class InvocationContractError(ValueError):
+    """Raised when an MCP invocation exceeds its declared contract."""
+
+
+_ALLOWED = frozenset(
+    {"interface_type", "tool_name", "action", "arguments_digest", "evidence_refs"}
+)
+_FORBIDDEN_KEYS = frozenset(
+    {
+        "url", "uri", "endpoint", "path", "file_path", "filename", "command",
+        "shell", "script", "secret", "token", "password", "api_key", "raw_rows",
+        "rows", "records", "arguments", "payload",
+    }
+)
+_TOOL = re.compile(r"^[A-Za-z][A-Za-z0-9_.:-]{1,159}$")
+_DIGEST = re.compile(r"^[a-f0-9]{64}$")
+
+
+def _closed(value: Any, allowed: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise InvocationContractError(f"{label}_invalid")
+    for key in value:
+        normalized = unicodedata.normalize("NFKC", str(key))
+        if normalized != key or normalized.casefold() in _FORBIDDEN_KEYS:
+            raise InvocationContractError("forbidden_contract_key")
+    unknown = set(value) - allowed
+    if unknown:
+        raise InvocationContractError("unknown_contract_field")
+    return copy.deepcopy(value)
+
+
+def _digest(value: Any, label: str) -> str:
+    if not isinstance(value, str) or not _DIGEST.fullmatch(value):
+        raise InvocationContractError(f"{label}_invalid")
+    return value
+
+
+def normalize_mcp_invocation(value: Any) -> dict[str, Any]:
+    """Accept hash-only, bounded MCP metadata; never raw arguments or locations."""
+    body = _closed(value, _ALLOWED, "invocation")
+    if body.get("interface_type") != "mcp":
+        raise InvocationContractError("interface_type_invalid")
+    tool_name = body.get("tool_name")
+    if not isinstance(tool_name, str) or not _TOOL.fullmatch(tool_name):
+        raise InvocationContractError("tool_name_invalid")
+    if body.get("action") not in {"read", "suggest", "execute"}:
+        raise InvocationContractError("action_invalid")
+    refs = body.get("evidence_refs")
+    if not isinstance(refs, list) or len(refs) > 20:
+        raise InvocationContractError("evidence_refs_invalid")
+    normalized_refs = []
+    for item in refs:
+        ref = _closed(item, frozenset({"evidence_id", "digest"}), "evidence_ref")
+        evidence_id = ref.get("evidence_id")
+        if not isinstance(evidence_id, str) or not re.fullmatch(r"[A-Za-z0-9_.:-]{1,120}", evidence_id):
+            raise InvocationContractError("evidence_id_invalid")
+        normalized_refs.append({"evidence_id": evidence_id, "digest": _digest(ref.get("digest"), "evidence_digest")})
+    return {
+        "interface_type": "mcp",
+        "tool_name": tool_name,
+        "action": body["action"],
+        "arguments_digest": _digest(body.get("arguments_digest"), "arguments_digest"),
+        "evidence_refs": normalized_refs,
+    }

+ 5 - 0
deployment/app/core/plugins/__init__.py

@@ -0,0 +1,5 @@
+"""Closed, fixture-only governed plugin platform primitives."""
+
+from .governance import PluginManifestError, normalize_plugin_manifest
+
+__all__ = ["PluginManifestError", "normalize_plugin_manifest"]

+ 178 - 0
deployment/app/core/plugins/governance.py

@@ -0,0 +1,178 @@
+"""Closed, local-only manifest contract for governed plugins.
+
+This module deliberately contains no loader, dynamic import, evaluator, shell,
+subprocess, network client or user-selected filesystem path.  A manifest is
+metadata for a fixed built-in fixture handler, never an executable package.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import re
+import unicodedata
+from typing import Any
+
+
+class PluginManifestError(ValueError):
+    """A plugin manifest did not meet the closed local-baseline contract."""
+
+
+_TOP_LEVEL = frozenset(
+    {
+        "schema_version",
+        "plugin_uid",
+        "name",
+        "version",
+        "api_version",
+        "type",
+        "capabilities",
+        "permissions",
+        "resource",
+        "compatibility",
+        "distribution",
+    }
+)
+_TYPES = frozenset({"connector", "parser", "quality", "notification", "approval", "agent_mcp"})
+_CAPABILITIES = {
+    "connector": frozenset({"discover", "snapshot", "evidence"}),
+    "parser": frozenset({"parse", "evidence"}),
+    "quality": frozenset({"evaluate", "evidence"}),
+    "notification": frozenset({"prepare", "evidence"}),
+    "approval": frozenset({"evaluate", "evidence"}),
+    "agent_mcp": frozenset({"read", "suggest", "evidence"}),
+}
+_PERMISSIONS = frozenset({"network", "file", "secret", "child_process"})
+_RESOURCE = frozenset({"timeout_ms", "max_output_bytes", "max_concurrency", "max_retries"})
+_COMPATIBILITY = frozenset({"platform_api"})
+_DISTRIBUTION = frozenset({"kind", "fixture_id", "artifact_digest"})
+_SENSITIVE = frozenset(
+    {
+        "url", "uri", "endpoint", "path", "file", "file_path", "filename", "command", "shell",
+        "script", "code", "module", "import", "eval", "exec", "secret", "token", "password",
+        "credential", "api_key", "authorization", "raw_rows", "rows", "records", "payload", "sql",
+    }
+)
+_ID = re.compile(r"^[a-z][a-z0-9-]{2,62}$")
+_SEMVER = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$")
+_HEX = re.compile(r"^[a-f0-9]{64}$")
+
+
+def canonical_digest(value: dict[str, Any]) -> str:
+    return hashlib.sha256(
+        json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode("utf-8")
+    ).hexdigest()
+
+
+def fixture_signature_digest(artifact_digest: str) -> str:
+    """Bind the sole local fixture artifact to the platform-owned trust key.
+
+    This is deliberately not a payload supplied public key or a general
+    signature verifier.  Enterprise CA and registry signing remain disabled.
+    """
+
+    if not isinstance(artifact_digest, str) or not _HEX.fullmatch(artifact_digest):
+        raise PluginManifestError("artifact_digest_invalid")
+    return hashlib.sha256(f"local-fixture-key-v1|{artifact_digest}".encode("ascii")).hexdigest()
+
+
+def _closed(value: Any, allowed: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict) or len(value) > len(allowed):
+        raise PluginManifestError(f"{label}_closed")
+    for key in value:
+        if not isinstance(key, str) or unicodedata.normalize("NFKC", key) != key:
+            raise PluginManifestError("manifest_unicode_rejected")
+        # The four declared capability switches are metadata, not values.  All
+        # other sensitive vocabulary remains forbidden even before unknown-key
+        # processing so it cannot become an accidental extension point.
+        if key.casefold() in _SENSITIVE and key not in allowed:
+            raise PluginManifestError("manifest_sensitive_key")
+    if set(value) != allowed:
+        raise PluginManifestError(f"{label}_closed")
+    return copy.deepcopy(value)
+
+
+def _ascii_text(value: Any, label: str, maximum: int = 120) -> str:
+    if not isinstance(value, str) or not value or len(value) > maximum:
+        raise PluginManifestError(f"{label}_invalid")
+    if unicodedata.normalize("NFKC", value) != value or not value.isascii():
+        raise PluginManifestError(f"{label}_unicode_rejected")
+    return value
+
+
+def _positive_int(value: Any, label: str, maximum: int) -> int:
+    if isinstance(value, bool) or not isinstance(value, int) or not 0 < value <= maximum:
+        raise PluginManifestError(f"{label}_invalid")
+    return value
+
+
+def normalize_plugin_manifest(value: Any) -> dict[str, Any]:
+    """Normalize a v1 manifest for the sole fixed engineering fixture.
+
+    Enterprise registry artifacts are intentionally rejected until an external
+    trust model is approved.  This validation makes that inactivity executable.
+    """
+
+    body = _closed(value, _TOP_LEVEL, "manifest")
+    if body["schema_version"] != 1 or body["api_version"] != "1":
+        raise PluginManifestError("manifest_version_invalid")
+    plugin_uid = _ascii_text(body["plugin_uid"], "plugin_uid", 63)
+    name = _ascii_text(body["name"], "name", 63)
+    if not _ID.fullmatch(plugin_uid) or not _ID.fullmatch(name) or plugin_uid != name:
+        raise PluginManifestError("plugin_identity_invalid")
+    version = _ascii_text(body["version"], "version", 80)
+    if not _SEMVER.fullmatch(version):
+        raise PluginManifestError("plugin_version_invalid")
+    plugin_type = _ascii_text(body["type"], "plugin_type", 20)
+    if plugin_type not in _TYPES:
+        raise PluginManifestError("plugin_type_invalid")
+    capabilities = body["capabilities"]
+    if not isinstance(capabilities, list) or not 1 <= len(capabilities) <= 8:
+        raise PluginManifestError("capabilities_invalid")
+    normalized_capabilities = tuple(_ascii_text(item, "capability", 40) for item in capabilities)
+    if len(set(normalized_capabilities)) != len(normalized_capabilities) or set(normalized_capabilities) - _CAPABILITIES[plugin_type]:
+        raise PluginManifestError("capabilities_invalid")
+    permissions = _closed(body["permissions"], _PERMISSIONS, "permissions")
+    if any(item is not False for item in permissions.values()):
+        raise PluginManifestError("permissions_denied")
+    resource = _closed(body["resource"], _RESOURCE, "resource")
+    normalized_resource = {
+        "timeout_ms": _positive_int(resource["timeout_ms"], "timeout_ms", 5000),
+        "max_output_bytes": _positive_int(resource["max_output_bytes"], "max_output_bytes", 65536),
+        "max_concurrency": _positive_int(resource["max_concurrency"], "max_concurrency", 1),
+        "max_retries": _positive_int(resource["max_retries"], "max_retries", 3),
+    }
+    if normalized_resource["max_output_bytes"] < 64:
+        raise PluginManifestError("max_output_bytes_invalid")
+    compatibility = _closed(body["compatibility"], _COMPATIBILITY, "compatibility")
+    if compatibility["platform_api"] != "1":
+        raise PluginManifestError("compatibility_invalid")
+    distribution = _closed(body["distribution"], _DISTRIBUTION, "distribution")
+    if distribution["kind"] != "builtin_fixture" or distribution["fixture_id"] != "ENGINEERING_EVIDENCE_ONLY":
+        raise PluginManifestError("distribution_denied")
+    artifact_digest = _ascii_text(distribution["artifact_digest"], "artifact_digest", 64)
+    if not _HEX.fullmatch(artifact_digest):
+        raise PluginManifestError("artifact_digest_invalid")
+    normalized = {
+        "schema_version": 1,
+        "plugin_uid": plugin_uid,
+        "name": name,
+        "version": version,
+        "api_version": "1",
+        "type": plugin_type,
+        "capabilities": list(normalized_capabilities),
+        "permissions": dict.fromkeys(sorted(_PERMISSIONS), False),
+        "resource": normalized_resource,
+        "compatibility": {"platform_api": "1"},
+        "distribution": {
+            "kind": "builtin_fixture",
+            "fixture_id": "ENGINEERING_EVIDENCE_ONLY",
+            "artifact_digest": artifact_digest,
+        },
+    }
+    normalized["manifest_digest"] = canonical_digest(normalized)
+    return normalized
+
+
+__all__ = ["PluginManifestError", "canonical_digest", "fixture_signature_digest", "normalize_plugin_manifest"]

+ 113 - 0
deployment/app/core/plugins/persistence.py

@@ -0,0 +1,113 @@
+"""Database adapters for the fixed WP13 control and runtime gateways."""
+
+from __future__ import annotations
+
+import json
+import os
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+from app.core.mcp.governed_invocation import normalize_mcp_invocation
+
+from .governance import fixture_signature_digest, normalize_plugin_manifest
+from .runtime import BuiltinFixtureDispatcher
+
+
+class PluginPersistenceError(ValueError):
+    """The persistent gateway rejected a closed plugin request."""
+
+
+def _digest(value: Any, label: str) -> str:
+    if not isinstance(value, str) or len(value) != 64 or set(value) - set("0123456789abcdef"):
+        raise PluginPersistenceError(f"{label}_invalid")
+    return value
+
+
+class DatabasePluginPlatformService:
+    """Uses only fixed SECURITY DEFINER functions; never direct fact SQL."""
+
+    def __init__(self) -> None:
+        self._runtime_url = os.environ.get("DATABASE_URL", "")
+        self._control_url = os.environ.get("PLUGIN_PLATFORM_CONTROL_DATABASE_URL", os.environ.get("BI_AI_CATALOG_CONTROL_DATABASE_URL", ""))
+        runtime = validate_postgresql_url(self._runtime_url, "DATABASE_URL")
+        control = validate_postgresql_url(self._control_url, "PLUGIN_PLATFORM_CONTROL_DATABASE_URL")
+        if runtime.username == control.username:
+            raise RuntimeError("plugin control and runtime identities must differ")
+
+    @staticmethod
+    def _scope() -> dict[str, str]:
+        tenant = os.environ.get("TRUSTED_PLUGIN_TENANT", "")
+        domain = os.environ.get("TRUSTED_PLUGIN_DOMAIN", "")
+        if not tenant or not domain or not tenant.isascii() or not domain.isascii():
+            raise PluginPersistenceError("trusted_plugin_scope_missing")
+        return {"tenant_ref": tenant, "domain_ref": domain}
+
+    def _control(self, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(text("SELECT public.plugin_platform_control_v5(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))}).scalar_one()
+        return dict(value)
+
+    def _claim(self, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._control_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(text("SELECT public.plugin_platform_issue_claim_v3(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))}).scalar_one()
+        return dict(value)
+
+    def _runtime(self, payload: dict[str, Any]) -> dict[str, Any]:
+        with create_engine(self._runtime_url, poolclass=NullPool, pool_pre_ping=True).begin() as connection:
+            value = connection.execute(text("SELECT public.plugin_platform_runtime_v3(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"))}).scalar_one()
+        return dict(value)
+
+    def register(self, *, manifest: Any, registry_record: Any, actor_ref: str) -> dict[str, Any]:
+        normalized = normalize_plugin_manifest(manifest)
+        if not isinstance(registry_record, dict) or set(registry_record) != {"artifact_digest", "signature", "sbom_digest", "license_digest", "vulnerability_digest", "provenance_digest"}:
+            raise PluginPersistenceError("registry_record_closed")
+        signature = registry_record["signature"]
+        if not isinstance(signature, dict) or set(signature) != {"trust_store_key_id", "signature_digest"} or signature["trust_store_key_id"] != "local-fixture-key-v1":
+            raise PluginPersistenceError("trust_store_denied")
+        payload = {
+            "action": "register", "plugin_uid": normalized["plugin_uid"], "version": normalized["version"], "actor_ref": actor_ref,
+            "plugin_type": normalized["type"], "manifest_digest": normalized["manifest_digest"],
+            "artifact_digest": _digest(registry_record["artifact_digest"], "artifact_digest"),
+            "signature_digest": _digest(signature["signature_digest"], "signature_digest"),
+            "sbom_digest": _digest(registry_record["sbom_digest"], "sbom_digest"), "license_digest": _digest(registry_record["license_digest"], "license_digest"),
+            "vulnerability_digest": _digest(registry_record["vulnerability_digest"], "vulnerability_digest"), "provenance_digest": _digest(registry_record["provenance_digest"], "provenance_digest"),
+            "capabilities": normalized["capabilities"], "resource": normalized["resource"],
+        }
+        if payload["artifact_digest"] != normalized["distribution"]["artifact_digest"]:
+            raise PluginPersistenceError("artifact_digest_mismatch")
+        if payload["signature_digest"] != fixture_signature_digest(payload["artifact_digest"]):
+            raise PluginPersistenceError("signature_binding_denied")
+        return self._control(payload)
+
+    def review(self, *, plugin_uid: str, version: str, actor_ref: str) -> dict[str, Any]:
+        return self._control({"action": "review", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref})
+
+    def issue_approval(self, *, plugin_uid: str, version: str, actor_ref: str, approval_action: str) -> dict[str, Any]:
+        return self._control({"action": "issue_approval", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref, "approval_action": approval_action, **self._scope(), "expires_in_seconds": 300})
+
+    def transition(self, *, plugin_uid: str, version: str, actor_ref: str, target_state: str, approval_uid: str, expected_fence: int, incident_uid: str = "") -> dict[str, Any]:
+        if not isinstance(expected_fence, int) or expected_fence < 0:
+            raise PluginPersistenceError("expected_fence_invalid")
+        return self._control({"action": "transition", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref, **self._scope(), "approval_uid": approval_uid, "target_state": target_state, "expected_fence": expected_fence, "incident_uid": incident_uid})
+
+    def invoke(self, *, plugin_uid: str, version: str, actor_ref: str, operation: str, input_digest: str, idempotency_key: str) -> dict[str, Any]:
+        _digest(input_digest, "input_digest")
+        if not isinstance(idempotency_key, str) or not idempotency_key.isascii() or not 1 <= len(idempotency_key) <= 120:
+            raise PluginPersistenceError("idempotency_key_invalid")
+        scope = self._scope()
+        description = self._control({"action": "describe", "plugin_uid": plugin_uid, "version": version, "actor_ref": actor_ref})
+        if description["plugin_type"] == "agent_mcp":
+            normalize_mcp_invocation({"interface_type": "mcp", "tool_name": "governed_plugin_fixture", "action": operation, "arguments_digest": input_digest, "evidence_refs": []})
+        claim = self._claim({"plugin_uid": plugin_uid, "version": version, "principal_ref": actor_ref, "operation_name": operation, "input_digest": input_digest, "idempotency_key": idempotency_key, **scope})
+        queued = self._runtime({"action": "enqueue", "claim_uid": claim["claim_uid"], "idempotency_key": idempotency_key, "input_digest": input_digest, "operation_name": operation})
+        lease = self._runtime({"action": "claim", "run_uid": queued["run_uid"], "worker": "fixed-builtin"})
+        fixture_manifest = {"distribution": {"kind": "builtin_fixture", "fixture_id": "ENGINEERING_EVIDENCE_ONLY"}, "permissions": {"child_process": False, "file": False, "network": False, "secret": False}, "type": description["plugin_type"], "capabilities": description["capabilities"], "resource": description["resource"], "manifest_digest": description["manifest_digest"]}
+        result = BuiltinFixtureDispatcher().execute(fixture_manifest, operation=operation, input_digest=input_digest)
+        settled = self._runtime({"action": "settle", "run_uid": queued["run_uid"], "worker": "fixed-builtin", "fence": lease["fence"], "success": True, "output_digest": result["output_digest"], "failure_digest": "0" * 64})
+        return {"run_uid": queued["run_uid"], **result, **settled}
+
+
+__all__ = ["DatabasePluginPlatformService", "PluginPersistenceError"]

+ 190 - 0
deployment/app/core/plugins/repository.py

@@ -0,0 +1,190 @@
+"""In-memory reference behavior for the fixed WP13 fixture dispatcher.
+
+The production persistence boundary is supplied by the WP13 PostgreSQL gateway.
+This small adapter exists for deterministic unit contracts; it never loads or
+executes a submitted artifact.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import threading
+import uuid
+from collections.abc import Callable
+from typing import Any
+
+from .governance import (
+    PluginManifestError,
+    canonical_digest,
+    fixture_signature_digest,
+    normalize_plugin_manifest,
+)
+
+
+class PluginLifecycleError(ValueError):
+    """A lifecycle transition, approval, registry record or invocation was denied."""
+
+
+_RECORD = frozenset(
+    {"artifact_digest", "signature", "sbom_digest", "license_digest", "vulnerability_digest", "provenance_digest"}
+)
+_SIGNATURE = frozenset({"trust_store_key_id", "signature_digest"})
+_TRUST_STORE = frozenset({"local-fixture-key-v1"})
+_HEX = frozenset("0123456789abcdef")
+_ACTIONS = frozenset({"activate", "pause", "rollback", "revoke", "recover"})
+
+
+def _digest(value: Any, label: str) -> str:
+    if not isinstance(value, str) or len(value) != 64 or set(value) - _HEX:
+        raise PluginLifecycleError(f"{label}_invalid")
+    return value
+
+
+def _closed(value: Any, keys: frozenset[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict) or set(value) != keys:
+        raise PluginLifecycleError(f"{label}_closed")
+    return copy.deepcopy(value)
+
+
+def _scope(value: Any, *, principal: bool) -> dict[str, str]:
+    keys = {"tenant_id", "domain"} | ({"principal_id"} if principal else set())
+    if not isinstance(value, dict) or set(value) != keys:
+        raise PluginLifecycleError("scope_closed")
+    normalized: dict[str, str] = {}
+    for key in keys:
+        item = value[key]
+        if not isinstance(item, str) or not item.isascii() or not 1 <= len(item) <= 120:
+            raise PluginLifecycleError("scope_invalid")
+        normalized[key] = item
+    return normalized
+
+
+class PluginPlatform:
+    """Thread-safe local state machine around one fixed evidence fixture."""
+
+    def __init__(self, *, now: Callable[[], int]) -> None:
+        self._now = now
+        self._lock = threading.RLock()
+        self._versions: dict[tuple[str, str], dict[str, Any]] = {}
+        self._approvals: dict[str, dict[str, Any]] = {}
+        self._runs: dict[tuple[str, str, str, str], dict[str, Any]] = {}
+
+    def register(self, manifest: Any, *, registry_record: Any) -> dict[str, Any]:
+        try:
+            normalized = normalize_plugin_manifest(manifest)
+        except PluginManifestError as exc:
+            raise PluginLifecycleError(str(exc)) from exc
+        record = _closed(registry_record, _RECORD, "registry_record")
+        signature = _closed(record["signature"], _SIGNATURE, "signature")
+        if signature["trust_store_key_id"] not in _TRUST_STORE:
+            raise PluginLifecycleError("trust_store_key_denied")
+        normalized_record = {
+            "artifact_digest": _digest(record["artifact_digest"], "artifact_digest"),
+            "signature": {
+                "trust_store_key_id": signature["trust_store_key_id"],
+                "signature_digest": _digest(signature["signature_digest"], "signature_digest"),
+            },
+            "sbom_digest": _digest(record["sbom_digest"], "sbom_digest"),
+            "license_digest": _digest(record["license_digest"], "license_digest"),
+            "vulnerability_digest": _digest(record["vulnerability_digest"], "vulnerability_digest"),
+            "provenance_digest": _digest(record["provenance_digest"], "provenance_digest"),
+        }
+        if normalized_record["artifact_digest"] != normalized["distribution"]["artifact_digest"]:
+            raise PluginLifecycleError("artifact_digest_mismatch")
+        if normalized_record["signature"]["signature_digest"] != fixture_signature_digest(normalized_record["artifact_digest"]):
+            raise PluginLifecycleError("signature_binding_denied")
+        key = (normalized["plugin_uid"], normalized["version"])
+        with self._lock:
+            if key in self._versions:
+                raise PluginLifecycleError("plugin_version_exists")
+            item = normalized | {"state": "draft", "registry": normalized_record, "reviewer_id": None}
+            self._versions[key] = item
+            return copy.deepcopy(item)
+
+    def review(self, plugin_uid: str, version: str, *, reviewer_id: str) -> dict[str, Any]:
+        if not isinstance(reviewer_id, str) or not reviewer_id.isascii() or not reviewer_id:
+            raise PluginLifecycleError("reviewer_invalid")
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            if item["state"] != "draft":
+                raise PluginLifecycleError("review_transition_denied")
+            item["state"] = "reviewed"
+            item["reviewer_id"] = reviewer_id
+            return copy.deepcopy(item)
+
+    def issue_approval(self, *, plugin_uid: str, version: str, action: str, actor_id: str, reviewer_id: str, scope: Any, expires_at: int) -> dict[str, Any]:
+        if action not in _ACTIONS or not isinstance(actor_id, str) or not isinstance(reviewer_id, str) or actor_id == reviewer_id:
+            raise PluginLifecycleError("approval_independence_denied")
+        if not isinstance(expires_at, int) or expires_at <= self._now():
+            raise PluginLifecycleError("approval_expiry_invalid")
+        bound_scope = _scope(scope, principal=False)
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            if (
+                item["state"] != "reviewed"
+                or item["reviewer_id"] != reviewer_id
+                or item["reviewer_id"] == actor_id
+            ):
+                raise PluginLifecycleError("approval_review_denied")
+            approval = {
+                "approval_id": str(uuid.uuid4()), "plugin_uid": plugin_uid, "version": version,
+                "action": action, "actor_id": actor_id, "reviewer_id": reviewer_id,
+                "scope": bound_scope, "manifest_digest": item["manifest_digest"],
+                "expires_at": expires_at, "consumed": False,
+            }
+            self._approvals[approval["approval_id"]] = approval
+            return copy.deepcopy(approval)
+
+    def activate(self, plugin_uid: str, version: str, *, actor_id: str, scope: Any, approval_id: str) -> dict[str, Any]:
+        bound_scope = _scope(scope, principal=False)
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            approval = self._approvals.get(approval_id)
+            if not approval or approval["consumed"] or approval["expires_at"] <= self._now() or approval["action"] != "activate" or approval["actor_id"] != actor_id or approval["reviewer_id"] != item["reviewer_id"] or approval["scope"] != bound_scope or approval["manifest_digest"] != item["manifest_digest"]:
+                raise PluginLifecycleError("approval_binding_denied")
+            if item["state"] != "reviewed":
+                raise PluginLifecycleError("activation_transition_denied")
+            if any(candidate["state"] == "active" for (uid, _), candidate in self._versions.items() if uid == plugin_uid):
+                raise PluginLifecycleError("plugin_active_collision")
+            approval["consumed"] = True
+            item["state"] = "active"
+            return copy.deepcopy(item)
+
+    def invoke(self, *, plugin_uid: str, version: str, operation: str, scope: Any, input_digest: str, idempotency_key: str) -> dict[str, Any]:
+        invocation_scope = _scope(scope, principal=True)
+        digest = _digest(input_digest, "input_digest")
+        if not isinstance(idempotency_key, str) or not idempotency_key.isascii() or not 1 <= len(idempotency_key) <= 120:
+            raise PluginLifecycleError("idempotency_key_invalid")
+        with self._lock:
+            item = self._version(plugin_uid, version)
+            if item["state"] != "active":
+                raise PluginLifecycleError("plugin_not_active")
+            if operation not in item["capabilities"]:
+                raise PluginLifecycleError("capability_denied")
+            key = (plugin_uid, version, invocation_scope["tenant_id"], idempotency_key)
+            replay = self._runs.get(key)
+            request = {"scope": invocation_scope, "input_digest": digest, "operation": operation}
+            request_digest = canonical_digest(request)
+            if replay:
+                if replay["request_digest"] != request_digest:
+                    raise PluginLifecycleError("idempotency_conflict")
+                return copy.deepcopy(replay["result"] | {"replay": True})
+            output_digest = hashlib.sha256(
+                f"ENGINEERING_EVIDENCE_ONLY|{item['manifest_digest']}|{request_digest}".encode("ascii")
+            ).hexdigest()
+            result = {
+                "plugin_uid": plugin_uid, "version": version, "run_digest": request_digest,
+                "output_digest": output_digest, "fixture_id": "ENGINEERING_EVIDENCE_ONLY", "replay": False,
+            }
+            self._runs[key] = {"request_digest": request_digest, "result": result}
+            return copy.deepcopy(result)
+
+    def _version(self, plugin_uid: str, version: str) -> dict[str, Any]:
+        item = self._versions.get((plugin_uid, version))
+        if item is None:
+            raise PluginLifecycleError("plugin_version_not_found")
+        return item
+
+
+__all__ = ["PluginLifecycleError", "PluginPlatform"]

+ 56 - 0
deployment/app/core/plugins/runtime.py

@@ -0,0 +1,56 @@
+"""Fixed, local-only plugin handlers and execution guard.
+
+No submitted artifact is imported or evaluated.  The mapping below is the
+complete executable surface for the engineering fixture baseline.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import time
+from typing import Any
+
+
+class PluginExecutionError(ValueError):
+    """A requested invocation cannot pass the fixed execution boundary."""
+
+
+_HANDLERS = {
+    "connector": frozenset({"discover", "snapshot", "evidence"}),
+    "parser": frozenset({"parse", "evidence"}),
+    "quality": frozenset({"evaluate", "evidence"}),
+    "notification": frozenset({"prepare", "evidence"}),
+    "approval": frozenset({"evaluate", "evidence"}),
+    "agent_mcp": frozenset({"read", "suggest", "evidence"}),
+}
+
+
+class BuiltinFixtureDispatcher:
+    """Deterministic hash-only handler for the six fixed plugin categories."""
+
+    def execute(self, manifest: dict[str, Any], *, operation: str, input_digest: str) -> dict[str, Any]:
+        if not isinstance(manifest, dict) or manifest.get("distribution", {}).get("kind") != "builtin_fixture" or manifest.get("distribution", {}).get("fixture_id") != "ENGINEERING_EVIDENCE_ONLY":
+            raise PluginExecutionError("execution_fixture_denied")
+        permissions = manifest.get("permissions")
+        if permissions != {"child_process": False, "file": False, "network": False, "secret": False}:
+            raise PluginExecutionError("execution_permissions_denied")
+        plugin_type = manifest.get("type")
+        if plugin_type not in _HANDLERS or operation not in _HANDLERS[plugin_type] or operation not in manifest.get("capabilities", []):
+            raise PluginExecutionError("execution_capability_denied")
+        if not isinstance(input_digest, str) or len(input_digest) != 64 or set(input_digest) - set("0123456789abcdef"):
+            raise PluginExecutionError("execution_input_digest_invalid")
+        resource = manifest.get("resource")
+        if not isinstance(resource, dict) or set(resource) != {"timeout_ms", "max_output_bytes", "max_concurrency", "max_retries"}:
+            raise PluginExecutionError("execution_resource_denied")
+        if any(isinstance(value, bool) or not isinstance(value, int) for value in resource.values()) or not 1 <= resource["timeout_ms"] <= 5000 or not 64 <= resource["max_output_bytes"] <= 65536 or not 1 <= resource["max_concurrency"] <= 1 or not 1 <= resource["max_retries"] <= 3:
+            raise PluginExecutionError("execution_resource_denied")
+        started = time.monotonic_ns()
+        output_digest = hashlib.sha256(
+            f"ENGINEERING_EVIDENCE_ONLY|{plugin_type}|{operation}|{manifest.get('manifest_digest')}|{input_digest}".encode("ascii")
+        ).hexdigest()
+        if len(output_digest.encode("ascii")) > resource["max_output_bytes"] or (time.monotonic_ns() - started) > resource["timeout_ms"] * 1_000_000:
+            raise PluginExecutionError("execution_resource_exceeded")
+        return {"output_digest": output_digest, "fixture_id": "ENGINEERING_EVIDENCE_ONLY", "provider_enabled": False}
+
+
+__all__ = ["BuiltinFixtureDispatcher", "PluginExecutionError"]

+ 59 - 11
deployment/app/core/system/permissions.py

@@ -79,6 +79,10 @@ CONNECTORS_MANAGE = "connectors:manage"
 EDGE_GATEWAYS_READ = "edge-gateways:read"
 EDGE_GATEWAYS_OPERATE = "edge-gateways:operate"
 EDGE_GATEWAYS_MANAGE = "edge-gateways:manage"
+BI_AI_CATALOG_READ = "bi-ai-catalog:read"
+BI_AI_CATALOG_MANAGE = "bi-ai-catalog:manage"
+METERING_READ = "metering:read"
+METERING_MANAGE = "metering:manage"
 
 ROLE_PERMISSIONS = {
     "viewer": frozenset(
@@ -96,6 +100,8 @@ ROLE_PERMISSIONS = {
             IDENTITY_READ,
             CONNECTORS_READ,
             EDGE_GATEWAYS_READ,
+            BI_AI_CATALOG_READ,
+            METERING_READ,
         }
     ),
     "editor": frozenset(
@@ -139,6 +145,8 @@ ROLE_PERMISSIONS = {
             CONNECTORS_OPERATE,
             EDGE_GATEWAYS_READ,
             EDGE_GATEWAYS_OPERATE,
+            BI_AI_CATALOG_READ,
+            METERING_READ,
         }
     ),
     "admin": frozenset(
@@ -215,6 +223,10 @@ ROLE_PERMISSIONS = {
             EDGE_GATEWAYS_READ,
             EDGE_GATEWAYS_OPERATE,
             EDGE_GATEWAYS_MANAGE,
+            BI_AI_CATALOG_READ,
+            BI_AI_CATALOG_MANAGE,
+            METERING_READ,
+            METERING_MANAGE,
         }
     ),
 }
@@ -255,7 +267,11 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
             return (EDGE_GATEWAYS_MANAGE,)
         if path == "/api/datasource/edge/tasks" and method == "POST":
             return (EDGE_GATEWAYS_OPERATE,)
-        if path.startswith("/api/datasource/edge/tasks/") and path.endswith("/cancel") and method == "POST":
+        if (
+            path.startswith("/api/datasource/edge/tasks/")
+            and path.endswith("/cancel")
+            and method == "POST"
+        ):
             return (EDGE_GATEWAYS_OPERATE,)
         if method == "GET":
             return (EDGE_GATEWAYS_READ,)
@@ -263,7 +279,10 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
     if path.startswith("/api/system/identity"):
         if path == "/api/system/identity/logout" and method == "POST":
             return (IDENTITY_READ,)
-        if path in {"/api/system/identity/idp-versions", "/api/system/identity/audit"} and method == "GET":
+        if (
+            path in {"/api/system/identity/idp-versions", "/api/system/identity/audit"}
+            and method == "GET"
+        ):
             return (IDENTITY_MANAGE,)
         if path == "/api/system/identity/sessions" and method == "GET":
             return (IDENTITY_OPERATE,)
@@ -272,6 +291,16 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
         if any(marker in path for marker in ("/idp-versions", "/emergency/")):
             return (IDENTITY_MANAGE,)
         return (IDENTITY_OPERATE,)
+    if path.startswith("/api/system/tenant/"):
+        return (IDENTITY_OPERATE,)
+    if path.startswith("/api/system/bi-ai-catalog/"):
+        return (
+            (BI_AI_CATALOG_READ,)
+            if method == "GET" or path.endswith("/search")
+            else (BI_AI_CATALOG_MANAGE,)
+        )
+    if path.startswith("/api/system/metering/"):
+        return (METERING_READ,) if method == "GET" else (METERING_MANAGE,)
     if path.startswith("/api/datasource/connectors"):
         if "/source-bindings" in path:
             return (CONNECTORS_MANAGE,)
@@ -322,16 +351,37 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
         ):
             return (SECURITY_GOVERNANCE_MANAGE,)
         return (SECURITY_GOVERNANCE_OPERATE,)
+    if path.startswith("/api/system/trusted-delivery"):
+        if path.startswith("/api/system/trusted-delivery/controls/"):
+            if method == "GET":
+                return (SECURITY_GOVERNANCE_READ,)
+            if any(
+                marker in path
+                for marker in (
+                    "/profiles/activate",
+                    "/profiles/rollback",
+                    "/capability-approvals",
+                    "/destruction-approvals",
+                )
+            ):
+                return (SECURITY_GOVERNANCE_MANAGE,)
+            return (SECURITY_GOVERNANCE_OPERATE,)
+        if "/legal-holds" in path or "/reclaim/" in path:
+            return (SECURITY_GOVERNANCE_MANAGE,)
+        return (SECURITY_GOVERNANCE_OPERATE,)
     if path.startswith("/api/dataservice/governance"):
         if method == "GET":
             return (DATA_PRODUCTS_READ,)
-        if any(
-            marker in path
-            for marker in (
-                "/reconcile",
-                "/fulfill",
+        if (
+            any(
+                marker in path
+                for marker in (
+                    "/reconcile",
+                    "/fulfill",
+                )
             )
-        ) or path == "/api/dataservice/governance/products":
+            or path == "/api/dataservice/governance/products"
+        ):
             return (DATA_PRODUCTS_MANAGE,)
         return (DATA_PRODUCTS_OPERATE,)
     if path.startswith("/api/knowledge/agents"):
@@ -435,9 +485,7 @@ def permission_for_request(path: str, method: str) -> tuple[str, ...]:
     if path.startswith("/api/development/v1/device-quality"):
         if method == "GET":
             return (READ_GOVERNANCE,)
-        if path.startswith(
-            "/api/development/v1/device-quality/issues"
-        ):
+        if path.startswith("/api/development/v1/device-quality/issues"):
             if path.endswith("/review"):
                 return (QUALITY_ISSUES_REVIEW,)
             return (QUALITY_ISSUES_EDIT,)

+ 34 - 0
deployment/app/core/system/tenant_approval_repository.py

@@ -0,0 +1,34 @@
+"""Dedicated, independent database identity for lifecycle approval facts."""
+
+from __future__ import annotations
+
+import json
+import os
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+
+
+class SqlAlchemyTenantApprovalRepository:
+    def __init__(self, database_url: str | None = None) -> None:
+        url = database_url or os.environ.get("TENANT_APPROVER_DATABASE_URL", "")
+        validate_postgresql_url(url, "TENANT_APPROVER_DATABASE_URL")
+        self.engine = create_engine(url, poolclass=NullPool, pool_pre_ping=True)
+
+    def issue(self, *, payload: dict[str, Any]) -> dict[str, Any]:
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_approver_issue(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            code = getattr(getattr(exc, "orig", None), "pgcode", "unknown")
+            raise ValueError(f"tenant_approval_denied:{code}") from exc
+        finally:
+            self.engine.dispose()

+ 130 - 0
deployment/app/core/system/tenant_context.py

@@ -0,0 +1,130 @@
+"""Closed, server-derived tenant scope for the conditional WP10 foundation."""
+
+from __future__ import annotations
+
+import re
+from collections.abc import Mapping
+from dataclasses import dataclass
+from enum import StrEnum
+
+
+class TenantContextError(ValueError):
+    """A tenant boundary was absent, unapproved, or contradicted by input."""
+
+
+class DeliveryMode(StrEnum):
+    PRIVATE_SINGLE_TENANT = "private_single_tenant"
+    SHARED_CONTROL_PLANE = "shared_control_plane"
+    SAAS = "saas"
+
+
+_TENANT_ID = re.compile(r"^[a-z][a-z0-9-]{0,62}$")
+_HOST = re.compile(r"^[a-z0-9][a-z0-9.-]{0,252}$")
+_EVENT_TYPE = re.compile(r"^[a-z][a-z0-9_.-]{0,80}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+
+
+def _tenant_id(value: str) -> str:
+    if not isinstance(value, str) or not _TENANT_ID.fullmatch(value):
+        raise TenantContextError("tenant_scope_denied")
+    return value
+
+
+@dataclass(frozen=True)
+class TenantScope:
+    tenant_id: str
+    mode: DeliveryMode
+    version: int = 1
+
+    def __post_init__(self) -> None:
+        _tenant_id(self.tenant_id)
+        if self.version != 1:
+            raise TenantContextError("tenant_context_version_denied")
+
+    def require_background_scope(self, declared_tenant_id: str | None) -> str:
+        if declared_tenant_id is None:
+            raise TenantContextError("tenant_scope_required")
+        if _tenant_id(declared_tenant_id) != self.tenant_id:
+            raise TenantContextError("tenant_scope_denied")
+        return self.tenant_id
+
+    def require_admin_scope(self, declared_tenant_id: str | None) -> str:
+        return self.require_background_scope(declared_tenant_id)
+
+
+TenantContext = TenantScope
+
+
+def validate_tenant_event_envelope(scope: TenantScope, envelope: Mapping[str, object]) -> dict[str, object]:
+    """Reject task/event dispatch unless its scope is explicit and server-matched."""
+    required = {"schema_version", "tenant_id", "event_type", "payload_digest"}
+    if set(envelope) - required:
+        raise TenantContextError("tenant_event_closed")
+    tenant_id = envelope.get("tenant_id")
+    if tenant_id is None:
+        raise TenantContextError("tenant_scope_required")
+    if set(envelope) != required:
+        raise TenantContextError("tenant_event_closed")
+    if not isinstance(tenant_id, str) or _tenant_id(tenant_id) != scope.tenant_id:
+        raise TenantContextError("tenant_scope_denied")
+    if envelope.get("schema_version") != 1 or not isinstance(envelope.get("event_type"), str) or not _EVENT_TYPE.fullmatch(envelope["event_type"]):
+        raise TenantContextError("tenant_event_closed")
+    if not isinstance(envelope.get("payload_digest"), str) or not _DIGEST.fullmatch(envelope["payload_digest"]):
+        raise TenantContextError("tenant_event_closed")
+    return dict(envelope)
+
+
+class TenantContextResolver:
+    """Resolve scope only from server-held delivery configuration and host mapping."""
+
+    def __init__(
+        self,
+        *,
+        mode: DeliveryMode,
+        approved_default_tenant: str | None,
+        route_tenants: Mapping[str, str],
+        activated_modes: frozenset[DeliveryMode] | None = None,
+    ) -> None:
+        self.mode = DeliveryMode(mode)
+        self.approved_default_tenant = (
+            _tenant_id(approved_default_tenant)
+            if approved_default_tenant is not None
+            else None
+        )
+        self.route_tenants = {
+            self._host(host): _tenant_id(tenant_id)
+            for host, tenant_id in route_tenants.items()
+        }
+        self.activated_modes = activated_modes or frozenset(
+            {DeliveryMode.PRIVATE_SINGLE_TENANT}
+        )
+
+    @staticmethod
+    def _host(host: str) -> str:
+        if not isinstance(host, str) or not _HOST.fullmatch(host.lower()):
+            raise TenantContextError("tenant_route_denied")
+        return host.lower()
+
+    def resolve_request(
+        self,
+        *,
+        host: str,
+        claimed_tenant_id: str | None,
+        principal_id: str,
+    ) -> TenantContext:
+        if not isinstance(principal_id, str) or not principal_id:
+            raise TenantContextError("tenant_principal_required")
+        if self.mode not in self.activated_modes:
+            raise TenantContextError("delivery_mode_not_approved")
+        self._host(host)
+        if self.mode is DeliveryMode.PRIVATE_SINGLE_TENANT:
+            if self.approved_default_tenant is None:
+                raise TenantContextError("tenant_default_not_approved")
+            # Client claim is intentionally ignored: it never selects a tenant.
+            return TenantContext(self.approved_default_tenant, self.mode)
+        resolved = self.route_tenants.get(self._host(host))
+        if resolved is None:
+            raise TenantContextError("tenant_route_denied")
+        if claimed_tenant_id is not None and _tenant_id(claimed_tenant_id) != resolved:
+            raise TenantContextError("tenant_spoof_denied")
+        return TenantContext(resolved, self.mode)

+ 149 - 0
deployment/app/core/system/tenant_control_repository.py

@@ -0,0 +1,149 @@
+"""Dedicated control-identity repository for tenant claims.
+
+This intentionally does not use the shared application SQLAlchemy session:
+the separate connection must authenticate as a member of
+``dataops_tenant_control``.  If that deployment input is absent, the route is
+unavailable rather than falling back to the shared runtime login.
+"""
+
+from __future__ import annotations
+
+import json
+import os
+import uuid
+from typing import Any
+
+from sqlalchemy import create_engine, text
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.pool import NullPool
+
+from app.config.database_urls import validate_postgresql_url
+from app.core.system.tenant_control_service import TenantControlError
+
+
+class SqlAlchemyTenantControlRepository:
+    def __init__(self, database_url: str | None = None) -> None:
+        url = database_url or os.environ.get("TENANT_CONTROL_DATABASE_URL", "")
+        validate_postgresql_url(url, "TENANT_CONTROL_DATABASE_URL")
+        self.engine = create_engine(url, poolclass=NullPool, pool_pre_ping=True)
+
+    def issue_claim(
+        self,
+        *,
+        principal_id: str,
+        host: str,
+        action: str,
+        request: dict[str, Any],
+    ) -> dict[str, Any]:
+        payload = {
+            "claim_uid": str(uuid.uuid4()),
+            "nonce": str(uuid.uuid4()),
+            "principal_id": principal_id,
+            "host": host.lower(),
+            "action": action,
+            "request": request,
+        }
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_control_issue_claim(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_control_claim_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def provision(self, *, tenant_id: str, principal_id: str, host: str, idempotency_key: str) -> dict[str, Any]:
+        payload = {"tenant_id": tenant_id, "principal_id": principal_id, "host": host.lower(), "idempotency_key": idempotency_key}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_control_provision(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            code = getattr(getattr(exc, "orig", None), "pgcode", "unknown")
+            raise TenantControlError(f"tenant_control_provision_denied:{code}") from exc
+        finally:
+            self.engine.dispose()
+
+    def lifecycle_transition(
+        self, *, principal_id: str, host: str, operation: str, request: dict[str, Any]
+    ) -> dict[str, Any]:
+        claim_payload = {
+            "claim_uid": str(uuid.uuid4()),
+            "nonce": str(uuid.uuid4()),
+            "principal_id": principal_id,
+            "host": host.lower(),
+            "action": "lifecycle_transition",
+            "request": request,
+        }
+        try:
+            with self.engine.begin() as connection:
+                connection.execute(
+                    text("SELECT public.tenant_control_issue_claim(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(claim_payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+                value = connection.execute(
+                    text("SELECT public.tenant_control_lifecycle_approved_mutate(CAST(:claim_uid AS uuid),CAST(:nonce AS uuid),CAST(:request AS jsonb))"),
+                    {
+                        "claim_uid": claim_payload["claim_uid"],
+                        "nonce": claim_payload["nonce"],
+                        "request": json.dumps(request, sort_keys=True, separators=(",", ":"), ensure_ascii=True),
+                    },
+                ).scalar_one()
+            return {**dict(value), "request": request}
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_lifecycle_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def read(self, *, principal_id: str, host: str, kind: str) -> dict[str, Any]:
+        functions = {
+            "status": "tenant_control_read_state",
+            "audit": "tenant_control_read_audit",
+            "manifests": "tenant_control_read_manifests",
+        }
+        function = functions.get(kind)
+        if function is None:
+            raise TenantControlError("tenant_read_denied")
+        payload = {"principal_id": principal_id, "host": host.lower()}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text(f"SELECT public.{function}(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_read_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def claim_outbox(self, *, outbox_uid: str, worker_id: str, lease_seconds: str = "30") -> dict[str, Any]:
+        payload = {"outbox_uid": outbox_uid, "worker_id": worker_id, "lease_seconds": lease_seconds}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(
+                    text("SELECT public.tenant_control_worker_claim(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_worker_scope_denied") from exc
+        finally:
+            self.engine.dispose()
+
+    def settle_outbox(self, *, outbox_uid: str, worker_id: str, lease_fence: int, payload_digest: str, outcome: str) -> dict[str, Any]:
+        payload = {"outbox_uid": outbox_uid, "worker_id": worker_id, "lease_fence": str(lease_fence), "payload_digest": payload_digest, "outcome": outcome}
+        try:
+            with self.engine.begin() as connection:
+                value = connection.execute(text("SELECT public.tenant_control_worker_settle(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True)}).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as exc:
+            raise TenantControlError("tenant_worker_settle_denied") from exc
+        finally:
+            self.engine.dispose()

+ 160 - 0
deployment/app/core/system/tenant_control_service.py

@@ -0,0 +1,160 @@
+"""Authenticated application boundary for tenant-control claims."""
+
+from __future__ import annotations
+
+import os
+import uuid
+from typing import Any
+
+from app.core.system.tenant_approval_repository import (
+    SqlAlchemyTenantApprovalRepository,
+)
+from app.core.system.tenant_context import (
+    DeliveryMode,
+    TenantScope,
+    validate_tenant_event_envelope,
+)
+from app.core.system.tenant_resources import build_tenant_namespace
+
+
+class TenantControlError(ValueError):
+    pass
+
+
+class TenantControlService:
+    _REQUEST_FIELDS = frozenset({"quota_name", "amount", "idempotency_key"})
+    _LIFECYCLE_FIELDS = frozenset({"expected_fence", "idempotency_key", "approval_ref", "backup_digest", "retention_seconds"})
+    _LIFECYCLE_OPERATIONS = frozenset({"activate", "freeze", "begin_recovery", "mark_deletion_candidate", "rollback", "delete"})
+
+    def __init__(self, repository: Any) -> None:
+        self.repository = repository
+
+    def provision_private(self, *, principal_id: str, host: str, request: dict[str, Any]) -> dict[str, Any]:
+        if set(request) != {"idempotency_key"} or not isinstance(request.get("idempotency_key"), str):
+            raise TenantControlError("tenant_payload_closed")
+        tenant_id = os.environ.get("PRIVATE_SINGLE_TENANT_ID", "")
+        trusted_host = os.environ.get("PRIVATE_SINGLE_TENANT_HOST", "").lower()
+        if not tenant_id or not trusted_host:
+            raise TenantControlError("tenant_default_not_approved")
+        return self.repository.provision(
+            tenant_id=tenant_id,
+            principal_id=principal_id,
+            host=trusted_host,
+            idempotency_key=request["idempotency_key"],
+        )
+
+    def issue_quota_claim(self, *, principal_id: str, host: str, request: dict[str, Any]) -> dict[str, Any]:
+        if set(request) != self._REQUEST_FIELDS:
+            raise TenantControlError("tenant_payload_closed")
+        if not isinstance(principal_id, str) or not principal_id or not isinstance(host, str) or not host:
+            raise TenantControlError("tenant_identity_required")
+        claim = self.repository.issue_claim(
+            principal_id=principal_id,
+            host=host,
+            action="quota_reserve",
+            request=request,
+        )
+        # This is the actual HTTP-service propagation point: the tenant is
+        # returned only after the database has matched principal+route, then
+        # copied into closed task/event and external-store namespace contracts.
+        tenant_id = claim.get("tenant_id")
+        digest = claim.get("request_digest")
+        if isinstance(tenant_id, str) and isinstance(digest, str):
+            scope = TenantScope(tenant_id, DeliveryMode.PRIVATE_SINGLE_TENANT)
+            event = validate_tenant_event_envelope(
+                scope,
+                {"schema_version": 1, "tenant_id": tenant_id, "event_type": "tenant.quota.claim", "payload_digest": digest},
+            )
+            claim["propagation"] = {
+                "task": event,
+                "event": event,
+                "namespaces": {
+                    resource: build_tenant_namespace(scope, resource, "quota-claim")
+                    for resource in ("object", "graph", "cache", "index")
+                },
+            }
+        return claim
+
+    def lifecycle_transition(
+        self, *, principal_id: str, host: str, operation: str, request: dict[str, Any]
+    ) -> dict[str, Any]:
+        if operation not in self._LIFECYCLE_OPERATIONS or not isinstance(request, dict):
+            raise TenantControlError("tenant_payload_closed")
+        if not set(request).issubset(self._LIFECYCLE_FIELDS) or set(request) < {"expected_fence", "idempotency_key"}:
+            raise TenantControlError("tenant_payload_closed")
+        if not isinstance(request["expected_fence"], str) or not isinstance(request["idempotency_key"], str):
+            raise TenantControlError("tenant_payload_closed")
+        normalized = {
+            "operation": operation,
+            "expected_fence": request["expected_fence"],
+            "idempotency_key": request["idempotency_key"],
+            "approval_ref": request.get("approval_ref"),
+            "backup_digest": request.get("backup_digest"),
+            "retention_seconds": request.get("retention_seconds"),
+        }
+        return self.repository.lifecycle_transition(
+            principal_id=principal_id, host=host, operation=operation, request=normalized
+        )
+
+    def read(self, *, principal_id: str, host: str, kind: str) -> dict[str, Any]:
+        if kind not in {"status", "audit", "manifests"}:
+            raise TenantControlError("tenant_read_denied")
+        return self.repository.read(principal_id=principal_id, host=host, kind=kind)
+
+    def issue_lifecycle_approval(self, *, reviewer_id: str, request: dict[str, Any]) -> dict[str, Any]:
+        allowed = frozenset({"operation", "expected_fence", "idempotency_key", "backup_digest", "retention_seconds"})
+        if not isinstance(request, dict) or not set(request).issubset(allowed) or set(request) < {"operation", "expected_fence", "idempotency_key"}:
+            raise TenantControlError("tenant_payload_closed")
+        operation = request["operation"]
+        if operation not in {"begin_recovery", "delete"} or not isinstance(reviewer_id, str):
+            raise TenantControlError("tenant_approval_denied")
+        tenant_id = os.environ.get("PRIVATE_SINGLE_TENANT_ID", "")
+        issuer_id = os.environ.get("TENANT_APPROVER_ISSUER_ID", "")
+        if not tenant_id or not issuer_id or issuer_id == reviewer_id:
+            raise TenantControlError("tenant_approval_identity_required")
+        approval_ref = str(uuid.uuid4())
+        normalized = {
+            "operation": operation,
+            "expected_fence": request["expected_fence"],
+            "idempotency_key": request["idempotency_key"],
+            "approval_ref": approval_ref,
+            "backup_digest": request.get("backup_digest"),
+            "retention_seconds": request.get("retention_seconds"),
+        }
+        value = SqlAlchemyTenantApprovalRepository().issue(
+            payload={
+                "approval_uid": approval_ref,
+                "tenant_id": tenant_id,
+                "action": operation,
+                "request": normalized,
+                "lease_fence": request["expected_fence"],
+                "issuer_id": issuer_id,
+                "reviewer_id": reviewer_id,
+                "ttl_seconds": os.environ.get("TENANT_APPROVAL_TTL_SECONDS", "120"),
+            }
+        )
+        return {**value, "approval_ref": approval_ref}
+
+    def claim_outbox(self, *, outbox_uid: str) -> dict[str, Any]:
+        worker_id = os.environ.get("TENANT_CONTROL_WORKER_ID", "")
+        if not worker_id:
+            raise TenantControlError("tenant_worker_identity_required")
+        value = self.repository.claim_outbox(outbox_uid=outbox_uid, worker_id=worker_id)
+        tenant_id = value.get("tenant_id")
+        if not isinstance(tenant_id, str):
+            raise TenantControlError("tenant_worker_scope_denied")
+        scope = TenantScope(tenant_id, DeliveryMode.PRIVATE_SINGLE_TENANT)
+        value["propagation"] = {
+            "event": validate_tenant_event_envelope(
+                scope,
+                {"schema_version": 1, "tenant_id": tenant_id, "event_type": value["event_type"], "payload_digest": value["payload_digest"]},
+            ),
+            "namespaces": {resource: build_tenant_namespace(scope, resource, "worker") for resource in ("object", "graph", "cache", "index")},
+        }
+        return value
+
+    def settle_outbox(self, *, outbox_uid: str, lease_fence: int, payload_digest: str, outcome: str) -> dict[str, Any]:
+        worker_id = os.environ.get("TENANT_CONTROL_WORKER_ID", "")
+        if not worker_id:
+            raise TenantControlError("tenant_worker_identity_required")
+        return self.repository.settle_outbox(outbox_uid=outbox_uid, worker_id=worker_id, lease_fence=lease_fence, payload_digest=payload_digest, outcome=outcome)

+ 113 - 0
deployment/app/core/system/tenant_lifecycle.py

@@ -0,0 +1,113 @@
+"""Deterministic lifecycle and fence contract used before tenant activation."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import re
+from dataclasses import dataclass, field
+from typing import Any
+
+
+class TenantLifecycleError(ValueError):
+    pass
+
+
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_TRANSITIONS = {
+    ("provisioning", "activate"): "active",
+    ("active", "freeze"): "frozen",
+    ("frozen", "begin_recovery"): "recovering",
+    ("recovering", "activate"): "active",
+    ("active", "mark_deletion_candidate"): "deletion_candidate",
+    ("frozen", "mark_deletion_candidate"): "deletion_candidate",
+    ("deletion_candidate", "delete"): "deleted",
+    ("deletion_candidate", "rollback"): "frozen",
+}
+
+
+@dataclass(frozen=True)
+class TenantLifecycleRecord:
+    tenant_id: str
+    state: str
+    fence: int
+
+
+@dataclass
+class TenantLifecycle:
+    tenant_id: str
+    state: str = "provisioning"
+    fence: int = 0
+    _replays: dict[str, tuple[str, TenantLifecycleRecord]] = field(default_factory=dict)
+
+    @classmethod
+    def provision(cls, tenant_id: str) -> TenantLifecycle:
+        return cls(tenant_id=tenant_id)
+
+    def _digest(self, action: str, expected_fence: int, values: dict[str, Any]) -> str:
+        payload = json.dumps(
+            {"action": action, "expected_fence": expected_fence, **values},
+            sort_keys=True,
+            separators=(",", ":"),
+        )
+        return hashlib.sha256(payload.encode("utf-8")).hexdigest()
+
+    def transition(
+        self,
+        action: str,
+        *,
+        expected_fence: int,
+        idempotency_key: str,
+        approval_ref: str | None = None,
+        backup_digest: str | None = None,
+        retention_seconds: int | None = None,
+        hold_active: bool = False,
+    ) -> TenantLifecycleRecord:
+        if not isinstance(expected_fence, int) or isinstance(expected_fence, bool):
+            raise TenantLifecycleError("tenant_fence_conflict")
+        if not isinstance(idempotency_key, str) or not idempotency_key:
+            raise TenantLifecycleError("tenant_replay_conflict")
+        values = {
+            "approval_ref": approval_ref,
+            "backup_digest": backup_digest,
+            "retention_seconds": retention_seconds,
+            "hold_active": hold_active,
+        }
+        request_digest = self._digest(action, expected_fence, values)
+        replay = self._replays.get(idempotency_key)
+        if replay is not None:
+            if replay[0] != request_digest:
+                raise TenantLifecycleError("tenant_replay_conflict")
+            return replay[1]
+        if expected_fence != self.fence:
+            raise TenantLifecycleError("tenant_fence_conflict")
+        target = _TRANSITIONS.get((self.state, action))
+        if target is None:
+            raise TenantLifecycleError("tenant_transition_denied")
+        if action in {"begin_recovery", "activate"} and self.state == "recovering" and not approval_ref:
+            raise TenantLifecycleError("tenant_recovery_approval_required")
+        if action in {"mark_deletion_candidate", "delete"}:
+            if not approval_ref:
+                raise TenantLifecycleError("tenant_deletion_approval_required")
+            if hold_active:
+                raise TenantLifecycleError("tenant_hold_active")
+            if not isinstance(backup_digest, str) or not _DIGEST.fullmatch(backup_digest):
+                raise TenantLifecycleError("tenant_backup_required")
+            if (
+                not isinstance(retention_seconds, int)
+                or isinstance(retention_seconds, bool)
+                or retention_seconds < 1
+            ):
+                raise TenantLifecycleError("tenant_retention_required")
+        self.state = target
+        self.fence += 1
+        result = TenantLifecycleRecord(self.tenant_id, self.state, self.fence)
+        self._replays[idempotency_key] = (request_digest, result)
+        return result
+
+    def require_active_task_scope(self, *, expected_fence: int) -> TenantLifecycleRecord:
+        if expected_fence != self.fence:
+            raise TenantLifecycleError("tenant_fence_conflict")
+        if self.state != "active":
+            raise TenantLifecycleError("tenant_not_active")
+        return TenantLifecycleRecord(self.tenant_id, self.state, self.fence)

+ 102 - 0
deployment/app/core/system/tenant_repository.py

@@ -0,0 +1,102 @@
+"""Runtime-only repository for the WP10 PostgreSQL tenant foundation."""
+
+from __future__ import annotations
+
+import json
+from typing import Any
+
+from sqlalchemy import text
+from sqlalchemy.exc import SQLAlchemyError
+
+
+class SqlAlchemyTenantFoundationRepository:
+    def __init__(self, connection: Any) -> None:
+        # 501--503 accepted tenant_id from a caller payload.  Those functions
+        # were revoked in 504 and this compatibility facade must never become
+        # a fallback around the claim-bound control identity introduced later.
+        raise RuntimeError("tenant_legacy_gateway_sealed")
+
+    def _set_runtime_scope(self, tenant_id: str) -> None:
+        if self._tenant_scope is not None and self._tenant_scope != tenant_id:
+            raise ValueError("tenant_scope_denied")
+        self.connection.execute(text("SET LOCAL ROLE dataops_app_runtime"))
+        self.connection.execute(
+            text("SELECT set_config('dataops.tenant_id', :tenant_id, true)"),
+            {"tenant_id": tenant_id},
+        )
+        self._tenant_scope = tenant_id
+
+    def _write(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
+        tenant_id = payload.get("tenant_id")
+        if not isinstance(tenant_id, str):
+            raise ValueError("tenant_scope_denied")
+        self._set_runtime_scope(tenant_id)
+        try:
+            with self.connection.begin_nested():
+                value = self.connection.execute(
+                    text("SELECT public.tenant_foundation_write(:action, CAST(:payload AS jsonb))"),
+                    {"action": action, "payload": json.dumps(payload, ensure_ascii=False)},
+                ).scalar_one()
+            return dict(value)
+        except SQLAlchemyError as error:
+            message = str(error)
+            for code in (
+                "tenant_quota_exhausted",
+                "tenant_not_active",
+                "tenant_replay_conflict",
+                "tenant_fence_conflict",
+                "tenant_payload_closed",
+                "tenant_payload_invalid",
+            ):
+                if code in message:
+                    raise ValueError(code) from error
+            raise ValueError("tenant_gateway_denied") from error
+
+    def provision(self, tenant_id: str, delivery_mode: str, idempotency_key: str) -> dict[str, Any]:
+        return self._write("provision", {"tenant_id": tenant_id, "delivery_mode": delivery_mode, "idempotency_key": idempotency_key})
+
+    def reserve_quota(self, tenant_id: str, quota_name: str, amount: int | float, idempotency_key: str) -> int:
+        if isinstance(amount, bool) or not isinstance(amount, (int, float)):
+            raise ValueError("tenant_payload_invalid")
+        payload = {"tenant_id": tenant_id, "quota_name": quota_name, "amount": amount, "idempotency_key": idempotency_key}
+        self._set_runtime_scope(tenant_id)
+        try:
+            with self.connection.begin_nested():
+                value = self.connection.execute(text("SELECT public.tenant_quota_reserve(CAST(:payload AS jsonb))"), {"payload": json.dumps(payload, ensure_ascii=False)}).scalar_one()
+            result = dict(value)
+        except SQLAlchemyError as error:
+            message = str(error)
+            for code in ("tenant_quota_exhausted", "tenant_not_active", "tenant_replay_conflict", "tenant_fence_conflict", "tenant_payload_closed", "tenant_payload_invalid"):
+                if code in message:
+                    raise ValueError(code) from error
+            raise ValueError("tenant_gateway_denied") from error
+        return int(result["lease_fence"])
+
+    def transition_lifecycle(
+        self,
+        tenant_id: str,
+        operation: str,
+        expected_fence: int,
+        idempotency_key: str,
+        *,
+        approval_ref: str | None = None,
+    ) -> int:
+        self._set_runtime_scope(tenant_id)
+        try:
+            with self.connection.begin_nested():
+                result = self.connection.execute(
+                    text("SELECT public.tenant_lifecycle_transition(CAST(:payload AS jsonb))"),
+                    {"payload": json.dumps({"tenant_id": tenant_id, "operation": operation, "expected_fence": expected_fence, "idempotency_key": idempotency_key, "approval_ref": approval_ref}, ensure_ascii=False)},
+                ).scalar_one()
+            return int(dict(result)["lease_fence"])
+        except SQLAlchemyError as error:
+            message = str(error)
+            for code in ("tenant_not_active", "tenant_replay_conflict", "tenant_fence_conflict", "tenant_payload_closed", "tenant_payload_invalid", "tenant_recovery_approval_required"):
+                if code in message:
+                    raise ValueError(code) from error
+            raise ValueError("tenant_lifecycle_denied") from error
+
+    def list_audit(self, tenant_id: str) -> list[dict[str, Any]]:
+        self._set_runtime_scope(tenant_id)
+        rows = self.connection.execute(text("SELECT tenant_id,event_type,payload_digest,lease_fence,created_at FROM public.tenant_audit_events ORDER BY created_at,event_uid")).mappings()
+        return [dict(row) for row in rows]

+ 66 - 0
deployment/app/core/system/tenant_resources.py

@@ -0,0 +1,66 @@
+"""Tenant namespace and hash-only manifest contracts for non-PostgreSQL stores."""
+
+from __future__ import annotations
+
+import re
+from typing import Any
+
+from app.core.system.tenant_context import TenantScope
+
+
+class TenantResourceError(ValueError):
+    pass
+
+
+_RESOURCE_TYPES = frozenset(
+    {
+        "object",
+        "graph",
+        "cache",
+        "index",
+        "keys",
+        "connectors",
+        "models",
+        "plugins",
+        "backup",
+        "audit_export",
+    }
+)
+_RESOURCE_NAME = re.compile(r"^[a-z0-9][a-z0-9._-]{0,120}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+
+
+def _resource_token(value: str, *, allowed: frozenset[str] | None = None) -> str:
+    if not isinstance(value, str) or not _RESOURCE_NAME.fullmatch(value):
+        raise TenantResourceError("tenant_resource_invalid")
+    if allowed is not None and value not in allowed:
+        raise TenantResourceError("tenant_resource_invalid")
+    return value
+
+
+def build_tenant_namespace(scope: TenantScope, resource: str, name: str) -> str:
+    """Return an opaque prefix; callers must not concatenate their own paths."""
+    resource = _resource_token(resource, allowed=_RESOURCE_TYPES)
+    name = _resource_token(name)
+    return f"{scope.tenant_id}/{resource}/v{scope.version}/{name}"
+
+
+def build_tenant_resource_manifest(
+    scope: TenantScope,
+    *,
+    resource: str,
+    name: str,
+    digest: str,
+) -> dict[str, Any]:
+    if not isinstance(digest, str) or not _DIGEST.fullmatch(digest):
+        raise TenantResourceError("tenant_resource_invalid")
+    namespace = build_tenant_namespace(scope, resource, name)
+    return {
+        "schema_version": 1,
+        "tenant_id": scope.tenant_id,
+        "delivery_mode": scope.mode.value,
+        "resource": resource,
+        "namespace": namespace,
+        "digest": f"sha256:{digest}",
+        "provider_enabled": False,
+    }

+ 670 - 0
deployment/app/core/system/trusted_delivery.py

@@ -0,0 +1,670 @@
+"""Closed, default-deny contracts for fine-grained trusted delivery.
+
+This module intentionally never executes a data query or contacts a target.
+It produces a bounded authorization projection and digest-only provider envelope.
+Concrete enterprise providers remain external integration work.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import re
+import uuid
+from collections.abc import Callable, Mapping
+from datetime import UTC, datetime
+from typing import Any
+
+from app.core.common.identifiers import new_governance_uid
+from app.core.common.timezone_utils import now_china
+
+_PROVIDERS = frozenset({"database", "api", "file", "iam", "kms", "dlp", "siem"})
+_ENVIRONMENTS = frozenset({"development", "test", "production"})
+_ACTIONS = frozenset({"read", "use", "display", "export"})
+_CLASSIFICATIONS = frozenset({"public", "internal", "sensitive", "highly_sensitive"})
+_FIELD = re.compile(r"^[A-Za-z_][A-Za-z0-9_.-]{0,199}$")
+_CODE = re.compile(r"^[A-Z][A-Z0-9_]{2,119}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_UNSAFE_TEXT = re.compile(
+    r"(?i)(?:https?://|ftp://|file://|www\.|\b(?:secret|token|password|private[ _-]?key)\b|"
+    r"-----BEGIN|<script|javascript:|;)")
+_UNSAFE_SQL = re.compile(r"(?i)\b(?:select|insert|update|delete|drop|alter)\s+")
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ValueError(f"{label} must be an object")
+    extra = sorted(set(value) - allowed)
+    if extra:
+        raise ValueError(f"{label} contains unsupported fields: {', '.join(extra)}")
+    result = copy.deepcopy(value)
+    _assert_safe_value(result, label)
+    return result
+
+
+def _assert_safe_value(value: Any, label: str) -> None:
+    """Reject values that could turn an authorization reference into payload data."""
+    if isinstance(value, str) and _UNSAFE_TEXT.search(value):
+        raise ValueError(f"{label} contains unsafe content")
+    if isinstance(value, dict):
+        for item in value.values():
+            _assert_safe_value(item, label)
+    elif isinstance(value, list):
+        for item in value:
+            _assert_safe_value(item, label)
+
+
+def _text(value: Any, label: str, maximum: int = 300) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise ValueError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum:
+        raise ValueError(f"{label} exceeds {maximum} characters")
+    return result
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as exc:
+        raise ValueError(f"{label} must be a UUID") from exc
+
+
+def _time(value: Any, label: str) -> datetime:
+    try:
+        result = value if isinstance(value, datetime) else datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as exc:
+        raise ValueError(f"{label} must be ISO-8601") from exc
+    if result.tzinfo is None:
+        raise ValueError(f"{label} must include a timezone")
+    return result.astimezone(UTC)
+
+
+def _values(value: Any, label: str, *, minimum: int = 1, maximum: int = 200) -> list[Any]:
+    if not isinstance(value, list) or not minimum <= len(value) <= maximum:
+        raise ValueError(f"{label} must contain between {minimum} and {maximum} items")
+    return copy.deepcopy(value)
+
+
+def _digest(value: Any) -> str:
+    return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(",", ":")).encode()).hexdigest()
+
+
+def _digest_value(value: Any, label: str) -> str:
+    result = _text(value, label, 64).lower()
+    if not _DIGEST.fullmatch(result):
+        raise ValueError(f"{label} must be SHA-256")
+    return result
+
+
+def _field(value: Any, label: str) -> str:
+    result = _text(value, label, 200)
+    if not _FIELD.fullmatch(result):
+        raise ValueError(f"{label} is invalid")
+    return result
+
+
+def _simple_values(value: Any, label: str, allowed: frozenset[str]) -> list[str]:
+    result = sorted({_text(item, label, 100) for item in _values(value, label)})
+    if not set(result) <= allowed:
+        raise ValueError(f"unsupported {label}")
+    return result
+
+
+def _row_filter(value: Any) -> dict[str, Any] | None:
+    if value is None:
+        return None
+    body = _closed(value, {"op", "field", "value", "items", "item"}, "row filter")
+    op = _text(body.get("op"), "row filter op", 10)
+    if op not in {"eq", "in", "and", "or", "not"}:
+        raise ValueError("unsupported row filter op")
+    if _UNSAFE_SQL.search(json.dumps(body, sort_keys=True)):
+        raise ValueError("row filter contains unsafe content")
+    if op in {"eq", "in"}:
+        if set(body) - {"op", "field", "value"}:
+            raise ValueError("row filter shape is invalid")
+        field = _field(body.get("field"), "row filter field")
+        raw = body.get("value")
+        if op == "eq" and not isinstance(raw, (str, int, float, bool)):
+            raise ValueError("row filter eq value must be scalar")
+        if op == "in":
+            if not isinstance(raw, list) or not 1 <= len(raw) <= 100 or not all(isinstance(item, (str, int, float, bool)) for item in raw):
+                raise ValueError("row filter in value must be bounded scalar list")
+            raw = sorted(raw, key=lambda item: (type(item).__name__, str(item)))
+        return {"op": op, "field": field, "value": raw}
+    if op == "not":
+        if set(body) != {"op", "item"}:
+            raise ValueError("row filter not shape is invalid")
+        return {"op": op, "item": _row_filter(body["item"])}
+    if set(body) != {"op", "items"}:
+        raise ValueError("row filter boolean shape is invalid")
+    items = [_row_filter(item) for item in _values(body.get("items"), "row filter items", minimum=1, maximum=20)]
+    return {"op": op, "items": items}
+
+
+class ClosedProviderRegistry:
+    """Provider names are a closed enum; tests may inject non-network adapters."""
+
+    def __init__(self, adapters: Mapping[str, Any] | None = None, *, test_mode: bool = False):
+        adapters = dict(adapters or {})
+        if set(adapters) - _PROVIDERS:
+            raise ValueError("unsupported trusted-delivery provider")
+        if adapters and not test_mode:
+            raise PermissionError("enterprise providers require approved external integration")
+        self._adapters = adapters
+        self._test_mode = test_mode
+
+    @classmethod
+    def for_tests(cls, adapters: Mapping[str, Any]):
+        return cls(adapters, test_mode=True)
+
+    @property
+    def is_enterprise_ready(self) -> bool:
+        return False
+
+    def dependency_status(self) -> dict[str, str]:
+        return dict.fromkeys(sorted(_PROVIDERS), "TBD_EXTERNAL")
+
+    def get(self, provider: str):
+        provider = _text(provider, "provider", 30)
+        if provider not in _PROVIDERS:
+            raise ValueError("unsupported trusted-delivery provider")
+        adapter = self._adapters.get(provider)
+        if adapter is None:
+            raise PermissionError(f"trusted-delivery provider {provider} is disabled")
+        return adapter
+
+
+class TrustedDeliveryService:
+    """Durable-service façade. Repositories own the database transaction boundary."""
+
+    def __init__(
+        self, repository, *, provider_registry: ClosedProviderRegistry | None = None,
+        uid_factory: Callable[[], str] = new_governance_uid,
+        now_factory: Callable[[], datetime] = now_china,
+    ):
+        self.repository = repository
+        self.provider_registry = provider_registry or ClosedProviderRegistry()
+        self.uid_factory = uid_factory
+        self.now_factory = now_factory
+
+    def _actor(self, value: Any) -> str:
+        actor = _uid(value, "actor_uid")
+        if self.repository.users_available({actor}) != {actor}:
+            raise ValueError("trusted-delivery actor is unavailable")
+        return actor
+
+    def _event(self, action: str, actor_uid: str, detail: dict[str, Any]) -> None:
+        if hasattr(self.repository, "add_evidence"):
+            self.repository.add_evidence({
+                "uid": self.uid_factory(), "action": action, "actor_uid": actor_uid,
+                "safe_detail": copy.deepcopy(detail), "created_at": self.now_factory().isoformat(),
+            })
+
+    def create_policy_version(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"code", "version", "selector", "resource_rules"}, "trusted delivery policy")
+        actor = self._actor(actor_uid)
+        code = _text(body.get("code"), "policy code", 120).upper()
+        if not _CODE.fullmatch(code):
+            raise ValueError("policy code is invalid")
+        selector = _closed(body.get("selector"), {"subjects", "roles", "business_domains", "assets", "purposes", "environments", "actions", "classifications", "expires_at"}, "policy selector")
+        subjects = sorted({_uid(item, "policy subject") for item in _values(selector.get("subjects", []), "policy subjects", minimum=0)})
+        roles = sorted({_text(item, "policy role", 80) for item in _values(selector.get("roles", []), "policy roles", minimum=0)})
+        if not subjects and not roles:
+            raise ValueError("policy selector requires a subject or role")
+        if subjects and self.repository.users_available(set(subjects)) != set(subjects):
+            raise ValueError("policy selector contains unavailable users")
+        rules = _closed(body.get("resource_rules"), {"row_filter", "field_rules"}, "resource rules")
+        field_rules = []
+        for item in _values(rules.get("field_rules"), "field rules", maximum=500):
+            field_rule = _closed(item, {"field", "effect", "mask_ref"}, "field rule")
+            effect = _text(field_rule.get("effect"), "field effect", 10)
+            if effect not in {"allow", "deny"}:
+                raise ValueError("unsupported field effect")
+            mask_ref = field_rule.get("mask_ref")
+            if mask_ref is not None:
+                mask_ref = _text(mask_ref, "mask ref", 120)
+                if not re.fullmatch(r"[a-z][a-z0-9-]{2,119}-v[1-9][0-9]*", mask_ref):
+                    raise ValueError("mask ref is invalid")
+            field_rules.append({"field": _field(field_rule.get("field"), "field rule field"), "effect": effect, "mask_ref": mask_ref})
+        if len({item["field"] for item in field_rules}) != len(field_rules):
+            raise ValueError("field rules must not duplicate fields")
+        expires_at = _time(selector.get("expires_at"), "policy expiry")
+        now = self.now_factory().astimezone(UTC)
+        if expires_at <= now:
+            raise ValueError("policy expiry must be in the future")
+        record = {
+            "uid": self.uid_factory(), "code": code, "version": _text(body.get("version"), "policy version", 30),
+            # A policy never becomes effective by creation alone.  This keeps
+            # both first and subsequent versions behind the durable approval
+            # transition, rather than treating an empty policy history as an
+            # implicit approval.
+            "status": "draft", "selector": {
+                "subjects": subjects, "roles": roles,
+                "business_domains": sorted({_uid(item, "business domain") for item in _values(selector.get("business_domains"), "business domains")}),
+                "assets": sorted({_uid(item, "asset") for item in _values(selector.get("assets"), "assets")}),
+                "purposes": sorted({_text(item, "purpose", 100) for item in _values(selector.get("purposes"), "purposes")}),
+                "environments": _simple_values(selector.get("environments"), "environments", _ENVIRONMENTS),
+                "actions": _simple_values(selector.get("actions"), "actions", _ACTIONS),
+                "classifications": _simple_values(selector.get("classifications"), "classifications", _CLASSIFICATIONS),
+                "expires_at": expires_at.isoformat(),
+            },
+            "resource_rules": {"row_filter": _row_filter(rules.get("row_filter")), "field_rules": sorted(field_rules, key=lambda item: item["field"])},
+            "created_by": actor, "created_at": now.isoformat(), "current_version": 1,
+        }
+        saved = self.repository.create_policy_version(record)
+        self._event("policy_version_created", actor, {"policy_code": code, "version": record["version"]})
+        return saved
+
+    def _lifecycle_request(self, payload: Any, *, label: str) -> tuple[dict[str, Any], str, str, str]:
+        body = _closed(payload, {"code", "version", "approval_ref", "approval_digest", "idempotency_key"}, label)
+        actor = self._actor(payload.get("actor_uid")) if isinstance(payload, dict) and "actor_uid" in payload else None
+        # Callers supply the actor separately.  This branch only keeps direct
+        # service use closed if a malformed payload is passed.
+        if actor is not None:
+            raise ValueError("actor_uid must not be in lifecycle payload")
+        return (
+            body,
+            _text(body.get("code"), "policy code", 120).upper(),
+            _text(body.get("version"), "policy version", 30),
+            _text(body.get("idempotency_key"), "idempotency key", 160),
+        )
+
+    def _policy_transition(self, payload: Any, *, actor_uid: str, operation: str) -> dict[str, Any]:
+        body = _closed(payload, {"code", "version", "approval_ref", "approval_digest", "idempotency_key"}, "policy transition")
+        actor = self._actor(actor_uid)
+        code = _text(body.get("code"), "policy code", 120).upper()
+        if not _CODE.fullmatch(code):
+            raise ValueError("policy code is invalid")
+        version = _text(body.get("version"), "policy version", 30)
+        approval_ref = _text(body.get("approval_ref"), "approval reference", 200)
+        approval_digest = _digest_value(body.get("approval_digest"), "approval digest")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        request_digest = _digest({"operation": operation, "code": code, "version": version, "approval_ref": approval_ref, "approval_digest": approval_digest})
+        if hasattr(self.repository, "transition_policy"):
+            saved = self.repository.transition_policy(code, version, operation, key, request_digest, actor, approval_ref, approval_digest)
+        elif hasattr(self.repository, "policies"):
+            # Small test repositories intentionally do not emulate PostgreSQL;
+            # preserve the same state rules for service-level tests.
+            history = getattr(self.repository, "policy_transitions", {})
+            existing = history.get(key)
+            if existing:
+                if existing["request_digest"] != request_digest:
+                    raise RuntimeError("trusted delivery idempotency conflict")
+                return copy.deepcopy(existing["result"])
+            target = next((item for item in self.repository.policies.values() if item["code"] == code and item["version"] == version), None)
+            if target is None:
+                raise LookupError("trusted delivery policy version was not found")
+            for item in self.repository.policies.values():
+                if item["code"] == code and item["uid"] != target["uid"] and item["status"] == "active":
+                    item["status"] = "retired"
+                    item["current_version"] += 1
+            if target["status"] != "active":
+                target["status"] = "active"
+                target["current_version"] += 1
+            saved = {key: target[key] for key in ("uid", "code", "version", "status", "current_version")}
+            history[key] = {"request_digest": request_digest, "result": copy.deepcopy(saved)}
+            self.repository.policy_transitions = history
+        else:
+            raise RuntimeError("durable policy transition repository is required")
+        self._event(f"policy_{operation}", actor, {"policy_code": code, "version": version, "approval_digest": approval_digest})
+        return saved
+
+    def activate_policy_version(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._policy_transition(payload, actor_uid=actor_uid, operation="activate")
+
+    def rollback_policy_version(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._policy_transition(payload, actor_uid=actor_uid, operation="rollback")
+
+    def evaluate_gateway(self, payload: Any) -> dict[str, Any]:
+        body = _closed(payload, {"subject_uid", "roles", "business_domain_uid", "asset_uid", "purpose", "environment", "action", "classification", "requested_fields"}, "gateway request")
+        context = {
+            "subject_uid": _uid(body.get("subject_uid"), "subject_uid"),
+            "roles": sorted({_text(item, "role", 80) for item in _values(body.get("roles"), "roles", minimum=0)}),
+            "business_domain_uid": _uid(body.get("business_domain_uid"), "business_domain_uid"),
+            "asset_uid": _uid(body.get("asset_uid"), "asset_uid"), "purpose": _text(body.get("purpose"), "purpose", 100),
+            "environment": _text(body.get("environment"), "environment", 30), "action": _text(body.get("action"), "action", 20),
+            "classification": _text(body.get("classification"), "classification", 30),
+            "requested_fields": sorted({_field(item, "requested field") for item in _values(body.get("requested_fields"), "requested fields", maximum=500)}),
+        }
+        if context["environment"] not in _ENVIRONMENTS or context["action"] not in _ACTIONS or context["classification"] not in _CLASSIFICATIONS:
+            raise ValueError("unsupported gateway environment, action, or classification")
+        if context["action"] == "export" and self.repository.active_hold_for_asset(context["asset_uid"]):
+            return {"decision": "deny", "reason_code": "active_legal_hold"}
+        if context["action"] == "export" and context["classification"] == "highly_sensitive":
+            return {"decision": "deny", "reason_code": "highly_sensitive_export_denied"}
+        now = self.now_factory().astimezone(UTC)
+        for policy in self.repository.active_policies():
+            selector = policy["selector"]
+            if _time(selector["expires_at"], "policy expiry") <= now:
+                continue
+            if not (context["subject_uid"] in selector["subjects"] or set(context["roles"]) & set(selector["roles"])):
+                continue
+            selector_keys = {
+                "business_domain_uid": "business_domains", "asset_uid": "assets",
+                "purpose": "purposes", "environment": "environments",
+                "action": "actions", "classification": "classifications",
+            }
+            if any(context[key] not in selector[selector_keys[key]] for key in selector_keys):
+                continue
+            rules = {rule["field"]: rule for rule in policy["resource_rules"]["field_rules"]}
+            if any(field not in rules or rules[field]["effect"] != "allow" for field in context["requested_fields"]):
+                continue
+            masks = {field: rules[field]["mask_ref"] for field in context["requested_fields"] if rules[field]["mask_ref"]}
+            return {"decision": "allow", "reason_code": "policy_allowed", "policy_code": policy["code"], "policy_version": policy["version"], "projected_fields": context["requested_fields"], "row_filter": policy["resource_rules"]["row_filter"], "field_masks": masks}
+        return {"decision": "deny", "reason_code": "default_deny"}
+
+    def create_grant(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"policy_uid", "approval_ref", "approval_digest", "subject_uid", "asset_uid", "provider", "expires_at", "decision"}, "trusted delivery grant")
+        actor = self._actor(actor_uid)
+        decision = _closed(body.get("decision"), {"decision", "reason_code", "policy_code", "policy_version", "projected_fields", "row_filter", "field_masks"}, "grant decision")
+        if decision.get("decision") != "allow":
+            raise PermissionError("trusted delivery grant requires allowed decision")
+        provider = _text(body.get("provider"), "provider", 30)
+        self.provider_registry.get(provider)
+        expires_at = _time(body.get("expires_at"), "grant expiry")
+        if expires_at <= self.now_factory().astimezone(UTC):
+            raise ValueError("grant expiry must be in the future")
+        record = {
+            "uid": self.uid_factory(), "policy_uid": _uid(body.get("policy_uid"), "policy_uid"),
+            "approval_ref": _text(body.get("approval_ref"), "approval reference", 200),
+            "approval_digest": _digest_value(body.get("approval_digest"), "approval digest"),
+            "subject_uid": _uid(body.get("subject_uid"), "subject_uid"), "asset_uid": _uid(body.get("asset_uid"), "asset_uid"),
+            "provider": provider, "expires_at": expires_at.isoformat(), "status": "active", "reason_code": "approval_bound",
+            "decision_digest": _digest(decision), "current_version": 1, "created_by": actor, "created_at": self.now_factory().isoformat(),
+        }
+        saved = self.repository.create_grant(record)
+        result = self.repository.get_grant(saved["uid"]) if hasattr(self.repository, "get_grant") else saved
+        self._event("grant_created", actor, {"grant_uid": result["uid"], "provider": provider, "decision_digest": record["decision_digest"]})
+        return result
+
+    def dispatch_grant(self, grant_uid: str, *, actor_uid: str) -> dict[str, Any]:
+        actor = self._actor(actor_uid)
+        if hasattr(self.repository, "get_grant"):
+            grant = self.repository.get_grant(_uid(grant_uid, "grant_uid"))
+        elif hasattr(self.repository, "grants"):
+            grant = copy.deepcopy(self.repository.grants.get(_uid(grant_uid, "grant_uid")))
+        else:
+            raise RuntimeError("durable dispatch repository is required")
+        if not grant or grant["status"] != "active":
+            raise LookupError("active trusted delivery grant was not found")
+        response = self.provider_registry.get(grant["provider"]).apply({
+            "schema": "dataops.trusted-delivery.v1", "grant_uid": grant["uid"], "provider": grant["provider"],
+            "subject_uid": grant["subject_uid"], "asset_uid": grant["asset_uid"], "expires_at": grant["expires_at"], "decision_digest": grant["decision_digest"],
+        })
+        response = _closed(response, {"status", "receipt_code", "response_digest"}, "provider receipt")
+        if response.get("status") != "applied":
+            raise RuntimeError("trusted delivery provider failed closed")
+        receipt = {"grant_uid": grant["uid"], "status": "applied", "receipt_code": _text(response.get("receipt_code"), "receipt code", 120), "response_digest": _digest_value(response.get("response_digest"), "provider response digest")}
+        self._event("grant_dispatched", actor, receipt)
+        return receipt
+
+    def provision(self, payload: Any, *, actor_uid: str, subject_roles: list[str] | None = None) -> dict[str, Any]:
+        """Create and apply one approval-bound, digest-only capability grant."""
+        body = _closed(payload, {"policy_uid", "approval_ref", "approval_digest", "subject_uid", "asset_uid", "business_domain_uid", "purpose", "environment", "action", "classification", "requested_fields", "expires_at", "target_capability", "provider", "idempotency_key"}, "trusted delivery provision")
+        actor = self._actor(actor_uid)
+        provider = _text(body.get("provider"), "provider", 30)
+        adapter = self.provider_registry.get(provider)
+        capability = _closed(body.get("target_capability"), {"actions", "fields"}, "target capability")
+        target_capability = {
+            "actions": _simple_values(capability.get("actions"), "capability actions", _ACTIONS),
+            "fields": sorted({_field(item, "capability field") for item in _values(capability.get("fields"), "capability fields", maximum=500)}),
+        }
+        approval_ref = _text(body.get("approval_ref"), "approval reference", 200)
+        approval_digest = _digest_value(body.get("approval_digest"), "approval digest")
+        policy_uid = _uid(body.get("policy_uid"), "policy_uid")
+        subject_uid = _uid(body.get("subject_uid"), "subject_uid")
+        asset_uid = _uid(body.get("asset_uid"), "asset_uid")
+        context = {
+            "subject_uid": subject_uid,
+            "roles": list(subject_roles or []),
+            "business_domain_uid": _uid(body.get("business_domain_uid"), "business_domain_uid"),
+            "asset_uid": asset_uid,
+            "purpose": _text(body.get("purpose"), "purpose", 100),
+            "environment": _text(body.get("environment"), "environment", 30),
+            "action": _text(body.get("action"), "action", 20),
+            "classification": _text(body.get("classification"), "classification", 30),
+            "requested_fields": sorted({_field(item, "requested field") for item in _values(body.get("requested_fields"), "requested fields", maximum=500)}),
+        }
+        # Re-evaluate from the durable, active policy version.  A caller's
+        # policy UID, capability and approval labels are only references; none
+        # of them is allowed to enlarge the authorisation projection.
+        decision = self.evaluate_gateway(context)
+        active = next((item for item in self.repository.active_policies() if item.get("uid") == policy_uid), None)
+        if active is None or decision.get("decision") != "allow" or active["code"] != decision.get("policy_code") or active["version"] != decision.get("policy_version"):
+            raise PermissionError("trusted delivery provision is not allowed by active policy")
+        if set(target_capability["actions"]) != {context["action"]} or set(target_capability["fields"]) != set(decision["projected_fields"]):
+            raise PermissionError("target capability exceeds server policy projection")
+        expires_at = _time(body.get("expires_at"), "grant expiry")
+        if expires_at <= self.now_factory().astimezone(UTC):
+            raise ValueError("grant expiry must be in the future")
+        policy_expiry = _time(active["selector"]["expires_at"], "policy expiry")
+        if expires_at > policy_expiry:
+            raise PermissionError("grant expiry exceeds active policy")
+        if "export" in target_capability["actions"] and self.repository.active_hold_for_asset(asset_uid):
+            raise PermissionError("active legal hold blocks export provision")
+        projection = {
+            "fields": decision["projected_fields"],
+            "row_predicate": decision["row_filter"],
+            "masking": decision["field_masks"],
+        }
+        decision_digest = _digest({"policy_uid": policy_uid, "policy_code": active["code"], "policy_version": active["version"], "context": context, "projection": projection, "approval_digest": approval_digest})
+        record = {
+            "uid": self.uid_factory(), "policy_uid": policy_uid,
+            "approval_ref": approval_ref, "approval_digest": approval_digest,
+            "subject_uid": subject_uid, "asset_uid": asset_uid,
+            "purpose": context["purpose"], "environment": context["environment"],
+            "target_capability": target_capability, "provider": provider,
+            "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160),
+            "expires_at": expires_at.isoformat(), "status": "active", "reason_code": "approval_bound",
+            "request_digest": _digest({"decision_digest": decision_digest, "provider": provider, "expires_at": expires_at.isoformat(), "idempotency_key": body.get("idempotency_key")}),
+            "decision_digest": decision_digest,
+            "current_version": 1, "created_by": actor,
+        }
+        if hasattr(self.repository, "enqueue_grant"):
+            grant = self.repository.enqueue_grant(record)
+            grant_uid = grant["uid"]
+            if hasattr(self.repository, "get_grant"):
+                stored = self.repository.get_grant(grant_uid)
+                if stored and stored.get("status") == "reclaimed":
+                    raise RuntimeError("trusted delivery grant was reclaimed")
+            if hasattr(self.repository, "get_provision_receipt"):
+                prior_receipt = self.repository.get_provision_receipt(grant_uid, record["idempotency_key"])
+                if prior_receipt:
+                    return {"grant_uid": grant_uid, "status": "applied", "receipt": prior_receipt}
+        else:
+            raise RuntimeError("durable provision repository is required")
+        # Persist a fenced, idempotent outbox intent before the adapter is
+        # permitted to see the request.  A process crash now leaves a retryable
+        # pending record rather than an unprovable external side effect.
+        if hasattr(self.repository, "prepare_provision_operation"):
+            operation = self.repository.prepare_provision_operation(
+                grant_uid, record["idempotency_key"], record["request_digest"]
+            )
+            if operation.get("completed"):
+                return {"grant_uid": grant_uid, "status": "applied", "receipt": operation["receipt"]}
+        elif hasattr(self.repository, "session"):
+            raise RuntimeError("durable provision outbox repository is required")
+        envelope = {"schema": "dataops.trusted-delivery.v2", "operation": "provision", "grant_uid": grant_uid, "policy_uid": record["policy_uid"], "provider": provider, "subject_uid": record["subject_uid"], "asset_uid": record["asset_uid"], "purpose": record["purpose"], "environment": record["environment"], "expires_at": record["expires_at"], "projection": projection, "decision_digest": decision_digest, "request_digest": record["request_digest"]}
+        claim = None
+        if hasattr(self.repository, "claim_provision_operation"):
+            worker = f"provision:{self.uid_factory()}"
+            claim = self.repository.claim_provision_operation(operation["delivery_uid"], worker)
+            if claim.get("state") == "completed":
+                return {"grant_uid": grant_uid, "status": "applied", "receipt": claim["receipt"]}
+            if claim.get("state") != "claimed":
+                # Another process owns the external side effect.  Returning a
+                # pending state is intentionally safer than performing a
+                # duplicate call while that DB-time lease is alive.
+                return {"grant_uid": grant_uid, "status": "pending", "retryable": True}
+        try:
+            response = _closed(adapter.apply(copy.deepcopy(envelope)), {"status", "receipt_code", "response_digest"}, "provider receipt")
+            if response.get("status") != "applied":
+                raise RuntimeError("trusted delivery provider failed closed")
+        except Exception:
+            if claim is not None:
+                # Commit the retryable outbox state before the HTTP boundary
+                # rolls back the failed request transaction.
+                self.repository.fail_provision_operation(operation["delivery_uid"], worker, claim["lease_fence"])
+                self.repository.session.commit()
+            raise
+        receipt = {"grant_uid": grant_uid, "status": "applied", "receipt_code": _text(response.get("receipt_code"), "receipt code", 120), "response_digest": _digest_value(response.get("response_digest"), "provider response digest"), "diff_digest": _digest({"operation": "provision", "request_digest": record["request_digest"], "response_digest": response.get("response_digest")})}
+        if claim is not None:
+            saved = self.repository.complete_provision_operation(
+                grant_uid, operation["delivery_uid"], worker, claim["lease_fence"], receipt
+            )
+            receipt = {**receipt, "grant_uid": saved.get("uid", grant_uid)}
+        elif hasattr(self.repository, "record_provision_receipt"):
+            receipt = self.repository.record_provision_receipt(grant_uid, record["idempotency_key"], record["request_digest"], receipt)
+        self._event("provision_applied", actor, {"grant_uid": grant_uid, "provider": provider, "request_digest": record["request_digest"], "response_digest": receipt["response_digest"]})
+        return {"grant_uid": grant_uid, "status": "applied", "receipt": receipt}
+
+    def create_legal_hold(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"asset_uid", "operation", "approver_refs", "evidence_digest"}, "legal hold")
+        actor = self._actor(actor_uid)
+        asset_uid = _uid(body.get("asset_uid"), "asset_uid")
+        if self.repository.active_hold_for_asset(asset_uid):
+            raise RuntimeError("active legal hold already exists")
+        operation = _text(body.get("operation"), "legal hold operation", 30)
+        if operation not in {"freeze", "export_review", "destruction_review"}:
+            raise ValueError("unsupported legal hold operation")
+        approvers = sorted({_text(item, "approver reference", 200) for item in _values(body.get("approver_refs"), "approver references", minimum=2, maximum=2)})
+        if len(approvers) != 2:
+            raise ValueError("legal hold requires two distinct approver references")
+        record = {
+            "uid": self.uid_factory(), "asset_uid": asset_uid, "operation": operation,
+            # The SQL schema intentionally stores the two approvals in separate
+            # columns so a parameter mapping cannot silently collapse them.
+            "approver_ref_one": approvers[0], "approver_ref_two": approvers[1],
+            "approver_refs": approvers, "evidence_digest": _digest_value(body.get("evidence_digest"), "evidence digest"),
+            "status": "active", "created_by": actor, "created_at": self.now_factory().isoformat(), "current_version": 1,
+        }
+        saved = self.repository.create_legal_hold(record)
+        self._event("legal_hold_active", actor, {"hold_uid": saved["uid"], "operation": operation})
+        return saved
+
+    def release_legal_hold(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"hold_uid", "approval_ref", "approval_digest", "idempotency_key"}, "legal hold release")
+        actor = self._actor(actor_uid)
+        hold_uid = _uid(body.get("hold_uid"), "hold_uid")
+        approval_ref = _text(body.get("approval_ref"), "approval reference", 200)
+        approval_digest = _digest_value(body.get("approval_digest"), "approval digest")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        request_digest = _digest({"hold_uid": hold_uid, "approval_ref": approval_ref, "approval_digest": approval_digest})
+        if hasattr(self.repository, "release_legal_hold"):
+            saved = self.repository.release_legal_hold(hold_uid, key, request_digest, actor, approval_ref, approval_digest)
+        elif hasattr(self.repository, "holds"):
+            releases = getattr(self.repository, "hold_releases", {})
+            existing = releases.get(key)
+            if existing:
+                if existing["request_digest"] != request_digest:
+                    raise RuntimeError("trusted delivery idempotency conflict")
+                return copy.deepcopy(existing["result"])
+            hold = self.repository.holds.get(hold_uid)
+            if not hold:
+                raise LookupError("trusted delivery legal hold was not found")
+            if hold["created_by"] == actor or approval_ref in hold["approver_refs"]:
+                raise PermissionError("legal hold release requires an independent approval")
+            hold["status"] = "released"
+            hold["current_version"] += 1
+            saved = {"uid": hold_uid, "status": "released", "current_version": hold["current_version"]}
+            releases[key] = {"request_digest": request_digest, "result": copy.deepcopy(saved)}
+            self.repository.hold_releases = releases
+        else:
+            raise RuntimeError("durable legal hold repository is required")
+        self._event("legal_hold_released", actor, {"hold_uid": hold_uid, "approval_digest": approval_digest})
+        return saved
+
+    def execute_reclaim(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        """Request provider revocation first; never delete or reclaim optimistically."""
+        body = _closed(payload, {"grant_uid", "idempotency_key"}, "trusted delivery reclaim")
+        actor = self._actor(actor_uid)
+        grant_uid = _uid(body.get("grant_uid"), "grant_uid")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        if not hasattr(self.repository, "get_grant"):
+            raise RuntimeError("durable reclaim repository is required")
+        grant = self.repository.get_grant(grant_uid)
+        if not grant:
+            raise LookupError("trusted delivery grant was not found")
+        now = self.now_factory().astimezone(UTC)
+        if grant.get("status") == "reclaimed":
+            return {"grant_uid": grant_uid, "status": "reclaimed", "idempotent": True}
+        if grant.get("status") != "active" or _time(grant["expires_at"], "grant expiry") > now:
+            raise ValueError("trusted delivery grant is not reclaimable")
+        if self.repository.active_hold_for_asset(grant["asset_uid"]):
+            raise PermissionError("active legal hold blocks reclaim")
+        expiry = _time(grant["expires_at"], "grant expiry").isoformat()
+        request_digest = _digest({"operation": "revoke", "grant_uid": grant_uid, "provider": grant["provider"], "expires_at": expiry})
+        worker_id = f"reclaim-{uuid.uuid4()}"
+        claim = None
+        if hasattr(self.repository, "claim_reclaim_operation"):
+            claim = self.repository.claim_reclaim_operation(grant_uid, key, request_digest, worker_id)
+            if claim["state"] == "completed":
+                return {"grant_uid": grant_uid, "status": "reclaimed", "idempotent": True}
+            if claim["state"] == "leased":
+                raise RuntimeError("trusted delivery reclaim is already leased")
+        try:
+            adapter = self.provider_registry.get(grant["provider"])
+        except PermissionError:
+            self._event("reclaim_provider_unavailable", actor, {"grant_uid": grant_uid, "provider": grant["provider"], "request_digest": request_digest})
+            raise
+        envelope = {"schema": "dataops.trusted-delivery.v2", "operation": "revoke", "grant_uid": grant_uid, "provider": grant["provider"], "asset_uid": grant["asset_uid"], "request_digest": request_digest}
+        revoke = getattr(adapter, "revoke", None)
+        if not callable(revoke):
+            self._event("reclaim_provider_unavailable", actor, {"grant_uid": grant_uid, "provider": grant["provider"], "request_digest": request_digest})
+            raise PermissionError("trusted delivery provider revoke is disabled")
+        try:
+            response = _closed(revoke(copy.deepcopy(envelope)), {"status", "receipt_code", "response_digest"}, "provider receipt")
+        except Exception:
+            if claim:
+                self.repository.fail_reclaim_operation(claim["delivery_uid"], worker_id, claim["lease_fence"])
+            raise
+        if response.get("status") != "revoked":
+            if claim:
+                self.repository.fail_reclaim_operation(claim["delivery_uid"], worker_id, claim["lease_fence"])
+            raise RuntimeError("trusted delivery provider failed closed")
+        receipt = {"grant_uid": grant_uid, "status": "reclaimed", "receipt_code": _text(response.get("receipt_code"), "receipt code", 120), "response_digest": _digest_value(response.get("response_digest"), "provider response digest"), "diff_digest": _digest({"operation": "revoke", "request_digest": request_digest, "response_digest": response.get("response_digest")})}
+        if claim:
+            saved = self.repository.complete_claimed_reclaim(grant_uid, claim["delivery_uid"], worker_id, claim["lease_fence"], receipt)
+        elif hasattr(self.repository, "complete_reclaim"):
+            saved = self.repository.complete_reclaim(grant_uid, key, request_digest, receipt)
+        else:
+            saved = self.repository.update_grant_status(grant_uid, grant["current_version"], "reclaimed", "expired_reclaimed")
+        self._event("grant_reclaimed", actor, {"grant_uid": grant_uid, "provider": grant["provider"], "request_digest": request_digest, "response_digest": receipt["response_digest"]})
+        return {"grant_uid": grant_uid, "status": saved["status"], "receipt": receipt}
+
+    def preview_reclaim(self, *, as_of: Any, actor_uid: str) -> list[dict[str, Any]]:
+        """Return eligible identifiers only; this query has no state transition."""
+        self._actor(actor_uid)
+        instant = _time(as_of, "as_of")
+        candidates = []
+        for grant in self.repository.grants_due_for_revoke(instant):
+            if grant.get("status") != "active" or _time(grant["expires_at"], "grant expiry") > instant:
+                continue
+            if self.repository.active_hold_for_asset(grant["asset_uid"]):
+                continue
+            candidates.append({"grant_uid": grant["uid"], "provider": grant.get("provider", "unknown"), "status": "eligible"})
+        return candidates
+
+    def revoke_expired(self, *, as_of: datetime, actor_uid: str) -> list[dict[str, Any]]:
+        actor = self._actor(actor_uid)
+        instant = _time(as_of, "as_of")
+        revoked = []
+        for grant in self.repository.grants_due_for_revoke(instant):
+            if _time(grant["expires_at"], "grant expiry") > instant or self.repository.active_hold_for_asset(grant["asset_uid"]):
+                continue
+            saved = self.repository.update_grant_status(grant["uid"], grant["current_version"], "revoked", "expired")
+            self._event("grant_revoked", actor, {"grant_uid": saved["uid"], "reason_code": "expired"})
+            revoked.append(saved)
+        return revoked
+
+    @staticmethod
+    def mask_preview(payload: Any) -> dict[str, Any]:
+        body = _closed(payload, {"mode", "mask_ref", "value"}, "mask preview")
+        mode = _text(body.get("mode"), "mask mode", 20)
+        if mode not in {"static", "dynamic", "display", "export"}:
+            raise ValueError("unsupported mask mode")
+        mask_ref = _text(body.get("mask_ref"), "mask ref", 120)
+        value = _text(body.get("value"), "mask value", 1000)
+        return {"mode": mode, "mask_ref": mask_ref, "masked_value": "***-****", "token_digest": _digest({"mask_ref": mask_ref, "value": value})}

+ 293 - 0
deployment/app/core/system/trusted_delivery_controls.py

@@ -0,0 +1,293 @@
+"""Fail-closed control-profile and trusted-delivery gate contracts.
+
+The module deliberately models only safe identifiers, digests and decision
+codes.  It neither stores scan payloads or credentials nor claims that an
+external legal, identity, network or industry assessment has happened.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import hmac
+import json
+import re
+from collections.abc import Callable, Mapping
+from datetime import UTC, datetime
+from typing import Any
+
+
+class TrustedDeliveryControlError(ValueError):
+    """The closed trusted-delivery controls rejected a caller supplied value."""
+
+
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_REF = re.compile(r"^[a-z][a-z0-9-]{2,40}:[A-Za-z0-9._-]{1,160}$")
+_ID = re.compile(r"^[A-Za-z][A-Za-z0-9._-]{2,159}$")
+_VERSION = re.compile(r"^[A-Za-z][A-Za-z0-9._-]{0,39}$")
+_UNSAFE = re.compile(
+    r"(?i)(?:https?://|ftp://|file://|\b(?:credential|secret|token|password|private[ _-]?key)\b|"
+    r"-----BEGIN|<script|javascript:|;|\b(?:select|insert|update|delete|drop|alter)\b)"
+)
+_CAPABILITIES = {
+    "kms": frozenset({"kms-key-wrap", "kms-evidence-seal"}),
+    "dlp": frozenset({"dlp-export-check"}),
+    "siem": frozenset({"siem-security-event"}),
+    "iam": frozenset({"iam-entitlement-provision"}),
+    "target": frozenset({"target-db-provision", "target-api-provision", "target-file-provision"}),
+}
+
+
+def _canonical(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _digest(value: Any) -> str:
+    return hashlib.sha256(_canonical(value).encode()).hexdigest()
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise TrustedDeliveryControlError(f"{label} must be an object")
+    extra = set(value) - allowed
+    if extra:
+        raise TrustedDeliveryControlError(f"{label} contains unsupported fields")
+    return copy.deepcopy(value)
+
+
+def _text(value: Any, label: str, maximum: int = 160) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise TrustedDeliveryControlError(f"{label} is required")
+    result = value.strip()
+    if len(result) > maximum:
+        raise TrustedDeliveryControlError(f"{label} exceeds {maximum} characters")
+    if _UNSAFE.search(result):
+        raise TrustedDeliveryControlError(f"{label} contains unsafe content")
+    return result
+
+
+def _sha256(value: Any, label: str) -> str:
+    result = _text(value, label, 64).lower()
+    if not _DIGEST.fullmatch(result):
+        raise TrustedDeliveryControlError(f"{label} must be a SHA-256 digest")
+    return result
+
+
+def _instant(value: Any, label: str) -> datetime:
+    try:
+        result = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as error:
+        raise TrustedDeliveryControlError(f"{label} must be ISO-8601") from error
+    if result.tzinfo is None:
+        raise TrustedDeliveryControlError(f"{label} must include a timezone")
+    return result.astimezone(UTC)
+
+
+class ControlProfileCatalog:
+    """Versioned engineering evidence mappings, never external certification."""
+
+    _profiles = {
+        "china_general": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-16", "SEC-20"),
+        "finance": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-17", "SEC-20", "SEC-21"),
+        "medical": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-18", "SEC-20", "SEC-21"),
+        "government": ("SEC-04", "SEC-05", "SEC-06", "SEC-07", "SEC-14", "SEC-19", "SEC-20", "SEC-22"),
+    }
+
+    def resolve(self, profile_id: Any, version: Any) -> dict[str, Any]:
+        name = _text(profile_id, "control profile", 40)
+        release = _text(version, "control profile version", 20)
+        if release != "1.0" or name not in self._profiles:
+            raise TrustedDeliveryControlError("unknown control profile version")
+        modules = self._profiles[name]
+        return {
+            "profile_id": name,
+            "version": release,
+            "conformance_state": "ENGINEERING_EVIDENCE_ONLY",
+            "external_required": True,
+            "external_dependencies": ["security_legal", "identity", "network"],
+            "evidence_mapping": [
+                {"module_id": module_id, "evidence_kind": "engineering_control_reference"}
+                for module_id in modules
+            ],
+        }
+
+
+class TrustedCapabilityRegistry:
+    """Closed, default-disabled capabilities with locally verifiable fake receipts."""
+
+    def __init__(self, approved: Mapping[str, Mapping[str, str]] | None = None, *, test_mode: bool = False):
+        values = dict(approved or {})
+        if values and not test_mode:
+            raise TrustedDeliveryControlError("enterprise capabilities require approved external integration")
+        if set(values) - set(_CAPABILITIES):
+            raise TrustedDeliveryControlError("unsupported capability provider")
+        self._approved: dict[str, dict[str, str]] = {}
+        for provider, descriptor in values.items():
+            body = _closed(descriptor, {"version", "config_digest"}, "capability descriptor")
+            version = _text(body.get("version"), "capability version", 30)
+            if not _VERSION.fullmatch(version):
+                raise TrustedDeliveryControlError("capability version is invalid")
+            self._approved[provider] = {
+                "version": version,
+                "config_digest": _sha256(body.get("config_digest"), "capability config digest"),
+            }
+        self._replay: dict[str, str] = {}
+
+    @classmethod
+    def for_tests(cls, approved: Mapping[str, Mapping[str, str]]):
+        return cls(approved, test_mode=True)
+
+    def dependency_status(self) -> dict[str, str]:
+        return {
+            provider: "LOCAL_FAKE_ONLY" if provider in self._approved else "TBD_EXTERNAL"
+            for provider in sorted(_CAPABILITIES)
+        }
+
+    def _key(self, provider: str) -> bytes:
+        descriptor = self._approved[provider]
+        return hashlib.sha256(
+            f"trusted-delivery-local-fake:{provider}:{descriptor['version']}:{descriptor['config_digest']}".encode()
+        ).digest()
+
+    def issue_envelope(self, provider: Any, capability: Any, payload: Any) -> dict[str, str]:
+        provider_name = _text(provider, "capability provider", 30)
+        operation = _text(capability, "capability", 80)
+        if provider_name not in _CAPABILITIES or operation not in _CAPABILITIES[provider_name]:
+            raise TrustedDeliveryControlError("unsupported capability")
+        if provider_name not in self._approved:
+            raise TrustedDeliveryControlError("capability provider is disabled")
+        body = _closed(payload, {"request_digest", "expires_at"}, "capability envelope request")
+        request_digest = _sha256(body.get("request_digest"), "request digest")
+        expires_at = _instant(body.get("expires_at"), "capability envelope expiry")
+        if expires_at <= datetime.now(UTC):
+            raise TrustedDeliveryControlError("capability envelope is expired")
+        replay_key = f"{provider_name}:{operation}:{request_digest}"
+        request_fingerprint = _digest({"request_digest": request_digest, "expires_at": expires_at.isoformat()})
+        if replay_key in self._replay:
+            if self._replay[replay_key] != request_fingerprint:
+                raise TrustedDeliveryControlError("capability replay conflict")
+            raise TrustedDeliveryControlError("capability replay rejected")
+        descriptor = self._approved[provider_name]
+        envelope = {
+            "capability": operation,
+            "version": descriptor["version"],
+            "config_digest": descriptor["config_digest"],
+            "request_digest": request_digest,
+            "expires_at": expires_at.isoformat(),
+            "receipt": f"LOCAL_FAKE_{_digest([provider_name, operation, request_digest])[:20].upper()}",
+        }
+        envelope["signature"] = hmac.new(self._key(provider_name), _canonical(envelope).encode(), hashlib.sha256).hexdigest()
+        self._replay[replay_key] = request_fingerprint
+        return envelope
+
+    def verify_envelope(self, envelope: Any) -> bool:
+        body = _closed(envelope, {"capability", "version", "config_digest", "request_digest", "expires_at", "receipt", "signature"}, "capability receipt")
+        operation = _text(body.get("capability"), "capability", 80)
+        provider = next((name for name, allowed in _CAPABILITIES.items() if operation in allowed), None)
+        if provider is None or provider not in self._approved:
+            raise TrustedDeliveryControlError("capability receipt is disabled")
+        descriptor = self._approved[provider]
+        if body.get("version") != descriptor["version"] or body.get("config_digest") != descriptor["config_digest"]:
+            raise TrustedDeliveryControlError("capability receipt binding is invalid")
+        _sha256(body.get("request_digest"), "request digest")
+        if _instant(body.get("expires_at"), "capability receipt expiry") <= datetime.now(UTC):
+            raise TrustedDeliveryControlError("capability receipt is expired")
+        receipt = _text(body.get("receipt"), "receipt", 80)
+        signature = _sha256(body.get("signature"), "receipt signature")
+        signed = {key: body[key] for key in body if key != "signature"}
+        expected = hmac.new(self._key(provider), _canonical(signed).encode(), hashlib.sha256).hexdigest()
+        if not hmac.compare_digest(signature, expected):
+            raise TrustedDeliveryControlError("capability receipt signature is invalid")
+        if not receipt.startswith("LOCAL_FAKE_"):
+            raise TrustedDeliveryControlError("capability receipt is invalid")
+        return True
+
+
+class SupplyChainReleaseGate:
+    """Digest-only release gate; a passing result is not a production approval."""
+
+    def __init__(self, *, now_factory: Callable[[], datetime] | None = None):
+        self.now_factory = now_factory or (lambda: datetime.now(UTC))
+
+    def evaluate(self, payload: Any) -> dict[str, str]:
+        body = _closed(payload, {
+            "artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest",
+            "approval_id", "approval_version", "scan_decision", "evidence_expires_at",
+        }, "release gate")
+        required = (
+            "artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest",
+            "approval_id", "approval_version", "scan_decision", "evidence_expires_at",
+        )
+        if any(key not in body or body[key] in (None, "") for key in required):
+            raise TrustedDeliveryControlError("missing release gate evidence")
+        digests = {key: _sha256(body[key], key.replace("_", " ")) for key in required[:4]}
+        approval_id = _text(body["approval_id"], "approval id", 160)
+        approval_version = _text(body["approval_version"], "approval version", 40)
+        if not _ID.fullmatch(approval_id) or not _VERSION.fullmatch(approval_version):
+            raise TrustedDeliveryControlError("release approval is invalid")
+        expiry = _instant(body["evidence_expires_at"], "release gate evidence expiry")
+        if expiry <= self.now_factory().astimezone(UTC):
+            raise TrustedDeliveryControlError("release gate evidence is expired")
+        if body["scan_decision"] != "passed":
+            raise TrustedDeliveryControlError("release gate rejected")
+        return {
+            "decision_code": "RELEASE_GATE_APPROVED",
+            **digests,
+            "approval_id": approval_id,
+            "approval_version": approval_version,
+            "evidence_expires_at": expiry.isoformat(),
+        }
+
+
+class EvidenceLedger:
+    """In-memory append-only contract used before its repository migration lands."""
+
+    def __init__(self):
+        self._entries: list[dict[str, str]] = []
+        self._audit: list[dict[str, str]] = []
+
+    def append(self, payload: Any) -> dict[str, str]:
+        body = _closed(payload, {"evidence_ref", "evidence_digest", "decision_code"}, "evidence entry")
+        if set(body) != {"evidence_ref", "evidence_digest", "decision_code"}:
+            raise TrustedDeliveryControlError("evidence entry is incomplete")
+        reference = _text(body["evidence_ref"], "evidence reference", 200)
+        if not _REF.fullmatch(reference):
+            raise TrustedDeliveryControlError("evidence reference is invalid")
+        entry = {
+            "evidence_ref": reference,
+            "evidence_digest": _sha256(body["evidence_digest"], "evidence digest"),
+            "decision_code": _text(body["decision_code"], "decision code", 120),
+        }
+        if any(item["evidence_ref"] == entry["evidence_ref"] for item in self._entries):
+            raise TrustedDeliveryControlError("evidence is immutable")
+        self._entries.append(entry)
+        return dict(entry)
+
+    def export_summary(self) -> list[dict[str, str]]:
+        return [dict(item) for item in self._entries]
+
+    def approve_destruction(self, payload: Any) -> dict[str, str]:
+        body = _closed(payload, {"approval_refs", "active_hold"}, "destruction approval")
+        refs = body.get("approval_refs")
+        if not isinstance(refs, list) or len(refs) != 2:
+            self._audit.append({"decision_code": "DESTRUCTION_REJECTED"})
+            raise TrustedDeliveryControlError("destruction requires two independent approvals")
+        approvals = [_text(item, "destruction approval reference", 160) for item in refs]
+        if approvals[0] == approvals[1]:
+            self._audit.append({"decision_code": "DESTRUCTION_REJECTED"})
+            raise TrustedDeliveryControlError("destruction requires two independent approvals")
+        if body.get("active_hold") is not False:
+            self._audit.append({"decision_code": "DESTRUCTION_HELD"})
+            raise TrustedDeliveryControlError("destruction blocked by active legal hold")
+        result = {"decision_code": "DESTRUCTION_DUAL_APPROVED", "approval_digest": _digest(sorted(approvals))}
+        self._audit.append(dict(result))
+        return result
+
+    def tamper(self, payload: Any) -> None:
+        # Never preserve an attempted replacement value, which may itself be sensitive.
+        _closed(payload, {"evidence_ref", "replacement"}, "tamper attempt")
+        self._audit.append({"decision_code": "TAMPER_REJECTED"})
+        raise TrustedDeliveryControlError("evidence ledger is immutable")
+
+    def audit_events(self) -> list[dict[str, str]]:
+        return [dict(item) for item in self._audit]

+ 150 - 0
deployment/app/core/system/trusted_delivery_controls_repository.py

@@ -0,0 +1,150 @@
+"""PostgreSQL persistence for digest-only trusted-delivery control evidence."""
+
+from __future__ import annotations
+
+import json
+import uuid
+from typing import Any
+
+from sqlalchemy import text
+
+
+def _json(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _row(value) -> dict[str, Any] | None:
+    return None if value is None else dict(value)
+
+
+class SqlAlchemyTrustedDeliveryControlsRepository:
+    """Closed-schema writes; service validation remains the public boundary."""
+
+    def __init__(self, session):
+        self.session = session
+
+    def _trusted_delivery_runtime_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_control_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        result = self.session.execute(text("SELECT public.trusted_delivery_runtime_control_write(:operation, CAST(:payload AS jsonb))"), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _runtime_restricted(self) -> bool:
+        return not self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_control_profile_versions', 'INSERT')
+        """)).scalar_one()
+
+    def users_available(self, values):
+        values = sorted(set(values))
+        if not values:
+            return set()
+        return set(self.session.execute(text("SELECT id::text FROM public.users WHERE status='active' AND id=ANY(CAST(:values AS uuid[]))"), {"values": values}).scalars())
+
+    def create_profile(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("create_control_profile", record))
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_control_profile_versions
+          (uid,profile_id,version,status,profile,profile_digest,created_by,current_version)
+          VALUES(CAST(:uid AS uuid),:profile_id,:version,'draft',CAST(:profile AS jsonb),:profile_digest,CAST(:created_by AS uuid),1)
+          RETURNING uid::text,profile_id,version,status,current_version"""), {**record, "profile": _json(record["profile"])}).mappings().one()
+        return _row(row)
+
+    def profile_exists(self, profile_id, version):
+        return self.session.execute(text("SELECT 1 FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND version=:version"), {"profile": profile_id, "version": version}).scalar_one_or_none() is not None
+
+    def activate_profile(self, profile_id, version, idempotency_key, request_digest, actor_uid, approval_ref, approval_digest, operation="activate"):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("activate_control_profile", {
+                "uid": str(uuid.uuid4()), "profile_id": profile_id, "version": version,
+                "idempotency_key": idempotency_key, "request_digest": request_digest,
+                "actor_uid": actor_uid, "approval_ref": approval_ref,
+                "approval_digest": approval_digest, "transition_operation": operation,
+            }))
+        existing = self.session.execute(text("SELECT profile_uid::text,request_digest FROM public.trusted_delivery_control_profile_transitions WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            row = self.session.execute(text("SELECT uid::text,profile_id,version,status,current_version FROM public.trusted_delivery_control_profile_versions WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["profile_uid"]}).mappings().one()
+            return _row(row)
+        target = self.session.execute(text("SELECT uid::text FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND version=:version FOR UPDATE"), {"profile": profile_id, "version": version}).mappings().one_or_none()
+        if target is None:
+            raise LookupError("control profile version was not found")
+        self.session.execute(text("SELECT uid FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND status='active' FOR UPDATE"), {"profile": profile_id})
+        self.session.execute(text("UPDATE public.trusted_delivery_control_profile_versions SET status='retired',current_version=current_version+1,updated_at=clock_timestamp() WHERE profile_id=:profile AND status='active' AND uid<>CAST(:uid AS uuid)"), {"profile": profile_id, "uid": target["uid"]})
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_control_profile_versions
+          SET status='active',current_version=current_version+CASE WHEN status='active' THEN 0 ELSE 1 END,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) RETURNING uid::text,profile_id,version,status,current_version"""), {"uid": target["uid"]}).mappings().one()
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_control_profile_transitions
+          (uid,profile_uid,operation,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+          VALUES(CAST(:uid AS uuid),CAST(:profile_uid AS uuid),:operation,:key,:request_digest,:approval_ref,:approval_digest,CAST(:actor AS uuid))"""), {"uid": str(uuid.uuid4()), "profile_uid": target["uid"], "operation": operation, "key": idempotency_key, "request_digest": request_digest, "approval_ref": approval_ref, "approval_digest": approval_digest, "actor": actor_uid})
+        return _row(row)
+
+    def active_profile_summary(self, profile_id):
+        row = self.session.execute(text("SELECT profile_id,version,profile_digest,status,current_version FROM public.trusted_delivery_control_profile_versions WHERE profile_id=:profile AND status='active'"), {"profile": profile_id}).mappings().one_or_none()
+        return _row(row)
+
+    def approve_capability(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_control_write("approve_capability", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_capability_approvals WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return {"uid": existing["uid"], "status": "approved"}
+        self.session.execute(text("UPDATE public.trusted_delivery_capability_approvals SET status='revoked' WHERE provider=:provider AND capability=:capability AND status='approved'"), record)
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_capability_approvals
+          (uid,provider,capability,version,config_digest,status,idempotency_key,request_digest,created_by,approval_ref,approval_digest)
+          VALUES(CAST(:uid AS uuid),:provider,:capability,:version,:config_digest,'approved',:idempotency_key,:request_digest,CAST(:created_by AS uuid),:approval_ref,:approval_digest)
+          RETURNING uid::text,provider,capability,version,config_digest,status"""), record).mappings().one()
+        return _row(row)
+
+    def record_release_gate(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_control_write("record_release_gate", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest,decision_code FROM public.trusted_delivery_supply_chain_gates WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return _row(existing)
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_supply_chain_gates
+          (uid,artifact_digest,sbom_digest,license_policy_digest,vulnerability_scan_digest,approval_id,approval_version,evidence_expires_at,decision_code,idempotency_key,request_digest,created_by,approval_ref,approval_digest)
+          VALUES(CAST(:uid AS uuid),:artifact_digest,:sbom_digest,:license_policy_digest,:vulnerability_scan_digest,:approval_id,:approval_version,CAST(:evidence_expires_at AS timestamptz),:decision_code,:idempotency_key,:request_digest,CAST(:created_by AS uuid),:approval_ref,:approval_digest)
+          RETURNING uid::text,decision_code,artifact_digest,sbom_digest,license_policy_digest,vulnerability_scan_digest,approval_id,approval_version,evidence_expires_at"""), record).mappings().one()
+        return _row(row)
+
+    def create_evidence(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_control_write("create_control_evidence", record))
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_control_evidence
+          (uid,evidence_ref,evidence_digest,decision_code,gate_uid,actor_uid,approval_ref,approval_digest)
+          VALUES(CAST(:uid AS uuid),:evidence_ref,:evidence_digest,:decision_code,CAST(:gate_uid AS uuid),CAST(:actor_uid AS uuid),:approval_ref,:approval_digest)
+          ON CONFLICT(evidence_ref) DO NOTHING
+          RETURNING uid::text,evidence_ref,evidence_digest,decision_code,gate_uid::text"""), record).mappings().one_or_none()
+        if row is None:
+            row = self.session.execute(text("SELECT uid::text,evidence_ref,evidence_digest,decision_code,gate_uid::text FROM public.trusted_delivery_control_evidence WHERE evidence_ref=:evidence_ref"), {"evidence_ref": record["evidence_ref"]}).mappings().one()
+        return _row(row)
+
+    def evidence_summary(self, limit=100):
+        rows = self.session.execute(text("SELECT evidence_ref,evidence_digest,decision_code,gate_uid::text FROM public.trusted_delivery_control_evidence ORDER BY created_at,uid LIMIT :limit"), {"limit": int(limit)}).mappings()
+        return [_row(row) for row in rows]
+
+    def approve_destruction(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("approve_destruction", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest,status FROM public.trusted_delivery_destruction_approvals WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return _row(existing)
+        if self.session.execute(text("SELECT 1 FROM public.trusted_delivery_legal_holds WHERE asset_uid=CAST(:asset AS uuid) AND status='active'"), {"asset": record["asset_uid"]}).scalar_one_or_none():
+            raise PermissionError("destruction blocked by active legal hold")
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_destruction_approvals
+          (uid,asset_uid,approval_ref_one,approval_ref_two,evidence_digest,status,idempotency_key,request_digest,created_by)
+          VALUES(CAST(:uid AS uuid),CAST(:asset_uid AS uuid),:approval_ref_one,:approval_ref_two,:evidence_digest,'approved',:idempotency_key,:request_digest,CAST(:created_by AS uuid))
+          RETURNING uid::text,status"""), record).mappings().one()
+        return _row(row)

+ 103 - 0
deployment/app/core/system/trusted_delivery_controls_service.py

@@ -0,0 +1,103 @@
+"""Service boundary for durable trusted-delivery control profiles and gates."""
+
+from __future__ import annotations
+
+import hashlib
+import uuid
+from typing import Any
+
+from app.core.system.trusted_delivery_controls import (
+    ControlProfileCatalog,
+    EvidenceLedger,
+    SupplyChainReleaseGate,
+    TrustedDeliveryControlError,
+    _closed,
+    _digest,
+    _sha256,
+    _text,
+)
+
+
+class TrustedDeliveryControlsService:
+    def __init__(self, repository, *, catalog=None, gate=None):
+        self.repository = repository
+        self.catalog = catalog or ControlProfileCatalog()
+        self.gate = gate or SupplyChainReleaseGate()
+
+    def _actor(self, actor_uid: str) -> str:
+        if self.repository.users_available({actor_uid}) != {actor_uid}:
+            raise TrustedDeliveryControlError("control actor is unavailable")
+        return actor_uid
+
+    def _transition(self, payload: Any, *, actor_uid: str, operation: str) -> dict[str, Any]:
+        body = _closed(payload, {"profile_id", "version", "approval_ref", "approval_digest", "idempotency_key"}, "control profile transition")
+        actor = self._actor(actor_uid)
+        profile = self.catalog.resolve(body.get("profile_id"), body.get("version"))
+        digest = _digest(profile)
+        profile_id = profile["profile_id"]
+        version = profile["version"]
+        if not self.repository.profile_exists(profile_id, version):
+            self.repository.create_profile({"uid": str(uuid.uuid4()), "profile_id": profile_id, "version": version, "profile_digest": digest, "profile": profile, "created_by": actor})
+        request = {
+            "profile_id": profile_id, "version": version,
+            "approval_ref": _text(body.get("approval_ref"), "approval reference", 200),
+            "approval_digest": _sha256(body.get("approval_digest"), "approval digest"),
+            "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160),
+            "operation": operation,
+        }
+        return self.repository.activate_profile(profile_id, version, request["idempotency_key"], _digest(request), actor, request["approval_ref"], request["approval_digest"], operation)
+
+    def activate_profile(self, payload: Any, *, actor_uid: str, operation: str = "activate") -> dict[str, Any]:
+        return self._transition(payload, actor_uid=actor_uid, operation=operation)
+
+    def active_profile_summary(self, profile_id: Any) -> dict[str, Any] | None:
+        return self.repository.active_profile_summary(_text(profile_id, "control profile", 40))
+
+    def approve_capability(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"provider", "capability", "version", "config_digest", "approval_ref", "approval_digest", "idempotency_key"}, "capability approval")
+        actor = self._actor(actor_uid)
+        provider = _text(body.get("provider"), "capability provider", 20)
+        capability = _text(body.get("capability"), "capability", 80)
+        allowed = {
+            "kms": {"kms-key-wrap", "kms-evidence-seal"}, "dlp": {"dlp-export-check"},
+            "siem": {"siem-security-event"}, "iam": {"iam-entitlement-provision"},
+            "target": {"target-db-provision", "target-api-provision", "target-file-provision"},
+        }
+        if provider not in allowed or capability not in allowed[provider]:
+            raise TrustedDeliveryControlError("unsupported capability")
+        record = {"uid": str(uuid.uuid4()), "provider": provider, "capability": capability, "version": _text(body.get("version"), "capability version", 40), "config_digest": _sha256(body.get("config_digest"), "config digest"), "approval_ref": _text(body.get("approval_ref"), "approval reference", 200), "approval_digest": _sha256(body.get("approval_digest"), "approval digest"), "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160), "created_by": actor}
+        record["request_digest"] = _digest({key: record[key] for key in ("provider", "capability", "version", "config_digest", "idempotency_key")})
+        return self.repository.approve_capability(record)
+
+    def evaluate_release_gate(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "scan_decision", "evidence_expires_at", "approval_ref", "approval_digest", "idempotency_key"}, "release gate request")
+        actor = self._actor(actor_uid)
+        # Approval proof binds the durable write, but is not an input to the
+        # release-policy evaluator's closed schema.
+        summary = self.gate.evaluate({key: body[key] for key in (
+            "artifact_digest", "sbom_digest", "license_policy_digest",
+            "vulnerability_scan_digest", "approval_id", "approval_version",
+            "scan_decision", "evidence_expires_at",
+        )})
+        record = {"uid": str(uuid.uuid4()), **{key: summary[key] for key in ("artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "evidence_expires_at", "decision_code")}, "approval_ref": _text(body.get("approval_ref"), "approval reference", 200), "approval_digest": _sha256(body.get("approval_digest"), "approval digest"), "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160), "created_by": actor}
+        record["request_digest"] = _digest({key: record[key] for key in record if key not in {"uid", "created_by"}})
+        result = self.repository.record_release_gate(record)
+        self.repository.create_evidence({"uid": str(uuid.uuid4()), "evidence_ref": f"trusted-evidence:gate-{result['uid']}", "evidence_digest": hashlib.sha256(result["uid"].encode()).hexdigest(), "decision_code": result["decision_code"], "gate_uid": result["uid"], "actor_uid": actor, "approval_ref": record["approval_ref"], "approval_digest": record["approval_digest"]})
+        return result
+
+    def evidence_summary(self) -> list[dict[str, Any]]:
+        return self.repository.evidence_summary()
+
+    def approve_destruction(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"asset_uid", "approval_refs", "evidence_digest", "idempotency_key"}, "destruction approval")
+        actor = self._actor(actor_uid)
+        refs = body.get("approval_refs")
+        ledger = EvidenceLedger()
+        ledger.approve_destruction({"approval_refs": refs, "active_hold": False})
+        try:
+            asset_uid = str(uuid.UUID(str(body.get("asset_uid"))))
+        except (TypeError, ValueError, AttributeError) as error:
+            raise TrustedDeliveryControlError("asset uid must be a UUID") from error
+        record = {"uid": str(uuid.uuid4()), "asset_uid": asset_uid, "approval_ref_one": refs[0], "approval_ref_two": refs[1], "evidence_digest": _sha256(body.get("evidence_digest"), "evidence digest"), "idempotency_key": _text(body.get("idempotency_key"), "idempotency key", 160), "created_by": actor}
+        record["request_digest"] = _digest({key: record[key] for key in ("asset_uid", "approval_ref_one", "approval_ref_two", "evidence_digest", "idempotency_key")})
+        return self.repository.approve_destruction(record)

+ 534 - 0
deployment/app/core/system/trusted_delivery_repository.py

@@ -0,0 +1,534 @@
+"""PostgreSQL repository for trusted-delivery state and digest-only receipts."""
+
+from __future__ import annotations
+
+import json
+import uuid
+from datetime import datetime
+from typing import Any
+
+from sqlalchemy import text
+
+
+def _json(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _row(row) -> dict[str, Any] | None:
+    return None if row is None else dict(row)
+
+
+class SqlAlchemyTrustedDeliveryRepository:
+    """All writes are parameterized and transactions are owned by the caller."""
+
+    def __init__(self, session):
+        self.session = session
+
+    def _trusted_delivery_gateway(self, operation: str, payload: dict[str, Any]) -> dict[str, Any] | None:
+        """Use the database definer gateway when this is a runtime session.
+
+        Migration/test identities retain direct DML while the long-running
+        runtime login receives only EXECUTE on the closed operation gateway.
+        The decision is derived from PostgreSQL privileges, not a caller flag.
+        """
+        direct_dml = self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_policy_versions', 'INSERT')
+        """)).scalar_one()
+        if direct_dml:
+            return None
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        """Execute one fixed database-side WP06 lifecycle operation."""
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_reclaim_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        """Use the atomic revoke outbox gateway for a restricted runtime login."""
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_reclaim_write(
+              :operation, CAST(:payload AS jsonb)
+            )
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _runtime_restricted(self) -> bool:
+        return not self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_grants', 'INSERT')
+        """)).scalar_one()
+
+    def users_available(self, values):
+        values = sorted(set(values))
+        if not values:
+            return set()
+        return set(self.session.execute(text("SELECT id::text FROM public.users WHERE status='active' AND id=ANY(CAST(:values AS uuid[]))"), {"values": values}).scalars())
+
+    def create_policy_version(self, record):
+        gateway = self._trusted_delivery_gateway("create_policy", {
+            key: record[key] for key in ("uid", "code", "version", "selector", "resource_rules", "created_by", "current_version") if key in record
+        })
+        if gateway is not None:
+            return gateway
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_policy_versions
+          (uid,code,version,status,selector,resource_rules,created_by,current_version)
+          VALUES(CAST(:uid AS uuid),:code,:version,:status,CAST(:selector AS jsonb),CAST(:resource_rules AS jsonb),CAST(:created_by AS uuid),:current_version)
+          RETURNING uid::text,code,version,status,current_version"""), {**record, "selector": _json(record["selector"]), "resource_rules": _json(record["resource_rules"])}).mappings().one()
+        # Compatibility for pre-WP06 fixture importers only: production policy
+        # creation always enters as draft and is activated through
+        # ``transition_policy``.  A repository caller that imports an already
+        # active historic record still receives an auditable bootstrap approval,
+        # so the DB active-grant trigger is never bypassed.
+        if record["status"] == "active":
+            self.session.execute(text("""INSERT INTO public.trusted_delivery_policy_transitions
+              (uid,policy_uid,operation,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+              VALUES(CAST(:uid AS uuid),CAST(:policy AS uuid),'activate',:key,:digest,:approval_ref,:digest,CAST(:actor AS uuid))
+              ON CONFLICT (idempotency_key) DO NOTHING"""), {
+                "uid": str(uuid.uuid4()), "policy": record["uid"],
+                "key": f"bootstrap:{record['uid']}", "digest": "0" * 64,
+                "approval_ref": f"bootstrap:{record['uid']}", "actor": record["created_by"],
+            })
+        return _row(row)
+
+    def transition_policy(self, code, version, operation, idempotency_key, request_digest, actor_uid, approval_ref, approval_digest):
+        gateway = self._trusted_delivery_gateway("transition_policy", {
+            "code": code, "version": version, "operation": operation,
+            "idempotency_key": idempotency_key, "request_digest": request_digest,
+            "actor_uid": actor_uid, "approval_ref": approval_ref,
+            "approval_digest": approval_digest,
+        })
+        if gateway is not None:
+            return gateway
+        existing = self.session.execute(text("SELECT policy_uid::text,request_digest FROM public.trusted_delivery_policy_transitions WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            row = self.session.execute(text("SELECT uid::text,code,version,status,current_version FROM public.trusted_delivery_policy_versions WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["policy_uid"]}).mappings().one()
+            return _row(row)
+        target = self.session.execute(text("SELECT uid::text,code,version,status,current_version FROM public.trusted_delivery_policy_versions WHERE code=:code AND version=:version FOR UPDATE"), {"code": code, "version": version}).mappings().one_or_none()
+        if target is None:
+            raise LookupError("trusted delivery policy version was not found")
+        # Lock all candidate active rows before changing the partial unique index.
+        self.session.execute(text("SELECT uid FROM public.trusted_delivery_policy_versions WHERE code=:code AND status='active' FOR UPDATE"), {"code": code})
+        self.session.execute(text("UPDATE public.trusted_delivery_policy_versions SET status='retired',current_version=current_version+1 WHERE code=:code AND status='active' AND uid<>CAST(:uid AS uuid)"), {"code": code, "uid": target["uid"]})
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_policy_versions
+          SET status='active',current_version=current_version+CASE WHEN status='active' THEN 0 ELSE 1 END
+          WHERE uid=CAST(:uid AS uuid)
+          RETURNING uid::text,code,version,status,current_version"""), {"uid": target["uid"]}).mappings().one()
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_policy_transitions
+          (uid,policy_uid,operation,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+          VALUES(CAST(:uid AS uuid),CAST(:policy_uid AS uuid),:operation,:key,:request_digest,:approval_ref,:approval_digest,CAST(:actor_uid AS uuid))"""), {"uid": str(uuid.uuid4()), "policy_uid": target["uid"], "operation": operation, "key": idempotency_key, "request_digest": request_digest, "approval_ref": approval_ref, "approval_digest": approval_digest, "actor_uid": actor_uid})
+        return _row(row)
+
+    def active_policies(self):
+        rows = self.session.execute(text("SELECT uid::text,code,version,status,selector,resource_rules FROM public.trusted_delivery_policy_versions WHERE status='active' ORDER BY created_at,uid")).mappings()
+        return [{**_row(row), "selector": dict(row["selector"]), "resource_rules": dict(row["resource_rules"])} for row in rows]
+
+    def enqueue_grant(self, record):
+        if record.get("approval_ref") and record.get("approval_digest") and record.get("target_capability") is not None:
+            gateway = self._trusted_delivery_gateway("create_grant", {
+                key: record[key] for key in (
+                    "uid", "policy_uid", "subject_uid", "asset_uid", "provider",
+                    "idempotency_key", "request_digest", "expires_at", "status",
+                    "reason_code", "current_version", "created_by", "approval_ref",
+                    "approval_digest", "purpose", "environment", "target_capability",
+                ) if key in record
+            })
+            if gateway is not None:
+                return {"uid": gateway["uid"]}
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_grants WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return {"uid": existing["uid"]}
+        # This method is also used by controlled legacy import tests.  Public
+        # provision paths always provide the real server-derived values; the
+        # import fallback remains database-validated and cannot be reproduced
+        # by direct SQL.
+        legacy_digest = record.get("request_digest")
+        values = {
+            "approval_ref": f"legacy-import:{record['uid']}", "approval_digest": legacy_digest,
+            "purpose": "legacy_import", "environment": "test", "target_capability": {}, **record,
+        }
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_grants
+          (uid,policy_uid,subject_uid,asset_uid,provider,idempotency_key,request_digest,expires_at,status,reason_code,current_version,created_by,approval_ref,approval_digest,purpose,environment,target_capability)
+          VALUES(CAST(:uid AS uuid),CAST(:policy_uid AS uuid),CAST(:subject_uid AS uuid),CAST(:asset_uid AS uuid),:provider,:idempotency_key,:request_digest,CAST(:expires_at AS timestamptz),:status,:reason_code,:current_version,CAST(:created_by AS uuid),:approval_ref,:approval_digest,:purpose,:environment,CAST(:target_capability AS jsonb))
+          RETURNING uid::text,status,current_version"""), {**values, "target_capability": None if values["target_capability"] is None else _json(values["target_capability"])}).mappings().one()
+        return _row(row)
+
+    def create_grant(self, record):
+        # Service-created grants retain closed-schema provenance as an idempotency input.
+        return self.enqueue_grant({
+            **record, "idempotency_key": f"grant:{record['uid']}", "request_digest": record["decision_digest"],
+        })
+
+    def get_grant(self, uid):
+        row = self.session.execute(text("""SELECT uid::text,policy_uid::text,subject_uid::text,asset_uid::text,provider,expires_at,status,reason_code,current_version,request_digest AS decision_digest,
+          approval_ref,approval_digest,purpose,environment,target_capability
+          FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid)"""), {"uid": uid}).mappings().one_or_none()
+        value = _row(row)
+        if value and value.get("target_capability") is not None:
+            value["target_capability"] = dict(value["target_capability"])
+        return value
+
+    def enqueue_delivery(self, grant_uid, idempotency_key, request_digest, operation="provision"):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("enqueue_delivery", {
+                "uid": str(uuid.uuid4()), "grant_uid": grant_uid,
+                "idempotency_key": idempotency_key, "request_digest": request_digest,
+                "operation": operation,
+            })
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_deliveries WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            return {"uid": existing["uid"]}
+        if operation == "provision":
+            # The partial unique index is a last line of defence.  Taking a
+            # per-grant transaction advisory lock first lets different HTTP
+            # keys converge on the same intent without making a second worker
+            # guess whether an IntegrityError represented a replay or a
+            # conflicting entitlement.
+            self.session.execute(text("SELECT pg_advisory_xact_lock(hashtextextended(CAST(:grant AS text),494))"), {"grant": grant_uid})
+            existing = self.session.execute(text("""SELECT uid::text,request_digest
+              FROM public.trusted_delivery_deliveries
+              WHERE grant_uid=CAST(:grant AS uuid) AND operation='provision' FOR UPDATE"""), {"grant": grant_uid}).mappings().one_or_none()
+            if existing:
+                if existing["request_digest"] != request_digest:
+                    raise RuntimeError("trusted delivery idempotency conflict")
+                return {"uid": existing["uid"]}
+        uid = str(uuid.uuid4())
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_deliveries(uid,grant_uid,idempotency_key,request_digest,status,operation)
+          VALUES(CAST(:uid AS uuid),CAST(:grant_uid AS uuid),:key,:digest,'pending',:operation) RETURNING uid::text,status,lease_fence"""), {"uid": uid, "grant_uid": grant_uid, "key": idempotency_key, "digest": request_digest, "operation": operation}).mappings().one()
+        return _row(row)
+
+    def claim_delivery(self, uid, worker):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("claim_delivery", {"uid": uid, "worker": worker})
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status='processing',lease_owner=:worker,
+          lease_fence=lease_fence+1,lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND ((status='pending' AND next_attempt_at<=clock_timestamp()) OR (status='processing' AND lease_expires_at<=clock_timestamp()))
+          RETURNING uid::text,grant_uid::text,status,lease_fence,lease_owner"""), {"uid": uid, "worker": worker}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease unavailable")
+        return _row(row)
+
+    def complete_delivery(self, uid, worker, fence, status, receipt_code, response_digest, diff_digest):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("complete_delivery", {
+                "uid": uid, "worker": worker, "fence": fence, "status": status,
+                "receipt_uid": str(uuid.uuid4()), "receipt_code": receipt_code,
+                "response_digest": response_digest, "diff_digest": diff_digest,
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status=:status,lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text,grant_uid::text,request_digest,status"""), {"uid": uid, "worker": worker, "fence": int(fence), "status": status}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_receipts(uid,delivery_uid,grant_uid,status,receipt_code,request_digest,response_digest,diff_digest)
+          VALUES(CAST(:uid AS uuid),CAST(:delivery_uid AS uuid),CAST(:grant_uid AS uuid),:status,:receipt_code,:request_digest,:response_digest,:diff_digest)"""), {"uid": str(uuid.uuid4()), "delivery_uid": row["uid"], "grant_uid": row["grant_uid"], "status": status, "receipt_code": receipt_code, "request_digest": row["request_digest"], "response_digest": response_digest, "diff_digest": diff_digest})
+        return {"uid": row["uid"], "status": row["status"]}
+
+    def record_provision_receipt(self, grant_uid, idempotency_key, request_digest, receipt):
+        key = f"provision:{idempotency_key}"
+        delivery = self.enqueue_delivery(grant_uid, key, request_digest, operation="provision")
+        existing = self.session.execute(text("""SELECT status,receipt_code,response_digest,diff_digest FROM public.trusted_delivery_receipts
+          WHERE delivery_uid=CAST(:uid AS uuid)"""), {"uid": delivery["uid"]}).mappings().one_or_none()
+        if existing:
+            return {"grant_uid": grant_uid, "status": existing["status"], "receipt_code": existing["receipt_code"], "response_digest": existing["response_digest"], "diff_digest": existing["diff_digest"]}
+        claimed = self.claim_delivery(delivery["uid"], "provision-sync")
+        self.complete_delivery(delivery["uid"], "provision-sync", claimed["lease_fence"], "applied", receipt["receipt_code"], receipt["response_digest"], receipt["diff_digest"])
+        return receipt
+
+    def prepare_provision_operation(self, grant_uid, idempotency_key, request_digest):
+        """Persist the outbox intent before any provider adapter is invoked.
+
+        The API boundary owns ordinary commits, but external I/O is different:
+        an adapter must never run for an intent that can still be rolled back.
+        This deliberately commits only the durable intent and leaves completion
+        for the receipt path.  A retry sees the same delivery/receipt.
+        """
+        delivery = self.enqueue_delivery(
+            grant_uid, f"provision:{idempotency_key}", request_digest, operation="provision"
+        )
+        existing = self.session.execute(text("""SELECT status,receipt_code,response_digest,diff_digest
+          FROM public.trusted_delivery_receipts WHERE delivery_uid=CAST(:uid AS uuid)"""), {
+            "uid": delivery["uid"],
+        }).mappings().one_or_none()
+        self.session.commit()
+        if existing:
+            return {"delivery_uid": delivery["uid"], "completed": True, "receipt": {
+                "grant_uid": grant_uid, "status": existing["status"],
+                "receipt_code": existing["receipt_code"],
+                "response_digest": existing["response_digest"], "diff_digest": existing["diff_digest"],
+            }}
+        return {"delivery_uid": delivery["uid"], "completed": False}
+
+    def claim_provision_operation(self, delivery_uid, worker_id):
+        """Lease one persisted provision intent using PostgreSQL's clock.
+
+        This is deliberately separate from ``prepare_provision_operation``:
+        intent durability is committed before any process is entitled to call
+        an external provider, while a crashed worker can be replaced after its
+        database-time lease expires.
+        """
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("claim_provision", {
+                "uid": delivery_uid, "worker": worker_id,
+            })
+        completed = self.session.execute(text("""SELECT r.status,r.receipt_code,r.response_digest,r.diff_digest
+          FROM public.trusted_delivery_deliveries d
+          JOIN public.trusted_delivery_receipts r ON r.delivery_uid=d.uid
+          WHERE d.uid=CAST(:uid AS uuid) AND d.operation='provision'"""), {"uid": delivery_uid}).mappings().one_or_none()
+        if completed:
+            return {"state": "completed", "receipt": _row(completed)}
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries
+          SET status='processing',lease_owner=:worker,lease_fence=lease_fence+1,
+              lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND operation='provision' AND (
+              (status='pending' AND next_attempt_at<=clock_timestamp()) OR
+              (status='processing' AND lease_expires_at<=clock_timestamp())
+          )
+          RETURNING uid::text,grant_uid::text,lease_fence,lease_owner,lease_expires_at"""), {
+            "uid": delivery_uid, "worker": worker_id,
+        }).mappings().one_or_none()
+        return ({"state": "claimed", **_row(row)} if row else {"state": "leased"})
+
+    def fail_provision_operation(self, delivery_uid, worker_id, fence):
+        """Release only the still-current provision lease for a safe retry."""
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("fail_provision", {
+                "uid": delivery_uid, "worker": worker_id, "fence": int(fence),
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries
+          SET status='pending',lease_owner=NULL,lease_expires_at=NULL,
+              next_attempt_at=clock_timestamp(),updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND operation='provision' AND status='processing'
+            AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text"""), {
+            "uid": delivery_uid, "worker": worker_id, "fence": int(fence),
+        }).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+        return _row(row)
+
+    def complete_provision_operation(self, grant_uid, delivery_uid, worker_id, fence, receipt):
+        """Atomically append a receipt, complete delivery, and mark its grant."""
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("complete_provision", {
+                "grant_uid": grant_uid, "uid": delivery_uid, "worker": worker_id,
+                "fence": int(fence), "receipt_uid": str(uuid.uuid4()),
+                "receipt_code": receipt["receipt_code"],
+                "response_digest": receipt["response_digest"],
+                "diff_digest": receipt["diff_digest"],
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries
+          SET status='applied',lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND grant_uid=CAST(:grant AS uuid)
+            AND operation='provision' AND status='processing' AND lease_owner=:worker
+            AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text,grant_uid::text,request_digest,status"""), {
+            "uid": delivery_uid, "grant": grant_uid, "worker": worker_id, "fence": int(fence),
+        }).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_receipts
+          (uid,delivery_uid,grant_uid,status,receipt_code,request_digest,response_digest,diff_digest)
+          VALUES(CAST(:uid AS uuid),CAST(:delivery AS uuid),CAST(:grant AS uuid),'applied',:code,:request,:response,:diff)"""), {
+            "uid": str(uuid.uuid4()), "delivery": row["uid"], "grant": row["grant_uid"],
+            "code": receipt["receipt_code"], "request": row["request_digest"],
+            "response": receipt["response_digest"], "diff": receipt["diff_digest"],
+        })
+        grant = self.session.execute(text("""UPDATE public.trusted_delivery_grants
+          SET reason_code='provision_applied',current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='active'
+          RETURNING uid::text,status,reason_code,current_version"""), {"uid": grant_uid}).mappings().one_or_none()
+        if grant is None:
+            raise RuntimeError("trusted delivery grant version conflict")
+        return {
+            "delivery_uid": row["uid"], "status": "applied",
+            "grant_uid": grant["uid"], "grant_status": grant["status"],
+            "reason_code": grant["reason_code"], "current_version": grant["current_version"],
+        }
+
+    def get_provision_receipt(self, grant_uid, idempotency_key):
+        row = self.session.execute(text("""SELECT r.status,r.receipt_code,r.response_digest,r.diff_digest
+          FROM public.trusted_delivery_deliveries d JOIN public.trusted_delivery_receipts r ON r.delivery_uid=d.uid
+          WHERE d.grant_uid=CAST(:grant_uid AS uuid) AND d.idempotency_key=:key"""), {"grant_uid": grant_uid, "key": f"provision:{idempotency_key}"}).mappings().one_or_none()
+        if row is None:
+            return None
+        return {"grant_uid": grant_uid, "status": row["status"], "receipt_code": row["receipt_code"], "response_digest": row["response_digest"], "diff_digest": row["diff_digest"]}
+
+    def complete_reclaim(self, grant_uid, idempotency_key, request_digest, receipt):
+        grant = self.session.execute(text("SELECT uid::text,status,current_version FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid) FOR UPDATE"), {"uid": grant_uid}).mappings().one_or_none()
+        if grant is None:
+            raise LookupError("trusted delivery grant was not found")
+        if grant["status"] == "reclaimed":
+            return {"uid": grant_uid, "status": "reclaimed", "current_version": grant["current_version"]}
+        key = f"reclaim:{idempotency_key}"
+        delivery = self.enqueue_delivery(grant_uid, key, request_digest, operation="revoke")
+        existing = self.session.execute(text("SELECT status FROM public.trusted_delivery_receipts WHERE delivery_uid=CAST(:uid AS uuid)"), {"uid": delivery["uid"]}).mappings().one_or_none()
+        if existing:
+            row = self.session.execute(text("SELECT uid::text,status,current_version FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid)"), {"uid": grant_uid}).mappings().one()
+            return _row(row)
+        claimed = self.claim_delivery(delivery["uid"], "reclaim-sync")
+        # The provider receipt is append-only evidence.  Store it before the
+        # final grant transition; both writes share the caller transaction, so
+        # a later conflict rolls the receipt back rather than exposing a claim
+        # that was never completed.
+        self.complete_delivery(delivery["uid"], "reclaim-sync", claimed["lease_fence"], "reclaimed", receipt["receipt_code"], receipt["response_digest"], receipt["diff_digest"])
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_grants SET status='reclaimed',reason_code='expired_reclaimed',
+          current_version=current_version+1,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='active'
+          RETURNING uid::text,status,current_version"""), {"uid": grant_uid}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery version conflict")
+        return _row(row)
+
+    def claim_reclaim_operation(self, grant_uid, idempotency_key, request_digest, worker_id):
+        """Durably lease the one revoke outbox operation before provider I/O."""
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_reclaim_write("claim_reclaim", {
+                "grant_uid": grant_uid, "idempotency_key": idempotency_key,
+                "request_digest": request_digest, "worker": worker_id,
+            })
+        grant = self.session.execute(text("""SELECT uid::text,asset_uid::text,status,expires_at
+          FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid) FOR UPDATE"""), {"uid": grant_uid}).mappings().one_or_none()
+        if grant is None:
+            raise LookupError("trusted delivery grant was not found")
+        self.session.execute(text("SELECT pg_advisory_xact_lock(hashtextextended(CAST(:asset AS text),485))"), {"asset": grant["asset_uid"]})
+        if grant["status"] == "reclaimed":
+            return {"state": "completed", "grant_uid": grant_uid}
+        if grant["status"] != "active" or grant["expires_at"] > self.session.execute(text("SELECT clock_timestamp()")).scalar_one():
+            raise ValueError("trusted delivery grant is not reclaimable")
+        if self.active_hold_for_asset(grant["asset_uid"]):
+            raise PermissionError("active legal hold blocks reclaim")
+        row = self.session.execute(text("""SELECT uid::text,request_digest,status,lease_owner,lease_fence,lease_expires_at
+          FROM public.trusted_delivery_deliveries WHERE grant_uid=CAST(:grant AS uuid) AND operation='revoke' FOR UPDATE"""), {"grant": grant_uid}).mappings().one_or_none()
+        if row is None:
+            uid = str(uuid.uuid4())
+            row = self.session.execute(text("""INSERT INTO public.trusted_delivery_deliveries
+              (uid,grant_uid,idempotency_key,request_digest,status,operation,lease_owner,lease_fence,lease_expires_at)
+              VALUES(CAST(:uid AS uuid),CAST(:grant AS uuid),:key,:digest,'processing','revoke',:worker,1,clock_timestamp()+interval '300 seconds')
+              RETURNING uid::text,lease_fence"""), {"uid": uid, "grant": grant_uid, "key": f"reclaim:{idempotency_key}", "digest": request_digest, "worker": worker_id}).mappings().one()
+            return {"state": "claimed", "delivery_uid": row["uid"], "lease_fence": row["lease_fence"]}
+        if row["request_digest"] != request_digest:
+            raise RuntimeError("trusted delivery idempotency conflict")
+        if row["status"] == "reclaimed":
+            return {"state": "completed", "grant_uid": grant_uid}
+        claimed = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status='processing',lease_owner=:worker,
+          lease_fence=lease_fence+1,lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND (status='pending' OR (status='processing' AND lease_expires_at<=clock_timestamp()))
+          RETURNING uid::text,lease_fence"""), {"uid": row["uid"], "worker": worker_id}).mappings().one_or_none()
+        return {"state": "claimed", "delivery_uid": claimed["uid"], "lease_fence": claimed["lease_fence"]} if claimed else {"state": "leased"}
+
+    def fail_reclaim_operation(self, delivery_uid, worker_id, fence):
+        if self._runtime_restricted():
+            self._trusted_delivery_runtime_reclaim_write("fail_reclaim", {
+                "delivery_uid": delivery_uid, "worker": worker_id, "fence": fence,
+            })
+            return
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_deliveries SET status='pending',lease_owner=NULL,
+          lease_expires_at=NULL,next_attempt_at=clock_timestamp()+interval '5 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+          RETURNING uid::text"""), {"uid": delivery_uid, "worker": worker_id, "fence": int(fence)}).one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery lease conflict")
+
+    def complete_claimed_reclaim(self, grant_uid, delivery_uid, worker_id, fence, receipt):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_reclaim_write("complete_reclaim", {
+                "grant_uid": grant_uid, "delivery_uid": delivery_uid,
+                "worker": worker_id, "fence": fence, "receipt_uid": str(uuid.uuid4()),
+                "receipt_code": receipt["receipt_code"],
+                "response_digest": receipt["response_digest"],
+                "diff_digest": receipt["diff_digest"],
+            })
+        self.complete_delivery(delivery_uid, worker_id, fence, "reclaimed", receipt["receipt_code"], receipt["response_digest"], receipt["diff_digest"])
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_grants SET status='reclaimed',reason_code='expired_reclaimed',current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='active' RETURNING uid::text,status,current_version"""), {"uid": grant_uid}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery version conflict")
+        return _row(row)
+
+    def create_legal_hold(self, record):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("create_hold", {
+                **record, "hold_operation": record["operation"],
+            })
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_legal_holds
+          (uid,asset_uid,operation,status,approver_ref_one,approver_ref_two,evidence_digest,created_by,current_version)
+          VALUES(CAST(:uid AS uuid),CAST(:asset_uid AS uuid),:operation,:status,:approver_ref_one,:approver_ref_two,:evidence_digest,CAST(:created_by AS uuid),:current_version)
+          RETURNING uid::text,status"""), record).mappings().one()
+        return _row(row)
+
+    def release_legal_hold(self, hold_uid, idempotency_key, request_digest, actor_uid, approval_ref, approval_digest):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("release_hold", {
+                "uid": str(uuid.uuid4()), "hold_uid": hold_uid,
+                "idempotency_key": idempotency_key, "request_digest": request_digest,
+                "actor_uid": actor_uid, "approval_ref": approval_ref,
+                "approval_digest": approval_digest,
+            })
+        existing = self.session.execute(text("SELECT hold_uid::text,request_digest FROM public.trusted_delivery_hold_releases WHERE idempotency_key=:key"), {"key": idempotency_key}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != request_digest:
+                raise RuntimeError("trusted delivery idempotency conflict")
+            row = self.session.execute(text("SELECT uid::text,status,current_version FROM public.trusted_delivery_legal_holds WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["hold_uid"]}).mappings().one()
+            return _row(row)
+        hold = self.session.execute(text("""SELECT uid::text,status,current_version,created_by::text,approver_ref_one,approver_ref_two
+          FROM public.trusted_delivery_legal_holds WHERE uid=CAST(:uid AS uuid) FOR UPDATE"""), {"uid": hold_uid}).mappings().one_or_none()
+        if hold is None:
+            raise LookupError("trusted delivery legal hold was not found")
+        if hold["created_by"] == actor_uid or approval_ref in {hold["approver_ref_one"], hold["approver_ref_two"]}:
+            raise PermissionError("legal hold release requires an independent approval")
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_legal_holds SET status='released',current_version=current_version+1
+          WHERE uid=CAST(:uid AS uuid) AND status='active' RETURNING uid::text,status,current_version"""), {"uid": hold_uid}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery legal hold is not active")
+        self.session.execute(text("""INSERT INTO public.trusted_delivery_hold_releases
+          (uid,hold_uid,idempotency_key,request_digest,approval_ref,approval_digest,actor_uid)
+          VALUES(CAST(:uid AS uuid),CAST(:hold_uid AS uuid),:key,:digest,:approval_ref,:approval_digest,CAST(:actor_uid AS uuid))"""), {"uid": str(uuid.uuid4()), "hold_uid": hold_uid, "key": idempotency_key, "digest": request_digest, "approval_ref": approval_ref, "approval_digest": approval_digest, "actor_uid": actor_uid})
+        return _row(row)
+
+    def active_hold_for_asset(self, asset_uid):
+        row = self.session.execute(text("SELECT uid::text,asset_uid::text,status FROM public.trusted_delivery_legal_holds WHERE asset_uid=CAST(:asset AS uuid) AND status='active'"), {"asset": asset_uid}).mappings().one_or_none()
+        return _row(row)
+
+    def grants_due_for_revoke(self, instant: datetime):
+        rows = self.session.execute(text("SELECT uid::text,asset_uid::text,expires_at,status,current_version FROM public.trusted_delivery_grants WHERE status='active' AND expires_at<=CAST(:instant AS timestamptz)"), {"instant": instant}).mappings()
+        return [_row(row) for row in rows]
+
+    def update_grant_status(self, uid, expected_version, status, reason_code):
+        if self._runtime_restricted():
+            return self._trusted_delivery_runtime_write("update_grant_status", {
+                "uid": uid, "expected_version": expected_version, "status": status,
+                "reason_code": reason_code,
+            })
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_grants SET status=:status,reason_code=:reason,current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND current_version=:expected RETURNING uid::text,status,reason_code,current_version"""), {"uid": uid, "expected": int(expected_version), "status": status, "reason": reason_code}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("trusted delivery version conflict")
+        return _row(row)
+
+    def expire_grants(self, instant, actor_uid):
+        expired = []
+        for grant in self.grants_due_for_revoke(instant):
+            if self.active_hold_for_asset(grant["asset_uid"]):
+                continue
+            expired.append(self.update_grant_status(grant["uid"], grant["current_version"], "revoked", "expired"))
+        return expired
+
+    def add_evidence(self, record):
+        if self._runtime_restricted():
+            self._trusted_delivery_runtime_write("subscription_evidence", {
+                "uid": record["uid"], "action": record["action"],
+                "actor_uid": record["actor_uid"], "safe_detail": record["safe_detail"],
+            })
+            return
+        self.session.execute(text("INSERT INTO public.trusted_delivery_evidence(uid,action,actor_uid,safe_detail) VALUES(CAST(:uid AS uuid),:action,CAST(:actor AS uuid),CAST(:detail AS jsonb))"), {"uid": record["uid"], "action": record["action"], "actor": record["actor_uid"], "detail": _json(record["safe_detail"])})

+ 203 - 0
deployment/app/core/system/trusted_delivery_subscription_repository.py

@@ -0,0 +1,203 @@
+"""PostgreSQL storage for fenced trusted-delivery subscription deliveries."""
+
+from __future__ import annotations
+
+import json
+from typing import Any
+
+from sqlalchemy import text
+
+
+def _json(value: Any) -> str:
+    return json.dumps(value, sort_keys=True, separators=(",", ":"))
+
+
+def _row(value) -> dict[str, Any] | None:
+    if value is None:
+        return None
+    result = dict(value)
+    for key, item in tuple(result.items()):
+        if hasattr(item, "isoformat"):
+            result[key] = item.isoformat()
+        elif hasattr(item, "hex"):
+            result[key] = str(item)
+    if result.get("trigger") is not None:
+        result["trigger"] = dict(result["trigger"])
+    return result
+
+
+class SqlAlchemyTrustedDeliverySubscriptionRepository:
+    def __init__(self, session):
+        self.session = session
+
+    def _trusted_delivery_gateway(self, operation: str, payload: dict[str, Any]) -> dict[str, Any] | None:
+        direct_dml = self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_subscriptions', 'INSERT')
+        """)).scalar_one()
+        if direct_dml:
+            return None
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _trusted_delivery_runtime_write(self, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
+        result = self.session.execute(text("""
+            SELECT public.trusted_delivery_runtime_write(:operation, CAST(:payload AS jsonb))
+        """), {"operation": operation, "payload": _json(payload)}).scalar_one()
+        return dict(result)
+
+    def _runtime_restricted(self) -> bool:
+        return not self.session.execute(text("""
+            SELECT has_table_privilege(current_user,
+              'public.trusted_delivery_subscriptions', 'INSERT')
+        """)).scalar_one()
+
+    def users_available(self, values):
+        values = sorted(set(values))
+        if not values:
+            return set()
+        return set(self.session.execute(text("SELECT id::text FROM public.users WHERE status='active' AND id=ANY(CAST(:values AS uuid[]))"), {"values": values}).scalars())
+
+    def create_subscription(self, record):
+        gateway = self._trusted_delivery_gateway("create_subscription", {
+            key: record[key] for key in (
+                "uid", "grant_uid", "asset_uid", "trigger", "purpose", "expires_at",
+                "idempotency_key", "request_digest", "status", "current_version", "created_by",
+            ) if key in record
+        })
+        if gateway is not None:
+            return _row(gateway)
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_subscriptions WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("subscription idempotency conflict")
+            return _row(self.session.execute(text("SELECT uid::text,grant_uid::text,asset_uid::text,trigger,purpose,expires_at,status,current_version FROM public.trusted_delivery_subscriptions WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["uid"]}).mappings().one())
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_subscriptions
+          (uid,grant_uid,asset_uid,trigger,purpose,expires_at,idempotency_key,request_digest,status,current_version,created_by)
+          VALUES(CAST(:uid AS uuid),CAST(:grant_uid AS uuid),CAST(:asset_uid AS uuid),CAST(:trigger AS jsonb),:purpose,CAST(:expires_at AS timestamptz),:idempotency_key,:request_digest,:status,:current_version,CAST(:created_by AS uuid))
+          RETURNING uid::text,grant_uid::text,asset_uid::text,trigger,purpose,expires_at,status,current_version"""), {**record, "trigger": _json(record["trigger"])}).mappings().one()
+        return _row(row)
+
+    def get_grant_for_subscription(self, uid):
+        row = self.session.execute(text("""SELECT uid::text,asset_uid::text,purpose,expires_at,status
+          FROM public.trusted_delivery_grants WHERE uid=CAST(:uid AS uuid) FOR KEY SHARE"""), {"uid": uid}).mappings().one_or_none()
+        return _row(row)
+
+    def transition_subscription(self, uid, expected_status, new_status):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("transition_subscription", {
+                "uid": uid, "expected_status": sorted(expected_status), "status": new_status,
+            }))
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscriptions SET status=:target,current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status=ANY(CAST(:expected AS varchar[]))
+          RETURNING uid::text,grant_uid::text,asset_uid::text,trigger,purpose,expires_at,status,current_version"""), {"uid": uid, "expected": sorted(expected_status), "target": new_status}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("subscription transition conflict")
+        return _row(row)
+
+    def enqueue_subscription_delivery(self, record):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("enqueue_subscription_delivery", record))
+        existing = self.session.execute(text("SELECT uid::text,request_digest FROM public.trusted_delivery_subscription_deliveries WHERE idempotency_key=:key"), {"key": record["idempotency_key"]}).mappings().one_or_none()
+        if existing:
+            if existing["request_digest"] != record["request_digest"]:
+                raise RuntimeError("subscription idempotency conflict")
+            return _row(self.session.execute(text("SELECT uid::text,subscription_uid::text,trigger_ref,event_digest,status,attempt_count,lease_fence FROM public.trusted_delivery_subscription_deliveries WHERE uid=CAST(:uid AS uuid)"), {"uid": existing["uid"]}).mappings().one())
+        state = self.session.execute(text("SELECT status FROM public.trusted_delivery_subscriptions WHERE uid=CAST(:uid AS uuid) FOR KEY SHARE"), {"uid": record["subscription_uid"]}).scalar_one_or_none()
+        if state != "active":
+            raise RuntimeError("subscription is not active")
+        row = self.session.execute(text("""INSERT INTO public.trusted_delivery_subscription_deliveries
+          (uid,subscription_uid,trigger_ref,event_digest,idempotency_key,request_digest,status,attempt_count,lease_fence)
+          VALUES(CAST(:uid AS uuid),CAST(:subscription_uid AS uuid),:trigger_ref,:event_digest,:idempotency_key,:request_digest,:status,:attempt_count,:lease_fence)
+          RETURNING uid::text,subscription_uid::text,trigger_ref,event_digest,status,attempt_count,lease_fence"""), record).mappings().one()
+        return _row(row)
+
+    def claim_subscription_delivery(self, uid, worker):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("claim_subscription_delivery", {
+                "uid": uid, "worker": worker,
+            }))
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscription_deliveries SET status='processing',lease_owner=:worker,lease_fence=lease_fence+1,
+          lease_expires_at=clock_timestamp()+interval '300 seconds',updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND ((status='pending' AND next_attempt_at<=clock_timestamp()) OR (status='processing' AND lease_expires_at<=clock_timestamp()))
+          RETURNING uid::text,subscription_uid::text,status,attempt_count,lease_owner,lease_fence,lease_expires_at"""), {"uid": uid, "worker": worker}).mappings().one_or_none()
+        return _row(row)
+
+    def record_subscription_attempt(self, uid, worker, fence, delivered):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("subscription_attempt", {
+                "uid": uid, "worker": worker, "fence": fence, "delivered": delivered,
+            }))
+        if delivered:
+            statement = """UPDATE public.trusted_delivery_subscription_deliveries SET status='delivered',lease_owner=NULL,lease_expires_at=NULL,updated_at=clock_timestamp()
+              WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+              RETURNING uid::text,subscription_uid::text,status,attempt_count,lease_fence"""
+            parameters = {"uid": uid, "worker": worker, "fence": fence}
+        else:
+            statement = """UPDATE public.trusted_delivery_subscription_deliveries SET attempt_count=attempt_count+1,lease_owner=NULL,lease_expires_at=NULL,
+              status=CASE WHEN attempt_count+1>=3 THEN 'dead_letter' ELSE 'pending' END,
+              next_attempt_at=clock_timestamp()+(LEAST(3600,60*(attempt_count+1))*interval '1 second'),last_reason_code='provider_unavailable',updated_at=clock_timestamp()
+              WHERE uid=CAST(:uid AS uuid) AND status='processing' AND lease_owner=:worker AND lease_fence=:fence AND lease_expires_at>clock_timestamp()
+              RETURNING uid::text,subscription_uid::text,status,attempt_count,lease_fence"""
+            parameters = {"uid": uid, "worker": worker, "fence": fence}
+        return _row(self.session.execute(text(statement), parameters).mappings().one_or_none())
+
+    def compensate_subscription_delivery(self, uid, reason_code, receipt_code):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("compensate_subscription_delivery", {
+                "uid": uid, "reason_code": reason_code, "receipt_code": receipt_code,
+            }))
+        current = self.session.execute(text("SELECT uid::text,status,compensation_reason_code,compensation_receipt_code FROM public.trusted_delivery_subscription_deliveries WHERE uid=CAST(:uid AS uuid) FOR UPDATE"), {"uid": uid}).mappings().one_or_none()
+        if current is None or current["status"] not in {"dead_letter", "compensated"}:
+            raise RuntimeError("subscription delivery is not compensable")
+        if current["status"] == "compensated":
+            if (current["compensation_reason_code"], current["compensation_receipt_code"]) != (reason_code, receipt_code):
+                raise RuntimeError("subscription compensation conflict")
+            return _row(current)
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscription_deliveries SET status='compensated',compensation_reason_code=:reason,
+          compensation_receipt_code=:receipt,updated_at=clock_timestamp() WHERE uid=CAST(:uid AS uuid) AND status='dead_letter'
+          RETURNING uid::text,subscription_uid::text,status,attempt_count,compensation_reason_code,compensation_receipt_code"""), {"uid": uid, "reason": reason_code, "receipt": receipt_code}).mappings().one()
+        return _row(row)
+
+    def add_subscription_evidence(self, record):
+        if self._runtime_restricted():
+            self._trusted_delivery_runtime_write("subscription_evidence", record)
+            return
+        self.session.execute(text("INSERT INTO public.trusted_delivery_evidence(uid,action,actor_uid,safe_detail) VALUES(CAST(:uid AS uuid),:action,CAST(:actor_uid AS uuid),CAST(:detail AS jsonb))"), {**record, "detail": _json(record["safe_detail"])})
+
+    def incident_exists(self, incident_uid):
+        return self.session.execute(text("SELECT 1 FROM public.data_incidents WHERE uid=CAST(:uid AS uuid)"), {"uid": incident_uid}).scalar_one_or_none() is not None
+
+    def link_anomaly_incident(self, incident_uid, asset_uid, label):
+        if self._runtime_restricted():
+            self.session.execute(text("""
+                SELECT public.trusted_delivery_runtime_incident_impact(
+                  CAST(:incident_uid AS uuid), CAST(:asset_uid AS uuid), :label
+                )
+            """), {"incident_uid": incident_uid, "asset_uid": asset_uid, "label": label})
+            return
+        self.session.execute(text("""INSERT INTO public.data_incident_impacts(incident_uid,target_type,target_uid,label)
+          VALUES(CAST(:incident_uid AS uuid),'asset',:asset_uid,:label)
+          ON CONFLICT(incident_uid,target_type,target_uid) DO NOTHING"""), {"incident_uid": incident_uid, "asset_uid": asset_uid, "label": label})
+
+    def subscriptions_due_for_reclaim(self, instant):
+        rows = self.session.execute(text("""SELECT s.uid::text,s.grant_uid::text,s.asset_uid::text,s.status,s.current_version
+          FROM public.trusted_delivery_subscriptions s
+          WHERE s.status IN ('active','expired') AND s.expires_at<=CAST(:instant AS timestamptz)
+          AND NOT EXISTS(SELECT 1 FROM public.trusted_delivery_legal_holds h WHERE h.asset_uid=s.asset_uid AND h.status='active')
+          ORDER BY s.expires_at,s.uid"""), {"instant": instant}).mappings()
+        return [_row(row) for row in rows]
+
+    def mark_subscription_reclaimed(self, uid, expected_version):
+        if self._runtime_restricted():
+            return _row(self._trusted_delivery_runtime_write("mark_subscription_reclaimed", {
+                "uid": uid, "expected_version": expected_version,
+            }))
+        row = self.session.execute(text("""UPDATE public.trusted_delivery_subscriptions SET status='reclaimed',current_version=current_version+1,updated_at=clock_timestamp()
+          WHERE uid=CAST(:uid AS uuid) AND status='expired' AND current_version=:version
+          RETURNING uid::text,grant_uid::text,asset_uid::text,status,current_version"""), {"uid": uid, "version": expected_version}).mappings().one_or_none()
+        if row is None:
+            raise RuntimeError("subscription reclaim conflict")
+        return _row(row)

+ 255 - 0
deployment/app/core/system/trusted_delivery_subscriptions.py

@@ -0,0 +1,255 @@
+"""Closed subscription and delivery controls for trusted data delivery.
+
+The service never carries data rows, target URLs, credentials, or provider
+configuration.  It persists only the minimal delivery control-plane facts and
+safe incident references; P3 production operations remains the incident source
+of truth.
+"""
+
+from __future__ import annotations
+
+import copy
+import hashlib
+import json
+import re
+import uuid
+from collections.abc import Callable
+from datetime import UTC, datetime
+from typing import Any
+
+from app.core.common.identifiers import new_governance_uid
+from app.core.common.timezone_utils import now_china
+
+_SAFE_CODE = re.compile(r"^[A-Za-z][A-Za-z0-9_.:-]{0,159}$")
+_DIGEST = re.compile(r"^[0-9a-f]{64}$")
+_UNSAFE = re.compile(
+    r"(?i)(?:https?://|ftp://|file://|www\.|\b(?:secret|token|password|private[ _-]?key)\b|"
+    r"-----BEGIN|<script|javascript:|;|\bselect\s+.+\bfrom\b)"
+)
+_ANOMALIES = frozenset({"unusual_access", "quota_exceeded", "purpose_breach", "secondary_propagation"})
+
+
+def _uid(value: Any, label: str) -> str:
+    try:
+        return str(uuid.UUID(str(value)))
+    except (TypeError, ValueError, AttributeError) as exc:
+        raise ValueError(f"{label} must be a UUID") from exc
+
+
+def _text(value: Any, label: str, maximum: int = 160) -> str:
+    if not isinstance(value, str) or not value.strip() or len(value.strip()) > maximum:
+        raise ValueError(f"{label} is invalid")
+    result = value.strip()
+    if _UNSAFE.search(result):
+        raise ValueError(f"{label} contains unsafe content")
+    return result
+
+
+def _instant(value: Any, label: str) -> str:
+    try:
+        result = value if isinstance(value, datetime) else datetime.fromisoformat(str(value).replace("Z", "+00:00"))
+    except (TypeError, ValueError) as exc:
+        raise ValueError(f"{label} must be ISO-8601") from exc
+    if result.tzinfo is None:
+        raise ValueError(f"{label} must include a timezone")
+    return result.astimezone(UTC).isoformat()
+
+
+def _digest(value: Any) -> str:
+    return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(",", ":")).encode()).hexdigest()
+
+
+def _closed(value: Any, allowed: set[str], label: str) -> dict[str, Any]:
+    if not isinstance(value, dict):
+        raise ValueError(f"{label} must be an object")
+    extra = set(value) - allowed
+    if extra:
+        raise ValueError(f"{label} contains unsupported fields")
+    return copy.deepcopy(value)
+
+
+class TrustedDeliverySubscriptionService:
+    """State machine façade; the repository owns DB time and transaction scope."""
+
+    def __init__(
+        self,
+        repository,
+        *,
+        uid_factory: Callable[[], str] = new_governance_uid,
+        now_factory: Callable[[], datetime] = now_china,
+    ):
+        self.repository = repository
+        self.uid_factory = uid_factory
+        self.now_factory = now_factory
+
+    def _actor(self, value: Any) -> str:
+        actor = _uid(value, "actor_uid")
+        if self.repository.users_available({actor}) != {actor}:
+            raise ValueError("trusted delivery actor is unavailable")
+        return actor
+
+    def _evidence(self, action: str, actor_uid: str, detail: dict[str, str]) -> None:
+        self.repository.add_subscription_evidence({
+            "uid": self.uid_factory(), "action": action, "actor_uid": actor_uid,
+            "safe_detail": copy.deepcopy(detail), "created_at": self.now_factory().astimezone(UTC).isoformat(),
+        })
+
+    def _trigger(self, value: Any) -> dict[str, str]:
+        body = _closed(value, {"kind", "schedule_ref", "event_type"}, "subscription trigger")
+        kind = _text(body.get("kind"), "trigger kind", 20)
+        if kind == "schedule":
+            if set(body) != {"kind", "schedule_ref"}:
+                raise ValueError("schedule trigger has unsupported fields")
+            return {"kind": kind, "schedule_ref": _text(body["schedule_ref"], "schedule ref", 120)}
+        if kind == "event":
+            if set(body) != {"kind", "event_type"}:
+                raise ValueError("event trigger has unsupported fields")
+            return {"kind": kind, "event_type": _text(body["event_type"], "event type", 120)}
+        raise ValueError("trigger kind is unsupported")
+
+    def create_subscription(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"grant_uid", "asset_uid", "trigger", "purpose", "expires_at", "idempotency_key"}, "subscription")
+        actor = self._actor(actor_uid)
+        expiry = _instant(body.get("expires_at"), "subscription expiry")
+        if datetime.fromisoformat(expiry) <= self.now_factory().astimezone(UTC):
+            raise ValueError("subscription expiry must be in the future")
+        key = _text(body.get("idempotency_key"), "idempotency key", 160)
+        if not _SAFE_CODE.fullmatch(key):
+            raise ValueError("idempotency key is invalid")
+        trigger = self._trigger(body.get("trigger"))
+        record = {
+            "uid": self.uid_factory(), "grant_uid": _uid(body.get("grant_uid"), "grant_uid"),
+            "asset_uid": _uid(body.get("asset_uid"), "asset_uid"), "trigger": trigger,
+            "purpose": _text(body.get("purpose"), "purpose", 100), "expires_at": expiry,
+            "idempotency_key": key, "status": "draft", "current_version": 1, "created_by": actor,
+        }
+        if not hasattr(self.repository, "get_grant_for_subscription"):
+            raise RuntimeError("durable trusted-delivery grant repository is required")
+        grant = self.repository.get_grant_for_subscription(record["grant_uid"])
+        if not grant or grant.get("status") != "active":
+            raise PermissionError("subscription grant is unavailable")
+        if grant.get("asset_uid") != record["asset_uid"] or grant.get("purpose") != record["purpose"]:
+            raise PermissionError("subscription grant does not bind asset and purpose")
+        if _instant(grant.get("expires_at"), "grant expiry") < record["expires_at"]:
+            raise PermissionError("subscription expiry exceeds grant")
+        record["request_digest"] = _digest({key: record[key] for key in ("grant_uid", "asset_uid", "trigger", "purpose", "expires_at", "idempotency_key")})
+        result = self.repository.create_subscription(record)
+        self._evidence("subscription_created", actor, {"subscription_uid": result["uid"], "trigger_kind": trigger["kind"]})
+        return result
+
+    def _transition(self, uid: Any, *, expected: set[str], target: str, actor_uid: str) -> dict[str, Any]:
+        actor = self._actor(actor_uid)
+        result = self.repository.transition_subscription(_uid(uid, "subscription_uid"), expected, target)
+        self._evidence(f"subscription_{target}", actor, {"subscription_uid": result["uid"], "status": target})
+        return result
+
+    def activate_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"draft", "paused"}, target="active", actor_uid=actor_uid)
+
+    def pause_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"active"}, target="paused", actor_uid=actor_uid)
+
+    def resume_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"paused"}, target="active", actor_uid=actor_uid)
+
+    def terminate_subscription(self, uid: Any, *, actor_uid: str) -> dict[str, Any]:
+        return self._transition(uid, expected={"draft", "active", "paused"}, target="terminated", actor_uid=actor_uid)
+
+    def enqueue_delivery(self, payload: Any, *, actor_uid: str) -> dict[str, Any]:
+        body = _closed(payload, {"subscription_uid", "trigger_ref", "event_digest"}, "subscription delivery")
+        actor = self._actor(actor_uid)
+        event_digest = _text(body.get("event_digest"), "event digest", 64).lower()
+        if not _DIGEST.fullmatch(event_digest):
+            raise ValueError("event digest must be SHA-256")
+        subscription_uid = _uid(body.get("subscription_uid"), "subscription_uid")
+        trigger_ref = _text(body.get("trigger_ref"), "trigger reference", 160)
+        if not _SAFE_CODE.fullmatch(trigger_ref):
+            raise ValueError("trigger reference is invalid")
+        record = {
+            "uid": self.uid_factory(), "subscription_uid": subscription_uid, "trigger_ref": trigger_ref,
+            "event_digest": event_digest, "status": "pending", "attempt_count": 0,
+            "lease_owner": None, "lease_fence": 0,
+        }
+        record["idempotency_key"] = f"{subscription_uid}:{trigger_ref}"
+        record["request_digest"] = _digest({key: record[key] for key in ("subscription_uid", "trigger_ref", "event_digest")})
+        result = self.repository.enqueue_subscription_delivery(record)
+        self._evidence("subscription_delivery_enqueued", actor, {"delivery_uid": result["uid"], "subscription_uid": subscription_uid})
+        return result
+
+    def claim_delivery(self, uid: Any, *, worker_id: str) -> dict[str, Any]:
+        result = self.repository.claim_subscription_delivery(_uid(uid, "delivery_uid"), _text(worker_id, "worker id", 80))
+        if result is None:
+            raise ValueError("subscription delivery is not claimable")
+        return result
+
+    def record_delivery_attempt(self, uid: Any, *, worker_id: str, lease_fence: Any, delivered: Any, actor_uid: str) -> dict[str, Any] | None:
+        actor = self._actor(actor_uid)
+        if not isinstance(lease_fence, int) or lease_fence < 1 or not isinstance(delivered, bool):
+            raise ValueError("subscription delivery attempt is invalid")
+        result = self.repository.record_subscription_attempt(_uid(uid, "delivery_uid"), _text(worker_id, "worker id", 80), lease_fence, delivered)
+        if result is not None:
+            self._evidence("subscription_delivery_delivered" if delivered else "subscription_delivery_failed", actor, {"delivery_uid": result["uid"], "status": result["status"]})
+        return result
+
+    def compensate_dead_letter(self, uid: Any, *, reason_code: Any, receipt_code: Any, actor_uid: str) -> dict[str, Any]:
+        actor = self._actor(actor_uid)
+        reason = _text(reason_code, "compensation reason", 64)
+        receipt = _text(receipt_code, "compensation receipt", 64)
+        if reason not in {"operator_review", "provider_recovered", "duplicate_suppressed"} or not re.fullmatch(r"[A-Z][A-Z0-9_]{0,63}", receipt):
+            raise ValueError("subscription compensation is invalid")
+        result = self.repository.compensate_subscription_delivery(_uid(uid, "delivery_uid"), reason, receipt)
+        self._evidence("subscription_dead_letter_compensated", actor, {"delivery_uid": result["uid"], "receipt_code": receipt})
+        return result
+
+    def report_anomaly(self, payload: Any, *, actor_uid: str) -> dict[str, str]:
+        body = _closed(payload, {"kind", "asset_uid", "subscription_uid", "incident_uid", "summary", "correlation_id"}, "subscription anomaly")
+        actor = self._actor(actor_uid)
+        kind = _text(body.get("kind"), "anomaly kind", 40)
+        if kind not in _ANOMALIES:
+            raise ValueError("anomaly kind is unsupported")
+        record = {
+            "kind": kind, "asset_uid": _uid(body.get("asset_uid"), "asset_uid"),
+            "subscription_uid": _uid(body.get("subscription_uid"), "subscription_uid"),
+            "incident_uid": _uid(body.get("incident_uid"), "incident_uid"),
+            "summary": _text(body.get("summary"), "anomaly summary", 160),
+            "correlation_id": _uid(body.get("correlation_id"), "correlation_id"),
+        }
+        if hasattr(self.repository, "incident_exists") and not self.repository.incident_exists(record["incident_uid"]):
+            raise ValueError("referenced incident is unavailable")
+        if not hasattr(self.repository, "link_anomaly_incident"):
+            raise RuntimeError("canonical incident linkage is unavailable")
+        # The P2 incident ledger remains the sole incident truth.  Trusted
+        # delivery only creates a bounded, idempotent asset impact link; it
+        # never creates a parallel incident record or accepts an unverified ID.
+        self.repository.link_anomaly_incident(
+            record["incident_uid"], record["asset_uid"], f"trusted_delivery:{kind}"
+        )
+        self._evidence("subscription_anomaly_reported", actor, {"kind": kind, "incident_uid": record["incident_uid"], "correlation_id": record["correlation_id"]})
+        return record
+
+    def expire_and_reclaim(self, *, as_of: Any, actor_uid: str, reclaim: Callable[[str, str], dict[str, Any]]) -> list[dict[str, Any]]:
+        """Reuse the trusted-delivery revocation path before changing state.
+
+        A legal hold is filtered by the repository; provider failures leave the
+        subscription unchanged so the next scheduler pass can retry safely.
+        """
+        actor = self._actor(actor_uid)
+        instant = _instant(as_of, "as_of")
+        results = []
+        for subscription in self.repository.subscriptions_due_for_reclaim(instant):
+            expired = subscription
+            if subscription.get("status", "active") == "active":
+                expired = self.repository.transition_subscription(subscription["uid"], {"active"}, "expired")
+            key = f"subscription-reclaim:{subscription['uid']}"
+            try:
+                receipt = reclaim(subscription["grant_uid"], key)
+            except (PermissionError, RuntimeError, ValueError):
+                self._evidence("subscription_reclaim_deferred", actor, {"subscription_uid": subscription["uid"], "grant_uid": subscription["grant_uid"]})
+                continue
+            if not isinstance(receipt, dict) or receipt.get("status") != "reclaimed":
+                self._evidence("subscription_reclaim_deferred", actor, {"subscription_uid": subscription["uid"], "grant_uid": subscription["grant_uid"]})
+                continue
+            saved = self.repository.mark_subscription_reclaimed(subscription["uid"], expired["current_version"])
+            self._evidence("subscription_reclaimed", actor, {"subscription_uid": saved["uid"], "grant_uid": subscription["grant_uid"]})
+            results.append(saved)
+        return results

+ 42 - 0
deployment/compose/backend.Dockerfile.eai

@@ -0,0 +1,42 @@
+FROM docker.m.daocloud.io/library/python:3.11-slim AS dependencies
+
+ENV PYTHONDONTWRITEBYTECODE=1 \
+    PYTHONUNBUFFERED=1 \
+    PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ \
+    APP_DIR=/app
+
+WORKDIR /app
+
+RUN sed -i 's|deb.debian.org|mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/debian.sources \
+    && apt-get update \
+    && apt-get install --no-install-recommends -y gcc libc6-dev libgomp1 linux-libc-dev \
+    && rm -rf /var/lib/apt/lists/*
+
+COPY requirements.txt ./requirements.txt
+RUN pip install --no-cache-dir -r requirements.txt \
+    && apt-get purge -y gcc libc6-dev linux-libc-dev \
+    && apt-get autoremove -y \
+    && rm -rf /var/lib/apt/lists/*
+
+FROM dependencies AS migrator
+
+COPY app/ ./app/
+COPY migrations/env.py migrations/script.py.mako ./migrations/
+COPY migrations/versions/[0-9]*.py ./migrations/versions/
+COPY alembic.ini ./alembic.ini
+
+CMD ["alembic", "-c", "alembic.ini", "upgrade", "head"]
+
+FROM dependencies AS runtime
+
+RUN pip uninstall -y alembic
+
+COPY app/ ./app/
+COPY datafactory/ ./datafactory/
+COPY wsgi.py gunicorn_config.py ./
+
+RUN mkdir -p /app/logs /data/upload /data/archive
+
+EXPOSE 5500
+
+CMD ["gunicorn", "--config", "gunicorn_config.py", "wsgi:application"]

+ 271 - 0
deployment/compose/docker-compose.eai-18188.yml

@@ -0,0 +1,271 @@
+name: dataops-eai
+
+services:
+  postgres:
+    image: docker.m.daocloud.io/pgvector/pgvector:pg16
+    environment:
+      POSTGRES_DB: dataops
+      POSTGRES_USER: ${DATAOPS_POSTGRES_USER}
+      POSTGRES_PASSWORD: ${DATAOPS_POSTGRES_PASSWORD}
+    volumes:
+      - dataops-eai-postgres:/var/lib/postgresql/data
+    healthcheck:
+      test: ["CMD-SHELL", "pg_isready -U ${DATAOPS_POSTGRES_USER} -d dataops"]
+      interval: 5s
+      timeout: 5s
+      retries: 30
+    networks: [dataops-eai]
+
+  kestra-db-init:
+    image: docker.m.daocloud.io/library/postgres:16-alpine
+    environment:
+      PGPASSWORD: ${DATAOPS_POSTGRES_PASSWORD}
+    command:
+      - /bin/sh
+      - -ec
+      - >-
+        until pg_isready -h postgres -U ${DATAOPS_POSTGRES_USER} -d dataops; do sleep 2; done;
+        psql -h postgres -U ${DATAOPS_POSTGRES_USER} -d postgres -tc "SELECT 1 FROM pg_database WHERE datname='kestra'" |
+        grep -q 1 || psql -h postgres -U ${DATAOPS_POSTGRES_USER} -d postgres -c "CREATE DATABASE kestra";
+    depends_on:
+      postgres:
+        condition: service_healthy
+    restart: "no"
+    profiles: ["orchestration"]
+    networks: [dataops-eai]
+
+  db-role-init:
+    image: dataops-eai-migrator:local
+    build:
+      context: ../..
+      dockerfile: deployment/compose/backend.Dockerfile.eai
+      target: migrator
+    environment:
+      DB_ROLE_INIT_DATABASE_URL: postgresql://${DATAOPS_POSTGRES_USER}:${DATAOPS_POSTGRES_PASSWORD}@postgres:5432/dataops
+      MIGRATION_DATABASE_URL: postgresql://${DATAOPS_POSTGRES_USER}:${DATAOPS_POSTGRES_PASSWORD}@postgres:5432/dataops
+      DATABASE_URL: postgresql://dataops_app:${DATAOPS_RUNTIME_PASSWORD}@postgres:5432/dataops
+      DATAOPS_MIGRATOR_USER: ${DATAOPS_POSTGRES_USER}
+      DATAOPS_RUNTIME_USER: dataops_app
+      DATAOPS_RUNTIME_PASSWORD: ${DATAOPS_RUNTIME_PASSWORD}
+    command: ["python", "-m", "app.core.edge_gateway.runtime_roles"]
+    depends_on:
+      postgres:
+        condition: service_healthy
+    restart: "no"
+    networks: [dataops-eai]
+
+  db-migrate:
+    image: dataops-eai-migrator:local
+    build:
+      context: ../..
+      dockerfile: deployment/compose/backend.Dockerfile.eai
+      target: migrator
+    command: ["alembic", "-c", "alembic.ini", "upgrade", "head"]
+    environment:
+      MIGRATION_DATABASE_URL: postgresql://${DATAOPS_POSTGRES_USER}:${DATAOPS_POSTGRES_PASSWORD}@postgres:5432/dataops
+    depends_on:
+      db-role-init:
+        condition: service_completed_successfully
+    restart: "no"
+    networks: [dataops-eai]
+
+  neo4j:
+    image: docker.m.daocloud.io/library/neo4j:5.26-community
+    environment:
+      NEO4J_AUTH: neo4j/${DATAOPS_NEO4J_PASSWORD}
+      NEO4J_server_memory_heap_initial__size: 256m
+      NEO4J_server_memory_heap_max__size: 512m
+      NEO4J_server_memory_pagecache_size: 256m
+    volumes:
+      - dataops-eai-neo4j:/data
+    healthcheck:
+      test: ["CMD-SHELL", "cypher-shell -u neo4j -p '${DATAOPS_NEO4J_PASSWORD}' 'RETURN 1' >/dev/null 2>&1"]
+      interval: 10s
+      timeout: 10s
+      retries: 30
+      start_period: 20s
+    networks: [dataops-eai]
+
+  minio:
+    image: docker.m.daocloud.io/minio/minio:RELEASE.2025-04-22T22-12-26Z
+    command: server /data --console-address ":9001"
+    environment:
+      MINIO_ROOT_USER: ${DATAOPS_MINIO_USER}
+      MINIO_ROOT_PASSWORD: ${DATAOPS_MINIO_PASSWORD}
+    volumes:
+      - dataops-eai-minio:/data
+    healthcheck:
+      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
+      interval: 5s
+      timeout: 5s
+      retries: 30
+    networks: [dataops-eai]
+
+  minio-init:
+    image: docker.m.daocloud.io/minio/mc:RELEASE.2025-04-16T18-13-26Z
+    environment:
+      MINIO_ROOT_USER: ${DATAOPS_MINIO_USER}
+      MINIO_ROOT_PASSWORD: ${DATAOPS_MINIO_PASSWORD}
+    entrypoint:
+      - /bin/sh
+      - -ec
+      - mc alias set local http://minio:9000 "$${MINIO_ROOT_USER}" "$${MINIO_ROOT_PASSWORD}" && mc mb --ignore-existing local/dataops-bucket
+    depends_on:
+      minio:
+        condition: service_healthy
+    restart: "no"
+    networks: [dataops-eai]
+
+  kestra:
+    image: docker.m.daocloud.io/kestra/kestra:v1.3.20
+    command: ["server", "standalone", "--worker-thread=8", "--config", "/etc/kestra/application.yml"]
+    environment:
+      KESTRA_DB_HOST: postgres
+      KESTRA_DB_NAME: kestra
+      KESTRA_DB_USERNAME: ${DATAOPS_POSTGRES_USER}
+      KESTRA_DB_PASSWORD: ${DATAOPS_POSTGRES_PASSWORD}
+      KESTRA_USERNAME: ${KESTRA_USERNAME}
+      KESTRA_PASSWORD: ${KESTRA_PASSWORD}
+    volumes:
+      - dataops-eai-kestra:/app/storage
+      - ../../deploy/docker/kestra/application.yml:/etc/kestra/application.yml:ro
+    depends_on:
+      kestra-db-init:
+        condition: service_completed_successfully
+    healthcheck:
+      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8081/health"]
+      interval: 10s
+      timeout: 5s
+      retries: 60
+      start_period: 60s
+    restart: unless-stopped
+    profiles: ["orchestration"]
+    networks: [dataops-eai]
+
+  runner:
+    image: dataops-eai-runner:local
+    build:
+      context: ../..
+      dockerfile: deployment/compose/runner.Dockerfile.eai
+    environment:
+      RUNNER_LISTEN_HOST: 0.0.0.0
+      RUNNER_LISTEN_PORT: 5600
+      RUNNER_TASK_TOKEN_SECRET: ${RUNNER_TASK_TOKEN_SECRET}
+      RUNNER_MINIO_HOST: minio:9000
+      RUNNER_MINIO_USER: ${DATAOPS_MINIO_USER}
+      RUNNER_MINIO_PASSWORD: ${DATAOPS_MINIO_PASSWORD}
+      RUNNER_MINIO_BUCKET: dataops-bucket
+      RUNNER_MINIO_SECURE: "false"
+      DATABASE_URL: postgresql://dataops_app:${DATAOPS_RUNTIME_PASSWORD}@postgres:5432/dataops
+      NEO4J_URI: bolt://neo4j:7687
+      NEO4J_USER: neo4j
+      NEO4J_PASSWORD: ${DATAOPS_NEO4J_PASSWORD}
+      DATASOURCE_CREDENTIAL_MASTER_KEY: ${DATASOURCE_CREDENTIAL_MASTER_KEY}
+      DATASOURCE_CREDENTIAL_KEY_VERSION: v1
+    read_only: true
+    tmpfs: [/tmp]
+    depends_on:
+      db-migrate:
+        condition: service_completed_successfully
+      neo4j:
+        condition: service_healthy
+      minio-init:
+        condition: service_completed_successfully
+    healthcheck:
+      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5600/health', timeout=5)"]
+      interval: 10s
+      timeout: 5s
+      retries: 20
+      start_period: 20s
+    networks: [dataops-eai]
+
+  backend:
+    image: dataops-eai-backend:local
+    build:
+      context: ../..
+      dockerfile: deployment/compose/backend.Dockerfile.eai
+      target: runtime
+    environment:
+      FLASK_ENV: production
+      LISTEN_HOST: 0.0.0.0
+      LISTEN_PORT: 5500
+      GUNICORN_WORKERS: 2
+      DATABASE_URL: postgresql://dataops_app:${DATAOPS_RUNTIME_PASSWORD}@postgres:5432/dataops
+      NEO4J_URI: bolt://neo4j:7687
+      NEO4J_HTTP_URI: http://neo4j:7474
+      NEO4J_USER: neo4j
+      NEO4J_PASSWORD: ${DATAOPS_NEO4J_PASSWORD}
+      NEO4J_ENCRYPTED: "false"
+      MINIO_HOST: minio:9000
+      MINIO_USER: ${DATAOPS_MINIO_USER}
+      MINIO_PASSWORD: ${DATAOPS_MINIO_PASSWORD}
+      MINIO_BUCKET: dataops-bucket
+      MINIO_SECURE: "false"
+      DATAFLOW_DEFAULT_DB_HOST: postgres
+      DATAFLOW_DEFAULT_DB_PORT: 5432
+      DATAFLOW_DEFAULT_DB_NAME: dataops
+      DATAFLOW_SCHEMA: dags
+      RUNNER_TASK_TOKEN_SECRET: ${RUNNER_TASK_TOKEN_SECRET}
+      API_BASE_URL: http://backend:5500/api
+      SECRET_KEY: ${DATAOPS_SECRET_KEY}
+      AUDIT_EVIDENCE_SECRET: ${AUDIT_EVIDENCE_SECRET}
+      AUDIT_EVIDENCE_KEY_VERSION: v1
+      RULE_GENERATION_RECEIPT_SECRET: ${RULE_GENERATION_RECEIPT_SECRET}
+      DATASOURCE_CREDENTIAL_MASTER_KEY: ${DATASOURCE_CREDENTIAL_MASTER_KEY}
+      DATASOURCE_CREDENTIAL_KEY_VERSION: v1
+      LOG_TO_CONSOLE: "true"
+    ports: ["127.0.0.1:${BACKEND_PORT}:5500"]
+    volumes:
+      - dataops-eai-backend-logs:/app/logs
+      - dataops-eai-upload:/data/upload
+      - dataops-eai-archive:/data/archive
+    depends_on:
+      db-migrate:
+        condition: service_completed_successfully
+      neo4j:
+        condition: service_healthy
+      minio-init:
+        condition: service_completed_successfully
+      runner:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:5500/api/system/health', timeout=5)"]
+      interval: 10s
+      timeout: 10s
+      retries: 20
+      start_period: 20s
+    networks: [dataops-eai]
+
+  frontend:
+    image: dataops-eai-frontend:local
+    build:
+      context: ../..
+      dockerfile: deployment/compose/frontend.Dockerfile.eai
+      args:
+        VUE_APP_N8N_URL: ""
+        VUE_APP_N8N_CHAT_URL: ""
+        VUE_APP_MINIO_PUBLIC_URL: ""
+        VUE_APP_PREVIEW_URL: ""
+    ports: ["127.0.0.1:${FRONTEND_PORT}:80"]
+    depends_on:
+      backend:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1/"]
+      interval: 10s
+      timeout: 5s
+      retries: 20
+    networks: [dataops-eai]
+
+networks:
+  dataops-eai:
+    name: dataops-eai-network
+
+volumes:
+  dataops-eai-postgres:
+  dataops-eai-neo4j:
+  dataops-eai-minio:
+  dataops-eai-kestra:
+  dataops-eai-backend-logs:
+  dataops-eai-upload:
+  dataops-eai-archive:

+ 25 - 0
deployment/compose/frontend.Dockerfile.eai

@@ -0,0 +1,25 @@
+FROM docker.m.daocloud.io/library/node:24-bookworm-slim AS build
+
+WORKDIR /workspace
+
+ARG VUE_APP_N8N_URL=
+ARG VUE_APP_N8N_CHAT_URL=
+ARG VUE_APP_MINIO_PUBLIC_URL=
+ARG VUE_APP_PREVIEW_URL=
+ENV VUE_APP_N8N_URL=${VUE_APP_N8N_URL}
+ENV VUE_APP_N8N_CHAT_URL=${VUE_APP_N8N_CHAT_URL}
+ENV VUE_APP_MINIO_PUBLIC_URL=${VUE_APP_MINIO_PUBLIC_URL}
+ENV VUE_APP_PREVIEW_URL=${VUE_APP_PREVIEW_URL}
+
+COPY frontend/package.json frontend/package-lock.json ./
+RUN npm ci --legacy-peer-deps
+
+COPY frontend/ ./
+RUN npm run build
+
+FROM docker.m.daocloud.io/library/nginx:1.27-alpine
+
+COPY deploy/docker/nginx.conf /etc/nginx/conf.d/default.conf
+COPY --from=build /workspace/dist/ /usr/share/nginx/html/
+
+EXPOSE 80

+ 6 - 0
deployment/compose/package_offline.sh

@@ -56,6 +56,8 @@ for required in \
   database \
   migrations \
   deployment/environments \
+  deployment/helm/dataops-platform \
+  deployment/enterprise \
   docs/architecture/OPENAPI.yaml \
   deployment/compose; do
   [[ -e "${REPO_ROOT}/${required}" ]] \
@@ -84,6 +86,8 @@ mkdir -p \
   "${BUNDLE_ROOT}/deploy" \
   "${BUNDLE_ROOT}/environments" \
   "${BUNDLE_ROOT}/operations" \
+  "${BUNDLE_ROOT}/helm" \
+  "${BUNDLE_ROOT}/enterprise" \
   "${BUNDLE_ROOT}/images" \
   "${BUNDLE_ROOT}/trace"
 cp -R "${REPO_ROOT}/deploy/docker" "${BUNDLE_ROOT}/deploy/docker"
@@ -91,6 +95,8 @@ cp -R "${REPO_ROOT}/database" "${BUNDLE_ROOT}/database"
 cp -R "${REPO_ROOT}/migrations" "${BUNDLE_ROOT}/migrations"
 cp -R "${REPO_ROOT}/deployment/environments/." "${BUNDLE_ROOT}/environments/"
 cp -R "${REPO_ROOT}/deployment/compose/." "${BUNDLE_ROOT}/operations/"
+cp -R "${REPO_ROOT}/deployment/helm/dataops-platform" "${BUNDLE_ROOT}/helm/dataops-platform"
+cp -R "${REPO_ROOT}/deployment/enterprise/." "${BUNDLE_ROOT}/enterprise/"
 cp "${REPO_ROOT}/deployment/MANIFEST.md" "${BUNDLE_ROOT}/MANIFEST.md"
 cp "${REPO_ROOT}/docs/architecture/OPENAPI.yaml" "${BUNDLE_ROOT}/trace/OPENAPI.yaml"
 

+ 26 - 0
deployment/compose/runner.Dockerfile.eai

@@ -0,0 +1,26 @@
+FROM docker.m.daocloud.io/library/python:3.11-slim AS runtime
+
+ENV PYTHONDONTWRITEBYTECODE=1 \
+    PYTHONUNBUFFERED=1 \
+    PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ \
+    APP_DIR=/app
+
+WORKDIR /app
+
+RUN sed -i 's|deb.debian.org|mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/debian.sources \
+    && apt-get update \
+    && apt-get install --no-install-recommends -y gcc libc6-dev libgomp1 linux-libc-dev \
+    && rm -rf /var/lib/apt/lists/*
+
+COPY requirements.txt ./requirements.txt
+RUN pip install --no-cache-dir -r requirements.txt \
+    && pip uninstall -y alembic \
+    && apt-get purge -y gcc libc6-dev linux-libc-dev \
+    && apt-get autoremove -y \
+    && rm -rf /var/lib/apt/lists/*
+
+COPY app/ ./app/
+
+EXPOSE 5600
+
+CMD ["gunicorn", "--config", "app/runner/gunicorn_config.py", "app.runner.wsgi:application"]

+ 34 - 0
deployment/config/Caddyfile.company.citupro.com

@@ -0,0 +1,34 @@
+{
+	# Nginx keeps port 80 for unrelated sites; Caddy uses port 443 for TLS-ALPN validation.
+	auto_https disable_redirects
+}
+
+https://company.citupro.com:18183 {
+	encode zstd gzip
+
+	handle_path /op/base/* {
+		reverse_proxy 127.0.0.1:7654
+	}
+
+	@vanna path /api/vanna*
+	handle @vanna {
+		uri replace /api/vanna /api
+		reverse_proxy 127.0.0.1:8084
+	}
+
+	@dags path /api/dags*
+	handle @dags {
+		reverse_proxy 127.0.0.1:5005
+	}
+
+	@api path /api*
+	handle @api {
+		reverse_proxy 127.0.0.1:5500
+	}
+
+	handle {
+		root * /home/ubuntu/webside/data-ops-web
+		try_files {path} /index.html
+		file_server
+	}
+}

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini