Document ownership and add replay build alias

This commit is contained in:
Carl Niklas Rydberg 2026-01-18 12:07:43 +01:00
parent d8a6603ddc
commit 282d1eb959
5 changed files with 62 additions and 18 deletions

View file

@ -264,6 +264,28 @@ Core resolve returns only artifact references. The middle layer is responsible
for fetching remote bytes by reference over its transport and caching them for fetching remote bytes by reference over its transport and caching them
separately from the authoritative local store. separately from the authoritative local store.
## Ownership and lifecycle
- `amduat_fed_registry_decode` allocates policy hash buffers; free with
`amduat_fed_registry_value_free`.
- `amduat_fed_registry_encode` returns allocated bytes; free with
`amduat_octets_free`.
- `amduat_fed_view_build` allocates view records and denies; free with
`amduat_fed_view_free`.
- `amduat_fed_replay_domain` allocates replay records; free with
`amduat_fed_replay_view_free`.
## Middle-layer fetch example (informative)
```c
err = amduat_fed_resolve(view, local_store, ref, &artifact);
if (err == AMDUAT_FED_RESOLVE_FOUND_REMOTE_NO_BYTES) {
if (fetch_remote_bytes(ref, &artifact) && cache_store_put(artifact)) {
err = amduat_fed_resolve(view, local_store, ref, &artifact);
}
}
```
## Tests (minimal) ## Tests (minimal)
1) Replay ordering determinism across two domains with interleaved logseq. 1) Replay ordering determinism across two domains with interleaved logseq.

View file

