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
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: fruwehq/determa-state-conformance
ref: 7f09321fb483a22eb677a4342f8d9537a7a18e82
ref: affe3fe3bcc4d13fa7c5374471568e94af36f0d1
path: .pinned/determa-state-conformance
- name: Check out pinned specification
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: fruwehq/determa-state-conformance
ref: 7f09321fb483a22eb677a4342f8d9537a7a18e82
ref: affe3fe3bcc4d13fa7c5374471568e94af36f0d1
path: .pinned/determa-state-conformance
- name: Check out pinned specification
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -126,7 +126,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: fruwehq/determa-state-conformance
ref: 7f09321fb483a22eb677a4342f8d9537a7a18e82
ref: affe3fe3bcc4d13fa7c5374471568e94af36f0d1
path: .pinned/determa-state-conformance
- name: Check out pinned specification
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The implementation is conformant only when it passes the language-neutral suite.
The implementation uses these immutable inputs:

- specification: `86bb88dd21cb1f799eefe5020b6e49dabf6e7225`;
- conformance: `7f09321fb483a22eb677a4342f8d9537a7a18e82` (99 format-1
- conformance: `affe3fe3bcc4d13fa7c5374471568e94af36f0d1` (99 format-1
core cases, 162 version-1 vectors, 142 durable-host vectors, 49 core inspection
vectors, 47 extension negotiation vectors, 7 optional native-provider vectors,
30 runtime-provider vectors, and 484 JSON artifacts).
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ commit `86bb88dd21cb1f799eefe5020b6e49dabf6e7225`. Correctness is determined by
99 format-1 core cases, 162 version-1 vectors, 142 durable-host vectors, 49 core
inspection vectors, 47 extension negotiation vectors, 7 native guard-provider
inspection vectors, 30 runtime-provider vectors, and 484 manifest artifacts at
conformance commit `7f09321fb483a22eb677a4342f8d9537a7a18e82`. The native
conformance commit `affe3fe3bcc4d13fa7c5374471568e94af36f0d1`. The native
runtime-provider profile is optional and is exercised through its production adapter.

The package metadata is `0.3.0`. Artifact and checkpoint schema version 1 is the
Expand All @@ -35,6 +35,23 @@ returns its receipt before current row input is mapped. The optional aggregate-o
step path uses the mapping's `reconstruct_aggregate` and `project_aggregate`
methods when no checkpoint exists.

`determa.state.public_client.PublicHostClient` binds deployment names to
`EndpointBinding(endpoint, scope_alias)` values. Initialize its SQLite journal with
`setup_schema()` and supply an authenticated transport callable. Before sending a
mutation it discovers the immutable scope binding and saves the complete request,
request digest and endpoint. `retry(operation_id)` and `receipt(operation_id)` use
that saved endpoint after restart, including when a deployment alias has changed.
A transport exception leaves the outcome unknown; it does not prove rollback.

`determa.state.public_host.SQLitePublicExecutionHost` implements the closed public
version-1 capabilities, create, admit, process, read, structural inspect and receipt
operations for one local scope. The transport authenticates a principal; the host
authorizes it before root or receipt lookup. Explicit schema setup verifies native
SQLite tables and retention triggers. A mutation commits its checkpoint and complete
first public response in one transaction; equal retries return that response before
calling the core or resolving definitions. This local profile advertises no authority,
native effects, timers, archive or recovery operations.

## Install

To try the `0.3.0` release candidate before publication, install it from a checkout:
Expand Down
2 changes: 1 addition & 1 deletion conformance/pins.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from pathlib import Path

CONFORMANCE_COMMIT = "7f09321fb483a22eb677a4342f8d9537a7a18e82"
CONFORMANCE_COMMIT = "affe3fe3bcc4d13fa7c5374471568e94af36f0d1"
SPEC_COMMIT = "86bb88dd21cb1f799eefe5020b6e49dabf6e7225"

ROOT = Path(__file__).resolve().parent.parent
Expand Down
117 changes: 117 additions & 0 deletions conformance/test_public_host.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"""Pinned public wire goldens and executable minimal local-host profile."""

from __future__ import annotations

import json
import os
from pathlib import Path

import pytest

from determa.state import MemoryArtifactResolver, load_bundle
from determa.state.public_client import (
PublicHostError,
public_request_digest,
validate_public_message,
)
from determa.state.public_host import SQLitePublicExecutionHost
from determa.state.wire import canonical_bytes, hash_value

from .harness import conformance_root


def goldens(name):
root = Path(os.environ["DETERMA_SPEC_DIR"])
return json.loads((root / "examples/public-host" / name).read_text())


def test_complete_public_golden_wire_and_hash_matrix():
positive = goldens("positive-v1.json")
negative = goldens("negative-v1.json")
for case in positive["cases"]:
validate_public_message(case["request"])
validate_public_message(case["response"], response=True)
assert public_request_digest(case["request"]) == case["request_digest"]
assert (
canonical_bytes(["determa-public-host-request-digest-1", "1", case["request"]]).decode()
== case["request_hash_operand_jcs"]
)
for case in negative["cases"]:
if "request_hash_operand_jcs" in case:
assert (
hash_value(["determa-public-host-request-digest-1", "1", case["request"]])
== case["request_digest"]
)
if "response" in case:
validate_public_message(case["response"], response=True)
for case in negative["invalid_responses"]:
if case["expected_error"] == "schema_validation":
with pytest.raises(PublicHostError):
validate_public_message(case["response"], response=True)


def test_local_host_exact_public_core_goldens(tmp_path):
bundle = load_bundle(
(
conformance_root()
/ "conformance/core/119-native-v1-aggregate-integrity/root-machine.yaml"
).read_text()
)
host = SQLitePublicExecutionHost(
tmp_path / "host.db",
scope_alias="scope",
scope_binding_identity="binding-local-1",
authorized_principals=frozenset({"alice"}),
resolver=MemoryArtifactResolver(definitions={bundle.fingerprint: bundle}),
)
host.setup_schema()
names = {
"create_committed",
"read_existing_checkpoint",
"inspect_absent_target_in_checkpoint",
"process_empty_mailbox",
"retained_operation_receipt",
}
observed = set()
for case in goldens("positive-v1.json")["cases"]:
if case["name"] in names:
assert host.handle(case["request"], principal="alice") == case["response"], case["name"]
observed.add(case["name"])
assert observed == names


@pytest.mark.parametrize(
("name", "fixture", "initial"),
[
("admit_declared_event", "execution-checkpoint-transfer-v1.json", "before_admission"),
("process_unhandled_event", "execution-checkpoint-transfer-v1.json", "after_admission"),
("process_deferred_event", "queue-placement-checkpoints-v1.json", "after_second_admission"),
("process_recall_event", "queue-placement-checkpoints-v1.json", "after_received_admission"),
],
)
def test_local_host_exact_delivery_goldens(tmp_path, name, fixture, initial):
import sqlite3

from determa.state import restore_execution_checkpoint_v1

spec = Path(os.environ["DETERMA_SPEC_DIR"])
bundle = load_bundle((spec / "examples/portable-event-deferral.yaml").read_text())
resolver = MemoryArtifactResolver(definitions={bundle.fingerprint: bundle})
checkpoint = json.loads((spec / "examples/delivery" / fixture).read_text())[initial]
restore_execution_checkpoint_v1(checkpoint, resolver)
host = SQLitePublicExecutionHost(
tmp_path / "host.db",
scope_alias="scope",
scope_binding_identity="binding-local-1",
authorized_principals=frozenset({"alice"}),
resolver=resolver,
)
host.setup_schema()
with sqlite3.connect(host.path) as db:
db.execute(
"INSERT INTO determa_public_host_checkpoints VALUES (?,?)",
(checkpoint["root_instance_id"], canonical_bytes(checkpoint)),
)
case = next(case for case in goldens("positive-v1.json")["cases"] if case["name"] == name)
assert host.handle(case["request"], principal="alice") == case["response"]
assert host.handle(case["request"], principal="alice") == case["response"]
5 changes: 4 additions & 1 deletion src/determa/state/checkpoint_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,10 @@ def step_checkpoint_v1(
candidate["root_record"]["aggregate_state"] = result["state"]
if result["disposition"] == "deferred":
_synchronize_mailbox_references(candidate)
return seal_execution_checkpoint(candidate)
sealed = seal_execution_checkpoint(candidate)
if _include_host_response:
return {"checkpoint": sealed, "core_result": copy.deepcopy(result), "receipt": None}
return sealed
receipt_sequence = candidate["next_operation_receipt_sequence"]
lifecycle_sequences = [
str(int(receipt_sequence) + index + 1)
Expand Down
56 changes: 56 additions & 0 deletions src/determa/state/data/archive-export-request-v1.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"type": "object",
"required": [
"request_format",
"request_schema_version",
"source",
"root_instance_ids",
"required_participant_ids",
"optional_participant_ids",
"consistency_token"
],
"additionalProperties": false,
"properties": {
"request_format": {
"const": "determa.archive_export_request"
},
"request_schema_version": {
"const": 1
},
"source": {
"$ref": "archive-v1.schema.json#/$defs/source"
},
"root_instance_ids": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"required_participant_ids": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z][a-z0-9.-]*$"
},
"uniqueItems": true
},
"optional_participant_ids": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z][a-z0-9.-]*$"
},
"uniqueItems": true
},
"consistency_token": {
"type": "string",
"minLength": 1
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://determa.dev/state/schema/archive-export-request-v1.schema.json",
"title": "Determa archive export request version 1"
}
56 changes: 56 additions & 0 deletions src/determa/state/data/archive-import-request-v1.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"type": "object",
"required": [
"request_format",
"request_schema_version",
"archive_digest",
"trusted_source_profile_digest",
"trusted_participant_contract_digest",
"expected_source",
"allow_optional_omission",
"requested_optional_participant_ids",
"staging_identity"
],
"additionalProperties": false,
"properties": {
"request_format": {
"const": "determa.archive_import_request"
},
"request_schema_version": {
"const": 1
},
"archive_digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"trusted_source_profile_digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"trusted_participant_contract_digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"expected_source": {
"$ref": "archive-v1.schema.json#/$defs/source"
},
"allow_optional_omission": {
"type": "boolean"
},
"requested_optional_participant_ids": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z][a-z0-9.-]*$"
},
"uniqueItems": true
},
"staging_identity": {
"type": "string",
"minLength": 1
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://determa.dev/state/schema/archive-import-request-v1.schema.json",
"title": "Determa archive import request version 1"
}
Loading