audit: kernel params bound and docgraph removal
This commit is contained in:
parent
a932363ad0
commit
b3d776adb4
26
AUDITS.md
26
AUDITS.md
|
|
@ -43,7 +43,7 @@ Status legend: ✅ completed, ⬜ pending.
|
||||||
15. ✅ `tier1/tgk-store-1.md`
|
15. ✅ `tier1/tgk-store-1.md`
|
||||||
16. ✅ `tier1/tgk-prov-1.md`
|
16. ✅ `tier1/tgk-prov-1.md`
|
||||||
17. ✅ `tier1/opreg-pel1-kernel.md`
|
17. ✅ `tier1/opreg-pel1-kernel.md`
|
||||||
18. ⬜ `tier1/opreg-pel1-kernel-params-1.md`
|
18. ✅ `tier1/opreg-pel1-kernel-params-1.md`
|
||||||
19. ⬜ `tier1/opreg-tgk-docgraph-1.md`
|
19. ⬜ `tier1/opreg-tgk-docgraph-1.md`
|
||||||
20. ⬜ `tier1/amduat20-stack-overview.md`
|
20. ⬜ `tier1/amduat20-stack-overview.md`
|
||||||
|
|
||||||
|
|
@ -246,8 +246,22 @@ Status legend: ✅ completed, ⬜ pending.
|
||||||
`AMDUAT_PEL_KERNEL_STATUS_INTERNAL`/`AMDUAT_PEL_KERNEL_STATUS_OOM`, which do
|
`AMDUAT_PEL_KERNEL_STATUS_INTERNAL`/`AMDUAT_PEL_KERNEL_STATUS_OOM`, which do
|
||||||
not follow the `kernel_op_code << 16 | error_index` scheme and are not
|
not follow the `kernel_op_code << 16 | error_index` scheme and are not
|
||||||
specified as kernel runtime error codes.
|
specified as kernel runtime error codes.
|
||||||
- Resolution: not addressed (needs spec clarification or implementation changes
|
- Resolution: documented `pel.bytes.params/1` in OPREG/PEL1-KERNEL and params
|
||||||
to either remove/relocate `pel.bytes.params`, suppress diagnostics for kernel
|
profile; missing global params now yields `INVALID_INPUTS`; Exec_DAG no longer
|
||||||
runtime failures, and/or treat internal/OOM as out-of-model rather than
|
emits diagnostics for kernel op runtime failures; internal/OOM paths now
|
||||||
kernel runtime errors).
|
return out-of-model (no `ExecutionResultValue`), avoiding non-registry status
|
||||||
- Tests: not run.
|
codes.
|
||||||
|
- Tests: `ctest --test-dir /home/niklas/build/amduat` (pass, 14 tests).
|
||||||
|
|
||||||
|
## 2025-12-22 — OPREG/PEL1-KERNEL-PARAMS/1 (`tier1/opreg-pel1-kernel-params-1.md`)
|
||||||
|
- Scope: kernel params canonical encodings/decoding, size bounds, and
|
||||||
|
`INVALID_PROGRAM` mapping for param decode errors.
|
||||||
|
- Findings: `amduat_decode_const` accepts `params_bytes` longer than
|
||||||
|
`0xFFFF_FFFF` as long as `bytes.len` fits in `size_t`, but the spec requires
|
||||||
|
any kernel params payload length exceeding `u32::MAX` to be treated as a
|
||||||
|
decode error (even for non-`ENC/PEL-PROGRAM-DAG` inputs).
|
||||||
|
- Resolution: added a `params_bytes.len <= UINT32_MAX` guard in
|
||||||
|
`amduat_pel_kernel_params_decode` so all kernel param decodes enforce the
|
||||||
|
u32 bound; added a regression test that feeds an oversized `params_bytes`
|
||||||
|
length and expects `INVALID_PROGRAM`.
|
||||||
|
- Tests: user reported “100% tests passed, 0 tests failed out of 14”.
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ bool amduat_pel_kernel_params_decode(
|
||||||
if (desc == NULL || out_params == NULL) {
|
if (desc == NULL || out_params == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (params_bytes.len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
out_params->kind = desc->kind;
|
out_params->kind = desc->kind;
|
||||||
switch (desc->kind) {
|
switch (desc->kind) {
|
||||||
|
|
|
||||||
|
|
@ -823,13 +823,8 @@ static bool amduat_pel_program_dag_exec_internal(
|
||||||
amduat_prepared_reset(&prepared);
|
amduat_prepared_reset(&prepared);
|
||||||
prep_result = amduat_program_prepare(program, &prepared, &prep_error);
|
prep_result = amduat_program_prepare(program, &prepared, &prep_error);
|
||||||
if (prep_result == AMDUAT_PEL_PROGRAM_PREP_OOM) {
|
if (prep_result == AMDUAT_PEL_PROGRAM_PREP_OOM) {
|
||||||
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
|
amduat_prepared_free(&prepared);
|
||||||
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
|
return false;
|
||||||
AMDUAT_PEL_KERNEL_STATUS_OOM);
|
|
||||||
amduat_diag_setf(out_result,
|
|
||||||
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
|
|
||||||
"runtime failed: out of memory");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (prep_result != AMDUAT_PEL_PROGRAM_PREP_OK) {
|
if (prep_result != AMDUAT_PEL_PROGRAM_PREP_OK) {
|
||||||
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
|
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
|
||||||
|
|
@ -988,13 +983,7 @@ static bool amduat_pel_program_dag_exec_internal(
|
||||||
program->nodes_len, sizeof(*node_results));
|
program->nodes_len, sizeof(*node_results));
|
||||||
if (node_results == NULL) {
|
if (node_results == NULL) {
|
||||||
amduat_prepared_free(&prepared);
|
amduat_prepared_free(&prepared);
|
||||||
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
|
return false;
|
||||||
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
|
|
||||||
AMDUAT_PEL_KERNEL_STATUS_OOM);
|
|
||||||
amduat_diag_setf(out_result,
|
|
||||||
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
|
|
||||||
"runtime failed: out of memory");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < program->nodes_len; ++i) {
|
for (i = 0; i < program->nodes_len; ++i) {
|
||||||
node_results[i].status = AMDUAT_PEL_NODE_TRACE_SKIPPED;
|
node_results[i].status = AMDUAT_PEL_NODE_TRACE_SKIPPED;
|
||||||
|
|
@ -1015,13 +1004,7 @@ static bool amduat_pel_program_dag_exec_internal(
|
||||||
if (resolved_inputs == NULL) {
|
if (resolved_inputs == NULL) {
|
||||||
amduat_node_results_free(node_results, program->nodes_len);
|
amduat_node_results_free(node_results, program->nodes_len);
|
||||||
amduat_prepared_free(&prepared);
|
amduat_prepared_free(&prepared);
|
||||||
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
|
return false;
|
||||||
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
|
|
||||||
AMDUAT_PEL_KERNEL_STATUS_OOM);
|
|
||||||
amduat_diag_setf(out_result,
|
|
||||||
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
|
|
||||||
"runtime failed: out of memory");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1091,33 +1074,18 @@ static bool amduat_pel_program_dag_exec_internal(
|
||||||
&prepared.params[node_index], params,
|
&prepared.params[node_index], params,
|
||||||
&node_results[node_index].outputs,
|
&node_results[node_index].outputs,
|
||||||
&node_results[node_index].outputs_len, &status_code)) {
|
&node_results[node_index].outputs_len, &status_code)) {
|
||||||
if (status_code == AMDUAT_PEL_KERNEL_STATUS_OOM) {
|
if (status_code == AMDUAT_PEL_KERNEL_STATUS_OOM ||
|
||||||
|
status_code == AMDUAT_PEL_KERNEL_STATUS_INTERNAL ||
|
||||||
|
status_code == 0) {
|
||||||
free(resolved_inputs);
|
free(resolved_inputs);
|
||||||
resolved_inputs = NULL;
|
resolved_inputs = NULL;
|
||||||
goto oom_finish;
|
goto env_fail;
|
||||||
}
|
|
||||||
if (status_code == 2 || status_code == 3 || status_code == 0) {
|
|
||||||
status_code = 1;
|
|
||||||
}
|
}
|
||||||
node_results[node_index].status = AMDUAT_PEL_NODE_TRACE_FAILED;
|
node_results[node_index].status = AMDUAT_PEL_NODE_TRACE_FAILED;
|
||||||
node_results[node_index].status_code = status_code;
|
node_results[node_index].status_code = status_code;
|
||||||
(void)amduat_node_diag_setf(
|
|
||||||
&node_results[node_index],
|
|
||||||
AMDUAT_PEL_DAG_DIAG_NODE_RUNTIME_FAILED,
|
|
||||||
"runtime failed: node %u (%.*s@%u) status_code %u",
|
|
||||||
(unsigned int)node->id,
|
|
||||||
(int)node->op.name.len,
|
|
||||||
(const char *)node->op.name.data,
|
|
||||||
(unsigned int)node->op.version,
|
|
||||||
(unsigned int)status_code);
|
|
||||||
any_node_executed = true;
|
any_node_executed = true;
|
||||||
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
|
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
|
||||||
AMDUAT_PEL_EXEC_ERROR_RUNTIME, status_code);
|
AMDUAT_PEL_EXEC_ERROR_RUNTIME, status_code);
|
||||||
amduat_diag_setf(out_result,
|
|
||||||
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
|
|
||||||
"runtime failed: node %u status_code %u",
|
|
||||||
(unsigned int)node->id,
|
|
||||||
(unsigned int)status_code);
|
|
||||||
free(resolved_inputs);
|
free(resolved_inputs);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
@ -1132,7 +1100,7 @@ static bool amduat_pel_program_dag_exec_internal(
|
||||||
if (*out_outputs == NULL) {
|
if (*out_outputs == NULL) {
|
||||||
free(resolved_inputs);
|
free(resolved_inputs);
|
||||||
resolved_inputs = NULL;
|
resolved_inputs = NULL;
|
||||||
goto oom_finish;
|
goto env_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1166,7 +1134,7 @@ static bool amduat_pel_program_dag_exec_internal(
|
||||||
*out_outputs_len = 0;
|
*out_outputs_len = 0;
|
||||||
free(resolved_inputs);
|
free(resolved_inputs);
|
||||||
resolved_inputs = NULL;
|
resolved_inputs = NULL;
|
||||||
goto oom_finish;
|
goto env_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1195,13 +1163,7 @@ finish:
|
||||||
amduat_prepared_free(&prepared);
|
amduat_prepared_free(&prepared);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
oom_finish:
|
env_fail:
|
||||||
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
|
|
||||||
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
|
|
||||||
AMDUAT_PEL_KERNEL_STATUS_OOM);
|
|
||||||
amduat_diag_setf(out_result,
|
|
||||||
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
|
|
||||||
"runtime failed: out of memory");
|
|
||||||
if (out_outputs != NULL && *out_outputs != NULL) {
|
if (out_outputs != NULL && *out_outputs != NULL) {
|
||||||
amduat_pel_program_dag_free_outputs(*out_outputs, *out_outputs_len);
|
amduat_pel_program_dag_free_outputs(*out_outputs, *out_outputs_len);
|
||||||
*out_outputs = NULL;
|
*out_outputs = NULL;
|
||||||
|
|
@ -1223,7 +1185,7 @@ oom_finish:
|
||||||
node_results = NULL;
|
node_results = NULL;
|
||||||
}
|
}
|
||||||
amduat_prepared_free(&prepared);
|
amduat_prepared_free(&prepared);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool amduat_pel_program_dag_exec(
|
bool amduat_pel_program_dag_exec(
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "amduat/hash/asl1.h"
|
#include "amduat/hash/asl1.h"
|
||||||
#include "amduat/pel/run.h"
|
#include "amduat/pel/run.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -247,6 +248,67 @@ static int test_invalid_params(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_oversized_params_len(void) {
|
||||||
|
amduat_pel_dag_input_t node_inputs[1];
|
||||||
|
amduat_pel_node_t nodes[1];
|
||||||
|
amduat_pel_root_ref_t roots[1];
|
||||||
|
amduat_pel_program_t program;
|
||||||
|
amduat_artifact_t inputs[1];
|
||||||
|
amduat_artifact_t *outputs = NULL;
|
||||||
|
size_t outputs_len = 0;
|
||||||
|
amduat_pel_execution_result_value_t result;
|
||||||
|
const char op_concat[] = "pel.bytes.concat";
|
||||||
|
uint8_t params_byte = 0x00u;
|
||||||
|
size_t oversized_len;
|
||||||
|
|
||||||
|
if (SIZE_MAX <= UINT32_MAX) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
oversized_len = (size_t)UINT32_MAX + 1u;
|
||||||
|
memset(&result, 0, sizeof(result));
|
||||||
|
|
||||||
|
node_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
node_inputs[0].value.external.input_index = 0;
|
||||||
|
|
||||||
|
nodes[0].id = 1;
|
||||||
|
nodes[0].op.name = amduat_octets(op_concat, strlen(op_concat));
|
||||||
|
nodes[0].op.version = 1;
|
||||||
|
nodes[0].inputs = node_inputs;
|
||||||
|
nodes[0].inputs_len = 1;
|
||||||
|
nodes[0].params = amduat_octets(¶ms_byte, oversized_len);
|
||||||
|
|
||||||
|
roots[0].node_id = 1;
|
||||||
|
roots[0].output_index = 0;
|
||||||
|
|
||||||
|
program.nodes = nodes;
|
||||||
|
program.nodes_len = 1;
|
||||||
|
program.roots = roots;
|
||||||
|
program.roots_len = 1;
|
||||||
|
|
||||||
|
inputs[0] = amduat_artifact(amduat_octets("x", 1));
|
||||||
|
|
||||||
|
if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs,
|
||||||
|
&outputs_len, &result)) {
|
||||||
|
fprintf(stderr, "exec failed\n");
|
||||||
|
amduat_pel_execution_result_free(&result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.status != AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM ||
|
||||||
|
result.summary.kind != AMDUAT_PEL_EXEC_ERROR_PROGRAM ||
|
||||||
|
result.summary.status_code != 2) {
|
||||||
|
fprintf(stderr, "unexpected oversized params status\n");
|
||||||
|
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
|
||||||
|
amduat_pel_execution_result_free(&result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
|
||||||
|
amduat_pel_execution_result_free(&result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int test_invalid_input_index(void) {
|
static int test_invalid_input_index(void) {
|
||||||
amduat_pel_dag_input_t node_inputs[1];
|
amduat_pel_dag_input_t node_inputs[1];
|
||||||
amduat_pel_node_t nodes[1];
|
amduat_pel_node_t nodes[1];
|
||||||
|
|
@ -363,6 +425,9 @@ int main(void) {
|
||||||
if (test_invalid_params() != 0) {
|
if (test_invalid_params() != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (test_oversized_params_len() != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (test_invalid_input_index() != 0) {
|
if (test_invalid_input_index() != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -770,14 +770,11 @@ static int test_surf_runtime_failure_trace_diag(void) {
|
||||||
amduat_pel_surface_execution_result_t decoded;
|
amduat_pel_surface_execution_result_t decoded;
|
||||||
amduat_artifact_t trace_artifact;
|
amduat_artifact_t trace_artifact;
|
||||||
amduat_pel_trace_dag_value_t trace;
|
amduat_pel_trace_dag_value_t trace;
|
||||||
char expected_msg[128];
|
|
||||||
int expected_len;
|
|
||||||
int exit_code = 1;
|
int exit_code = 1;
|
||||||
uint8_t payload_a[] = {'a'};
|
uint8_t payload_a[] = {'a'};
|
||||||
uint8_t payload_b[] = {'b'};
|
uint8_t payload_b[] = {'b'};
|
||||||
amduat_artifact_t input_a;
|
amduat_artifact_t input_a;
|
||||||
amduat_artifact_t input_b;
|
amduat_artifact_t input_b;
|
||||||
const uint32_t diag_code = 0x00030002u;
|
|
||||||
|
|
||||||
cfg.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
cfg.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
||||||
cfg.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
cfg.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
||||||
|
|
@ -861,20 +858,11 @@ static int test_surf_runtime_failure_trace_diag(void) {
|
||||||
}
|
}
|
||||||
artifact_free(&trace_artifact);
|
artifact_free(&trace_artifact);
|
||||||
|
|
||||||
expected_len = snprintf(expected_msg, sizeof(expected_msg),
|
if (trace.node_traces_len != 1 ||
|
||||||
"runtime failed: node 1 (pel.bytes.concat@1) "
|
|
||||||
"status_code %u",
|
|
||||||
(unsigned int)
|
|
||||||
AMDUAT_PEL_KERNEL_STATUS_CONCAT_TYPE_TAG_MISMATCH);
|
|
||||||
if (expected_len < 0 ||
|
|
||||||
trace.node_traces_len != 1 ||
|
|
||||||
trace.node_traces[0].status != AMDUAT_PEL_NODE_TRACE_FAILED ||
|
trace.node_traces[0].status != AMDUAT_PEL_NODE_TRACE_FAILED ||
|
||||||
trace.node_traces[0].diagnostics_len < 1 ||
|
trace.node_traces[0].status_code !=
|
||||||
trace.node_traces[0].diagnostics[0].code != diag_code ||
|
AMDUAT_PEL_KERNEL_STATUS_CONCAT_TYPE_TAG_MISMATCH ||
|
||||||
trace.node_traces[0].diagnostics[0].message.len !=
|
trace.node_traces[0].diagnostics_len != 0) {
|
||||||
(size_t)expected_len ||
|
|
||||||
memcmp(trace.node_traces[0].diagnostics[0].message.data,
|
|
||||||
expected_msg, (size_t)expected_len) != 0) {
|
|
||||||
fprintf(stderr, "trace runtime diagnostics mismatch\n");
|
fprintf(stderr, "trace runtime diagnostics mismatch\n");
|
||||||
amduat_enc_pel_trace_dag_free(&trace);
|
amduat_enc_pel_trace_dag_free(&trace);
|
||||||
goto cleanup_decoded;
|
goto cleanup_decoded;
|
||||||
|
|
|
||||||
|
|
@ -1,240 +0,0 @@
|
||||||
# OPREG/TGK-DOCGRAPH/1 — Document Graph Registry
|
|
||||||
|
|
||||||
Status: Draft
|
|
||||||
Owner: Architecture
|
|
||||||
Version: 0.1.0
|
|
||||||
SoT: Plan
|
|
||||||
Last Updated: 2025-12-01
|
|
||||||
Linked Phase Pack: PH12
|
|
||||||
Tags: [registry, tgk, docgraph]
|
|
||||||
|
|
||||||
<!-- Source: /amduat/logs/ph12/evidence/import/PH12-EV-IMPORT-001/opreg-tgk-docgraph-design-20251201.md | Canonical: /amduat/tier1/opreg-tgk-docgraph-1.md -->
|
|
||||||
|
|
||||||
**Document ID:** `OPREG/TGK-DOCGRAPH/1`
|
|
||||||
**Layer:** L1 Profile (TGK Doc Graph Registry over `TGK/1-CORE` + `ENC/TGK1-EDGE/1`)
|
|
||||||
|
|
||||||
**Depends on (normative):**
|
|
||||||
|
|
||||||
* `ASL/1-CORE v0.4.x` — `Artifact`, `Reference`, `TypeTag`, `HashId`
|
|
||||||
* `ENC/ASL1-CORE v1.x` — canonical encodings for Artifacts and References
|
|
||||||
* `HASH/ASL1 v0.2.x` — ASL1 hash family (`HASH-ASL1-256`)
|
|
||||||
* `TGK/1-CORE v0.7.x` — trace graph kernel: `Node`, `EdgeBody`, `EdgeTypeId`
|
|
||||||
* `ENC/TGK1-EDGE/1 v0.1.x` — canonical encoding for `EdgeBody` / EdgeArtifacts
|
|
||||||
* `AMDUAT-DOCID` (Tier-0) — document identity and SoT/surface model
|
|
||||||
|
|
||||||
**Integrates with (informative):**
|
|
||||||
|
|
||||||
* `TGK/STORE/1` — graph store/query profile over ASL/1-STORE + TGK
|
|
||||||
* ADR-032 and PH10/PH12 import designs (RΩ / export)
|
|
||||||
* Future doc graph consumers (assistant overlays, IDX, provenance views)
|
|
||||||
|
|
||||||
© 2025 Amduat Programme.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Except where otherwise noted, this document (text and diagrams) is licensed under
|
|
||||||
the Creative Commons Attribution 4.0 International License (CC BY 4.0).
|
|
||||||
|
|
||||||
The identifier registries and mapping tables (e.g. TypeTag IDs, HashId
|
|
||||||
assignments, EdgeTypeId tables) are additionally made available under CC0 1.0
|
|
||||||
Universal (CC0) to enable unrestricted reuse in implementations and derivative
|
|
||||||
specifications.
|
|
||||||
|
|
||||||
Code examples in this document are provided under the Apache License 2.0 unless
|
|
||||||
explicitly stated otherwise. Test vectors, where present, are dedicated to the
|
|
||||||
public domain under CC0 1.0.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 0. Purpose and Non-Goals
|
|
||||||
|
|
||||||
### 0.1 Purpose
|
|
||||||
|
|
||||||
`OPREG/TGK-DOCGRAPH/1` defines a **doc/import/navigation graph registry** for Amduat:
|
|
||||||
|
|
||||||
* It names **node concepts** (as ASL/1 Artifacts) for:
|
|
||||||
* conceptual documents (DOCID lineages),
|
|
||||||
* document versions at a given snapshot (e.g. RΩ),
|
|
||||||
* Git commits and blobs,
|
|
||||||
* Amduat SoT instances.
|
|
||||||
* It names **edge types** (`EdgeTypeId`s) that connect those concepts:
|
|
||||||
* document ↔ version, surface, SoT state,
|
|
||||||
* version ↔ Git blob/commit,
|
|
||||||
* document ↔ Amduat instance.
|
|
||||||
* It constrains how those edges are represented as EdgeArtifacts under
|
|
||||||
`ENC/TGK1-EDGE/1` and consumed via `TGK/STORE/1`.
|
|
||||||
|
|
||||||
This registry is intentionally **doc/import scoped**. Execution, fact, and
|
|
||||||
certificate edges live in their own TGK/OPREG registries and MUST NOT reuse
|
|
||||||
`EdgeTypeId` assignments from this doc graph registry.
|
|
||||||
|
|
||||||
This Tier-1 stub is the **canonical registry companion** to the PH12 design
|
|
||||||
note `PH12-EV-IMPORT-001 — Doc Graph OPREG Profile Design
|
|
||||||
(/logs/ph12/evidence/import/PH12-EV-IMPORT-001/opreg-tgk-docgraph-design-20251201.md)`,
|
|
||||||
which records design intent and sandbox experience; this document is the SoT
|
|
||||||
for the node and edge vocabulary.
|
|
||||||
|
|
||||||
### 0.2 Non-goals
|
|
||||||
|
|
||||||
This registry does **not** define:
|
|
||||||
|
|
||||||
* any storage API (`ASL/1-STORE`, `TGK/STORE/1` already cover that),
|
|
||||||
* any provenance algorithms or queries (`TGK/PROV/1` and higher layers),
|
|
||||||
* any assistant or overlay behavior (those consume this registry),
|
|
||||||
* concrete import/export profiles (ADR-032 handles those).
|
|
||||||
|
|
||||||
It only defines **concepts and edge types**; encoding and storage use existing
|
|
||||||
Tier-1 profiles.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Node Concepts (Informative overview)
|
|
||||||
|
|
||||||
This section summarizes node concepts; canonical encodings and type_tags are
|
|
||||||
defined in companion encoding profiles (TBD).
|
|
||||||
|
|
||||||
### 1.1 DOC_CONCEPT
|
|
||||||
|
|
||||||
Conceptual governed document identity per `AMDUAT-DOCID`:
|
|
||||||
|
|
||||||
* `identity_authority` (string),
|
|
||||||
* `lineage_id` (string),
|
|
||||||
* optional `doc_code` (string),
|
|
||||||
* optional `code_status` (e.g. `tentative`, `stable`).
|
|
||||||
|
|
||||||
There is exactly one `DOC_CONCEPT` node per `(identity_authority, lineage_id)`.
|
|
||||||
|
|
||||||
### 1.2 DOC_VERSION
|
|
||||||
|
|
||||||
Versioned SoT slice of a governed document at a snapshot commit:
|
|
||||||
|
|
||||||
* `identity_authority`, `lineage_id`, `doc_code`, `code_status`,
|
|
||||||
* `g_commit` (Git commit id),
|
|
||||||
* `sha256` (content hash of the doc bytes at `g_commit`),
|
|
||||||
* `path` (repository path at `g_commit`, e.g. `/amduat/tier0/docid.md`),
|
|
||||||
* `surface`, `sot` (SoT state) per DOCID header.
|
|
||||||
|
|
||||||
Multiple `DOC_VERSION` nodes may exist for a `DOC_CONCEPT` across commits.
|
|
||||||
|
|
||||||
### 1.3 GIT_COMMIT
|
|
||||||
|
|
||||||
Git commit metadata:
|
|
||||||
|
|
||||||
* `commit` (sha1),
|
|
||||||
* `parents` (list of parent commit ids),
|
|
||||||
* `tree` (tree id),
|
|
||||||
* `author_name`, `author_email`, `authored_at`,
|
|
||||||
* `committer_name`, `committer_email`, `committed_at`,
|
|
||||||
* summary or truncated message.
|
|
||||||
|
|
||||||
### 1.4 GIT_BLOB
|
|
||||||
|
|
||||||
Content snapshot for a single blob at `g_commit`:
|
|
||||||
|
|
||||||
* `blob_sha` (sha1),
|
|
||||||
* `sha256` (content hash),
|
|
||||||
* `size_bytes`,
|
|
||||||
* `mode` (tree mode, including exec/symlink bits),
|
|
||||||
* `path` at `g_commit`.
|
|
||||||
|
|
||||||
### 1.5 AMDUAT_INSTANCE
|
|
||||||
|
|
||||||
Descriptor for an Amduat SoT instance:
|
|
||||||
|
|
||||||
* `g_commit` (RΩ commit),
|
|
||||||
* `store_root` (SoT store root),
|
|
||||||
* `store_backend_id`,
|
|
||||||
* references to RΩ FER/1 receipts and manifests,
|
|
||||||
* optional labels (environment, hostname, etc.).
|
|
||||||
|
|
||||||
### 1.6 Helper nodes
|
|
||||||
|
|
||||||
* `SURFACE` — surface classification nodes (e.g. `tier0`, `tier1`, `phase`, `evidence`).
|
|
||||||
* `SOT_STATE` — SoT state nodes (`Yes`, `Plan`, `Ref`).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Edge Types (Doc Graph Domain)
|
|
||||||
|
|
||||||
`EdgeTypeId` values in this registry are reserved for doc/import/navigation
|
|
||||||
edges. Concrete numeric assignments live in the encoding/catalogue layer.
|
|
||||||
|
|
||||||
Implementations and other OPREG registries MUST treat these `EdgeTypeId`s as
|
|
||||||
belonging exclusively to the **Amduat doc graph domain**:
|
|
||||||
|
|
||||||
* the eventual allocation for this registry is expected to reserve a contiguous
|
|
||||||
`EdgeTypeId` band (informally: an `AMDUAT-DOCGRAPH` band),
|
|
||||||
* only doc/import/navigation semantics (edges in §§2.1–2.4) may occupy that
|
|
||||||
band,
|
|
||||||
* PEL execution, FER/1, CIL, FCT, and other TGK domains MUST use their own
|
|
||||||
registries and bands.
|
|
||||||
|
|
||||||
### 2.1 Identity & version edges
|
|
||||||
|
|
||||||
* `EDGE_DOC_HAS_VERSION`
|
|
||||||
`DOC_CONCEPT → DOC_VERSION` — this version belongs to this conceptual document.
|
|
||||||
|
|
||||||
* `EDGE_VERSION_OF`
|
|
||||||
`DOC_VERSION → DOC_CONCEPT` — reverse link; derivable from `EDGE_DOC_HAS_VERSION`.
|
|
||||||
|
|
||||||
* `EDGE_DOC_HAS_IDENTITY`
|
|
||||||
`DOC_VERSION → DOC_CONCEPT` — DOCID identity is attached to this version.
|
|
||||||
|
|
||||||
### 2.2 Surface & SoT edges
|
|
||||||
|
|
||||||
* `EDGE_DOC_ON_SURFACE`
|
|
||||||
`DOC_VERSION → SURFACE` — surface classification (governance/spec/phase/evidence).
|
|
||||||
|
|
||||||
* `EDGE_DOC_SOT`
|
|
||||||
`DOC_VERSION → SOT_STATE` — SoT status (`Yes`, `Plan`, `Ref`) for this version.
|
|
||||||
|
|
||||||
### 2.3 Git provenance edges
|
|
||||||
|
|
||||||
* `EDGE_VERSION_HAS_BLOB`
|
|
||||||
`DOC_VERSION → GIT_BLOB` — ties a document version to the blob at `g_commit`.
|
|
||||||
|
|
||||||
* `EDGE_VERSION_FROM_COMMIT`
|
|
||||||
`DOC_VERSION → GIT_COMMIT` — last commit that touched this path at/before the snapshot.
|
|
||||||
|
|
||||||
### 2.4 SoT instance edges
|
|
||||||
|
|
||||||
* `EDGE_DOC_MEMBER_OF_AMDUAT`
|
|
||||||
`DOC_CONCEPT → AMDUAT_INSTANCE` — this document is part of a particular Amduat instance.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Encoding & Store Integration (Summary)
|
|
||||||
|
|
||||||
All doc-graph edges:
|
|
||||||
|
|
||||||
* are represented as TGK `EdgeBody` values with `EdgeTypeId` from this registry,
|
|
||||||
* are encoded as EdgeArtifacts via `ENC/TGK1-EDGE/1` using `TYPE_TAG_TGK1_EDGE_V1`,
|
|
||||||
* derive `EdgeRef` identities via `HASH/ASL1` over `EdgeBytes`,
|
|
||||||
* live in ASL/1-STORE instances alongside other Artifacts.
|
|
||||||
|
|
||||||
Nodes (`DOC_CONCEPT`, `DOC_VERSION`, `GIT_COMMIT`, `GIT_BLOB`, `AMDUAT_INSTANCE`, etc.) are ordinary
|
|
||||||
ASL/1 Artifacts; their `Reference`s are the TGK nodes.
|
|
||||||
|
|
||||||
`TGK/STORE/1` provides query semantics over the resulting graph.
|
|
||||||
|
|
||||||
JSON overlays or other projected views (for example, PH12 doc graph sandboxes)
|
|
||||||
MAY be emitted for human navigation and experiments, but they are always
|
|
||||||
derived from the underlying node Artifacts and EdgeArtifacts governed by this
|
|
||||||
registry and `ENC/TGK1-EDGE/1`; overlays are never the source of truth for
|
|
||||||
doc graph semantics.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Ingest & Encoder Interaction (Informative)
|
|
||||||
|
|
||||||
Implementations are expected to:
|
|
||||||
|
|
||||||
* materialise node Artifacts per this registry (and companion encoding profiles),
|
|
||||||
* emit FER/1 receipts for ingest pipelines,
|
|
||||||
* emit an idempotent edge worklist (doc-edge queue) that references `EdgeTypeId`s
|
|
||||||
from this registry and node `Reference`s,
|
|
||||||
* use a separate encoder to turn worklist items into EdgeArtifacts using `ENC/TGK1-EDGE/1`,
|
|
||||||
writing them into ASL/1-STORE for consumption via `TGK/STORE/1`.
|
|
||||||
|
|
||||||
Details of worklist format and encoder scheduling are left to PH12/PHB01
|
|
||||||
implementation notes; this registry only fixes the conceptual node/edge space.
|
|
||||||
Loading…
Reference in a new issue