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
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)
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. */
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,
size_t count,
uint32_t domain_id,

View file

@ -153,12 +153,12 @@ bool amduat_fed_record_validate(const amduat_fed_record_t *record) {
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) {
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) {
amduat_fed_record_t *scratch;
amduat_reference_t *tombstones;
size_t tombstones_len;
@ -278,6 +278,20 @@ bool amduat_fed_replay_domain(const amduat_fed_record_t *records,
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) {
size_t i;

View file

@ -241,12 +241,12 @@ amduat_fed_view_error_t amduat_fed_view_build(
domain_count++;
}
ok = amduat_fed_replay_domain(domain_records,
domain_count,
bound.domain_id,
bound.snapshot_id,
bound.log_prefix,
&domain_view);
ok = amduat_fed_replay_build(domain_records,
domain_count,
bound.domain_id,
bound.snapshot_id,
bound.log_prefix,
&domain_view);
for (j = 0; j < domain_count; ++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,
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");
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[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");
return 1;
}
@ -85,7 +85,7 @@ static int test_tombstone_scope(void) {
}
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");
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[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");
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,
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");
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");
amduat_fed_replay_view_free(&view_a);
return 1;