@ -47,6 +47,14 @@ typedef struct {
/* Caller frees record ids with amduat_fed_replay_view_free. */ /* Caller frees record ids with amduat_fed_replay_view_free. */
bool amduat_fed_record_validate(const amduat_fed_record_t *record); bool amduat_fed_record_validate(const amduat_fed_record_t *record);
bool amduat_fed_replay_build(const amduat_fed_record_t *records,
size_t count,
uint32_t domain_id,
uint64_t snapshot_id,
uint64_t log_prefix,
amduat_fed_replay_view_t *out_view);
/* Backwards-compatible alias for amduat_fed_replay_build. */
bool amduat_fed_replay_domain(const amduat_fed_record_t *records, bool amduat_fed_replay_domain(const amduat_fed_record_t *records,
size_t count, size_t count,
uint32_t domain_id, uint32_t domain_id,

View file

@ -153,12 +153,12 @@ bool amduat_fed_record_validate(const amduat_fed_record_t *record) {
return true; return true;
} }
bool amduat_fed_replay_domain(const amduat_fed_record_t *records, bool amduat_fed_replay_build(const amduat_fed_record_t *records,
size_t count, size_t count,
uint32_t domain_id, uint32_t domain_id,
uint64_t snapshot_id, uint64_t snapshot_id,
uint64_t log_prefix, uint64_t log_prefix,
amduat_fed_replay_view_t *out_view) { amduat_fed_replay_view_t *out_view) {
amduat_fed_record_t *scratch; amduat_fed_record_t *scratch;
amduat_reference_t *tombstones; amduat_reference_t *tombstones;
size_t tombstones_len; size_t tombstones_len;
@ -278,6 +278,20 @@ bool amduat_fed_replay_domain(const amduat_fed_record_t *records,
return true; return true;
} }
bool amduat_fed_replay_domain(const amduat_fed_record_t *records,
size_t count,
uint32_t domain_id,
uint64_t snapshot_id,
uint64_t log_prefix,
amduat_fed_replay_view_t *out_view) {
return amduat_fed_replay_build(records,
count,
domain_id,
snapshot_id,
log_prefix,
out_view);
}
void amduat_fed_replay_view_free(amduat_fed_replay_view_t *view) { void amduat_fed_replay_view_free(amduat_fed_replay_view_t *view) {
size_t i; size_t i;

View file

@ -241,12 +241,12 @@ amduat_fed_view_error_t amduat_fed_view_build(
domain_count++; domain_count++;
} }
ok = amduat_fed_replay_domain(domain_records, ok = amduat_fed_replay_build(domain_records,
domain_count, domain_count,
bound.domain_id, bound.domain_id,
bound.snapshot_id, bound.snapshot_id,
bound.log_prefix, bound.log_prefix,
&domain_view); &domain_view);
for (j = 0; j < domain_count; ++j) { for (j = 0; j < domain_count; ++j) {
amduat_fed_record_free(&domain_records[j]); amduat_fed_record_free(&domain_records[j]);
} }

View file

@ -43,7 +43,7 @@ static int test_ordering(void) {
records[2] = make_record(1, 4, 1, 10, AMDUAT_FED_REC_ARTIFACT, records[2] = make_record(1, 4, 1, 10, AMDUAT_FED_REC_ARTIFACT,
make_ref(1, d2, sizeof(d2))); make_ref(1, d2, sizeof(d2)));
if (!amduat_fed_replay_domain(records, 3, 1, 1, 10, &view)) { if (!amduat_fed_replay_build(records, 3, 1, 1, 10, &view)) {
fprintf(stderr, "replay failed\n"); fprintf(stderr, "replay failed\n");
return 1; return 1;
} }
@ -74,7 +74,7 @@ static int test_tombstone_scope(void) {
records[1] = make_record(1, 2, 1, 10, AMDUAT_FED_REC_TOMBSTONE, ref); records[1] = make_record(1, 2, 1, 10, AMDUAT_FED_REC_TOMBSTONE, ref);
records[2] = make_record(2, 1, 1, 10, AMDUAT_FED_REC_ARTIFACT, ref); records[2] = make_record(2, 1, 1, 10, AMDUAT_FED_REC_ARTIFACT, ref);
if (!amduat_fed_replay_domain(records, 3, 1, 1, 10, &view)) { if (!amduat_fed_replay_build(records, 3, 1, 1, 10, &view)) {
fprintf(stderr, "replay domain 1 failed\n"); fprintf(stderr, "replay domain 1 failed\n");
return 1; return 1;
} }
@ -85,7 +85,7 @@ static int test_tombstone_scope(void) {
} }
amduat_fed_replay_view_free(&view); amduat_fed_replay_view_free(&view);
if (!amduat_fed_replay_domain(records, 3, 2, 1, 10, &view)) { if (!amduat_fed_replay_build(records, 3, 2, 1, 10, &view)) {
fprintf(stderr, "replay domain 2 failed\n"); fprintf(stderr, "replay domain 2 failed\n");
return 1; return 1;
} }
@ -107,7 +107,7 @@ static int test_bounds(void) {
records[0] = make_record(3, 1, 2, 10, AMDUAT_FED_REC_ARTIFACT, ref); records[0] = make_record(3, 1, 2, 10, AMDUAT_FED_REC_ARTIFACT, ref);
records[1] = make_record(3, 5, 1, 4, AMDUAT_FED_REC_ARTIFACT, ref); records[1] = make_record(3, 5, 1, 4, AMDUAT_FED_REC_ARTIFACT, ref);
if (!amduat_fed_replay_domain(records, 2, 3, 1, 4, &view)) { if (!amduat_fed_replay_build(records, 2, 3, 1, 4, &view)) {
fprintf(stderr, "replay bounds failed\n"); fprintf(stderr, "replay bounds failed\n");
return 1; return 1;
} }
@ -137,11 +137,11 @@ static int test_multi_domain_ordering(void) {
records[3] = make_record(2, 2, 1, 10, AMDUAT_FED_REC_ARTIFACT, records[3] = make_record(2, 2, 1, 10, AMDUAT_FED_REC_ARTIFACT,
make_ref(1, d2, sizeof(d2))); make_ref(1, d2, sizeof(d2)));
if (!amduat_fed_replay_domain(records, 4, 1, 1, 10, &view_a)) { if (!amduat_fed_replay_build(records, 4, 1, 1, 10, &view_a)) {
fprintf(stderr, "replay domain 1 failed\n"); fprintf(stderr, "replay domain 1 failed\n");
return 1; return 1;
} }
if (!amduat_fed_replay_domain(records, 4, 2, 1, 10, &view_b)) { if (!amduat_fed_replay_build(records, 4, 2, 1, 10, &view_b)) {
fprintf(stderr, "replay domain 2 failed\n"); fprintf(stderr, "replay domain 2 failed\n");
amduat_fed_replay_view_free(&view_a); amduat_fed_replay_view_free(&view_a);
return 1; return 1;