the-custodian/docs/changes/netkingdom-target-2026-10-16/approval-go-fact/implementation.patch
codex 3add9f8790
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Reject generated-only commits / generated-commit-guard (push) Successful in 25s
docs: preserve reviewed NetKingdom session artifacts
2026-11-01 22:45:01 +01:00

5744 lines
218 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/adapters/go/approvalfact/README.md b/adapters/go/approvalfact/README.md
new file mode 100644
index 0000000..fdffd1f
--- /dev/null
+++ b/adapters/go/approvalfact/README.md
@@ -0,0 +1,55 @@
+# Approval fact data adapter
+
+Provider-owned pure Go module for Access's Approval B2 source reader. No network,
+credentials, subprocess, policy evaluator, server or consume mutation exists here.
+Python `approval_engine.binding` remains the authoritative native format.
+
+API:
+
+- `CanonicalBinding(rawJSON)` returns native five-field canonical UTF-8 bytes
+ and sha256 digest; extra binding metadata is excluded.
+- `ValidateClaim(rawClaim, Expected, now)` validates one exact human/PDP-path
+ claim against independently owner-derived `Expected.NativeBindingJSON`, exact
+ approval ID and actual Access approval-free PDP digest.
+- `MatchObserved(submitted, observed)` requires two validated facts at the same
+ captured instant and identical nonfreshness authority facts. No request is
+ rewritten. `Fact.RawJSON()` returns a detached original byte copy; deadlines
+ preserve each input's own freshness and approval expiry.
+
+`Fact` means validated data, never authenticated provider origin. Access must
+fetch provider bytes through its independently admitted fixed origin/identity,
+then wrap this data in its own unforgeable source handle. A caller-supplied claim
+cannot become source truth merely by passing this helper. Access remains the
+single evaluator and must bound decision/operation/caller lifetimes separately.
+PEP consume CAS and live one-shot journal remain required before any effect.
+
+Expected native act bytes must preserve the actual owner/compiler/normalization
+representation. Marshaling float64-decoded CheckRequest maps loses 1.0/1 and
+large integers. Raw submitted resource is sufficient only when Access proves
+the active registry cannot override that target and applies its exact existing
+normalization. Otherwise authoritative raw enrichment/compiler evidence is
+needed. This helper supplies no fallback or invented restricted numeric domain.
+
+The strict parser retains integer/floating lexical types, arbitrary integer
+magnitudes, finite IEEE-754 float semantics and valid Unicode scalar values.
+Canonical float/string formatting follows Python source, including negative
+floating zero, exponent switching/padding, HTML and U+2028/U+2029. Duplicate
+object keys, nonfinite/overflow numbers, invalid UTF-8 and lone surrogates refuse.
+Inputs are bounded to 1 MiB and 128 container levels. Timestamp precision is at
+most nanoseconds with strict zoned RFC3339; current producer emits whole seconds.
+These explicit parser/resource limits fail closed, never normalize authority.
+
+`go test -race ./...` checks the portable producer vectors, typed fact pairing,
+strict JSON/Unicode and exact deadline semantics. From the owner repo root,
+`python3 scripts/check_go_approvalfact.py` runs a deterministic 14,114-case
+development-only differential corpus against the actual Python producer,
+including random finite IEEE bit patterns, exponent boundaries/subnormals and
+Unicode. It uses a test-only local oracle file; production imports no oracle or
+Python runtime. Sample conformance is evidence, not a formal proof over all JSON.
+
+The module pins Go 1.26.7 to match the existing Access consumer toolchain.
+`testdata/owner-vectors.json` is an unchanged portable copy of the Approval owner
+fixture, SHA256 `dfb0a8810cd91847d7af6a7af6a51607a67a66fad7b86fc57365308c36bd9323`.
+Transport cases requiring HTTP remain the Access adapter's tests; this module
+checks their duplicate/nonfinite bodies only. Import/deployment/native identity
+admission and positive policy gates require separate owner evidence.
diff --git a/adapters/go/approvalfact/canonical.go b/adapters/go/approvalfact/canonical.go
new file mode 100644
index 0000000..06f14b5
--- /dev/null
+++ b/adapters/go/approvalfact/canonical.go
@@ -0,0 +1,295 @@
+// Package approvalfact provides data-only Approval claim correspondence.
+// It neither authenticates a provider nor decides permission or consumes objects.
+package approvalfact
+
+import (
+ "bytes"
+ "crypto/sha256"
+ "encoding/hex"
+ "encoding/json"
+ "errors"
+ "io"
+ "math"
+ "math/big"
+ "sort"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+const MaxJSONBytes = 1 << 20
+
+var errJSON = errors.New("invalid Approval JSON")
+
+// DecodeJSON retains numeric lexical types, refuses duplicates and invalid
+// Unicode, and bounds work. A Go map previously decoded into float64 cannot
+// recover the producer's integer-versus-floating identity; pass source bytes.
+func DecodeJSON(raw []byte) (any, error) {
+ if len(raw) > MaxJSONBytes || !utf8.Valid(raw) || !validSurrogates(raw) {
+ return nil, errJSON
+ }
+ d := json.NewDecoder(bytes.NewReader(raw))
+ d.UseNumber()
+ var read func(int) (any, error)
+ read = func(depth int) (any, error) {
+ if depth > 128 {
+ return nil, errJSON
+ }
+ t, e := d.Token()
+ if e != nil {
+ return nil, errJSON
+ }
+ switch x := t.(type) {
+ case json.Delim:
+ if x == '{' {
+ m := map[string]any{}
+ for d.More() {
+ k, e := d.Token()
+ if e != nil {
+ return nil, errJSON
+ }
+ s, ok := k.(string)
+ if !ok {
+ return nil, errJSON
+ }
+ if _, ok = m[s]; ok {
+ return nil, errJSON
+ }
+ v, e := read(depth + 1)
+ if e != nil {
+ return nil, e
+ }
+ m[s] = v
+ }
+ end, e := d.Token()
+ if e != nil || end != json.Delim('}') {
+ return nil, errJSON
+ }
+ return m, nil
+ }
+ if x == '[' {
+ a := []any{}
+ for d.More() {
+ v, e := read(depth + 1)
+ if e != nil {
+ return nil, e
+ }
+ a = append(a, v)
+ }
+ end, e := d.Token()
+ if e != nil || end != json.Delim(']') {
+ return nil, errJSON
+ }
+ return a, nil
+ }
+ return nil, errJSON
+ case json.Number:
+ if _, e := pythonNumber(x); e != nil {
+ return nil, e
+ }
+ return x, nil
+ case string, bool, nil:
+ return x, nil
+ default:
+ return nil, errJSON
+ }
+ }
+ v, e := read(0)
+ if e != nil {
+ return nil, e
+ }
+ if _, e = d.Token(); e != io.EOF {
+ return nil, errJSON
+ }
+ return v, nil
+}
+
+// encoding/json replaces lone UTF-16 surrogates, whereas the Python producer
+// cannot encode them as UTF-8. Reject before the decoder can erase that fact.
+func validSurrogates(raw []byte) bool {
+ in := false
+ for i := 0; i < len(raw); i++ {
+ if raw[i] == '"' {
+ in = !in
+ continue
+ }
+ if !in || raw[i] != '\\' {
+ continue
+ }
+ i++
+ if i >= len(raw) {
+ return false
+ }
+ if raw[i] != 'u' {
+ continue
+ }
+ if i+4 >= len(raw) {
+ return false
+ }
+ n, e := strconv.ParseUint(string(raw[i+1:i+5]), 16, 16)
+ if e != nil {
+ return false
+ }
+ i += 4
+ if n >= 0xdc00 && n <= 0xdfff {
+ return false
+ }
+ if n < 0xd800 || n > 0xdbff {
+ continue
+ }
+ if i+6 >= len(raw) || raw[i+1] != '\\' || raw[i+2] != 'u' {
+ return false
+ }
+ low, e := strconv.ParseUint(string(raw[i+3:i+7]), 16, 16)
+ if e != nil || low < 0xdc00 || low > 0xdfff {
+ return false
+ }
+ i += 6
+ }
+ return !in
+}
+
+func pythonNumber(n json.Number) (string, error) {
+ s := string(n)
+ if !strings.ContainsAny(s, ".eE") {
+ i, ok := new(big.Int).SetString(s, 10)
+ if !ok {
+ return "", errJSON
+ }
+ return i.String(), nil
+ }
+ f, e := strconv.ParseFloat(s, 64)
+ if e != nil || math.IsInf(f, 0) || math.IsNaN(f) {
+ return "", errJSON
+ }
+ // Python repr uses shortest round-trip digits, fixed form for exponents
+ // -4..15, a mandatory .0 for integral floats, and two exponent digits.
+ sci := strconv.FormatFloat(f, 'e', -1, 64)
+ at := strings.IndexByte(sci, 'e')
+ exp, _ := strconv.Atoi(sci[at+1:])
+ if exp >= -4 && exp < 16 {
+ s = strconv.FormatFloat(f, 'f', -1, 64)
+ if !strings.Contains(s, ".") {
+ s += ".0"
+ }
+ return s, nil
+ }
+ sign := "+"
+ if exp < 0 {
+ sign = "-"
+ exp = -exp
+ }
+ digits := strconv.Itoa(exp)
+ if len(digits) < 2 {
+ digits = "0" + digits
+ }
+ return sci[:at] + "e" + sign + digits, nil
+}
+
+func quote(s string) string {
+ var b strings.Builder
+ b.WriteByte('"')
+ for _, r := range s {
+ switch r {
+ case '"', '\\':
+ b.WriteByte('\\')
+ b.WriteRune(r)
+ case '\b':
+ b.WriteString(`\b`)
+ case '\f':
+ b.WriteString(`\f`)
+ case '\n':
+ b.WriteString(`\n`)
+ case '\r':
+ b.WriteString(`\r`)
+ case '\t':
+ b.WriteString(`\t`)
+ default:
+ if r < 32 {
+ b.WriteString(`\u00`)
+ const h = "0123456789abcdef"
+ b.WriteByte(h[byte(r)>>4])
+ b.WriteByte(h[byte(r)&15])
+ } else {
+ b.WriteRune(r)
+ }
+ }
+ }
+ b.WriteByte('"')
+ return b.String()
+}
+
+func canonical(v any) (string, error) {
+ switch x := v.(type) {
+ case nil:
+ return "null", nil
+ case bool:
+ if x {
+ return "true", nil
+ }
+ return "false", nil
+ case string:
+ return quote(x), nil
+ case json.Number:
+ return pythonNumber(x)
+ case []any:
+ a := make([]string, len(x))
+ for i, v := range x {
+ s, e := canonical(v)
+ if e != nil {
+ return "", e
+ }
+ a[i] = s
+ }
+ return "[" + strings.Join(a, ",") + "]", nil
+ case map[string]any:
+ keys := make([]string, 0, len(x))
+ for k := range x {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+ a := make([]string, 0, len(keys))
+ for _, k := range keys {
+ s, e := canonical(x[k])
+ if e != nil {
+ return "", e
+ }
+ a = append(a, quote(k)+":"+s)
+ }
+ return "{" + strings.Join(a, ",") + "}", nil
+ default:
+ return "", errJSON
+ }
+}
+
+// CanonicalBinding reproduces approval_engine.binding.binding_digest over the
+// five native act fields. Extra binding metadata is excluded by that contract.
+func CanonicalBinding(raw []byte) ([]byte, string, error) {
+ v, e := DecodeJSON(raw)
+ if e != nil {
+ return nil, "", e
+ }
+ m, ok := v.(map[string]any)
+ if !ok {
+ return nil, "", errJSON
+ }
+ act := map[string]any{}
+ for _, k := range []string{"action", "actor", "principal", "purpose"} {
+ s, ok := m[k].(string)
+ if !ok || s == "" {
+ return nil, "", errJSON
+ }
+ act[k] = s
+ }
+ target, ok := m["target"].(map[string]any)
+ if !ok {
+ return nil, "", errJSON
+ }
+ act["target"] = target
+ s, e := canonical(act)
+ if e != nil {
+ return nil, "", e
+ }
+ sum := sha256.Sum256([]byte(s))
+ return []byte(s), "sha256:" + hex.EncodeToString(sum[:]), nil
+}
diff --git a/adapters/go/approvalfact/claim.go b/adapters/go/approvalfact/claim.go
new file mode 100644
index 0000000..169643f
--- /dev/null
+++ b/adapters/go/approvalfact/claim.go
@@ -0,0 +1,170 @@
+package approvalfact
+
+import (
+ "encoding/json"
+ "errors"
+ "regexp"
+ "strconv"
+ "time"
+)
+
+var errClaim = errors.New("Approval fact does not match required claim")
+var digestPattern = regexp.MustCompile(`^sha256:[0-9a-f]{64}$`)
+var uuidPattern = regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`)
+var timePattern = regexp.MustCompile(`^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,9})?(Z|[+-]([01][0-9]|2[0-3]):[0-5][0-9])$`)
+
+// Expected contains independently owner-derived native act bytes and the actual
+// Access approval-free digest. Marshaling an already float64-decoded Go request
+// is not an authoritative reconstruction of the native act.
+type Expected struct {
+ ApprovalID string
+ NativeBindingJSON []byte
+ PDPDigest string
+}
+
+// Fact is validated data shape/correspondence, NOT authenticated provider origin
+// or execution authority. Access must wrap it only after its own source admission.
+type Fact struct {
+ raw []byte
+ stable string
+ digest string
+ observed, timeLimit, validatedAt time.Time
+}
+
+func (f Fact) RawJSON() []byte { return append([]byte(nil), f.raw...) }
+func (f Fact) ObservedAt() time.Time { return f.observed }
+func (f Fact) Deadline() time.Time { return f.timeLimit }
+func (f Fact) NativeDigest() string { return f.digest }
+
+func members(m map[string]any, required, optional []string) bool {
+ allowed := map[string]bool{}
+ for _, k := range required {
+ allowed[k] = true
+ if _, ok := m[k]; !ok {
+ return false
+ }
+ }
+ for _, k := range optional {
+ allowed[k] = true
+ }
+ for k := range m {
+ if !allowed[k] {
+ return false
+ }
+ }
+ return true
+}
+func object(v any) (map[string]any, bool) { m, ok := v.(map[string]any); return m, ok }
+func stamp(v any) (time.Time, error) {
+ s, ok := v.(string)
+ if !ok || !timePattern.MatchString(s) {
+ return time.Time{}, errClaim
+ }
+ t, e := time.Parse(time.RFC3339Nano, s)
+ if e != nil {
+ return time.Time{}, errClaim
+ }
+ return t, nil
+}
+
+// ValidateClaim checks one original or fetched schema-0.1 human/PDP-path claim
+// at a caller-captured instant, using the existing Approval producer semantics.
+// It has no I/O, policy evaluator, credentials, cache, or consume mutation.
+func ValidateClaim(raw []byte, expected Expected, now time.Time) (Fact, error) {
+ if now.IsZero() || !uuidPattern.MatchString(expected.ApprovalID) || !digestPattern.MatchString(expected.PDPDigest) {
+ return Fact{}, errClaim
+ }
+ _, want, e := CanonicalBinding(expected.NativeBindingJSON)
+ if e != nil {
+ return Fact{}, errClaim
+ }
+ v, e := DecodeJSON(raw)
+ if e != nil {
+ return Fact{}, errClaim
+ }
+ m, ok := object(v)
+ if !ok || !members(m, []string{"schema_version", "kind", "issuer", "approval_id", "state", "valid_now", "consumed", "binding", "freshness", "validity", "reason_code"}, []string{"yields_to"}) {
+ return Fact{}, errClaim
+ }
+ if y, ok := m["yields_to"]; ok {
+ if _, ok = y.(string); !ok {
+ return Fact{}, errClaim
+ }
+ }
+ if m["schema_version"] != "0.1" || m["kind"] != "approval-claim" || m["issuer"] != "approval-engine" || m["approval_id"] != expected.ApprovalID || m["state"] != "valid" || m["valid_now"] != true || m["consumed"] != false || m["reason_code"] != "ok" {
+ return Fact{}, errClaim
+ }
+ b, ok := object(m["binding"])
+ if !ok || !members(b, []string{"action", "actor", "principal", "purpose", "target", "digest", "pdp_digest", "pdp_path", "human_control"}, nil) {
+ return Fact{}, errClaim
+ }
+ if b["digest"] != want || b["pdp_digest"] != expected.PDPDigest || b["pdp_path"] != true || b["human_control"] != true {
+ return Fact{}, errClaim
+ }
+ text, e := canonical(b)
+ if e != nil {
+ return Fact{}, errClaim
+ }
+ _, got, e := CanonicalBinding([]byte(text))
+ if e != nil || got != want {
+ return Fact{}, errClaim
+ }
+ f, ok := object(m["freshness"])
+ if !ok || !members(f, []string{"observed_at", "ttl_seconds", "not_after"}, nil) {
+ return Fact{}, errClaim
+ }
+ observed, e := stamp(f["observed_at"])
+ if e != nil {
+ return Fact{}, e
+ }
+ notAfter, e := stamp(f["not_after"])
+ if e != nil {
+ return Fact{}, e
+ }
+ ttl, ok := f["ttl_seconds"].(json.Number)
+ if !ok {
+ return Fact{}, errClaim
+ }
+ seconds, e := strconv.ParseInt(string(ttl), 10, 64)
+ if e != nil || seconds < 1 {
+ return Fact{}, errClaim
+ }
+ // Bound arithmetic to time.Duration's representable seconds, not a new
+ // semantic freshness grant or configured TTL. Unsupported extremes refuse.
+ if seconds > int64((1<<63-1)/int64(time.Second)) || !observed.Add(time.Duration(seconds)*time.Second).Equal(notAfter) || now.Before(observed) || !now.Before(notAfter) {
+ return Fact{}, errClaim
+ }
+ validity, ok := object(m["validity"])
+ if !ok || !members(validity, []string{"not_before", "expires_at"}, nil) {
+ return Fact{}, errClaim
+ }
+ before, e := stamp(validity["not_before"])
+ if e != nil {
+ return Fact{}, e
+ }
+ expires, e := stamp(validity["expires_at"])
+ if e != nil || now.Before(before) || !now.Before(expires) {
+ return Fact{}, errClaim
+ }
+ limit := notAfter
+ if expires.Before(limit) {
+ limit = expires
+ }
+ delete(m, "freshness")
+ delete(m, "yields_to")
+ stable, e := canonical(m)
+ if e != nil {
+ return Fact{}, errClaim
+ }
+ return Fact{raw: append([]byte(nil), raw...), stable: stable, digest: want, observed: observed, timeLimit: limit, validatedAt: now}, nil
+}
+
+// MatchObserved requires independently validated original/fetched facts at the
+// same captured instant and exact nonfreshness authority correspondence. It
+// never rewrites the original request or extends its original deadline.
+func MatchObserved(submitted, observed Fact) error {
+ if submitted.stable == "" || observed.stable == "" || !submitted.validatedAt.Equal(observed.validatedAt) || submitted.stable != observed.stable {
+ return errClaim
+ }
+ return nil
+}
diff --git a/adapters/go/approvalfact/claim_test.go b/adapters/go/approvalfact/claim_test.go
new file mode 100644
index 0000000..26623c8
--- /dev/null
+++ b/adapters/go/approvalfact/claim_test.go
@@ -0,0 +1,144 @@
+package approvalfact
+
+import (
+ "bytes"
+ "encoding/json"
+ "os"
+ "strings"
+ "testing"
+ "time"
+)
+
+type vectors struct {
+ Native []struct {
+ Binding json.RawMessage `json:"binding"`
+ Canonical string `json:"canonical_binding_utf8"`
+ Digest string `json:"native_digest"`
+ } `json:"native_binding_vectors"`
+ Claims []struct {
+ Name string `json:"name"`
+ Now time.Time `json:"validation_time"`
+ Submitted json.RawMessage `json:"submitted_claim"`
+ Observed json.RawMessage `json:"observed_claim"`
+ Binding json.RawMessage `json:"expected_binding"`
+ PDP string `json:"expected_pdp_digest"`
+ Accept bool `json:"expected_accept"`
+ } `json:"claim_cases"`
+ Transport []struct {
+ Name string `json:"name"`
+ Body string `json:"body_utf8"`
+ } `json:"transport_cases"`
+}
+
+func load(t *testing.T) vectors {
+ t.Helper()
+ raw, e := os.ReadFile("testdata/owner-vectors.json")
+ if e != nil {
+ t.Fatal(e)
+ }
+ var v vectors
+ if e = json.Unmarshal(raw, &v); e != nil {
+ t.Fatal(e)
+ }
+ return v
+}
+
+func TestProducerCanonicalVectors(t *testing.T) {
+ for _, v := range load(t).Native {
+ t.Run(v.Digest, func(t *testing.T) {
+ raw, d, e := CanonicalBinding(v.Binding)
+ if e != nil || string(raw) != v.Canonical || d != v.Digest {
+ t.Fatalf("producer parity: %q %s %v, want %q %s", raw, d, e, v.Canonical, v.Digest)
+ }
+ })
+ }
+}
+
+func TestProducerClaimVectors(t *testing.T) {
+ for _, v := range load(t).Claims {
+ t.Run(v.Name, func(t *testing.T) {
+ var id struct {
+ ID string `json:"approval_id"`
+ }
+ if e := json.Unmarshal(v.Submitted, &id); e != nil {
+ t.Fatal(e)
+ }
+ expected := Expected{id.ID, v.Binding, v.PDP}
+ old, e1 := ValidateClaim(v.Submitted, expected, v.Now)
+ fresh, e2 := ValidateClaim(v.Observed, expected, v.Now)
+ accepted := e1 == nil && e2 == nil && MatchObserved(old, fresh) == nil
+ if accepted != v.Accept {
+ t.Fatalf("accepted=%v want=%v original=%v observed=%v", accepted, v.Accept, e1, e2)
+ }
+ if accepted {
+ raw := old.RawJSON()
+ if !bytes.Equal(raw, v.Submitted) {
+ t.Fatal("original bytes changed")
+ }
+ raw[0] = 'x'
+ if old.RawJSON()[0] != '{' {
+ t.Fatal("mutable fact storage")
+ }
+ if !old.Deadline().Before(fresh.Deadline()) {
+ t.Fatal("refresh must not extend original deadline")
+ }
+ }
+ })
+ }
+}
+
+func TestStrictJSONRefusals(t *testing.T) {
+ for _, raw := range []string{`{"a":1,"a":2}`, `{"a":{"x":1,"x":2}}`, `{"a":NaN}`, `{"a":1e999}`, `{"a":"\ud800"}`, `{"a":"\udfff"}`, `{"a":"\ud800x"}`, `{"a":1} {}`, `{"a":"` + string([]byte{0xff}) + `"}`, strings.Repeat("[", 130) + strings.Repeat("]", 130), strings.Repeat(" ", MaxJSONBytes+1)} {
+ if _, e := DecodeJSON([]byte(raw)); e == nil {
+ t.Fatalf("accepted malformed JSON %.80q", raw)
+ }
+ }
+}
+
+func TestUnicodeAndControlEncoding(t *testing.T) {
+ for _, raw := range []string{`{"v":"\ud83d\ude00"}`, `{"v":"escaped \\\" quote"}`, `{"v":"\u0000\b\f\n\r\t"}`} {
+ if _, e := DecodeJSON([]byte(raw)); e != nil {
+ t.Fatalf("refused valid Unicode %q", raw)
+ }
+ }
+}
+
+func TestGoldenDuplicateAndNonfiniteBodies(t *testing.T) {
+ for _, v := range load(t).Transport {
+ if v.Name == "duplicate_valid_now" || v.Name == "nonfinite_json" {
+ if _, e := DecodeJSON([]byte(v.Body)); e == nil {
+ t.Fatal(v.Name)
+ }
+ }
+ }
+}
+
+func TestInvalidExpectedAndZeroFacts(t *testing.T) {
+ v := load(t).Claims[0]
+ if _, e := ValidateClaim(v.Submitted, Expected{}, v.Now); e == nil {
+ t.Fatal("missing expected act accepted")
+ }
+ if MatchObserved(Fact{}, Fact{}) == nil {
+ t.Fatal("zero facts accepted")
+ }
+ expected := Expected{"11111111-1111-4111-8111-111111111111", v.Binding, v.PDP}
+ a, e := ValidateClaim(v.Submitted, expected, v.Now)
+ if e != nil {
+ t.Fatal(e)
+ }
+ b, e := ValidateClaim(v.Observed, expected, v.Now.Add(time.Second))
+ if e != nil {
+ t.Fatal(e)
+ }
+ if MatchObserved(a, b) == nil {
+ t.Fatal("different validation instants accepted")
+ }
+}
+
+func TestTimestampPrecisionAndOffsetRefusals(t *testing.T) {
+ for _, value := range []string{"2026-08-29T12:00:00,1Z", "2026-08-29T12:00:00+24:00", "2026-08-29T12:00:00+00:60", "2026-08-29T12:00:00.0000000001Z", "2026-08-29T12:00:00"} {
+ if _, err := stamp(value); err == nil {
+ t.Fatalf("accepted unsupported timestamp %q", value)
+ }
+ }
+}
diff --git a/adapters/go/approvalfact/go.mod b/adapters/go/approvalfact/go.mod
new file mode 100644
index 0000000..bcb1783
--- /dev/null
+++ b/adapters/go/approvalfact/go.mod
@@ -0,0 +1,3 @@
+module github.com/netkingdom/approval-engine/adapters/go/approvalfact
+
+go 1.26.7
diff --git a/adapters/go/approvalfact/oracle_test.go b/adapters/go/approvalfact/oracle_test.go
new file mode 100644
index 0000000..b845388
--- /dev/null
+++ b/adapters/go/approvalfact/oracle_test.go
@@ -0,0 +1,42 @@
+package approvalfact
+
+import (
+ "bufio"
+ "encoding/json"
+ "os"
+ "testing"
+)
+
+// This test-only input is produced by scripts/check_go_approvalfact.py using
+// the actual Python owner primitive. Production has no subprocess or oracle.
+func TestPythonDifferential(t *testing.T) {
+ path := os.Getenv("APPROVAL_TEST_ORACLE")
+ if path == "" {
+ t.Skip("run scripts/check_go_approvalfact.py for Python differential corpus")
+ }
+ f, e := os.Open(path)
+ if e != nil {
+ t.Fatal(e)
+ }
+ defer f.Close()
+ s := bufio.NewScanner(f)
+ count := 0
+ for s.Scan() {
+ var v struct{ Raw, Canonical, Digest string }
+ if e = json.Unmarshal(s.Bytes(), &v); e != nil {
+ t.Fatal(e)
+ }
+ raw, d, e := CanonicalBinding([]byte(v.Raw))
+ if e != nil || string(raw) != v.Canonical || d != v.Digest {
+ t.Fatalf("Python differential row %d: got %q %s %v want %q %s", count, raw, d, e, v.Canonical, v.Digest)
+ }
+ count++
+ }
+ if e = s.Err(); e != nil {
+ t.Fatal(e)
+ }
+ if count < 10000 {
+ t.Fatalf("incomplete differential corpus: %d", count)
+ }
+ t.Logf("matched %d Python source canonical bytes and digests", count)
+}
diff --git a/adapters/go/approvalfact/testdata/owner-vectors.json b/adapters/go/approvalfact/testdata/owner-vectors.json
new file mode 100644
index 0000000..81caf34
--- /dev/null
+++ b/adapters/go/approvalfact/testdata/owner-vectors.json
@@ -0,0 +1,2305 @@
+{
+ "producer_revision": "eece796b8bbee19551f6aa07ad389cbf83cabcdb",
+ "fixture_only": true,
+ "source": "Engine.claim with fixed synthetic identities; mutated consumer refusal cases explicitly labeled; no native identity admission",
+ "schema_version": "0.1",
+ "claim_cases": [
+ {
+ "name": "fresh_out_of_band_observation_unchanged_original",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": true,
+ "reason": "matching_valid_facts_original_digest_unchanged"
+ },
+ {
+ "name": "requested",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "requested",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "requested"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "insufficient_distinct_humans",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "requested",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "requested"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "foreign_issuer",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "foreign",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "foreign_id",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "22222222-2222-4222-8222-222222222222",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "nonhuman_control",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": false
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "legacy_missing_human_control",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "human_control_integer",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": 1
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "wrong_pdp_digest",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:abababababababababababababababababababababababababababababababab",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "null_pdp_digest",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": null,
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "undeclared_pdp_path",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": false,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "valid_now_integer",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": 1,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "wrong_native_digest",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:abababababababababababababababababababababababababababababababab",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "wrong_act",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "other",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "future_observation",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:06+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "inconsistent_ttl",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 31,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "zero_ttl",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 0,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "naive_observation",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "original_observation_expired_even_when_provider_fresh",
+ "validation_time": "2026-08-29T12:00:30+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "refetch_cannot_extend_original_freshness",
+ "validation_time": "2026-08-29T12:00:30+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:30+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:01:00+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "consumed_source",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "consumed",
+ "valid_now": false,
+ "consumed": true,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "consumed"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "expired_after_consumption_preserves_consumed_true",
+ "validation_time": "2026-08-30T12:00:00+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "expired",
+ "valid_now": false,
+ "consumed": true,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-30T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-30T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "expired"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "source_revoked",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "6302eb08-215e-4a17-8e6f-66717874c6af",
+ "state": "revoked",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "revoked"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "6302eb08-215e-4a17-8e6f-66717874c6af",
+ "state": "revoked",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "revoked"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "terminal_source_refusal"
+ },
+ {
+ "name": "source_superseded",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "8c8f9c0f-b2dd-4a1f-964a-54ac7022803b",
+ "state": "superseded",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "superseded"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "8c8f9c0f-b2dd-4a1f-964a-54ac7022803b",
+ "state": "superseded",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "superseded"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "terminal_source_refusal"
+ }
+ ],
+ "native_binding_vectors": [
+ {
+ "input_target_json": "{\"value\":true}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": true
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":true}}",
+ "native_digest": "sha256:e1f537daa849e5da023efb5f3d62cc33d94cce20f9ca9c5a708c76e225fd702f"
+ },
+ {
+ "input_target_json": "{\"value\":1}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1}}",
+ "native_digest": "sha256:3a3d2da6267e4b917505a7c2247e6ce36fd8ee074eef37251bcc66839b602332"
+ },
+ {
+ "input_target_json": "{\"value\":1.0}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1.0
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1.0}}",
+ "native_digest": "sha256:21c2cdb9b161071ebfe361e50703511b2abf6c6f327f153282d247aa92c3898e"
+ },
+ {
+ "input_target_json": "{\"value\":false}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": false
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":false}}",
+ "native_digest": "sha256:278cbcd013f7923db5258dd860f911d688505a8259f15ccb77983b044f312c74"
+ },
+ {
+ "input_target_json": "{\"value\":0}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 0
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":0}}",
+ "native_digest": "sha256:e691b8fb55d4bf82a310dee37c045331100c8031e26ea6f51bdcceeeb3b1f20e"
+ },
+ {
+ "input_target_json": "{\"value\":-0.0}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": -0.0
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":-0.0}}",
+ "native_digest": "sha256:eccde458c686bff67506bb2d94c750e648a311bf23967cb22b37f11e84b6844f"
+ },
+ {
+ "input_target_json": "{\"value\":1e-7}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e-07
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e-07}}",
+ "native_digest": "sha256:779042b6c0e675f6aacdcd3a02199aab66f534bb84dd410a95c18657afae563c"
+ },
+ {
+ "input_target_json": "{\"value\":1e-6}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e-06
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e-06}}",
+ "native_digest": "sha256:d021f402231fcd59e764b31e6f08a5298ebb328dfd93da58ecde8feb11fde0b5"
+ },
+ {
+ "input_target_json": "{\"value\":1e20}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e+20
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e+20}}",
+ "native_digest": "sha256:14270ffca4ab10e9d9302d52e988b4aa3e2facd494c12a60e2edafef70277a20"
+ },
+ {
+ "input_target_json": "{\"value\":1e21}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e+21
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e+21}}",
+ "native_digest": "sha256:75a60a595b2578430b0be466b6bf9a46b62ddc99bbbcebd7fa0e8d22e3078c0a"
+ },
+ {
+ "input_target_json": "{\"value\":2.5e-7}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 2.5e-07
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":2.5e-07}}",
+ "native_digest": "sha256:50af37ff75a3e7a22629e746f814995c0c2cd96adb7f1ed5b26999b71d0ac498"
+ },
+ {
+ "input_target_json": "{\"value\":9007199254740993}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 9007199254740993
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":9007199254740993}}",
+ "native_digest": "sha256:765360dc5a1d949bd114c6b749d83069123d8b4b6b1d939f831428a800f50dab"
+ },
+ {
+ "input_target_json": "{\"html\":\"<>&\", \"unicode\":\"é雪😀\", \"separator\":\"\\u2028\\u2029\"}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "html": "<>&",
+ "unicode": "é雪😀",
+ "separator": "

"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"html\":\"<>&\",\"separator\":\"

\",\"unicode\":\"é雪😀\"}}",
+ "native_digest": "sha256:c203d934743e2954342038a3746b6c37a0f3101e886ef855b1c6ad824adf5dea"
+ },
+ {
+ "input_target_json": "{\"b\":[true,1,1.0,null,{\"z\":\"x\",\"a\":\"y\"}],\"a\":{}}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "b": [
+ true,
+ 1,
+ 1.0,
+ null,
+ {
+ "z": "x",
+ "a": "y"
+ }
+ ],
+ "a": {}
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"a\":{},\"b\":[true,1,1.0,null,{\"a\":\"y\",\"z\":\"x\"}]}}",
+ "native_digest": "sha256:56306505c882af6edfae5f3d2a5b42e92737a0859236fe5574a21d1874655d51"
+ }
+ ],
+ "transport_cases": [
+ {
+ "name": "duplicate_valid_now",
+ "status": 200,
+ "content_type": "application/json",
+ "body_utf8": "{\"schema_version\":\"0.1\",\"kind\":\"approval-claim\",\"yields_to\":\"net-kingdom taxonomy request-claim schema (statute §17; unassigned)\",\"issuer\":\"approval-engine\",\"approval_id\":\"11111111-1111-4111-8111-111111111111\",\"state\":\"valid\",\"valid_now\":true,\"consumed\":false,\"binding\":{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"id\":\"lane-openbao-root\",\"stage\":\"prod\"},\"digest\":\"sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b\",\"pdp_digest\":\"sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\",\"pdp_path\":true,\"human_control\":true},\"freshness\":{\"observed_at\":\"2026-08-29T12:00:05+00:00\",\"ttl_seconds\":30,\"not_after\":\"2026-08-29T12:00:35+00:00\"},\"validity\":{\"not_before\":\"2026-08-29T11:00:00+00:00\",\"expires_at\":\"2026-08-29T15:00:00+00:00\"},\"reason_code\":\"ok\",\"valid_now\":false}",
+ "expected_accept": false
+ },
+ {
+ "name": "nonfinite_json",
+ "status": 200,
+ "content_type": "application/json",
+ "body_utf8": "{\"schema_version\":\"0.1\",\"kind\":\"approval-claim\",\"yields_to\":\"net-kingdom taxonomy request-claim schema (statute §17; unassigned)\",\"issuer\":\"approval-engine\",\"approval_id\":\"11111111-1111-4111-8111-111111111111\",\"state\":\"valid\",\"valid_now\":true,\"consumed\":false,\"binding\":{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"id\":\"lane-openbao-root\",\"stage\":\"prod\"},\"digest\":\"sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b\",\"pdp_digest\":\"sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\",\"pdp_path\":true,\"human_control\":true},\"freshness\":{\"observed_at\":\"2026-08-29T12:00:05+00:00\",\"ttl_seconds\":NaN,\"not_after\":\"2026-08-29T12:00:35+00:00\"},\"validity\":{\"not_before\":\"2026-08-29T11:00:00+00:00\",\"expires_at\":\"2026-08-29T15:00:00+00:00\"},\"reason_code\":\"ok\"}",
+ "expected_accept": false
+ },
+ {
+ "name": "redirect",
+ "status": 302,
+ "location": "https://foreign.example/claim",
+ "expected_accept": false,
+ "required_secondary_requests": 0
+ },
+ {
+ "name": "wrong_media_type",
+ "status": 200,
+ "content_type": "text/plain",
+ "body_utf8": "{\"schema_version\":\"0.1\",\"kind\":\"approval-claim\",\"yields_to\":\"net-kingdom taxonomy request-claim schema (statute §17; unassigned)\",\"issuer\":\"approval-engine\",\"approval_id\":\"11111111-1111-4111-8111-111111111111\",\"state\":\"valid\",\"valid_now\":true,\"consumed\":false,\"binding\":{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"id\":\"lane-openbao-root\",\"stage\":\"prod\"},\"digest\":\"sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b\",\"pdp_digest\":\"sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\",\"pdp_path\":true,\"human_control\":true},\"freshness\":{\"observed_at\":\"2026-08-29T12:00:05+00:00\",\"ttl_seconds\":30,\"not_after\":\"2026-08-29T12:00:35+00:00\"},\"validity\":{\"not_before\":\"2026-08-29T11:00:00+00:00\",\"expires_at\":\"2026-08-29T15:00:00+00:00\"},\"reason_code\":\"ok\"}",
+ "expected_accept": false
+ },
+ {
+ "name": "provider_unavailable",
+ "status": 503,
+ "expected_accept": false
+ },
+ {
+ "name": "declared_body_over_limit",
+ "status": 200,
+ "content_length": 1048577,
+ "consumer_limit_bytes": 1048576,
+ "expected_accept": false
+ },
+ {
+ "name": "environment_proxy_configured",
+ "required_environment_proxy_requests": 0,
+ "expected_accept": false,
+ "note": "If fixed origin is unavailable, proxy cannot supply a replacement fact."
+ }
+ ]
+}
diff --git a/docs/access-claim-fact-reader.md b/docs/access-claim-fact-reader.md
new file mode 100644
index 0000000..4669f64
--- /dev/null
+++ b/docs/access-claim-fact-reader.md
@@ -0,0 +1,137 @@
+# Thin Access Approval fact reader — owner source contract proposal
+
+Owner scope: Approval Engine / PIP. Work: APPROVAL-WP-0005-T01, selected source
+subset of APPROVAL-WP-0002-T01/T05 under CUST-WP-0080. This interprets the existing
+claim schema 0.1, not a new API/schema/signature or policy grant. Access's B2
+implementation stays DENY until its separately reviewed complete successor.
+
+## Authoritative source and guarantee
+
+Only server-installed, independently admitted provider origin and transport may
+GET `/v1/approvals/{id}/claim`, with least-scope `approval:read` credential and
+exact admitted store tenant. No caller URL/opener/key/verified flag, redirects,
+environment proxy, caller JSON or public same-channel key bootstrap can supply
+this provenance. Owner transport must enforce total deadline/size, exact 200
+application/json UTF-8, no encoding, duplicate-key/nonfinite/malformed JSON
+refusal, no retry and bounded errors without bearer/body leakage. Provider
+unavailability refuses this source join. Never invoke a credential-carrying
+Python subprocess as the Go adapter; reuse Go's existing transport boundary.
+
+At the provider observation, `valid_now: true` AND `binding.human_control: true`
+means the configured required count of distinct entries is met and every entry
+has verified `principal_type=human`. `/entries` obtains identities/types only from
+its authenticator, rejects non-human binds for this declaration, and persists
+UNIQUE(approval_id, subject_id); `_evaluate` repeats the threshold/human check.
+It does NOT mean required_count is two, requester/actor/principal is human,
+directory-derived tenant membership, a particular MFA/assurance level, policy
+eligibility, uncompromised source, native issuer admission, or continuing
+validity after the observation. Consumer trusts this owner evaluation instead
+of fetching identities/counting approvers or revalidating human JWTs. Native
+issuer/profile acceptance is still T01, not established by synthetic vectors.
+
+## Minimal typed fact validation
+
+The submitted claim and fetched observation must each satisfy existing schema
+0.1 with exact JSON types; `human_control` must be present and exactly true on
+this lane despite being historically optional in the generic schema. Require
+schema_version=0.1, kind=approval-claim, issuer=approval-engine, exact expected
+approval UUID, state=valid, valid_now=true, consumed=false, reason_code=ok,
+pdp_path=true and non-null lowercase sha256 pdp_digest. Reject decision-shaped
+keys and unknown schema members (except optional informational yields_to).
+The signed/requesting service must never become a human approver by inference.
+
+At one captured UTC validation instant now, require zoned RFC3339 timestamps,
+positive integral ttl_seconds, observed_at<=now<not_after and
+not_after=observed_at+ttl_seconds. Require not_before<=now<expires_at. Do not
+invent skew or extend TTL; a separately admitted clock policy is needed to
+relax the zero-skew default. The provider default TTL is 30 seconds but source
+configuration may differ; an Access-owned maximum may only shorten it.
+
+Compare exact five-field act against the owner-derived normalized proposed act,
+including all nested target values; no action vocabulary translation is owned
+here. Recompute native binding.digest from those five fields and require exact
+served and expected digest correspondence. Match pdp_digest to Access's actual
+ApprovalBindingDigest over the exact normalized original request (excludes only
+top-level context.approval). Preserve execution_contract and all other context.
+Never substitute full request_digest, native act digest or a guessed Go digest.
+The PDP digest proves correspondence, not decision authenticity or approval
+source authenticity. Registry/normalization changes must fail or reissue.
+
+## Original request is immutable; fresh observation stays out-of-band
+
+The original submitted context.approval must remain byte/value-equivalent under
+Access's existing canonical request rules. Do not replace it, update freshness,
+change binding/declarations, or manufacture an evaluated refreshed request.
+Validate its own original freshness/validity too; a newly fetched observation
+cannot rescue a stale original claim. Require all non-freshness authority facts
+to match between the submitted and fetched claims: schema/kind/issuer/id,
+state/valid_now/consumed/reason_code, binding and validity. Optional yields_to
+is informational only. Each native binding is independently recomputed.
+Freshness is validated separately on both observations; a later observation
+may have a later freshness window without changing the signed request.
+
+Return a package-private/server-created typed observation handle only after
+these checks. Access may bind its source identity/revision, observed_at,
+not_after, fetched-claim content digest and validation time into owner-produced
+signed provenance separately from unchanged request_digest and
+approval_binding_digest. This does not require changing the Approval schema;
+Access owns the minimal existing provenance representation and signer contract.
+An HTTP caller cannot instantiate this handle or set its verified state.
+
+Suggested Go boundary, for Access to implement in its existing process:
+`ApprovalFactSource.Observe(ctx, approvalID) (Observation, error)` reads only
+provider bytes plus source provenance; a separate package-private validator
+joins Observation with the immutable normalized request, submitted claim and
+captured validation time. The handle retains detached raw provider bytes and
+strict parsed numbers (json.Number), not caller-installable validation flags.
+Neither this reader nor its validator evaluates policy. Access's existing
+single policy evaluator consumes the verified factual handle without rewriting
+the request. Callers may not supply a ready-made Observation on the HTTP body.
+
+Effective input deadline is the minimum of ORIGINAL submitted freshness,
+fetched freshness, approval expiry, authenticated caller expiry and operation/
+decision deadlines. No equality at an expiry boundary is accepted. Refetching
+does not renew the original full request. Revocation/use may race a read; the
+PEP still performs one original exact consume CAS before effect and retains
+the same live Platform journal admission, deadlines and unknown-outcome rules.
+Access never consumes or executes. Historical confirm_consumption cannot
+substitute for this fresh predecision source validation.
+
+## Go canonicalization and golden vectors
+
+`examples/access-claim-reader-vectors.json` contains producer-generated native
+canonical UTF-8 bytes/digests and source lifecycle observations, plus explicitly
+mutated refusal fixtures. Python dict equality and Go decoding numbers into
+float64 lose authority distinctions: True/1, 1/1.0 and integers above 2^53 differ.
+Go default json.Marshal additionally escapes HTML/U+2028 differently. Retain
+number tokens with UseNumber and implement/test compatibility with Approval's
+existing Python json.dumps(sort_keys=True,separators=(',', ':'),ensure_ascii=False)
+format; do not silently normalize types or hash whole binding/freshness.
+UseNumber preserves number tokens but is NOT a canonicalizer: producer parsing
+of `1e-7` emits `1e-07`, `1e20` emits `1e+20`, `1.0` remains distinct from `1`,
+and negative floating zero emits `-0.0`. A signed typed Go envelope alone does
+not preserve or authenticate Python's original numeric representation.
+
+These finite vectors are a minimum, not proof of a complete Python float/string
+port. A thin pilot may fail closed on unsupported numeric/string domains only
+if its actual owner-compiled operation contract excludes those values and Access
+declares/tests that boundary. It may not silently change the global Approval
+algorithm or accept a digest without checking the proposed act. Required vectors
+cover bool/int/float distinction, large integer, Unicode/HTML/U+2028, reordered
+keys, nested containers, exponent formatting and negative floating zero. These
+are authoritative producer vectors for the domains shown, not arbitrary new
+restrictions on current pilot metadata. No currently authoritative narrow numeric
+restriction was established by this review, so it cannot be presumed. If a
+small shared producer-owned Go canonicalization helper becomes necessary, scope
+it explicitly to the actual consumer need and test against these producer bytes;
+do not invent a second unverified serialization algorithm in the adapter. This
+initial review provided vectors only. Subsequent scoped WP0005-T03 supplies
+`adapters/go/approvalfact`, a producer-owned pure data implementation agreed with
+Access; it adds no credential transport/runtime. The Go consumer owner must
+return exact accepted/refused vector results and transport negatives
+(redirect/proxy/duplicate/size/deadline).
+
+The superseded service-http-join-proposal-r1 B3 refreshed-evaluation wording is
+changes-requested for this immutable-context path. B2's source reader can proceed
+against this proposal after Access's own design/conformance review. No foreign
+owner assent, policy activation, live credential or native acceptance is implied.
diff --git a/docs/reviews/2026-10-16-access-claim-fact-reader-owner-review.json b/docs/reviews/2026-10-16-access-claim-fact-reader-owner-review.json
new file mode 100644
index 0000000..bc5bad1
--- /dev/null
+++ b/docs/reviews/2026-10-16-access-claim-fact-reader-owner-review.json
@@ -0,0 +1,15 @@
+{
+ "reviewer": "approval-engine-owner (agent approval-engine, codex)",
+ "decision": "changes_requested",
+ "comment": "INTENT Purpose and exact binding/claim boundary: B2 can reuse existing GET claim schema0.1 and verified human-control predicate without republishing approver identities. Superseded B3 refreshed evaluated-request/context design cannot satisfy the exact original strict handoff; retain original context/full and approval-free digests and verify fresh provider observation out-of-band. Work APPROVAL-WP-0005-T01; source base eece796b8bbee19551f6aa07ad389cbf83cabcdb. No policy activation, issuer admission, foreign owner assent or native acceptance.",
+ "reviewed_artifact": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/access-native-source/service-http-join-proposal-r1.json",
+ "reviewed_sha256": "e0f8f12c48faf2331cf366591028577beffe617250d7005dcaf2a8b7396535fc",
+ "owner_contract": "docs/access-claim-fact-reader.md",
+ "owner_contract_sha256": "3dfb7987a4d9fe461b917cfa5bae7beef61bc4d9a4561fdded3e90128f5966de",
+ "required_returns": [
+ "Access own B2 contract/conformance review and exact native canonicalization parity; original submitted context/digests retained",
+ "Owner-admitted read identity/store tenant and trusted provider transport separate from source fixture tests",
+ "Actual runtime source integration and original consumer/journal/cas path before any policy eligibility successor"
+ ],
+ "native_accepted": false
+}
diff --git a/examples/access-claim-reader-vectors.json b/examples/access-claim-reader-vectors.json
new file mode 100644
index 0000000..81caf34
--- /dev/null
+++ b/examples/access-claim-reader-vectors.json
@@ -0,0 +1,2305 @@
+{
+ "producer_revision": "eece796b8bbee19551f6aa07ad389cbf83cabcdb",
+ "fixture_only": true,
+ "source": "Engine.claim with fixed synthetic identities; mutated consumer refusal cases explicitly labeled; no native identity admission",
+ "schema_version": "0.1",
+ "claim_cases": [
+ {
+ "name": "fresh_out_of_band_observation_unchanged_original",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": true,
+ "reason": "matching_valid_facts_original_digest_unchanged"
+ },
+ {
+ "name": "requested",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "requested",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "requested"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "insufficient_distinct_humans",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "requested",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "requested"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "foreign_issuer",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "foreign",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "foreign_id",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "22222222-2222-4222-8222-222222222222",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "nonhuman_control",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": false
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "legacy_missing_human_control",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "human_control_integer",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": 1
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "wrong_pdp_digest",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:abababababababababababababababababababababababababababababababab",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "null_pdp_digest",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": null,
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "undeclared_pdp_path",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": false,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "valid_now_integer",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": 1,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "wrong_native_digest",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:abababababababababababababababababababababababababababababababab",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "wrong_act",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "other",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "future_observation",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:06+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "inconsistent_ttl",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 31,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "zero_ttl",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 0,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "naive_observation",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "original_observation_expired_even_when_provider_fresh",
+ "validation_time": "2026-08-29T12:00:30+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "refetch_cannot_extend_original_freshness",
+ "validation_time": "2026-08-29T12:00:30+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:30+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:01:00+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "consumed_source",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "consumed",
+ "valid_now": false,
+ "consumed": true,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:05+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:35+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "consumed"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "expired_after_consumption_preserves_consumed_true",
+ "validation_time": "2026-08-30T12:00:00+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "valid",
+ "valid_now": true,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "ok"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "11111111-1111-4111-8111-111111111111",
+ "state": "expired",
+ "valid_now": false,
+ "consumed": true,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-30T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-30T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "expired"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "source_fact_refusal"
+ },
+ {
+ "name": "source_revoked",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "6302eb08-215e-4a17-8e6f-66717874c6af",
+ "state": "revoked",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "revoked"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "6302eb08-215e-4a17-8e6f-66717874c6af",
+ "state": "revoked",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "revoked"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "terminal_source_refusal"
+ },
+ {
+ "name": "source_superseded",
+ "validation_time": "2026-08-29T12:00:05+00:00",
+ "submitted_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "8c8f9c0f-b2dd-4a1f-964a-54ac7022803b",
+ "state": "superseded",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "superseded"
+ },
+ "observed_claim": {
+ "schema_version": "0.1",
+ "kind": "approval-claim",
+ "yields_to": "net-kingdom taxonomy request-claim schema (statute §17; unassigned)",
+ "issuer": "approval-engine",
+ "approval_id": "8c8f9c0f-b2dd-4a1f-964a-54ac7022803b",
+ "state": "superseded",
+ "valid_now": false,
+ "consumed": false,
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "digest": "sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b",
+ "pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "pdp_path": true,
+ "human_control": true
+ },
+ "freshness": {
+ "observed_at": "2026-08-29T12:00:00+00:00",
+ "ttl_seconds": 30,
+ "not_after": "2026-08-29T12:00:30+00:00"
+ },
+ "validity": {
+ "not_before": "2026-08-29T11:00:00+00:00",
+ "expires_at": "2026-08-29T15:00:00+00:00"
+ },
+ "reason_code": "superseded"
+ },
+ "expected_binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "id": "lane-openbao-root",
+ "stage": "prod"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "expected_pdp_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "expected_accept": false,
+ "reason": "terminal_source_refusal"
+ }
+ ],
+ "native_binding_vectors": [
+ {
+ "input_target_json": "{\"value\":true}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": true
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":true}}",
+ "native_digest": "sha256:e1f537daa849e5da023efb5f3d62cc33d94cce20f9ca9c5a708c76e225fd702f"
+ },
+ {
+ "input_target_json": "{\"value\":1}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1}}",
+ "native_digest": "sha256:3a3d2da6267e4b917505a7c2247e6ce36fd8ee074eef37251bcc66839b602332"
+ },
+ {
+ "input_target_json": "{\"value\":1.0}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1.0
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1.0}}",
+ "native_digest": "sha256:21c2cdb9b161071ebfe361e50703511b2abf6c6f327f153282d247aa92c3898e"
+ },
+ {
+ "input_target_json": "{\"value\":false}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": false
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":false}}",
+ "native_digest": "sha256:278cbcd013f7923db5258dd860f911d688505a8259f15ccb77983b044f312c74"
+ },
+ {
+ "input_target_json": "{\"value\":0}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 0
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":0}}",
+ "native_digest": "sha256:e691b8fb55d4bf82a310dee37c045331100c8031e26ea6f51bdcceeeb3b1f20e"
+ },
+ {
+ "input_target_json": "{\"value\":-0.0}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": -0.0
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":-0.0}}",
+ "native_digest": "sha256:eccde458c686bff67506bb2d94c750e648a311bf23967cb22b37f11e84b6844f"
+ },
+ {
+ "input_target_json": "{\"value\":1e-7}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e-07
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e-07}}",
+ "native_digest": "sha256:779042b6c0e675f6aacdcd3a02199aab66f534bb84dd410a95c18657afae563c"
+ },
+ {
+ "input_target_json": "{\"value\":1e-6}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e-06
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e-06}}",
+ "native_digest": "sha256:d021f402231fcd59e764b31e6f08a5298ebb328dfd93da58ecde8feb11fde0b5"
+ },
+ {
+ "input_target_json": "{\"value\":1e20}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e+20
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e+20}}",
+ "native_digest": "sha256:14270ffca4ab10e9d9302d52e988b4aa3e2facd494c12a60e2edafef70277a20"
+ },
+ {
+ "input_target_json": "{\"value\":1e21}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 1e+21
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":1e+21}}",
+ "native_digest": "sha256:75a60a595b2578430b0be466b6bf9a46b62ddc99bbbcebd7fa0e8d22e3078c0a"
+ },
+ {
+ "input_target_json": "{\"value\":2.5e-7}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 2.5e-07
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":2.5e-07}}",
+ "native_digest": "sha256:50af37ff75a3e7a22629e746f814995c0c2cd96adb7f1ed5b26999b71d0ac498"
+ },
+ {
+ "input_target_json": "{\"value\":9007199254740993}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "value": 9007199254740993
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"value\":9007199254740993}}",
+ "native_digest": "sha256:765360dc5a1d949bd114c6b749d83069123d8b4b6b1d939f831428a800f50dab"
+ },
+ {
+ "input_target_json": "{\"html\":\"<>&\", \"unicode\":\"é雪😀\", \"separator\":\"\\u2028\\u2029\"}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "html": "<>&",
+ "unicode": "é雪😀",
+ "separator": "

"
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"html\":\"<>&\",\"separator\":\"

\",\"unicode\":\"é雪😀\"}}",
+ "native_digest": "sha256:c203d934743e2954342038a3746b6c37a0f3101e886ef855b1c6ad824adf5dea"
+ },
+ {
+ "input_target_json": "{\"b\":[true,1,1.0,null,{\"z\":\"x\",\"a\":\"y\"}],\"a\":{}}",
+ "binding": {
+ "action": "secrets.kv.destroy",
+ "target": {
+ "b": [
+ true,
+ 1,
+ 1.0,
+ null,
+ {
+ "z": "x",
+ "a": "y"
+ }
+ ],
+ "a": {}
+ },
+ "actor": "agt-secrets-engine",
+ "principal": "bernd",
+ "purpose": "rotate-exposed-key"
+ },
+ "canonical_binding_utf8": "{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"a\":{},\"b\":[true,1,1.0,null,{\"a\":\"y\",\"z\":\"x\"}]}}",
+ "native_digest": "sha256:56306505c882af6edfae5f3d2a5b42e92737a0859236fe5574a21d1874655d51"
+ }
+ ],
+ "transport_cases": [
+ {
+ "name": "duplicate_valid_now",
+ "status": 200,
+ "content_type": "application/json",
+ "body_utf8": "{\"schema_version\":\"0.1\",\"kind\":\"approval-claim\",\"yields_to\":\"net-kingdom taxonomy request-claim schema (statute §17; unassigned)\",\"issuer\":\"approval-engine\",\"approval_id\":\"11111111-1111-4111-8111-111111111111\",\"state\":\"valid\",\"valid_now\":true,\"consumed\":false,\"binding\":{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"id\":\"lane-openbao-root\",\"stage\":\"prod\"},\"digest\":\"sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b\",\"pdp_digest\":\"sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\",\"pdp_path\":true,\"human_control\":true},\"freshness\":{\"observed_at\":\"2026-08-29T12:00:05+00:00\",\"ttl_seconds\":30,\"not_after\":\"2026-08-29T12:00:35+00:00\"},\"validity\":{\"not_before\":\"2026-08-29T11:00:00+00:00\",\"expires_at\":\"2026-08-29T15:00:00+00:00\"},\"reason_code\":\"ok\",\"valid_now\":false}",
+ "expected_accept": false
+ },
+ {
+ "name": "nonfinite_json",
+ "status": 200,
+ "content_type": "application/json",
+ "body_utf8": "{\"schema_version\":\"0.1\",\"kind\":\"approval-claim\",\"yields_to\":\"net-kingdom taxonomy request-claim schema (statute §17; unassigned)\",\"issuer\":\"approval-engine\",\"approval_id\":\"11111111-1111-4111-8111-111111111111\",\"state\":\"valid\",\"valid_now\":true,\"consumed\":false,\"binding\":{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"id\":\"lane-openbao-root\",\"stage\":\"prod\"},\"digest\":\"sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b\",\"pdp_digest\":\"sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\",\"pdp_path\":true,\"human_control\":true},\"freshness\":{\"observed_at\":\"2026-08-29T12:00:05+00:00\",\"ttl_seconds\":NaN,\"not_after\":\"2026-08-29T12:00:35+00:00\"},\"validity\":{\"not_before\":\"2026-08-29T11:00:00+00:00\",\"expires_at\":\"2026-08-29T15:00:00+00:00\"},\"reason_code\":\"ok\"}",
+ "expected_accept": false
+ },
+ {
+ "name": "redirect",
+ "status": 302,
+ "location": "https://foreign.example/claim",
+ "expected_accept": false,
+ "required_secondary_requests": 0
+ },
+ {
+ "name": "wrong_media_type",
+ "status": 200,
+ "content_type": "text/plain",
+ "body_utf8": "{\"schema_version\":\"0.1\",\"kind\":\"approval-claim\",\"yields_to\":\"net-kingdom taxonomy request-claim schema (statute §17; unassigned)\",\"issuer\":\"approval-engine\",\"approval_id\":\"11111111-1111-4111-8111-111111111111\",\"state\":\"valid\",\"valid_now\":true,\"consumed\":false,\"binding\":{\"action\":\"secrets.kv.destroy\",\"actor\":\"agt-secrets-engine\",\"principal\":\"bernd\",\"purpose\":\"rotate-exposed-key\",\"target\":{\"id\":\"lane-openbao-root\",\"stage\":\"prod\"},\"digest\":\"sha256:0982954d4ecbaad0c7368c207ec530e51d7508c3304b67c10885d112175f929b\",\"pdp_digest\":\"sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\",\"pdp_path\":true,\"human_control\":true},\"freshness\":{\"observed_at\":\"2026-08-29T12:00:05+00:00\",\"ttl_seconds\":30,\"not_after\":\"2026-08-29T12:00:35+00:00\"},\"validity\":{\"not_before\":\"2026-08-29T11:00:00+00:00\",\"expires_at\":\"2026-08-29T15:00:00+00:00\"},\"reason_code\":\"ok\"}",
+ "expected_accept": false
+ },
+ {
+ "name": "provider_unavailable",
+ "status": 503,
+ "expected_accept": false
+ },
+ {
+ "name": "declared_body_over_limit",
+ "status": 200,
+ "content_length": 1048577,
+ "consumer_limit_bytes": 1048576,
+ "expected_accept": false
+ },
+ {
+ "name": "environment_proxy_configured",
+ "required_environment_proxy_requests": 0,
+ "expected_accept": false,
+ "note": "If fixed origin is unavailable, proxy cannot supply a replacement fact."
+ }
+ ]
+}
diff --git a/scripts/check_go_approvalfact.py b/scripts/check_go_approvalfact.py
new file mode 100644
index 0000000..c71f576
--- /dev/null
+++ b/scripts/check_go_approvalfact.py
@@ -0,0 +1,53 @@
+"""Development-only Go parity check against the actual Python producer."""
+from pathlib import Path
+import json
+import math
+import os
+import random
+import struct
+import subprocess
+import sys
+import tempfile
+
+ROOT = Path(__file__).resolve().parents[1]
+sys.path.insert(0, str(ROOT))
+from approval_engine.binding import binding_digest, canonical_binding, canonical_json
+
+
+def main():
+ rng = random.Random(20261016)
+ values = [0.0, -0.0, 5e-324, -5e-324, sys.float_info.max,
+ sys.float_info.min, 1.0, 1e-4, 1e-5, 1e15, 1e16, 1e20, 1e21]
+ for _ in range(12000):
+ value = struct.unpack(">d", rng.getrandbits(64).to_bytes(8, "big"))[0]
+ if math.isfinite(value):
+ values.append(value)
+ for power in range(-323, 309):
+ value = float("1e" + str(power))
+ values.extend([value, math.nextafter(value, 0.0), math.nextafter(value, math.inf)])
+ targets = [{"value": value} for value in values if math.isfinite(value)]
+ targets += [{"value": n} for n in [0, -1, 1, 2**53+1, 10**100, -(10**100)]]
+ targets += [json.loads('{"value":' + token + '}') for token in
+ ["-0", "-0.0", "1E0", "1.000", "100e-2", "1e-07", "1e+20"]]
+ targets += [{"text": "".join(chr(i) for i in range(32)) + '<>&é雪😀\u2028\u2029'}]
+ for _ in range(200):
+ points = [rng.randrange(0x110000) for _ in range(20)]
+ targets.append({"text": "".join(chr(c) for c in points if not 0xD800 <= c <= 0xDFFF)})
+ with tempfile.TemporaryDirectory(prefix="approval-go-oracle-") as tmp:
+ path = Path(tmp) / "oracle.jsonl"
+ with path.open("w") as stream:
+ for target in targets:
+ act = dict(action="execute-ccr", actor="service:secrets-engine",
+ principal="principal", purpose="differential", target=target)
+ row = {"Raw": json.dumps(act, ensure_ascii=False, allow_nan=False),
+ "Canonical": canonical_json(canonical_binding(act)).decode(),
+ "Digest": binding_digest(act)}
+ stream.write(json.dumps(row, ensure_ascii=True, allow_nan=False) + "\n")
+ env = dict(os.environ, APPROVAL_TEST_ORACLE=str(path))
+ subprocess.run(["go", "test", "-count=1", "-run", "TestPythonDifferential", "-v", "./..."],
+ cwd=ROOT / "adapters/go/approvalfact", env=env, check=True)
+ print(f"Python producer corpus: {len(targets)} cases")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/test_access_claim_vectors.py b/tests/test_access_claim_vectors.py
new file mode 100644
index 0000000..72e5191
--- /dev/null
+++ b/tests/test_access_claim_vectors.py
@@ -0,0 +1,42 @@
+"""Producer facts/canonical vectors only; not a Go consumer acceptance test."""
+import json
+from pathlib import Path
+
+import jsonschema
+
+from approval_engine.binding import binding_digest, canonical_binding, canonical_json
+from approval_engine.store import Engine
+from tests.conftest import FROZEN, binding, validity
+
+ROOT = Path(__file__).resolve().parents[1]
+VECTORS = json.loads((ROOT / "examples/access-claim-reader-vectors.json").read_text())
+
+
+def test_native_vectors_match_actual_producer_bytes_and_digest():
+ for case in VECTORS["native_binding_vectors"]:
+ act = binding(target=json.loads(case["input_target_json"]))
+ assert act == case["binding"]
+ assert canonical_json(canonical_binding(act)).decode() == case["canonical_binding_utf8"]
+ assert binding_digest(act) == case["native_digest"]
+ digests = [v["native_digest"] for v in VECTORS["native_binding_vectors"]]
+ assert len(set(digests)) == len(digests)
+
+
+def test_positive_claim_vector_matches_actual_provider_and_schema():
+ case = VECTORS["claim_cases"][0]
+ engine = Engine(clock=lambda: FROZEN)
+ obj = engine.create(binding(), validity(), approval_id=case["submitted_claim"]["approval_id"],
+ required_count=2, pdp_digest=case["expected_pdp_digest"],
+ pdp_path=True, human_control=True)
+ engine.add_entry(obj.id, "human:one", principal_type="human")
+ assert engine.claim(obj.id)["valid_now"] is False
+ engine.add_entry(obj.id, "human:two", principal_type="human")
+ assert engine.claim(obj.id) == case["submitted_claim"]
+ from datetime import timedelta
+ engine.clock = lambda: FROZEN + timedelta(seconds=5)
+ assert engine.claim(obj.id) == case["observed_claim"]
+ assert case["submitted_claim"]["freshness"] != case["observed_claim"]["freshness"]
+ schema = json.loads((ROOT / "schemas/approval_claim.schema.json").read_text())
+ jsonschema.Draft202012Validator(schema, format_checker=jsonschema.FormatChecker()).validate(
+ case["observed_claim"])
+ engine.close()
diff --git a/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md b/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md
index 856ebc7..2a95d0d 100644
--- a/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md
+++ b/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md
@@ -26,6 +26,12 @@ state_hub_workstream_id: "4fa25ad5-f5d0-5592-aa59-085f8ee3edaf"
# APPROVAL-WP-0002 — Production readiness and consumer adoption
+2026-10-16 additional scoped demand before Access B2 implementation:
+CUST-WP-0080 selects T01/T05's authoritative claim/human-control/freshness and
+exact-source consumer contract review and producer fixtures only, tracked in
+APPROVAL-WP-0005. Existing residual/native statuses and authority gates remain;
+this does not activate other residual work, a consumer policy or live transport.
+
Move the completed first-cut engine spine into an authenticated, durable,
observable production service and prove one PEP integration end to end. This is
the residual production scope deliberately excluded from APPROVAL-WP-0001.
diff --git a/workplans/APPROVAL-WP-0005-access-claim-fact-contract.md b/workplans/APPROVAL-WP-0005-access-claim-fact-contract.md
new file mode 100644
index 0000000..abdb945
--- /dev/null
+++ b/workplans/APPROVAL-WP-0005-access-claim-fact-contract.md
@@ -0,0 +1,83 @@
+---
+id: APPROVAL-WP-0005
+type: workplan
+title: "Approval fact contract and reusable Go data adapter"
+domain: infotech
+repo: approval-engine
+status: active
+flavor: implementation
+owner: codex
+topic_slug: netkingdom
+created: "2026-10-16"
+updated: "2026-10-16"
+depends_on: []
+---
+
+CUST-WP-0080 explicitly selects the necessary Approval-WP-0002-T01/T05 source
+contract subset for the Access service HTTP B2 join. Initial scope is owner
+review and producer fixtures; subsequent explicit CUST-WP-0080 demand selects
+T03's pure reusable data adapter, agreed with Access before implementation.
+No broad residual activation, credential transport runtime, trust admission,
+policy eligibility or live action is included.
+
+## Review authoritative claim guarantees and publish thin consumer vectors
+
+```task
+id: APPROVAL-WP-0005-T01
+status: done
+priority: high
+```
+
+INTENT basis: factual exact-bound approval claims supplied to Access, never a
+second PDP. Source contract documents verified human-control semantics and their
+issuer admission limit, both original/subsequent observation bounds, exact
+native/PDP correspondence and immutable original submitted context. Producer
+vectors cover current lifecycle and canonical types. The superseded proposal's
+request-refresh design requires change; fresh facts are verified out-of-band.
+
+## Independently integrate owner contract and coordinate Access reader conformance
+
+```task
+id: APPROVAL-WP-0005-T02
+status: todo
+priority: high
+```
+
+Coordinator reviews/integrates these source records. Access owns the thin Go
+reader/normalization and conformance implementation under FLEX-WP-0024-T06;
+Secrets owns strict immutable handoff and Platform owns provider origin/custody
+and final client pin. Native issuer/profile and served-PEP obligations remain
+live under APPROVAL-WP-0002-T01/T05, with audit under T04. No new native residual
+is created, promoted or marked complete by these source-only fixtures.
+
+## Supply producer-owned reusable Go claim and native binding data adapter
+
+```task
+id: APPROVAL-WP-0005-T03
+status: done
+priority: high
+```
+
+Explicit bounded implementation demand after Access confirmed the exact module
+and raw-JSON API: adapters/go/approvalfact contains the existing Python-native
+five-field canonicalization port and strict human/PDP-path typed claim validation
+plus original/fresh fact matching. It is pure data code, not a source transport,
+credential runtime, policy evaluator or consume service. Fact means validated
+shape/correspondence, never authenticated provider origin.
+
+Fourteen pinned native vectors and 24 claim cases pass in Go, with strict
+duplicate/Unicode/type/expiry defenses and detached original bytes. A 14,114-case
+deterministic differential corpus matches actual Python producer canonical bytes
+and digests; Go race tests pass. This is source sample evidence, not exhaustive
+proof or native acceptance. An initial module toolchain selection failure and
+shared cache sandbox refusal are retained in preparation evidence; final module
+uses Access's existing Go1.26.7 and completed tests.
+
+Access explicitly retains the expected-native-raw-source correspondence gate:
+its current decoded float64 maps cannot recover Python float/int identity.
+The current pilot's raw resource may be used only with proof of no active target
+registry override plus exact existing tenant normalization. Other enrichment
+needs authoritative raw source/compiler representation. No numeric restriction,
+digest substitution, foreign review, runtime enable or live proof is invented.
+T02 still owns independent source integration/handoff; existing T01/T05 native
+residual obligations and actual Access conformance/integration remain unchanged.