From 4925a0219bb87c123ac9011846bf7544ae429b72 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 17:56:41 +0000 Subject: [PATCH 1/2] fix(k9): correct security levels + deploy pedigree so Validate K9 contracts passes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three K9 contract errors flagged by k9-validate: coordination.k9 and session/custom-checks.k9 set security_level "data-only", which is not a valid level (must be kennel|yard|hunt) — set to "kennel" to match their leash=Kennel and 'no network/write/subprocess' intent. container/deploy.k9.ncl: the validator scans for a word-boundary 'pedigree = {' block, but this template used 'let component_pedigree = {' (unmatched), so it fell back to the 'pedigree = component_pedigree' reference and reported name/version/security_level missing — renamed the binding to 'pedigree', added the top-level security_level="hunt" the header comment already promised, and updated the export reference. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01PWMMxryCcPrAjJ8tuGvygG --- container/deploy.k9.ncl | 5 +++-- coordination.k9 | 2 +- session/custom-checks.k9 | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/container/deploy.k9.ncl b/container/deploy.k9.ncl index 7a4da8b..c17458d 100644 --- a/container/deploy.k9.ncl +++ b/container/deploy.k9.ncl @@ -14,7 +14,7 @@ K9! # k9-svc deploy container/deploy.k9.ncl --env production # The component's pedigree (self-description across five layers) -let component_pedigree = { +let pedigree = { # Top-level identity fields — duplicated from metadata so the K9 # validator (which inspects the literal `pedigree = { ... }` block # at the toplevel of the file rather than the resolved Nickel value) @@ -22,6 +22,7 @@ let component_pedigree = { # `component_pedigree` indirection. name = "{{SERVICE_NAME}}-deploy", version = "{{VERSION}}", + security_level = "hunt", # ───────────────────────────────────────────────────────────── # L1: The Snout — Identity @@ -153,7 +154,7 @@ echo "K9: Rollback complete." # Export the component { - pedigree = component_pedigree, + pedigree = pedigree, deployment = deployment, scripts = scripts, diff --git a/coordination.k9 b/coordination.k9 index 9c4804d..a0666b8 100644 --- a/coordination.k9 +++ b/coordination.k9 @@ -10,7 +10,7 @@ pedigree = { schema_version = "1.0.0", component_type = "session-coordination", leash = "Kennel", - security_level = "data-only", + security_level = "kennel", } session_management: diff --git a/session/custom-checks.k9 b/session/custom-checks.k9 index b2f7338..6c8420b 100644 --- a/session/custom-checks.k9 +++ b/session/custom-checks.k9 @@ -10,7 +10,7 @@ pedigree = { schema_version = "1.0.0", component_type = "session-checks", leash = "Kennel", - security_level = "data-only", + security_level = "kennel", } version: "0.1" From fc09fad0fceea8200853a32eacb6dfcc289d4c6a Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 18:02:38 +0000 Subject: [PATCH 2/2] fix(k9): make deploy.k9.ncl pedigree a literal field the validator can read k9-validate scans for a line-anchored literal 'pedigree = {' field and cannot follow the 'let component_pedigree' indirection (it was matching the bare 'pedigree = component_pedigree' reference and reporting all fields missing). Inline a visible pedigree block with schema_version/component_type/security_level/metadata.name, merged (& component_pedigree) with the full L1-L5 pedigree so nothing is lost. Mirrors the passing template-hunt.k9.ncl shape. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01PWMMxryCcPrAjJ8tuGvygG --- container/deploy.k9.ncl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/container/deploy.k9.ncl b/container/deploy.k9.ncl index c17458d..30e6ddf 100644 --- a/container/deploy.k9.ncl +++ b/container/deploy.k9.ncl @@ -14,7 +14,7 @@ K9! # k9-svc deploy container/deploy.k9.ncl --env production # The component's pedigree (self-description across five layers) -let pedigree = { +let component_pedigree = { # Top-level identity fields — duplicated from metadata so the K9 # validator (which inspects the literal `pedigree = { ... }` block # at the toplevel of the file rather than the resolved Nickel value) @@ -22,7 +22,6 @@ let pedigree = { # `component_pedigree` indirection. name = "{{SERVICE_NAME}}-deploy", version = "{{VERSION}}", - security_level = "hunt", # ───────────────────────────────────────────────────────────── # L1: The Snout — Identity @@ -154,7 +153,19 @@ echo "K9: Rollback complete." # Export the component { - pedigree = pedigree, + pedigree = { + # k9-validate scans for a literal `pedigree = { … }` field (it cannot + # follow the `let component_pedigree` indirection). This visible block + # carries the required identity/security fields; `& component_pedigree` + # then layers on the full L1–L5 component pedigree. + schema_version = "1.0.0", + component_type = "deployment", + security_level = "hunt", + metadata = { + name = "{{SERVICE_NAME}}-deploy", + version = "{{VERSION}}", + }, + } & component_pedigree, deployment = deployment, scripts = scripts,