Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ rich>=14.0.0

typing_extensions>=4.14.0
google-genai>=2.12.1
google-cloud-datastore==2.26.0
36 changes: 36 additions & 0 deletions services/guardian/execution/production_composition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Production composition for Guardian execution authority.

Production execution authority consumption must use persistent,
transactional storage. Failure to construct the Datastore client is
intentionally propagated: production must never silently fall back to
process-local in-memory consumption state.
"""

from google.cloud import datastore

from services.guardian.execution.authorization_consumption_store import (
DatastoreAuthorizationConsumptionStore,
)
from services.guardian.execution.execution_layer import (
AutonomousExecutionLayer,
)


def build_authorization_consumption_store():
"""Build the production authorization-consumption store."""

client = datastore.Client()

return DatastoreAuthorizationConsumptionStore(
client=client,
)


def build_execution_layer():
"""Build the production Guardian execution layer."""

store = build_authorization_consumption_store()

return AutonomousExecutionLayer(
authorization_consumption=store,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import pytest

from services.guardian.execution.authorization_consumption_store import (
DatastoreAuthorizationConsumptionStore,
)


def test_production_composition_uses_datastore_store(monkeypatch):
from services.guardian.execution import production_composition

sentinel_client = object()

monkeypatch.setattr(
production_composition.datastore,
"Client",
lambda: sentinel_client,
)

store = (
production_composition
.build_authorization_consumption_store()
)

assert isinstance(
store,
DatastoreAuthorizationConsumptionStore,
)
assert store._client is sentinel_client


def test_production_execution_layer_receives_datastore_store(
monkeypatch,
):
from services.guardian.execution import production_composition

sentinel_client = object()

monkeypatch.setattr(
production_composition.datastore,
"Client",
lambda: sentinel_client,
)

engine = production_composition.build_execution_layer()

assert isinstance(
engine.authorization_consumption,
DatastoreAuthorizationConsumptionStore,
)
assert (
engine.authorization_consumption._client
is sentinel_client
)


def test_production_composition_does_not_fallback_to_memory(
monkeypatch,
):
from services.guardian.execution import production_composition

def fail_client():
raise RuntimeError("DATASTORE_UNAVAILABLE")

monkeypatch.setattr(
production_composition.datastore,
"Client",
fail_client,
)

with pytest.raises(
RuntimeError,
match="DATASTORE_UNAVAILABLE",
):
production_composition.build_execution_layer()
Loading