Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f444ffe
WIP: correct native slot identity, snapshots and initialization writes
fruwe Oct 5, 2026
c0c51d6
WIP: pin corrected native conformance and refresh only version-1 schemas
fruwe Oct 5, 2026
537c26e
Adapt native source-slot regression to recorded snapshots
fruwe Oct 5, 2026
c4fdf0e
WIP retain compilation evidence and reject inert source locators
fruwe Oct 5, 2026
4968699
WIP support typed native component environment forwarding
fruwe Oct 5, 2026
befa708
Reverify each compiler region and pin reviewed provider coverage
fruwe Oct 5, 2026
d1d626a
Align CI pins and exercise sealed manifest fingerprint mismatch
fruwe Oct 5, 2026
42d589a
Add unfinished durable foreground timer helper foundation
fruwe Oct 5, 2026
d61a63a
Merge remote-tracking branch 'origin/main' into fruwe/external-timer-…
fruwe Oct 5, 2026
27c3fa8
WIP timers: persist authenticated due claims and refuse ambiguous rec…
fruwe Oct 5, 2026
20457d7
WIP timers: coordinate firing and actual admission in host-owned SQLi…
fruwe Oct 5, 2026
7ae17a2
WIP timers: isolate protected storage and recheck lease before native…
fruwe Oct 5, 2026
96da0ff
Expose explicit shared SQLite transactions and align timer worker ref…
fruwe Oct 5, 2026
0d095bb
Prove coordinated timer restart after actual SIGKILL at native commit…
fruwe Oct 5, 2026
5d284e8
Retain storage-bound timer origin and immutable native operation evid…
fruwe Oct 5, 2026
c7a17b8
Implement strict local timer reclaim from native transaction fate
fruwe Oct 5, 2026
cb68436
Bind native timer fate proof dispatch before checking overrides
fruwe Oct 5, 2026
fd90681
Attest retained timer proof code before native fate dispatch
fruwe Oct 5, 2026
b32ba12
Validate pinned native result incarnations before dispatch
fruwe Oct 5, 2026
67f3ca6
Keep cancelled and terminal native work unclaimable
fruwe Oct 5, 2026
9dfc9af
Reject missing retry evidence and superseded terminal attempts
fruwe Oct 5, 2026
e53809e
Retain native dispatch starts and verify call boundaries (WIP)
fruwe Oct 5, 2026
9b6b770
Keep dispatch starts private and reject incomplete native inventories…
fruwe Oct 5, 2026
fdb4152
Refuse native reseeding when retained ownership roles disagree
fruwe Oct 5, 2026
4d08e39
fix(effects): reverify destination retry proof after native staging
fruwe Oct 6, 2026
8b5fdf7
feat(effects): verify scoped native retry decisions (WIP)
fruwe Oct 6, 2026
40140ad
fix(effects): refuse non-string native retry receipts before verifica…
fruwe Oct 6, 2026
e943f1d
WIP: seal the final native retry clock read
fruwe Oct 6, 2026
ce10166
WIP: pin native clock slots and source mode at retry commit
fruwe Oct 6, 2026
eeaaba1
fix: preserve terminal effects and validate cancellation payloads
fruwe Oct 6, 2026
d7ff173
fix: refuse standalone writes to native effects checkpoints
fruwe Oct 6, 2026
39def1a
fix: refuse checkpoint-only native SQLite access before execution
fruwe Oct 6, 2026
76d7192
Record reviewed prerequisites for native effect creation
fruwe Oct 6, 2026
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: c6949440f5b9fd6e06ea5571f4e01681dd59ee04
ref: 090aa297389e416121c25ef29fb0a75671d83233
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: c6949440f5b9fd6e06ea5571f4e01681dd59ee04
ref: 090aa297389e416121c25ef29fb0a75671d83233
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: c6949440f5b9fd6e06ea5571f4e01681dd59ee04
ref: 090aa297389e416121c25ef29fb0a75671d83233
path: .pinned/determa-state-conformance
- name: Check out pinned specification
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ The implementation is conformant only when it passes the language-neutral suite.
The implementation uses these immutable inputs:

- specification: `77c0a2e60cd0771a6d44ae170a079ddd51d7d9f0`;
- conformance: `c6949440f5b9fd6e06ea5571f4e01681dd59ee04` (99 format-1
- conformance: `090aa297389e416121c25ef29fb0a75671d83233` (reviewed coordinated
draft #114; 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,
52 runtime-provider vectors, and 487 JSON artifacts).
52 runtime-provider vectors, 62 committed-native-effect vectors, and 487 JSON artifacts).

