Skip to content

Commit aa596c8

Browse files
k9: deploy template render, Hunt capability grant, push-time K9 lane, K9-aware layout docs (#167)
## Why #166 was squash-merged at `85e71b2`. Two follow-up commits that fix four of its Codex review findings were pushed after the merge, so they missed it. The review threads were resolved as "fixed in dc04df7 / 882dd75", but `main` does not have those fixes. This PR lands them. The branch carries a merge of the #166 squash. Its diff against `main` is exactly those two commits: 7 files, +226/−147. ## What **`dc04df7`: deploy template, Hunt grant, push coverage** - **`panel-clades/container/deploy.k9.ncl.in`** - Replaced with the K9 contract v1.0.0 template ported from rsr-template-repo and adapted to this layout (`container/`, `compose.toml`). It has the `K9!` envelope, a capability grant, `side_effects`, and a signature block. - `just container-init` now renders it to `container/deploy.k9.ncl` once no `{{…}}` token is left. It never overwrites an existing file. - Before this, nothing created the `deploy.k9.ncl` that the docs use. - **`.machine_readable/svc/k9/template-hunt.k9.ncl.in`** - Grants `net.fetch`, `fs.write` and `process.spawn`, which its `allow_*` flags request (K9-S007). - Adds the Ed25519 presence block (K9-S009). - **`dogfood-gate.yml`** - Runs the standards K9-DEED lane on pushes to `main`/`master`, so a direct push is checked again. - Pull requests still run the lane once, in `fork-governance.yml`. - `actions.lock` records the call. **`882dd75`: layout docs** - **`layouts/README.adoc`** validates presets with `k9-validate.sh`, and evaluates the Nickel body with `tail -n +2 <preset> | nickel export`, run from `layouts/`. - The `K9!` envelope is not Nickel, so the old direct `nickel typecheck layouts/*.k9.ncl` no longer works. ## Verification (local, standards `1fdc61c`) - **K9 corpus:** 106 pass, 1 routed (`coordination.k9`), 0 fail. - **Templates:** - A Hunt template copy with its TODOs filled passes `--strict --layer L2`. - The deploy template, rendered via `just container-init` with sample values, passes L2. - **Layouts:** `logic-and-proofs` exports. A preset whose pane sizes do not sum to 100 is still rejected. - **Workflows:** - Every workflow parses. - The duplicate-key check is clean. - The lock gate, the lock validator and `update-actions-lock.sh --verify-local` pass. - **Build checks:** the panel-clades Justfile parses, and `gen-budgets.sh --check` reports current. ## Known, not in this PR - `governance / Allowlist Preflight` stays red until standards' allowlist gains `"metadatastician/*"`. - Fork-PR comment posting is being fixed upstream in standards. Once that merges, panll adds the `fork-governance-publish.yml` caller. --- _Generated by [Claude Code](https://claude.ai/code/session_01BCQeL169ZnUirUVaDXQLA3)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 86ddcee commit aa596c8

7 files changed

Lines changed: 226 additions & 147 deletions

File tree

‎.github/workflows/actions.lock‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ workflows:
2121
'.github/workflows/dogfood-gate.yml':
2222
- 'actions/checkout@v7.0.1'
2323
- 'hyperpolymath/deed-ecosystem@main'
24+
- 'metadatastician/standards@1fdc61c0c1c8f4c94324f956700d78d1ea9584a8'
2425
'.github/workflows/e2e.yml':
2526
- 'actions/checkout@v7.0.1'
2627
- 'dtolnay/rust-toolchain@v1'

‎.github/workflows/dogfood-gate.yml‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,24 @@ jobs:
6363
echo "Scanned **${MANIFEST_COUNT}** .a2ml/.deed manifest(s). See step output for details." >> "$GITHUB_STEP_SUMMARY"
6464
fi
6565
66-
# K9 contract validation moved to fork-governance.yml, which runs the
67-
# canonical K9-DEED conformance lane (metadatastician/standards
68-
# k9-conformance.yml, contract v1.0.0) and reports it in the PR comment.
69-
# The k9-ecosystem validate-action that ran here rejected the `K9!`
70-
# envelope the contract requires, so the two could not both pass.
66+
# ---------------------------------------------------------------------------
67+
# Job 2: K9-DEED conformance on pushes to main/master
68+
# ---------------------------------------------------------------------------
69+
# The canonical lane (metadatastician/standards k9-conformance.yml, contract
70+
# v1.0.0). Pull requests run it in fork-governance.yml, which reports it in
71+
# the PR comment, so it runs here on push only: a PR does not check twice,
72+
# and a direct push to main is still checked. It replaces the k9-ecosystem
73+
# validate-action, which rejected the `K9!` envelope the contract requires.
74+
k9-conformance:
75+
name: K9-DEED conformance (push)
76+
if: github.event_name == 'push'
77+
uses: metadatastician/standards/.github/workflows/k9-conformance.yml@1fdc61c0c1c8f4c94324f956700d78d1ea9584a8
78+
permissions:
79+
contents: read
80+
pull-requests: read
81+
with:
82+
require-files: true
83+
fail-on-indeterminate: false
7184

7285
# ---------------------------------------------------------------------------
7386
# Job 3: Empty-linter — invisible character detection

‎.machine_readable/svc/k9/template-hunt.k9.ncl.in‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ K9!
2727
allow_filesystem_write = true,
2828
allow_subprocess = true,
2929
signature_required = true,
30+
# Default-deny (K9-S007): each flag above must be granted here. Drop the
31+
# ones the component does not need, together with their flags.
32+
capabilities = [
33+
"net.fetch", # allow_network
34+
"fs.write", # allow_filesystem_write
35+
"process.spawn", # allow_subprocess
36+
],
3037
},
3138
metadata = {
3239
name = "TODO: component-name",
@@ -45,6 +52,12 @@ K9!
4552
"TODO: List what commands this executes",
4653
"TODO: List what network access this requires",
4754
],
55+
# Ed25519, presence only (K9-S009). Signing (step 6 below) adds
56+
# payload_hash and signature; verification is K9-C001 (L3).
57+
signature = {
58+
algorithm = "Ed25519",
59+
key_id = "TODO: signing-key-id",
60+
},
4861
},
4962

