From d0005e54c31960e9982a70bca63ff8f4a566f653 Mon Sep 17 00:00:00 2001 From: Carl Niklas Rydberg Date: Mon, 22 Dec 2025 11:50:00 +0100 Subject: [PATCH] Fix TGK store conflict error mapping and add regression test --- AUDITS.md | 13 ++- src/adapters/tgk_store_mem/tgk_store_mem.c | 2 +- tests/tgk/test_tgk_store_mem.c | 118 +++++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) diff --git a/AUDITS.md b/AUDITS.md index e081e99..ab01bcb 100644 --- a/AUDITS.md +++ b/AUDITS.md @@ -40,7 +40,7 @@ Status legend: ✅ completed, ⬜ pending. 12. ✅ `tier1/enc-pel-trace-dag-1.md` 13. ✅ `tier1/tgk-1-core.md` 14. ✅ `tier1/enc-tgk1-edge-1.md` -15. ⬜ `tier1/tgk-store-1.md` +15. ✅ `tier1/tgk-store-1.md` 16. ⬜ `tier1/tgk-prov-1.md` 17. ⬜ `tier1/opreg-pel1-kernel.md` 18. ⬜ `tier1/opreg-pel1-kernel-params-1.md` @@ -214,3 +214,14 @@ Status legend: ✅ completed, ⬜ pending. edge references. - Tests: command not provided — pass (user reported “100% tests passed, 0 tests failed out of 14”). + +## 2025-12-22 — TGK/STORE/1 (`tier1/tgk-store-1.md`) +- Scope: graph store configuration, edge resolution error mapping, adjacency + ordering, scan/pagination, and neighbor semantics for TGK store adapters. +- Findings: `resolve_edge` maps conflicting artifacts (same `EdgeRef` with + different bytes) to `GS_ERR_INTEGRITY`, but the spec requires artifact-layer + integrity conflicts from `resolve_artifact` to surface as + `GS_ERR_ARTIFACT_ERROR`. +- Resolution: mapped conflicting artifacts during `resolve_edge` to + `GS_ERR_ARTIFACT_ERROR` to match artifact-level integrity error handling. +- Tests: user reported “100% tests passed, 0 tests failed out of 14”. diff --git a/src/adapters/tgk_store_mem/tgk_store_mem.c b/src/adapters/tgk_store_mem/tgk_store_mem.c index dd2ebbe..5150e8c 100644 --- a/src/adapters/tgk_store_mem/tgk_store_mem.c +++ b/src/adapters/tgk_store_mem/tgk_store_mem.c @@ -977,7 +977,7 @@ static amduat_tgk_graph_error_t amduat_tgk_store_mem_resolve_edge( } entry = amduat_tgk_store_mem_lookup_artifact(mem, ref, &conflict); if (conflict) { - return GS_ERR_INTEGRITY; + return GS_ERR_ARTIFACT_ERROR; } if (entry == NULL) { return GS_ERR_ARTIFACT_ERROR; diff --git a/tests/tgk/test_tgk_store_mem.c b/tests/tgk/test_tgk_store_mem.c index cf97c19..9ef8082 100644 --- a/tests/tgk/test_tgk_store_mem.c +++ b/tests/tgk/test_tgk_store_mem.c @@ -640,6 +640,123 @@ static int test_duplicate_edge_ref_conflict(void) { return 0; } +static int test_resolve_edge_conflict_maps_artifact_error(void) { + amduat_tgk_store_mem_t mem; + amduat_tgk_store_t store; + amduat_tgk_store_config_t config; + amduat_tgk_identity_domain_t domains[1]; + uint32_t edge_tags[1]; + amduat_tgk_edge_type_id_t edge_types[1]; + amduat_asl_encoding_profile_id_t encodings[1]; + amduat_tgk_store_mem_artifact_t artifacts[2]; + amduat_tgk_edge_body_t edge_a; + amduat_tgk_edge_body_t edge_b; + amduat_reference_t from_refs[1]; + amduat_reference_t to_refs[1]; + amduat_reference_t ref_edge; + amduat_reference_t node_a; + amduat_reference_t node_b; + amduat_reference_t payload_a; + amduat_reference_t payload_b; + amduat_octets_t bytes_a; + amduat_octets_t bytes_b; + amduat_tgk_graph_error_t err; + uint8_t digest_edge[32]; + uint8_t digest_a[32]; + uint8_t digest_b[32]; + uint8_t digest_payload_a[32]; + uint8_t digest_payload_b[32]; + int exit_code = 1; + + memset(&mem, 0, sizeof(mem)); + memset(&store, 0, sizeof(store)); + memset(&config, 0, sizeof(config)); + memset(&edge_a, 0, sizeof(edge_a)); + memset(&edge_b, 0, sizeof(edge_b)); + bytes_a = amduat_octets(NULL, 0); + bytes_b = amduat_octets(NULL, 0); + + domains[0].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1; + domains[0].hash_id = AMDUAT_HASH_ASL1_ID_SHA256; + edge_tags[0] = TYPE_TAG_TGK1_EDGE_V1; + edge_types[0] = 0x10; + encodings[0] = TGK1_EDGE_ENC_V1; + + config.id_space.domains = domains; + config.id_space.domains_len = 1; + config.tgk_profiles.edge_tags = edge_tags; + config.tgk_profiles.edge_tags_len = 1; + config.tgk_profiles.edge_types = edge_types; + config.tgk_profiles.edge_types_len = 1; + config.tgk_profiles.encodings = encodings; + config.tgk_profiles.encodings_len = 1; + + if (!amduat_tgk_store_mem_init(&mem, config, NULL, 0)) { + fprintf(stderr, "conflict resolve init failed\n"); + return 1; + } + + ref_edge = make_ref(0x72, digest_edge); + node_a = make_ref(0xa1, digest_a); + node_b = make_ref(0xb1, digest_b); + payload_a = make_ref(0xe1, digest_payload_a); + payload_b = make_ref(0xe2, digest_payload_b); + + edge_a.type = 0x10; + from_refs[0] = node_a; + edge_a.from = from_refs; + edge_a.from_len = 1; + to_refs[0] = node_b; + edge_a.to = to_refs; + edge_a.to_len = 1; + edge_a.payload = payload_a; + + edge_b.type = 0x10; + edge_b.from = from_refs; + edge_b.from_len = 1; + edge_b.to = to_refs; + edge_b.to_len = 1; + edge_b.payload = payload_b; + + if (!amduat_enc_tgk1_edge_encode_v1(&edge_a, &bytes_a) || + !amduat_enc_tgk1_edge_encode_v1(&edge_b, &bytes_b)) { + fprintf(stderr, "conflict resolve encode failed\n"); + goto cleanup_mem; + } + + artifacts[0].ref = ref_edge; + artifacts[0].artifact = + amduat_artifact_with_type(bytes_a, + amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)); + artifacts[1].ref = ref_edge; + artifacts[1].artifact = + amduat_artifact_with_type(bytes_b, + amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)); + + mem.artifacts = artifacts; + mem.artifacts_len = 2; + mem.artifacts_cap = 2; + + amduat_tgk_store_init(&store, config, amduat_tgk_store_mem_ops(), &mem); + + err = amduat_tgk_store_resolve_edge(&store, ref_edge, &edge_a); + if (err != GS_ERR_ARTIFACT_ERROR) { + fprintf(stderr, "resolve_edge conflict error mismatch: %d\n", err); + goto cleanup_mem; + } + + exit_code = 0; + +cleanup_mem: + mem.artifacts = NULL; + mem.artifacts_len = 0; + mem.artifacts_cap = 0; + amduat_tgk_store_mem_free(&mem); + free((void *)bytes_a.data); + free((void *)bytes_b.data); + return exit_code; +} + static int ref_cmp(const void *a, const void *b) { const amduat_reference_t *ref_a = (const amduat_reference_t *)a; const amduat_reference_t *ref_b = (const amduat_reference_t *)b; @@ -1437,6 +1554,7 @@ int main(void) { test_init_rejects_invalid_profile_config() != 0 || test_duplicate_edge_ref_same_artifact() != 0 || test_duplicate_edge_ref_conflict() != 0 || + test_resolve_edge_conflict_maps_artifact_error() != 0 || test_scan_edges_pagination() != 0 || test_ingest_remove_epoch() != 0 || test_ingest_batch_epoch() != 0 ||