The package metadata is `0.3.0`.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ commit `77c0a2e60cd0771a6d44ae170a079ddd51d7d9f0`. 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, 52 runtime-provider vectors, and 487 manifest artifacts at
conformance commit `c6949440f5b9fd6e06ea5571f4e01681dd59ee04`. The native
conformance commit `090aa297389e416121c25ef29fb0a75671d83233`. 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 Down
85 changes: 70 additions & 15 deletions conformance/effects_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ def equal(left: Any, right: Any) -> bool:
class _FixtureNativeProvider:
def __init__(self, invocation: Any) -> None:
self.invocation = invocation
self.retry_checker_available = True

def validate_configuration(self, configuration: dict[str, Any]) -> dict[str, Any]:
return copy.deepcopy(configuration)
Expand All @@ -410,9 +411,21 @@ def invoke(self, instance: Any, payload: Any, metadata: Any, attempt: Any) -> An
return self.invocation(payload, metadata, attempt)

def verify_deduplication_evidence(self, instance: Any, evidence: Any) -> bool:
return instance["destination_binding_digest"] == _sha(
_destination_configuration()
) and evidence == _destination_proof(evidence["scope_identity"], evidence["effect_id"])
return (
self.retry_checker_available
and instance["destination_binding_digest"] == _sha(_destination_configuration())
and {
key: evidence[key]
for key in (
"scope_identity",
"effect_id",
"destination_binding_digest",
"first_attempt_receipt_bytes_base64",
"repeat_attempt_receipt_bytes_base64",
)
}
== _destination_proof(evidence["scope_identity"], evidence["effect_id"])
)


def _run_operation(payload: dict[str, Any], control: Path | None = None) -> dict[str, Any]:
Expand Down Expand Up @@ -533,6 +546,8 @@ def verify_native(source: Any, selected: Any) -> bool:
},
)
installed_handler = VerifiedNativeHandler(handler_registry, configured_handler)
from determa.state.native_clock import NativeCommitClock

host = SQLiteCommittedEffectHost(
_PATH,
resolver,
Expand All @@ -541,6 +556,7 @@ def verify_native(source: Any, selected: Any) -> bool:
authority_scope=_AUTHORITY_SCOPE,
core_observer=observe_core,
trusted_clock=lambda: payload["auth_context"]["trusted_host_now"],
commit_clock=NativeCommitClock.controlled(int(payload["auth_context"]["trusted_host_now"])),
)
# Install the vector's pre-existing authority facts as trusted test setup.
# The production seed path may restore these claims, but cannot issue them.
Expand Down Expand Up @@ -581,6 +597,43 @@ def verify_native(source: Any, selected: Any) -> bool:
fault = payload["fault"]
response: dict[str, Any] | None = None
caller_kind = "completed"
retry_evidence = None
original_record = next(
(
record
for record in journal["effect_records"]
if record["effect_id"] == arguments.get("effect_id")
),
None,
)
retry_decision = (
operation == "submit_result" and arguments["outcome_kind"] == "retryable_failure"
) or (
operation == "claim"
and original_record is not None
and original_record["attempt_fence"] != "0"
)
if retry_decision and configuration["destination_deduplication_proven"]:
_destination_call(_AUTHORITY_SCOPE, arguments["effect_id"], None)
_destination_call(_AUTHORITY_SCOPE, arguments["effect_id"], None)
retry_evidence = {
**SQLiteCommittedEffectHost._retry_context(before, original_record),
**_destination_proof(_AUTHORITY_SCOPE, arguments["effect_id"]),
}
if fault == "retry_safety_missing":
retry_evidence = None
elif fault == "retry_safety_boolean":
retry_evidence = True
elif fault == "retry_safety_fabricated":
retry_evidence["first_attempt_receipt_bytes_base64"] = retry_evidence[
"repeat_attempt_receipt_bytes_base64"
] = base64.b64encode(b"fabricated equal receipts").decode()
elif fault == "retry_safety_wrong_work":
retry_evidence["effect_id"] = "sha256:" + "0" * 64
elif fault == "retry_safety_wrong_destination":
retry_evidence["destination_binding_digest"] = "sha256:" + "0" * 64
elif fault == "retry_safety_verifier_unavailable":
provider.retry_checker_available = False
if operation in {"produce", "produce_replay"}:
request = arguments["original_request"]
aggregate = checkpoint["root_record"]["aggregate_state"]
Expand Down Expand Up @@ -641,25 +694,14 @@ def before_commit(candidate: dict[str, Any], proposed_journal: dict[str, Any]) -
caller_kind = "aborted"
elif operation == "claim":
try:
evidence = None
if configuration["destination_deduplication_proven"] and any(
record["effect_id"] == arguments["effect_id"]
and record["invocation_state"] == "ambiguous"
for record in journal["effect_records"]
):
# Exercise the actual installed destination twice. The configuration
# requests this probe; only native receipt verification permits retry.
_destination_call(_AUTHORITY_SCOPE, arguments["effect_id"], None)
_destination_call(_AUTHORITY_SCOPE, arguments["effect_id"], None)
evidence = _destination_proof(_AUTHORITY_SCOPE, arguments["effect_id"])
claim = host.claim(
_ROOT,
arguments["effect_id"],
context["principal"],
context["scope_authority_epoch"],
expires_at=str(int(context["trusted_host_now"]) + 1),
trusted_now=context["trusted_host_now"],
deduplication_evidence=evidence,
deduplication_evidence=retry_evidence,
)
new_claims.append(
{
Expand Down Expand Up @@ -704,6 +746,7 @@ def before_commit(candidate: dict[str, Any], proposed_journal: dict[str, Any]) -
scope=context["scope_identity"],
epoch=context["scope_authority_epoch"],
trusted_now=context["trusted_host_now"],
deduplication_evidence=retry_evidence,
)
caller_kind = "response"
if fault == "after_outcome_before_admission":
Expand Down Expand Up @@ -800,6 +843,18 @@ def before_commit(candidate: dict[str, Any], proposed_journal: dict[str, Any]) -
"claim_guard_observed": operation in {"claim", "dispatch", "submit_result"},
"native_transaction_id": str(uuid.uuid4()),
"destination_call_evidence": destination_call_evidence,
"retry_safety_evidence": (
copy.deepcopy(after["destination_evidence"][arguments["effect_id"]][-1]["evidence"])
if retry_decision
and (
operation == "claim"
and new_claims
or operation == "submit_result"
and response is not None
and response.get("status") == "report_recorded"
)
else None
),
},
}

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 = "c6949440f5b9fd6e06ea5571f4e01681dd59ee04"
CONFORMANCE_COMMIT = "090aa297389e416121c25ef29fb0a75671d83233"
SPEC_COMMIT = "77c0a2e60cd0771a6d44ae170a079ddd51d7d9f0"