5063
# Configuration with contracts (Yard-level validation)

‎layouts/README.adoc‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,31 @@ The `pedigree-layout.ncl` schema enforces:
5454

5555
== Validating a Preset
5656

57+
Each preset is a K9 component: line 1 is the `K9!` envelope, which is not
58+
Nickel, so the `nickel` CLI cannot read the file directly. Validate it with
59+
the K9 validator, or evaluate the Nickel body (everything after line 1) from
60+
inside `layouts/` so the `./pedigree-layout.ncl` import resolves:
61+
5762
[source,bash]
5863
----
59-
nickel typecheck layouts/logic-and-proofs.k9.ncl
60-
nickel export layouts/logic-and-proofs.k9.ncl --format json
64+
# K9 contract v1.0.0 conformance (envelope, pedigree, and a body typecheck)
65+
k9-validate.sh --strict --layer L2 layouts/logic-and-proofs.k9.ncl
66+
67+
# Evaluate the preset against pedigree-layout.ncl's contracts
68+
cd layouts
69+
tail -n +2 logic-and-proofs.k9.ncl | nickel typecheck
70+
tail -n +2 logic-and-proofs.k9.ncl | nickel export --format json
6171
----
6272

73+
`k9-validate.sh` is standards' `1-formats/k9/tools/k9-validate.sh`; CI runs
74+
it on every PR through the K9-DEED conformance lane.
75+
6376
== Creating a Custom Layout
6477

6578
. Copy an existing preset
6679
. Modify pane sizes (must sum to 100)
6780
. Change panel visibility and prover priority
68-
. Run `nickel typecheck` to validate
81+
. Validate it as above (`k9-validate.sh`, then `nickel export` on the body)
6982

7083
Community-contributed presets are welcome — submit a PR with your `.k9.ncl`
7184
file and it will be validated against the pedigree schema automatically.

‎panel-clades/Justfile‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,26 @@ container-init:
529529
fi
530530
done
531531
532+
# The k9-svc deploy component ships as a template (deploy.k9.ncl.in): a
533+
# file with brace tokens is not a K9 component. Render it once nothing is
534+
# left to fill (init fills PROJECT_NAME and VERSION), so the K9 lane
535+
# validates the real thing. The bracket spellings keep just from reading
536+
# the token pattern as an interpolation.
537+
DEPLOY_IN="container/deploy.k9.ncl.in"
538+
DEPLOY_OUT="${DEPLOY_IN%.in}"
539+
if [ -f "$DEPLOY_IN" ]; then
540+
LEFT=$(grep -oE '[{][{][A-Za-z_]+[}][}]' "$DEPLOY_IN" | sort -u | tr '\n' ' ' || true)
541+
if [ -n "$LEFT" ]; then
542+
echo "Kept $DEPLOY_IN: unfilled tokens ${LEFT}remain."
543+
echo " Run 'just init', then 'just container-init' again to render it."
544+
elif [ -e "$DEPLOY_OUT" ]; then
545+
echo "Kept $DEPLOY_IN: $DEPLOY_OUT already exists, so it was not overwritten."
546+
else
547+
mv "$DEPLOY_IN" "$DEPLOY_OUT"
548+
echo "Rendered $DEPLOY_OUT (K9 component, contract v1.0.0)."
549+
fi
550+
fi
551+
532552
echo "Container templates initialised."
533553
echo ""
534554
echo "Next steps:"

‎panel-clades/container/README.adoc‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ All files use `container` tokens that are replaced by `just container-init`
6060
crash detection, resource thresholds, and log output.
6161

6262
| `deploy.k9.ncl.in`
63-
| **k9-svc** deployment component at Hunt trust level. Full pedigree
64-
(L1--L5), environment configs (dev/staging/prod), container
65-
configuration, and rolling deployment strategy.
63+
| **k9-svc** deployment component template at Hunt trust level (K9
64+
contract v1.0.0): pedigree with capability grant, side effects and a
65+
signature block, environment configs (dev/staging/prod), container
66+
configuration, and rolling deployment strategy. `just container-init`
67+
renders it to `deploy.k9.ncl`.
6668

6769
| `0-AI-MANIFEST.a2ml`
6870
| AI-readable manifest describing the container directory, file
@@ -154,8 +156,9 @@ For k9-svc managed deployments:
154156

155157
[source,bash]
156158
----
157-
# Validate the deployment component
158-
nickel typecheck container/deploy.k9.ncl # after rendering deploy.k9.ncl.in
159+
# `just container-init` renders deploy.k9.ncl.in to deploy.k9.ncl once
160+
# `just init` and it have filled every placeholder. Then validate it:
161+
k9-validate.sh --strict --layer L2 container/deploy.k9.ncl
159162
160163
# Deploy (requires Hunt-level authorisation)
161164
k9-svc deploy container/deploy.k9.ncl --env production

0 commit comments

Comments
 (0)