ROOT = Path(__file__).resolve().parent.parent
Expand Down
96 changes: 96 additions & 0 deletions reviews/native-effect-creation-v030.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Native effect creation: bounded acceptance plan

Status: first independent review requires shared creation/journal tests before
implementation. Python implementation has not started.

This owner-local optional-host slice adds atomic creation to
`SQLiteCommittedEffectHost`. It does not change the portable core, add event
admission, implement a public transport endpoint, or start example integration.
Version 0.3.0 remains unreleased; schemas stay version 1 and machines `format: 1`.

## Fixed inputs and prior evidence

- Specification: `77c0a2e60cd0771a6d44ae170a079ddd51d7d9f0`, SPEC
§§17.3, 18 and 19.1–19.2, 19.5.
- Conformance: `090aa297389e416121c25ef29fb0a75671d83233`, reviewed draft
#114. The committed-native-effects generator exercises an existing admitted
event producing an intent; its 62 vectors do not prove native creation.
- Python baseline: `39def1ac8268de55237f90e5cb8d7110fe27fc78`. The
reviewed ownership boundary prevents ordinary adapters from bypassing native
ownership. `seed` restores existing artifacts; it is not atomic core creation.
- Rust baseline: `cc24d28d4f88790e1bdc046dad01867110dfc2be`.
`tests/native_handler.rs` already exercises actual creation, fresh trusted
source selection, retained replay, changed identity, and SIGKILL fate. Credit
that reviewed evidence; do not rewrite the existing implementation merely to
match Python's internal layout.

## Contract and executable coverage

| Obligation | Existing contract/tests | Required Python evidence |
|---|---|---|
| Actual core initialization produces revision 0, creation receipt and every initial external intent | §17.3; portable checkpoint creation cases | Real format-1 initialization with multiple effects; no hand-assembled candidate checkpoint |
| Checkpoint, all pinned effect records, exact original request/first response and native authority role evidence commit together | §§18, 19.1–19.2 | One SQLite transaction; reopened exact bytes and matching root/history inventory |
| Equal creation replay survives later checkpoint changes and unavailable executable source without a core/provider call | §§17.3, 19.2 | Retain original response; check request equality before resolver activation, route lookup or CAS; current authority authorization still applies |
| Changed creation ID, definition or typed bindings cannot reuse an existing root | §17.3 | Exact conflict, unchanged checkpoint/journal/authority bytes and zero core/provider calls |
| Trusted configured executable source and exact pinned route are checked before core and again at commit | §19.2; existing route-change vectors | Refuse untrusted/mismatched source, invalid mapping or changed route generation; post-staging source/route loss rolls back all native rows |
| Every initial intent has its own exact effect ID/digest, token, handler/destination/mapping and runtime incarnation | §§19.1–19.2 | Compare actual initial emissions to all journal records; support empty initial outbox; reject unsupported token/target combinations before commit |
| No hidden bypass through a competing helper-only or ordinary checkpoint row | §§18, 19.2; completed ownership tests | Concurrent root creation serializes; pre-existing ownership is rejected or replayed through retained native evidence, never overwritten |
| Process death preserves one atomic fate | §19.5 | Real child SIGKILL after SQL staging before commit, and after commit before response; reopen, compare bytes, retry exactly once without dispatch |

The existing shared artifacts specify portable creation and journal semantics
separately; they do not execute their coupling at initialization. Add a shared
executable native-creation case before Python implementation: input is the actual
trusted definition, machine/root/creation identities, typed bindings and configured
route; observed output contains the exact actual creation checkpoint, receipt,
all initial external intents and journal pins, and retained first response. The
runner forwards inputs only. Independent semantic/hash checks must validate the
coupling, rather than accepting a copied expected result.

The additional acceptance cases must distinguish committed faulted initialization
at revision 0 from rejection before any aggregate exists. A rejection reserves no
root and permits a later valid creation. Preserve creation receipt sequence 0,
initialization lifecycle receipts in defined order, and internal mailbox emissions,
in addition to all initial external effects. Creation identity uses §17.3 normalized
typed-binding digest semantics, including numeric types and defaults, rather than
ad hoc raw request equality. Equal replay and conflict also apply after tombstoning.

Machine-visible operation tokens must originate in declared bindings/variables and
emitted data. A host-only token may instead use the §19.1 derivation, without
claiming that the machine already knows it. Do not interchange a separate optional
owner-local operation identity with the creation identity or imply §25 transport
semantics. The exact owner-local response contract must be fixed by these cases.

Fresh creation requires active authorized native authority and permanent allocation
evidence. It must not activate seed/imported artifacts, repair history gaps, or
overwrite pre-existing checkpoint/helper ownership. Recheck source and authorization
at the actual commit boundary. Creation makes zero SDK handler calls; independently
count zero core/provider calls on replay and conflict.

Language-native transaction, source-race and SIGKILL tests remain additional
required implementation evidence. The existing approved prose suffices; no new
portable behavior, grammar or schema version is proposed.

## Ordered checkpoints and reviews

1. Independently review this contract/test mapping before source changes.
2. Add and independently review the shared executable creation/journal cases,
deterministic generator, semantic validator and input-only runner. Push this
conformance checkpoint before Python source changes. Then add meaningful
failing tests against the unchanged Python baseline, using the
actual configured authority and handler fixtures. Record RED separately from
setup failures. Commit and ordinary-push the explicitly unfinished checkpoint;
verify the remote SHA.
3. Implement creation only. Freeze each meaningful checkpoint for focused checks
and independent review; commit and ordinary-push corrections. Keep PR #111 draft.
4. At the final clean Python SHA run static checks, full unit/conformance tests,
actual configured 62-vector effects/authority gate, actual PostgreSQL checks,
and independent review. Parent gates are not current-head evidence.
5. Review Rust parity against that acceptance set. Reuse exact-head existing
evidence where unchanged; run focused additional tests for any new case, and
review/gate any correction separately. No parallel Cargo runs.
6. Mark creation complete in the cross-repository audit only after these proofs.
Choose event admission as its own next slice. Examples and publication remain
blocked on their wider dependencies.

No force pushes, main writes, tags, package publication, release dispatch or
deployment are part of these checkpoints.
1 change: 1 addition & 0 deletions scripts/sync_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"runtime-action-output-v1.schema.json",
"runtime-provider-descriptor-v1.schema.json",
"timer-helper-operation-v1.schema.json",
"timer-record-v1.schema.json",
)
SPEC_COMMIT = "77c0a2e60cd0771a6d44ae170a079ddd51d7d9f0"

Expand Down
Loading