Skip to content

fix(k9): M1 contractile pedigrees + M2 PROTOCOL.k9 rename (#1058) - #1149

Merged
hyperpolymath merged 7 commits into
mainfrom
arena/01a10a3b-standards
Oct 5, 2026
Merged

hyperpolymath merged 7 commits into
mainfrom
arena/01a10a3b-standards

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Executes migration item M2 / issue #B of 1-formats/k9/spec/MIGRATION-1058.adoc (parent campaign: standards#1058).

Ruling

M2 offered two outcomes. Ruling: (a) rename off the reserved suffix. The twelve files are plain YAML session-management contracts: no Nickel body, no K9! envelope, no k9-coordination schema, and no K9 host loads them. Outcome (b) would mean inventing a dialect so a naming collision could keep its name. All twelve are now PROTOCOL.yaml; the K9 spec's extension reservation (§4.2) and the discriminator (K9-E005) stay intact.

What changed

  • Renames — 3-practice/session-management-standards/{continuity,handover,verify}/*/PROTOCOL.k9 → PROTOCOL.yaml (12 files, contents otherwise unchanged).
  • SPDX — the 11 files that lacked a header gained MPL-2.0, matching planned-session-close and the directory's other machine artefacts. *.yaml is inside .githooks/validate-spdx.sh's is_source_file scope, so without this the rename would have planted 11 files that fail the SPDX pre-commit gate on their next touch.
  • Ledger — .machine_readable/k9-contract-debt.txt 17 → 5 entries; nothing left to grandfather for this home (the renamed files leave the *.k9 population entirely).
  • Scorecard (session-management-standards.scorecard.a2ml)
    • repointed the dead 1-formats/k9/actions/validate/validate-k9.sh path (no such directory) at 1-formats/k9/tools/k9-validate.sh — this was the explicit ask in M2's note;
    • S1 re-graded fail → pass on the extension-reservation rule, with an executable check (git ls-files for *.k9/*.k9.ncl under the home) so the pass is grounded, not asserted;
    • M1–M4 and S4 suffix/line-count references refreshed; M4's stale 22 of 42 recount is now 19 of 51 (measured).
    • assessed_date 2026-07-03 → 2026-10-05.
  • Docs — README Protocol File Contract (item 2 = PROTOCOL.yaml, with the reservation rule cited), verify/substantial-completion/CHECKLIST.adoc (link + the wrong "K9 coordination format" wording), K9-CONTRACT-SPEC.adoc §4.2 (past tense; also fixes its "migration item M4" → M2), MIGRATION-1058.adoc §M2 (ruling recorded, note marked fixed), fixture/validator comments kept truthful, CI comment de-numbered.
  • Derived artefacts — REGISTRY.a2ml regenerated (source_hash is sha256(git ls-files -s <home>), so the rename moves it) and 0-canon/COMPLIANCE-DASHBOARD.adoc regenerated. The same regeneration also clears 3 pre-existing registry drifts (1-formats/k9, 2-protocols/axel, form-fill-provenance — the last was carrying the empty-string hash), so registry-check goes from red to green.

Verification

1-formats/k9/tools/k9-validate.sh --self-test          → all assertions passed
1-formats/k9/tools/k9-validate.sh --fixtures tools/fixtures → 5 positive, 21 negative (2 need nickel), 0 failures
bash .githooks/validate-k9.sh                          → 8 violations, 0 stale ledger entries
    (the 8 are the pre-existing contractile/Axel items owned by #A/#C/#D —
     no session-management path appears; 5 grandfather entries remain)
git ls-files '3-practice/session-management-standards/*.k9*' → 0
bash scripts/build-registry.sh --check                 → OK
bash scripts/build-scorecards.sh --check --strict      → OK
bash scripts/tests/build-registry-test.sh              → 9 passed, 0 failed
link-rot-guard diff vs a41f369                         → no new findings

scripts/tests/build-scorecards-test.sh reports 3 failures in this sandbox only because --verify's preflight refuses to judge passes without xmllint, which is not installable here; the scorecard's three pass-row checks were extracted and run directly (M5, S1, S2 → all exit 0).

Known-red context

The corpus K9 job runs .githooks/validate-k9.sh over the whole repo and exits non-zero on the 8 pre-existing violations above, which predate this PR and belong to sibling items #A (contractiles) and #D (Axel configs). This PR removes 12 errors from the reported population and adds none.

Refs: #1058 (M2 · #B).


M1 · #A also landed on this branch (added 2026-10-05)

6d96f8a — fix(k9): give contractiles a resolvable pedigree (M1, #1058) — rides on top of the M2 commit above: the branch is this session's branch, so #A's half of the fix could not land anywhere else.

What the six files now say. import "../k9/template-hunt.k9.ncl" (which resolved to nothing — there is no k9/ below .machine_readable/contractiles/) is replaced by base.pedigree_schema from ../_base.ncl, the file that actually defines it. Each of the six now declares §5.5's core — schema_version, component_type = "contractile:<verb>", semantics — plus the §8.4 security.capabilities that pay for its allow_* flags: process.spawn for all six (allow_subprocess), fs.write additionally for adjust and dust (the conditional write path). The four 'Hunt components (bust, intend, must, trust) gain signature_required, a signature block and 3 irreducible side_effects; the signature block is a claim, so the §10.2 verdict is 'Present_Unverified and §10.4 leaves Hunt unauthorised until the signing ceremony replaces it. variance_schema | not_exported because its fields are declarations with no definitions, and Nickel's export refuses a record containing one (missing field definition for \entry_id``).

The must naming collision, stated rather than implied. The collision is between K9's execution triad (must/just/nickel) and the contractiles family (must/trust/dust/intend). Resolution: the K9 contract never names a contractile verb. A contractile component is an ordinary K9 component whose component_type begins contractile: — that prefix is the entire tie, and it is the only name K9 machinery ever sees. DEED translation therefore renames nothing the K9 spec depends on, and the contractile family keeps its verbs.

'Yard vs 'Hunt for the two 'Yard verbs. adjust and dust request process.spawn (and fs.write) while sitting at 'Yard. §7.3 makes 'Yard pure evaluation, so those entries are requests recorded in the grant, not permissions in force: at 'Yard the leash is still the cap. Recording them is nonetheless mandatory — §8.4/K9-S007 makes a flag whose capability the grant does not cover a self-contradiction inside the pedigree, not a preference, and leaving the request unwritten would make the file lie about what it asks for.

Ledger. No re-listing and no re-grandfathering: no contractile path is in .machine_readable/k9-contract-debt.txt before or after this commit (count 5 entries, unchanged by #A). The removal of the six recorded in the ledger header is now backed by conforming files instead of being premature — before this commit the hook reported all six as hard FAILs precisely because they had no exemption and did not conform.

Verification (this branch, run 37262876162):

k9_contract.ncl typecheck                ok
--self-test                              ok  (all assertions passed)
--fixtures (--strict, Nickel on PATH)    ok  5 positive, 21 negative (0 needing nickel), 0 failures
corpus through the local hook            FAIL 2 violation(s), 0 stale
    the 2 are 2-protocols/axel/config/{ci,metadata}.k9.ncl (K9-S001) — #D/M4, untouched here
    (was 8: the six contractiles are gone from the report)

Locally: --layer L1 --json over the six → pass, 0 findings each; bash .githooks/validate-k9.sh → 2 violations, 0 stale.

Known L2 caveat for #F/M7 — recorded, not hidden. The corpus step runs the hook at L1, so the six were not evaluated against K9.Component in CI. §5.5 says unknown fields anywhere are PERMITTED and names the contractiles' own security.probe_scope / authorised_probes_only as legitimate extension fields — but k9_contract.ncl's Component, Pedigree and Security are Nickel record contracts, which are closed by default. Nickel's own record_contract_extra_field.ncl fixture is the EvalError::BlameError control for exactly this. So when #F raises the corpus to L2, a contractile would be blamed for the extension fields it keeps inside the pedigree — pedigree.semantics / contractile_verb / tier / authority / variance_schema / execution / failure_mode_defenses, and security.probe_scope / probe_kinds_* / allow_filesystem_write_conditional — i.e. on Pedigree and Security (M4's note records the same for Component, for components that keep a payload at top level). The fix belongs to #F and is a .. tail on those three records: the prose already permits the fields, and the contract's own header says the prose wins where the two disagree.

Docs. 47751ee records the resolution where the prose still called the six files broken: K9-CONTRACT-SPEC §11.2 (it claimed "no envelope" — the envelope was already there, and the item was misnumbered) and §11.4 (the dangling import), plus a "M1 — resolved" note in MIGRATION-1058 in the same shape M2/M3/M4 used. CI on 47751ee: run 37263079909 — identical K9 result (all steps green except the corpus step, still the two Axel files of #D).

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 22 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 62cb6e66-9384-4c5f-a940-033f3f1500ec
📥 Commits

Reviewing files that changed from the base of the PR and between c33b22b and 42bef07.

📒 Files selected for processing (33)
  • .github/workflows/k9-contractile.yml
  • .machine_readable/REGISTRY.a2ml
  • .machine_readable/contractiles/adjust/adjust.k9.ncl
  • .machine_readable/contractiles/bust/bust.k9.ncl
  • .machine_readable/contractiles/dust/dust.k9.ncl
  • .machine_readable/contractiles/intend/intend.k9.ncl
  • .machine_readable/contractiles/must/must.k9.ncl
  • .machine_readable/contractiles/trust/trust.k9.ncl
  • .machine_readable/k9-contract-debt.txt
  • .machine_readable/scorecards/session-management-standards.scorecard.a2ml
  • 0-canon/COMPLIANCE-DASHBOARD.adoc
  • 1-formats/k9/SPEC.adoc
  • 1-formats/k9/spec/K9-CONTRACT-SPEC.adoc
  • 1-formats/k9/spec/MIGRATION-1058.adoc
  • 1-formats/k9/spec/contract/k9_contract.ncl
  • 1-formats/k9/tools/README.adoc
  • 1-formats/k9/tools/fixtures/invalid/L0-K9-E005-unclaimed-body.k9.ncl
  • 1-formats/k9/tools/fixtures/valid/extension-fields.k9.ncl
  • 1-formats/k9/tools/k9-validate.sh
  • 3-practice/session-management-standards/README.adoc
  • 3-practice/session-management-standards/continuity/checkpoint-before-major-change/PROTOCOL.yaml
  • 3-practice/session-management-standards/continuity/emergency-termination/PROTOCOL.yaml
  • 3-practice/session-management-standards/continuity/planned-session-close/PROTOCOL.yaml
  • 3-practice/session-management-standards/continuity/recovery-operation/PROTOCOL.yaml
  • 3-practice/session-management-standards/continuity/repo-intake/PROTOCOL.yaml
  • 3-practice/session-management-standards/handover/collaborative-transfer/PROTOCOL.yaml
  • 3-practice/session-management-standards/handover/full-transfer/PROTOCOL.yaml
  • 3-practice/session-management-standards/handover/human-transfer/PROTOCOL.yaml
  • 3-practice/session-management-standards/handover/model-transfer/PROTOCOL.yaml
  • 3-practice/session-management-standards/verify/maintenance-sweep/PROTOCOL.yaml
  • 3-practice/session-management-standards/verify/release-audit/PROTOCOL.yaml
  • 3-practice/session-management-standards/verify/substantial-completion/CHECKLIST.adoc
  • 3-practice/session-management-standards/verify/substantial-completion/PROTOCOL.yaml
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37262479888

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 26 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 5 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance

[validate-k9] FAIL .machine_readable/contractiles/adjust/adjust.k9.ncl (fail) — K9-S002 K9-S003 K9-S007 K9-S013
[validate-k9] FAIL .machine_readable/contractiles/bust/bust.k9.ncl (fail) — K9-S002 K9-S003 K9-S007 K9-S008 K9-S009 K9-S010 K9-S013
[validate-k9] FAIL .machine_readable/contractiles/dust/dust.k9.ncl (fail) — K9-S002 K9-S003 K9-S007 K9-S013
[validate-k9] FAIL .machine_readable/contractiles/intend/intend.k9.ncl (fail) — K9-S002 K9-S003 K9-S007 K9-S008 K9-S009 K9-S010 K9-S013
[validate-k9] FAIL .machine_readable/contractiles/must/must.k9.ncl (fail) — K9-S002 K9-S003 K9-S007 K9-S008 K9-S009 K9-S010 K9-S013
[validate-k9] FAIL .machine_readable/contractiles/trust/trust.k9.ncl (fail) — K9-S002 K9-S003 K9-S007 K9-S008 K9-S009 K9-S010 K9-S013
[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] FAIL 2-protocols/axel/config/ci.k9.ncl (fail) — K9-S001
[validate-k9] FAIL 2-protocols/axel/config/metadata.k9.ncl (fail) — K9-S001
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 8 violation(s), 0 stale ledger entr(ies)
[validate-k9] spec: 1-formats/k9/spec/K9-CONTRACT-SPEC.adoc · plan: 1-formats/k9/spec/MIGRATION-1058.adoc

Copy link
Copy Markdown
Owner Author

Note for whoever merges the #A–#E batch: PR #1148 (#C) also edits .machine_readable/k9-contract-debt.txt and regenerates .machine_readable/REGISTRY.a2ml. Whichever of the two lands second needs a trivial rebase + re-run of just registry (ledger count line and the session-management/svc/k9 home hashes will conflict textually; the generator resolves the hashes). Neither PR depends on the other.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37262876162

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 26 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 5 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] FAIL 2-protocols/axel/config/ci.k9.ncl (fail) — K9-S001
[validate-k9] FAIL 2-protocols/axel/config/metadata.k9.ncl (fail) — K9-S001
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 2 violation(s), 0 stale ledger entr(ies)
[validate-k9] spec: 1-formats/k9/spec/K9-CONTRACT-SPEC.adoc · plan: 1-formats/k9/spec/MIGRATION-1058.adoc

@hyperpolymath hyperpolymath changed the title fix(k9): settle the PROTOCOL.k9 suffix collision — rename to PROTOCOL.yaml (#1058 M2/#B) fix(k9): M1 contractile pedigrees + M2 PROTOCOL.k9 rename (#1058) Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37263079909

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 26 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 5 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] FAIL 2-protocols/axel/config/ci.k9.ncl (fail) — K9-S001
[validate-k9] FAIL 2-protocols/axel/config/metadata.k9.ncl (fail) — K9-S001
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 2 violation(s), 0 stale ledger entr(ies)
[validate-k9] spec: 1-formats/k9/spec/K9-CONTRACT-SPEC.adoc · plan: 1-formats/k9/spec/MIGRATION-1058.adoc

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37263205797

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 26 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 5 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] FAIL 2-protocols/axel/config/ci.k9.ncl (fail) — K9-S001
[validate-k9] FAIL 2-protocols/axel/config/metadata.k9.ncl (fail) — K9-S001
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 2 violation(s), 0 stale ledger entr(ies)
[validate-k9] spec: 1-formats/k9/spec/K9-CONTRACT-SPEC.adoc · plan: 1-formats/k9/spec/MIGRATION-1058.adoc

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37263947191

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-N001 K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 13 conforming, 5 grandfathered (layer all, contract v1.0.0)

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37264039138

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-N001 K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 13 conforming, 5 grandfathered (layer all, contract v1.0.0)

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37264301468

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-N001 K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 13 conforming, 5 grandfathered (layer all, contract v1.0.0)

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37264400793

K9 fmt probe (temporary)

diff (unformatted -> formatted)

--- 1-formats/k9/spec/contract/k9_contract.ncl	2026-10-05 04:38:36.445798949 +0000
+++ /dev/fd/63	2026-10-05 04:38:41.300978720 +0000
@@ -1,509 +0,0 @@
-# SPDX-License-Identifier: MPL-2.0
-# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
-#
-# k9_contract.ncl — THE NORMATIVE K9 COMPONENT CONTRACT (v1.0.0).
-#
-# Ruling D173 (standards#1058, 2026-09-30): "K9 needs a Nickel contract, not an
-# ABNF." This file is that contract. It is normative; the prose that governs it
-# is ../K9-CONTRACT-SPEC.adoc, and where the two disagree the prose wins and
-# this file is a bug.
-#
-# WHAT THIS FILE IS
-#   The closed, versioned, machine-checkable shape of a K9 component's
-#   `pedigree` block, plus the decision functions a host must consult before
-#   it lets a component do anything:
-#
-#     leash_levels / is_leash      §7  the leash taxonomy as a CLOSED set
-#     required_capabilities        §8  what a security flag costs you
-#     granted_ok / denied          §8  default-deny capability arithmetic
-#     authorize_hunt               §9  all five preconditions, always
-#     signature_verdict            §10 presence is NOT verification
-#
-# WHAT THIS FILE IS NOT
-#   * It is not a grammar. K9 has no syntax of its own: the body of a
-#     `.k9.ncl` file is a Nickel term and Nickel's grammar is normative by
-#     reference (K9-CONTRACT-SPEC §3.5). Re-specifying it here, in ABNF or
-#     otherwise, would fork a language we do not own.
-#   * It is not a validator. A contract states what holds; the canonical
-#     validator (../../tools/k9-validate.sh) decides whether a check could be
-#     run at all, and reports a check it could not run as SKIPPED rather than
-#     as a pass.
-#   * It does not verify signatures. Nickel has no cryptographic primitive,
-#     so nothing in this file can produce `signature_check = 'Passed`. See
-#     §10: an implementation that has not run a verifier MUST report 'Not_Run,
-#     and 'Not_Run can never authorise Hunt.
-#
-# NAMING HAZARD — carried from SPEC.adoc, unchanged:
-#   K9's execution triad is  must / just / nickel.
-#   The contractiles family is  must / trust / dust / intend.
-#   `must` appears in both and means different things. Never conflate them.
-#   Nothing in this file names a contractile verb; a contractile component is
-#   an ordinary K9 component whose `component_type` begins "contractile:".
-#
-# API SURFACE DISCIPLINE
-#   Every std function used below is one already exercised by a `.ncl` file
-#   this repository typechecks in CI (capabilities.ncl, leash.ncl,
-#   pedigree.ncl): std.string.length, std.string.substring, std.string.split,
-#   std.string.join, std.array.length, std.array.any, std.array.filter,
-#   std.record.has_field, std.contract.from_predicate. A normative artefact
-#   must not be the first thing in the estate to touch an unexercised corner
-#   of a dependency's standard library.
-#
-# ─────────────────────────────────────────────────────────────────────────
-# Type aliases (top-level `let` — the idiom pedigree.ncl and leash.ncl use)
-# ─────────────────────────────────────────────────────────────────────────
-
-# §7 — the leash taxonomy. CLOSED: three members, and adding a fourth is a
-# MAJOR change to this contract, not an extension.
-let SecurityLevel = [| 'Kennel, 'Yard, 'Hunt |] in
-
-# §10 — the result of an attempted cryptographic check. 'Not_Run is the honest
-# default and it is load-bearing: it is the value a validator reports when no
-# verifier was available, and it must never be silently upgraded.
-let SignatureCheck = [| 'Not_Run, 'Passed, 'Failed |] in
-
-# §10 — what a host may infer from "does the file carry a signature block"
-# (lexical) combined with "did a verifier accept it" (cryptographic).
-let SignatureVerdict = [| 'Absent, 'Present_Unverified, 'Verified, 'Rejected |] in
-
-# §8.1 — the reserved extension namespace prefix.
-let ExtensionPrefix = "x-" in
-
-# ─────────────────────────────────────────────────────────────────────────
-# §5.2 / §8.1 — name shapes, using nothing beyond length and substring
-# ─────────────────────────────────────────────────────────────────────────
-
-let is_digit = fun c =>
-  c == "0"
-    || c == "1"
-    || c == "2"
-    || c == "3"
-    || c == "4"
-    || c == "5"
-    || c == "6"
-    || c == "7"
-    || c == "8"
-    || c == "9" in
-
-# A numeric dot-triple whose MAJOR segment equals `major`. Walks the string
-# once. Rejects: non-digits, a leading or trailing dot, an empty segment, a
-# leading zero in any segment ("1.00.0"), and the wrong number of segments.
-#
-# `prev_dot` starts TRUE so a leading "." is refused by the same branch that
-# refuses ".."; `seg_len` must end > 0 so a trailing "." is refused too.
-let is_semver_of = fun major v =>
-  let want = major ++ "." in
-  let rec go = fun i dots seg_len first_zero s =>
-    if i >= std.string.length s then
-      dots == 2 && seg_len > 0
-    else
-      # `substring start end str`, NOT (start, length, str): 1.18.0's
-      # std.ncl documents `substring start end str` as the slice from `start`
-      # (included) to `end` (excluded), so the single character at `i` is
-      # `substring i (i + 1) s`. Written as `substring i 1 s` it returned "1"
-      # at i=0 by coincidence and "" at every later index, so the walk fell
-      # out at the second character and `is_semver_of` rejected "1.0.0" —
-      # every positive control with it. Verified against core/stdlib/std.ncl.
-      let c = std.string.substring i (i + 1) s in
-      if c == "." then
-        seg_len > 0 && go (i + 1) (dots + 1) 0 false s
-      else if is_digit c then
-        (first_zero == false || seg_len == 0)
-          && go (i + 1) dots (seg_len + 1) (c == "0") s
-      else
-        false
-  in
-  # A dot-triple is at least `want` plus "N.N": three more characters.
-  std.string.length v >= (std.string.length want + 3)
-    && std.string.substring 0 (std.string.length want) v == want
-    && go 0 0 0 false v in
-
-# ─────────────────────────────────────────────────────────────────────────
-# The contract record. Nickel records are recursive, so fields below refer to
-# their siblings by name; the type aliases above stay top-level so no field
-# ever shadows the binding it is defined in terms of.
-# ─────────────────────────────────────────────────────────────────────────
-{
-  # ── §5 Identity and versioning ───────────────────────────────────────
-  #
-  # `contract_version` is the version of THIS file. `schema_major` is the
-  # major segment a conforming component's `pedigree.schema_version` must
-  # carry to be readable by this contract. They are separate numbers on
-  # purpose: this contract can be revised (1.0.0 -> 1.0.1) without changing
-  # what a component must look like.
-  contract_name = "k9-svc-component",
-  contract_version = "1.0.0",
-  schema_major = "1",
-
-  # §4 — the dialects a K9 envelope may carry. A file whose body is not one of
-  # these is not a K9 file, whatever its suffix says.
-  dialect = {
-    # `K9!` envelope + Nickel body declaring a `pedigree`. In scope here.
-    component = "k9-svc-component",
-    # No `K9!` envelope, Nickel body, no top-level `pedigree`. Imported, never
-    # executed. In scope for §11 only.
-    library = "k9-svc-library",
-    # `K9!` envelope + YAML body. Governed by
-    # 2-protocols/k9-coordination/spec/abnf/coordination-k9-grammar_v1.1.abnf,
-    # NOT by this contract. Named here so a validator can route it instead of
-    # misreporting it as a broken component.
-    coordination = "k9-coordination",
-  },
-
-  # ── §7 Leash taxonomy — CLOSED SET ───────────────────────────────────
-  #
-  # Machine-checkable enumeration of the three levels in ascending order of
-  # what they permit. This list IS the closed set the prose promises, and it
-  # lives in the same file as the `SecurityLevel` enum it mirrors so the two
-  # cannot drift silently; the conformance suite asserts they agree.
-  leash_levels = ['Kennel, 'Yard, 'Hunt],
-
-  # Total order over the closed set. Used for the monotonicity rule (§7.4): a
-  # host may enforce a level STRICTER than the component declares, never laxer.
-  level_rank = fun l =>
-    if l == 'Kennel then
-      0
-    else if l == 'Yard then
-      1
-    else
-      2,
-
-  is_leash = fun v =>
-    std.array.length (std.array.filter (fun l => l == v) leash_levels) == 1,
-
-  # The leash a component DECLARES. Fail-closed: a pedigree with no readable
-  # `security.leash` ranks as 'Kennel here, and is rejected outright by the
-  # Pedigree contract below. This helper exists so a host handed a partial
-  # pedigree cannot crash on it.
-  leash_of = fun pedigree =>
-    if std.record.has_field "security" pedigree
-      && std.record.has_field "leash" pedigree.security
-    then
-      pedigree.security.leash
-    else
-      'Kennel,
-
-  # ── §8 Capability model — DEFAULT-DENY ───────────────────────────────
-  #
-  # §8.1 CLOSED CORE SET. Exhaustive for the core namespace. Adding or
-  # removing a name here is a MAJOR change to this contract.
-  core_capabilities = [
-    "fs.read",
-    "fs.write",
-    "net.fetch",
-    "process.spawn",
-    "container.run",
-    "secret.read",
-    "deploy.apply",
-    "rollback.apply",
-  ],
-
-  # §8.1 RESERVED EXTENSION NAMESPACE. Non-core names MUST be "x-<vendor>.<p>"
-  # so they can never collide with a future core name.
-  extension_prefix = ExtensionPrefix,
-
-  is_core = fun name => std.array.any (fun c => c == name) core_capabilities,
-
-  # A well-formed extension: starts with the prefix and has at least one "."
-  # after the vendor segment, i.e. "x-vendor.something", never bare "x-vendor".
-  is_extension = fun name =>
-    std.string.length name > std.string.length ExtensionPrefix
-      && std.string.substring 0 (std.string.length ExtensionPrefix) name
-        == ExtensionPrefix
-      && std.array.length (std.string.split "." name) >= 2,
-
-  Capability = std.contract.from_predicate (fun name =>
-    is_core name || is_extension name
-  ),
-
-  # An explicit allow-list. DEFAULT-DENY is expressed by the empty grant: it
-  # permits nothing, and "nothing" is the correct answer for an absent grant.
-  CapabilityGrant = Array Capability,
-
-  default_grant = [],
-
-  permits = fun grant name => std.array.any (fun g => g == name) grant,
-
-  denied = fun grant requested =>
-    std.array.filter (fun r => !(permits grant r)) requested,
-
-  granted_ok = fun grant requested =>
-    std.array.length (denied grant requested) == 0,
-
-  # §8.4 DERIVED REQUIREMENTS — the rule that makes the grant load-bearing.
-  #
-  # A security flag is a REQUEST for a capability, and a request the grant
-  # does not cover is a contradiction inside the pedigree, not a preference.
-  # `allow_network = true` with an empty grant is therefore INVALID, not
-  # merely unwise: the component asks for the network while granting itself
-  # nothing. This STRENGTHENS the pre-#1058 state, where the flags and the
-  # grant were two unrelated opinions in the same block.
-  required_capabilities = fun security =>
-    (
-      if std.record.has_field "allow_network" security
-        && security.allow_network
-      then
-        ["net.fetch"]
-      else
-        []
-    )
-      @ (
-        if std.record.has_field "allow_filesystem_write" security
-          && security.allow_filesystem_write
-        then
-          ["fs.write"]
-        else
-          []
-      )
-      @ (
-        if std.record.has_field "allow_subprocess" security
-          && security.allow_subprocess
-        then
-          ["process.spawn"]
-        else
-          []
-      ),
-
-  # What the grant fails to cover. Empty iff the pedigree is self-consistent.
-  grant_deficit = fun grant security =>
-    denied grant (required_capabilities security),
-
-  # ── §9 Hunt preconditions — ALL FIVE, ALWAYS ─────────────────────────
-  #
-  # Owner directive 2026-06-03, restated and NOT RELAXED by this contract:
-  # Hunt requires all five, always. There is no configurable subset, and a
-  # valid signature alone is not sufficient. Reproduced from leash.ncl
-  # verbatim so the two cannot drift; the conformance suite asserts equality.
-  hunt_preconditions = [
-    "signature",
-    "policy",
-    "sandbox",
-    "dry_run",
-    "capability_grant",
-  ],
-
-  # The host supplies one Bool of EVIDENCE per precondition. Evidence is
-  # runtime fact, not a static component field — which is why `check_level`
-  # in leash.ncl can never authorise Hunt on its own.
-  # Host-side, and deliberately CLOSED unlike the component-facing records
-  # above: §9.2 says the host supplies one Boolean of evidence per
-  # precondition, so a misspelt evidence field must be an error rather than a
-  # silently ignored precondition. §5.5's openness is about a *component's*
-  # fields.
-  HuntEvidence = {
-    signature | Bool,
-    policy | Bool,
-    sandbox | Bool,
-    dry_run | Bool,
-    capability_grant | Bool,
-  },
-
-  # §9.2 The gate. Identical semantics to leash.ncl `authorize_hunt`, and
-  # deliberately so: a host implementing this file and a host implementing
-  # leash.ncl must reach the same verdict on the same evidence.
-  authorize_hunt = fun evidence =>
-    let unmet =
-      (if evidence.signature then [] else ["signature"])
-        @ (if evidence.policy then [] else ["policy"])
-        @ (if evidence.sandbox then [] else ["sandbox"])
-        @ (if evidence.dry_run then [] else ["dry_run"])
-        @ (if evidence.capability_grant then [] else ["capability_grant"])
-    in
-    if std.array.length unmet == 0 then
-      {
-        permitted = true,
-        enforced_level = 'Hunt,
-        unmet_preconditions = [],
-      }
-    else
-      {
-        permitted = false,
-        enforced_level = 'Yard,
-        reason =
-          "Hunt requires all five preconditions; unmet: "
-            ++ std.string.join ", " unmet,
-        unmet_preconditions = unmet,
-      },
-
-  # ── §10 Signature semantics — PRESENCE IS NOT VERIFICATION ───────────
-  #
-  # A `signature` block in a pedigree is a CLAIM. Reading it proves the file
-  # says it was signed. It does not prove the file was signed, and it does not
-  # prove the signature covers the bytes about to be executed.
-  signature_checks = ['Not_Run, 'Passed, 'Failed],
-  signature_verdicts = ['Absent, 'Present_Unverified, 'Verified, 'Rejected],
-
-  # §10.2 — the only mapping a conforming implementation may make.
-  #   no block                 -> 'Absent             (nothing was claimed)
-  #   block, verifier passed   -> 'Verified           (cryptographic fact)
-  #   block, verifier rejected -> 'Rejected           (cryptographic fact)
-  #   block, no verifier ran   -> 'Present_Unverified (lexical fact ONLY)
-  #
-  # Note what is absent from that table: there is no input that turns
-  # 'Not_Run into 'Verified. An implementation cannot infer verification from
-  # presence, and a validator that reports 'Verified without having run a
-  # verifier is non-conforming (§10.3).
-  signature_verdict = fun has_block check =>
-    if has_block == false then
-      'Absent
-    else if check == 'Passed then
-      'Verified
-    else if check == 'Failed then
-      'Rejected
-    else
-      'Present_Unverified,
-
-  # §10.4 — the Hunt `signature` precondition is satisfiable by 'Verified and
-  # by nothing else. Presence yields 'Present_Unverified, which is false here.
-  # This is the line that stops a lexical check from becoming an execution
-  # licence, and it is the reason this contract cannot be replaced by a grep.
-  hunt_signature_evidence = fun verdict => verdict == 'Verified,
-
-  # The signature block a component MAY carry. Every field but `algorithm` is
-  # optional at the CONTRACT level, because §10.1 makes presence a per-leash
-  # rule rather than a universal one: 'Kennel and 'Yard components are
-  # ordinarily unsigned, and that is correct rather than a defect.
-  Signature = {
-    algorithm | String | default = "Ed25519",
-    public_key | String | optional,
-    signature | String | optional,
-    payload_hash | String | optional,
-    signed_at | String | optional,
-    key_id | String | default = "primary",
-    # §5.5 — unknown fields are PERMITTED; see the `..` block above `Metadata`.
-    # A host that reads `signature.public_key` MUST NOT be the reason a future
-    # `counter_signature` field is rejected.
-    ..
-  },
-
-  # ── §6 The component pedigree, v1 ────────────────────────────────────
-  #
-  # Field-for-field this is the shape the estate's `.k9.ncl` components
-  # actually carry (`.machine_readable/svc/k9/template-*.k9.ncl`), with two
-  # normative tightenings: `component_type` is REQUIRED (§6.2), and the
-  # security flags must be paid for in the capability grant (§8.4).
-  #
-  # ── THE `..` TAIL, AND WHY EVERY COMPONENT-FACING RECORD HERE HAS ONE ──
-  #
-  # §5.5's table ends with "Unknown fields anywhere | PERMITTED. A reader SHOULD
-  # report them and MUST NOT consult them to relax any requirement of §8 or §9."
-  # That is normative prose, and by this file's own first rule the prose wins:
-  # where the two disagree, this file is the bug.
-  #
-  # They disagreed until 2026-10-05. A Nickel record contract is CLOSED by
-  # default — the sharp edge is recorded in Nickel's own integration suite,
-  # core/tests/integration/inputs/contracts/record_contract_extra_field.ncl,
-  # which asserts `EvalError::BlameError` with the message "extra field" and
-  # advises appending `, ..`. So a component carrying a legitimate extension
-  # field was blamed by this file while §5.5 permitted the field. The six
-  # `.machine_readable/contractiles/*/*.k9.ncl` components are the live case
-  # (they keep `semantics`, `contractile_verb`, `tier`, `authority`,
-  # `variance_schema`, `execution`, `failure_mode_defenses` in the pedigree;
-  # `probe_scope`, `probe_kinds_*`, `allow_filesystem_write_conditional` in
-  # security; `paired_xfile`, `paired_runner` in metadata), and
-  # `2-protocols/axel/config/*.k9.ncl` keep their payload at top level.
-  #
-  # Opening these five records is a CONFORMANCE fix, not a contract revision:
-  # the specified contract (the prose) never changed, so `contract_version`
-  # stays 1.0.0. It does not weaken §8 or §9 either — §5.5's own last clause
-  # forbids that, and the validator enforces the capability arithmetic over the
-  # extracted facts whatever an extension field claims (K9-S007, K9-S008).
-  #
-  # The positive control `tools/fixtures/valid/extension-fields.k9.ncl` exists
-  # so this cannot silently regress: it fails at L2 the moment any of these
-  # records closes again.
-
-  Metadata = {
-    name | String,
-    version | String | default = "0.0.0",
-    description | String | optional,
-    author | String | optional,
-    # §5.5 — see the block comment above. The estate's contractiles add
-    # `paired_xfile` / `paired_runner` here.
-    ..
-  },
-
-  Security = {
-    # §7 — closed set. An unknown LEASH TAG is a contract violation, not a
-    # warning; an unknown FIELD in this block is §5.5's business.
-    leash | SecurityLevel,
-    trust_level | String | default = "unset",
-    allow_network | Bool | default = false,
-    allow_filesystem_write | Bool | default = false,
-    allow_subprocess | Bool | default = false,
-    # §10.1 — REQUIRED to be true when leash == 'Hunt. The validator enforces
-    # the implication; this contract cannot, because it is a cross-field rule.
-    signature_required | Bool | default = false,
-    # §8.3 — the explicit grant. Default-deny: absent means empty.
-    capabilities | CapabilityGrant | default = [],
-    # §5.5 — unknown fields are PERMITTED, and the prose names this block's own
-    # examples: "the estate's contractiles use `probe_scope` and
-    # `authorised_probes_only`". No conforming reader may let one of them
-    # weaken §8 or §9 — the grant above is what a host enforces.
-    ..
-  },
-
-  Pedigree = {
-    # §5.2 — a numeric dot-triple whose major segment equals `schema_major`.
-    # A component from another major is not "older"; it is unreadable, and
-    # must be refused rather than guessed at (§5.4).
-    schema_version | std.contract.from_predicate (is_semver_of schema_major),
-    # §6.2 — REQUIRED: what this component IS. A template placeholder is not
-    # a value; the canonical validator rejects "TODO" here at L1.
-    component_type | String,
-    security | Security,
-    metadata | Metadata,
-    # §6.5 — advisory to a reader, mandatory to declare. A 'Hunt component
-    # with an empty side_effects list claims full system access and describes
-    # none of it, which the validator rejects at L1.
-    warnings | Array String | default = [],
-    side_effects | Array String | default = [],
-    # §10.1 — the signature claim. Presence is per-leash; see Signature above.
-    signature | Signature | optional,
-    # §5.5 — unknown fields are PERMITTED. This is the line MIGRATION-1058 M1
-    # turned on: the contractile family keeps its own vocabulary in the pedigree
-    # (`semantics`, `contractile_verb`, `tier`, `authority`, `variance_schema`,
-    # `execution`, `failure_mode_defenses`), and nothing in this file may force
-    # those names out of it.
-    ..
-  },
-
-  # The whole component: the pedigree plus the optional Nickel payload.
-  # `config`, `recipes` and `validation` stay open on purpose — they are the
-  # component's own business — but §6.7 makes one thing non-negotiable: a
-  # non-empty `recipes` block is an execution surface and therefore forces
-  # 'Hunt. The validator enforces that; this contract only shapes the blocks.
-  Component = {
-    pedigree | Pedigree,
-    # An open record: any fields, any values. These three blocks are the
-    # component's own business and the contract deliberately does not shape
-    # them — §6.7's `recipes`-forces-'Hunt rule is enforced by the validator
-    # over the extracted facts, not by a type here.
-    #
-    # Two names were tried and rejected by Nickel before this one: `Record`
-    # and then `Any`. Neither exists; the dynamic type is `Dyn`. Both failures
-    # were invisible locally — no nickel binary is obtainable in the sandbox
-    # that wrote this file — and both made every L2 verdict downstream void,
-    # because a contract that does not typecheck cannot judge anything. That
-    # is why k9-contractile.yml now typechecks this file as its own named step
-    # before the fixtures run.
-    config | { _ : Dyn } | optional,
-    recipes | { _ : Dyn } | optional,
-    validation | { _ : Dyn } | optional,
-    # §5.5 — unknown fields are PERMITTED at top level too, which is the case
-    # MIGRATION-1058 M4 recorded for whoever first ran the corpus at L2:
-    # `2-protocols/axel/config/*.k9.ncl` keep their payload (`ci`, `local_dev`,
-    # `quality`; `metadata.k9.ncl`: `project`, `tech_stack`, `deployment`,
-    # `features`, `status`) beside `pedigree`.
-    ..
-  },
-
-  # ── §11 Library dialect ──────────────────────────────────────────────
-  #
-  # A library is imported; it is never executed as a component and never
-  # carries an envelope. The contract it must satisfy is the negative one:
-  # no pedigree, no leash claim, no execution licence of any kind.
-  is_library = fun lib =>
-    !(std.record.has_field "pedigree" lib)
-      && !(std.record.has_field "leash" lib),
-}

formatted file, base64 -w 100

idempotence

idempotent: yes

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-N001 K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 13 conforming, 5 grandfathered (layer all, contract v1.0.0)

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37264538561

K9 fmt probe (temporary)

nickel format --help (first lines)

Formats Nickel files

Usage: nickel format [OPTIONS] [FILES]...

Arguments:
  [FILES]...
          Input files. Omit to read from stdin. If multiple files are provided, the corresponding
          Nickel expressions are merged (combined with `&`) to produce the result

Options:
      --apply-contract <APPLY_CONTRACT>
          Validates the final configuration against a contract specified as a Nickel file. If this
          argument is used multiple times, all specified contracts will be applied sequentially

      --color <COLOR>
          Configure when to output messages in color
          
          [default: auto]
          [possible values: auto, always, never]

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37264691994

K9 fmt probe (temporary)

formatted bytes / sha256

exit=0
24245
d68f75cb5662bd2af9b219203b43e6ecd84270a15612b8bb5018bc7e98608c7b  /home/runner/work/_temp/formatted.ncl
stderr:

diff (unformatted -> formatted)

--- 1-formats/k9/spec/contract/k9_contract.ncl	2026-10-05 04:42:38.189676676 +0000
+++ /home/runner/work/_temp/formatted.ncl	2026-10-05 04:42:43.295666817 +0000
@@ -72,18 +72,18 @@
 # ─────────────────────────────────────────────────────────────────────────
 # §5.2 / §8.1 — name shapes, using nothing beyond length and substring
 # ─────────────────────────────────────────────────────────────────────────
-
 let is_digit = fun c =>
   c == "0"
-    || c == "1"
-    || c == "2"
-    || c == "3"
-    || c == "4"
-    || c == "5"
-    || c == "6"
-    || c == "7"
-    || c == "8"
-    || c == "9" in
+  || c == "1"
+  || c == "2"
+  || c == "3"
+  || c == "4"
+  || c == "5"
+  || c == "6"
+  || c == "7"
+  || c == "8"
+  || c == "9"
+in
 
 # A numeric dot-triple whose MAJOR segment equals `major`. Walks the string
 # once. Rejects: non-digits, a leading or trailing dot, an empty segment, a
@@ -109,14 +109,15 @@
         seg_len > 0 && go (i + 1) (dots + 1) 0 false s
       else if is_digit c then
         (first_zero == false || seg_len == 0)
-          && go (i + 1) dots (seg_len + 1) (c == "0") s
+        && go (i + 1) dots (seg_len + 1) (c == "0") s
       else
         false
   in
   # A dot-triple is at least `want` plus "N.N": three more characters.
   std.string.length v >= (std.string.length want + 3)
-    && std.string.substring 0 (std.string.length want) v == want
-    && go 0 0 0 false v in
+  && std.string.substring 0 (std.string.length want) v == want
+  && go 0 0 0 false v
+in
 
 # ─────────────────────────────────────────────────────────────────────────
 # The contract record. Nickel records are recursive, so fields below refer to
@@ -177,8 +178,7 @@
   # pedigree cannot crash on it.
   leash_of = fun pedigree =>
     if std.record.has_field "security" pedigree
-      && std.record.has_field "leash" pedigree.security
-    then
+    && std.record.has_field "leash" pedigree.security then
       pedigree.security.leash
     else
       'Kennel,
@@ -208,13 +208,13 @@
   # after the vendor segment, i.e. "x-vendor.something", never bare "x-vendor".
   is_extension = fun name =>
     std.string.length name > std.string.length ExtensionPrefix
-      && std.string.substring 0 (std.string.length ExtensionPrefix) name
-        == ExtensionPrefix
-      && std.array.length (std.string.split "." name) >= 2,
-
-  Capability = std.contract.from_predicate (fun name =>
-    is_core name || is_extension name
-  ),
+    && std.string.substring 0 (std.string.length ExtensionPrefix) name == ExtensionPrefix
+    && std.array.length (std.string.split "." name) >= 2,
+
+  Capability =
+    std.contract.from_predicate (fun name =>
+      is_core name || is_extension name
+    ),
 
   # An explicit allow-list. DEFAULT-DENY is expressed by the empty grant: it
   # permits nothing, and "nothing" is the correct answer for an absent grant.
@@ -241,28 +241,25 @@
   required_capabilities = fun security =>
     (
       if std.record.has_field "allow_network" security
-        && security.allow_network
-      then
+      && security.allow_network then
         ["net.fetch"]
       else
         []
     )
-      @ (
-        if std.record.has_field "allow_filesystem_write" security
-          && security.allow_filesystem_write
-        then
-          ["fs.write"]
-        else
-          []
-      )
-      @ (
-        if std.record.has_field "allow_subprocess" security
-          && security.allow_subprocess
-        then
-          ["process.spawn"]
-        else
-          []
-      ),
+    @ (
+      if std.record.has_field "allow_filesystem_write" security
+      && security.allow_filesystem_write then
+        ["fs.write"]
+      else
+        []
+    )
+    @ (
+      if std.record.has_field "allow_subprocess" security
+      && security.allow_subprocess then
+        ["process.spawn"]
+      else
+        []
+    ),
 
   # What the grant fails to cover. Empty iff the pedigree is self-consistent.
   grant_deficit = fun grant security =>
@@ -304,10 +301,10 @@
   authorize_hunt = fun evidence =>
     let unmet =
       (if evidence.signature then [] else ["signature"])
-        @ (if evidence.policy then [] else ["policy"])
-        @ (if evidence.sandbox then [] else ["sandbox"])
-        @ (if evidence.dry_run then [] else ["dry_run"])
-        @ (if evidence.capability_grant then [] else ["capability_grant"])
+      @ (if evidence.policy then [] else ["policy"])
+      @ (if evidence.sandbox then [] else ["sandbox"])
+      @ (if evidence.dry_run then [] else ["dry_run"])
+      @ (if evidence.capability_grant then [] else ["capability_grant"])
     in
     if std.array.length unmet == 0 then
       {
@@ -321,7 +318,7 @@
         enforced_level = 'Yard,
         reason =
           "Hunt requires all five preconditions; unmet: "
-            ++ std.string.join ", " unmet,
+          ++ std.string.join ", " unmet,
         unmet_preconditions = unmet,
       },
 
@@ -505,5 +502,5 @@
   # no pedigree, no leash claim, no execution licence of any kind.
   is_library = fun lib =>
     !(std.record.has_field "pedigree" lib)
-      && !(std.record.has_field "leash" lib),
+    && !(std.record.has_field "leash" lib),
 }

formatted file, base64 -w 100

IyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTVBMLTIuMAojIFNQRFgtRmlsZUNvcHlyaWdodFRleHQ6IDIwMjYgSm9uYXRoYW4g
RC5BLiBKZXdlbGwgKGh5cGVycG9seW1hdGgpIDxqLmQuYS5qZXdlbGxAb3Blbi5hYy51az4KIwojIGs5X2NvbnRyYWN0Lm5jbCDi
gJQgVEhFIE5PUk1BVElWRSBLOSBDT01QT05FTlQgQ09OVFJBQ1QgKHYxLjAuMCkuCiMKIyBSdWxpbmcgRDE3MyAoc3RhbmRhcmRz
IzEwNTgsIDIwMjYtMDktMzApOiAiSzkgbmVlZHMgYSBOaWNrZWwgY29udHJhY3QsIG5vdCBhbgojIEFCTkYuIiBUaGlzIGZpbGUg
aXMgdGhhdCBjb250cmFjdC4gSXQgaXMgbm9ybWF0aXZlOyB0aGUgcHJvc2UgdGhhdCBnb3Zlcm5zIGl0CiMgaXMgLi4vSzktQ09O
VFJBQ1QtU1BFQy5hZG9jLCBhbmQgd2hlcmUgdGhlIHR3byBkaXNhZ3JlZSB0aGUgcHJvc2Ugd2lucyBhbmQKIyB0aGlzIGZpbGUg
aXMgYSBidWcuCiMKIyBXSEFUIFRISVMgRklMRSBJUwojICAgVGhlIGNsb3NlZCwgdmVyc2lvbmVkLCBtYWNoaW5lLWNoZWNrYWJs
ZSBzaGFwZSBvZiBhIEs5IGNvbXBvbmVudCdzCiMgICBgcGVkaWdyZWVgIGJsb2NrLCBwbHVzIHRoZSBkZWNpc2lvbiBmdW5jdGlv
bnMgYSBob3N0IG11c3QgY29uc3VsdCBiZWZvcmUKIyAgIGl0IGxldHMgYSBjb21wb25lbnQgZG8gYW55dGhpbmc6CiMKIyAgICAg
bGVhc2hfbGV2ZWxzIC8gaXNfbGVhc2ggICAgICDCpzcgIHRoZSBsZWFzaCB0YXhvbm9teSBhcyBhIENMT1NFRCBzZXQKIyAgICAg
cmVxdWlyZWRfY2FwYWJpbGl0aWVzICAgICAgICDCpzggIHdoYXQgYSBzZWN1cml0eSBmbGFnIGNvc3RzIHlvdQojICAgICBncmFu
dGVkX29rIC8gZGVuaWVkICAgICAgICAgIMKnOCAgZGVmYXVsdC1kZW55IGNhcGFiaWxpdHkgYXJpdGhtZXRpYwojICAgICBhdXRo
b3JpemVfaHVudCAgICAgICAgICAgICAgIMKnOSAgYWxsIGZpdmUgcHJlY29uZGl0aW9ucywgYWx3YXlzCiMgICAgIHNpZ25hdHVy
ZV92ZXJkaWN0ICAgICAgICAgICAgwqcxMCBwcmVzZW5jZSBpcyBOT1QgdmVyaWZpY2F0aW9uCiMKIyBXSEFUIFRISVMgRklMRSBJ
UyBOT1QKIyAgICogSXQgaXMgbm90IGEgZ3JhbW1hci4gSzkgaGFzIG5vIHN5bnRheCBvZiBpdHMgb3duOiB0aGUgYm9keSBvZiBh
CiMgICAgIGAuazkubmNsYCBmaWxlIGlzIGEgTmlja2VsIHRlcm0gYW5kIE5pY2tlbCdzIGdyYW1tYXIgaXMgbm9ybWF0aXZlIGJ5
CiMgICAgIHJlZmVyZW5jZSAoSzktQ09OVFJBQ1QtU1BFQyDCpzMuNSkuIFJlLXNwZWNpZnlpbmcgaXQgaGVyZSwgaW4gQUJORiBv
cgojICAgICBvdGhlcndpc2UsIHdvdWxkIGZvcmsgYSBsYW5ndWFnZSB3ZSBkbyBub3Qgb3duLgojICAgKiBJdCBpcyBub3QgYSB2
YWxpZGF0b3IuIEEgY29udHJhY3Qgc3RhdGVzIHdoYXQgaG9sZHM7IHRoZSBjYW5vbmljYWwKIyAgICAgdmFsaWRhdG9yICguLi8u
Li90b29scy9rOS12YWxpZGF0ZS5zaCkgZGVjaWRlcyB3aGV0aGVyIGEgY2hlY2sgY291bGQgYmUKIyAgICAgcnVuIGF0IGFsbCwg
YW5kIHJlcG9ydHMgYSBjaGVjayBpdCBjb3VsZCBub3QgcnVuIGFzIFNLSVBQRUQgcmF0aGVyIHRoYW4KIyAgICAgYXMgYSBwYXNz
LgojICAgKiBJdCBkb2VzIG5vdCB2ZXJpZnkgc2lnbmF0dXJlcy4gTmlja2VsIGhhcyBubyBjcnlwdG9ncmFwaGljIHByaW1pdGl2
ZSwKIyAgICAgc28gbm90aGluZyBpbiB0aGlzIGZpbGUgY2FuIHByb2R1Y2UgYHNpZ25hdHVyZV9jaGVjayA9ICdQYXNzZWRgLiBT
ZWUKIyAgICAgwqcxMDogYW4gaW1wbGVtZW50YXRpb24gdGhhdCBoYXMgbm90IHJ1biBhIHZlcmlmaWVyIE1VU1QgcmVwb3J0ICdO
b3RfUnVuLAojICAgICBhbmQgJ05vdF9SdW4gY2FuIG5ldmVyIGF1dGhvcmlzZSBIdW50LgojCiMgTkFNSU5HIEhBWkFSRCDigJQg
Y2FycmllZCBmcm9tIFNQRUMuYWRvYywgdW5jaGFuZ2VkOgojICAgSzkncyBleGVjdXRpb24gdHJpYWQgaXMgIG11c3QgLyBqdXN0
IC8gbmlja2VsLgojICAgVGhlIGNvbnRyYWN0aWxlcyBmYW1pbHkgaXMgIG11c3QgLyB0cnVzdCAvIGR1c3QgLyBpbnRlbmQuCiMg
ICBgbXVzdGAgYXBwZWFycyBpbiBib3RoIGFuZCBtZWFucyBkaWZmZXJlbnQgdGhpbmdzLiBOZXZlciBjb25mbGF0ZSB0aGVtLgoj
ICAgTm90aGluZyBpbiB0aGlzIGZpbGUgbmFtZXMgYSBjb250cmFjdGlsZSB2ZXJiOyBhIGNvbnRyYWN0aWxlIGNvbXBvbmVudCBp
cwojICAgYW4gb3JkaW5hcnkgSzkgY29tcG9uZW50IHdob3NlIGBjb21wb25lbnRfdHlwZWAgYmVnaW5zICJjb250cmFjdGlsZToi
LgojCiMgQVBJIFNVUkZBQ0UgRElTQ0lQTElORQojICAgRXZlcnkgc3RkIGZ1bmN0aW9uIHVzZWQgYmVsb3cgaXMgb25lIGFscmVh
ZHkgZXhlcmNpc2VkIGJ5IGEgYC5uY2xgIGZpbGUKIyAgIHRoaXMgcmVwb3NpdG9yeSB0eXBlY2hlY2tzIGluIENJIChjYXBhYmls
aXRpZXMubmNsLCBsZWFzaC5uY2wsCiMgICBwZWRpZ3JlZS5uY2wpOiBzdGQuc3RyaW5nLmxlbmd0aCwgc3RkLnN0cmluZy5zdWJz
dHJpbmcsIHN0ZC5zdHJpbmcuc3BsaXQsCiMgICBzdGQuc3RyaW5nLmpvaW4sIHN0ZC5hcnJheS5sZW5ndGgsIHN0ZC5hcnJheS5h
bnksIHN0ZC5hcnJheS5maWx0ZXIsCiMgICBzdGQucmVjb3JkLmhhc19maWVsZCwgc3RkLmNvbnRyYWN0LmZyb21fcHJlZGljYXRl
LiBBIG5vcm1hdGl2ZSBhcnRlZmFjdAojICAgbXVzdCBub3QgYmUgdGhlIGZpcnN0IHRoaW5nIGluIHRoZSBlc3RhdGUgdG8gdG91
Y2ggYW4gdW5leGVyY2lzZWQgY29ybmVyCiMgICBvZiBhIGRlcGVuZGVuY3kncyBzdGFuZGFyZCBsaWJyYXJ5LgojCiMg4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiMgVHlwZSBhbGlh
c2VzICh0b3AtbGV2ZWwgYGxldGAg4oCUIHRoZSBpZGlvbSBwZWRpZ3JlZS5uY2wgYW5kIGxlYXNoLm5jbCB1c2UpCiMg4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgojIMKnNyDigJQg
dGhlIGxlYXNoIHRheG9ub215LiBDTE9TRUQ6IHRocmVlIG1lbWJlcnMsIGFuZCBhZGRpbmcgYSBmb3VydGggaXMgYQojIE1BSk9S
IGNoYW5nZSB0byB0aGlzIGNvbnRyYWN0LCBub3QgYW4gZXh0ZW5zaW9uLgpsZXQgU2VjdXJpdHlMZXZlbCA9IFt8ICdLZW5uZWws
ICdZYXJkLCAnSHVudCB8XSBpbgoKIyDCpzEwIOKAlCB0aGUgcmVzdWx0IG9mIGFuIGF0dGVtcHRlZCBjcnlwdG9ncmFwaGljIGNo
ZWNrLiAnTm90X1J1biBpcyB0aGUgaG9uZXN0CiMgZGVmYXVsdCBhbmQgaXQgaXMgbG9hZC1iZWFyaW5nOiBpdCBpcyB0aGUgdmFs
dWUgYSB2YWxpZGF0b3IgcmVwb3J0cyB3aGVuIG5vCiMgdmVyaWZpZXIgd2FzIGF2YWlsYWJsZSwgYW5kIGl0IG11c3QgbmV2ZXIg
YmUgc2lsZW50bHkgdXBncmFkZWQuCmxldCBTaWduYXR1cmVDaGVjayA9IFt8ICdOb3RfUnVuLCAnUGFzc2VkLCAnRmFpbGVkIHxd
IGluCgojIMKnMTAg4oCUIHdoYXQgYSBob3N0IG1heSBpbmZlciBmcm9tICJkb2VzIHRoZSBmaWxlIGNhcnJ5IGEgc2lnbmF0dXJl
IGJsb2NrIgojIChsZXhpY2FsKSBjb21iaW5lZCB3aXRoICJkaWQgYSB2ZXJpZmllciBhY2NlcHQgaXQiIChjcnlwdG9ncmFwaGlj
KS4KbGV0IFNpZ25hdHVyZVZlcmRpY3QgPSBbfCAnQWJzZW50LCAnUHJlc2VudF9VbnZlcmlmaWVkLCAnVmVyaWZpZWQsICdSZWpl
Y3RlZCB8XSBpbgoKIyDCpzguMSDigJQgdGhlIHJlc2VydmVkIGV4dGVuc2lvbiBuYW1lc3BhY2UgcHJlZml4LgpsZXQgRXh0ZW5z
aW9uUHJlZml4ID0gIngtIiBpbgoKIyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIAKIyDCpzUuMiAvIMKnOC4xIOKAlCBuYW1lIHNoYXBlcywgdXNpbmcgbm90aGluZyBiZXlvbmQgbGVu
Z3RoIGFuZCBzdWJzdHJpbmcKIyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIAKbGV0IGlzX2RpZ2l0ID0gZnVuIGMgPT4KICBjID09ICIwIgogIHx8IGMgPT0gIjEiCiAgfHwgYyA9PSAi
MiIKICB8fCBjID09ICIzIgogIHx8IGMgPT0gIjQiCiAgfHwgYyA9PSAiNSIKICB8fCBjID09ICI2IgogIHx8IGMgPT0gIjciCiAg
fHwgYyA9PSAiOCIKICB8fCBjID09ICI5IgppbgoKIyBBIG51bWVyaWMgZG90LXRyaXBsZSB3aG9zZSBNQUpPUiBzZWdtZW50IGVx
dWFscyBgbWFqb3JgLiBXYWxrcyB0aGUgc3RyaW5nCiMgb25jZS4gUmVqZWN0czogbm9uLWRpZ2l0cywgYSBsZWFkaW5nIG9yIHRy
YWlsaW5nIGRvdCwgYW4gZW1wdHkgc2VnbWVudCwgYQojIGxlYWRpbmcgemVybyBpbiBhbnkgc2VnbWVudCAoIjEuMDAuMCIpLCBh
bmQgdGhlIHdyb25nIG51bWJlciBvZiBzZWdtZW50cy4KIwojIGBwcmV2X2RvdGAgc3RhcnRzIFRSVUUgc28gYSBsZWFkaW5nICIu
IiBpcyByZWZ1c2VkIGJ5IHRoZSBzYW1lIGJyYW5jaCB0aGF0CiMgcmVmdXNlcyAiLi4iOyBgc2VnX2xlbmAgbXVzdCBlbmQgPiAw
IHNvIGEgdHJhaWxpbmcgIi4iIGlzIHJlZnVzZWQgdG9vLgpsZXQgaXNfc2VtdmVyX29mID0gZnVuIG1ham9yIHYgPT4KICBsZXQg
d2FudCA9IG1ham9yICsrICIuIiBpbgogIGxldCByZWMgZ28gPSBmdW4gaSBkb3RzIHNlZ19sZW4gZmlyc3RfemVybyBzID0+CiAg
ICBpZiBpID49IHN0ZC5zdHJpbmcubGVuZ3RoIHMgdGhlbgogICAgICBkb3RzID09IDIgJiYgc2VnX2xlbiA+IDAKICAgIGVsc2UK
ICAgICAgIyBgc3Vic3RyaW5nIHN0YXJ0IGVuZCBzdHJgLCBOT1QgKHN0YXJ0LCBsZW5ndGgsIHN0cik6IDEuMTguMCdzCiAgICAg
ICMgc3RkLm5jbCBkb2N1bWVudHMgYHN1YnN0cmluZyBzdGFydCBlbmQgc3RyYCBhcyB0aGUgc2xpY2UgZnJvbSBgc3RhcnRgCiAg
ICAgICMgKGluY2x1ZGVkKSB0byBgZW5kYCAoZXhjbHVkZWQpLCBzbyB0aGUgc2luZ2xlIGNoYXJhY3RlciBhdCBgaWAgaXMKICAg
ICAgIyBgc3Vic3RyaW5nIGkgKGkgKyAxKSBzYC4gV3JpdHRlbiBhcyBgc3Vic3RyaW5nIGkgMSBzYCBpdCByZXR1cm5lZCAiMSIK
ICAgICAgIyBhdCBpPTAgYnkgY29pbmNpZGVuY2UgYW5kICIiIGF0IGV2ZXJ5IGxhdGVyIGluZGV4LCBzbyB0aGUgd2FsayBmZWxs
CiAgICAgICMgb3V0IGF0IHRoZSBzZWNvbmQgY2hhcmFjdGVyIGFuZCBgaXNfc2VtdmVyX29mYCByZWplY3RlZCAiMS4wLjAiIOKA
lAogICAgICAjIGV2ZXJ5IHBvc2l0aXZlIGNvbnRyb2wgd2l0aCBpdC4gVmVyaWZpZWQgYWdhaW5zdCBjb3JlL3N0ZGxpYi9zdGQu
bmNsLgogICAgICBsZXQgYyA9IHN0ZC5zdHJpbmcuc3Vic3RyaW5nIGkgKGkgKyAxKSBzIGluCiAgICAgIGlmIGMgPT0gIi4iIHRo
ZW4KICAgICAgICBzZWdfbGVuID4gMCAmJiBnbyAoaSArIDEpIChkb3RzICsgMSkgMCBmYWxzZSBzCiAgICAgIGVsc2UgaWYgaXNf
ZGlnaXQgYyB0aGVuCiAgICAgICAgKGZpcnN0X3plcm8gPT0gZmFsc2UgfHwgc2VnX2xlbiA9PSAwKQogICAgICAgICYmIGdvIChp
ICsgMSkgZG90cyAoc2VnX2xlbiArIDEpIChjID09ICIwIikgcwogICAgICBlbHNlCiAgICAgICAgZmFsc2UKICBpbgogICMgQSBk
b3QtdHJpcGxlIGlzIGF0IGxlYXN0IGB3YW50YCBwbHVzICJOLk4iOiB0aHJlZSBtb3JlIGNoYXJhY3RlcnMuCiAgc3RkLnN0cmlu
Zy5sZW5ndGggdiA+PSAoc3RkLnN0cmluZy5sZW5ndGggd2FudCArIDMpCiAgJiYgc3RkLnN0cmluZy5zdWJzdHJpbmcgMCAoc3Rk
LnN0cmluZy5sZW5ndGggd2FudCkgdiA9PSB3YW50CiAgJiYgZ28gMCAwIDAgZmFsc2UgdgppbgoKIyDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKIyBUaGUgY29udHJhY3QgcmVjb3Jk
LiBOaWNrZWwgcmVjb3JkcyBhcmUgcmVjdXJzaXZlLCBzbyBmaWVsZHMgYmVsb3cgcmVmZXIgdG8KIyB0aGVpciBzaWJsaW5ncyBi
eSBuYW1lOyB0aGUgdHlwZSBhbGlhc2VzIGFib3ZlIHN0YXkgdG9wLWxldmVsIHNvIG5vIGZpZWxkCiMgZXZlciBzaGFkb3dzIHRo
ZSBiaW5kaW5nIGl0IGlzIGRlZmluZWQgaW4gdGVybXMgb2YuCiMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACnsKICAjIOKUgOKUgCDCpzUgSWRlbnRpdHkgYW5kIHZlcnNpb25pbmcg
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgIwogICMgYGNvbnRyYWN0X3ZlcnNpb25gIGlzIHRo
ZSB2ZXJzaW9uIG9mIFRISVMgZmlsZS4gYHNjaGVtYV9tYWpvcmAgaXMgdGhlCiAgIyBtYWpvciBzZWdtZW50IGEgY29uZm9ybWlu
ZyBjb21wb25lbnQncyBgcGVkaWdyZWUuc2NoZW1hX3ZlcnNpb25gIG11c3QKICAjIGNhcnJ5IHRvIGJlIHJlYWRhYmxlIGJ5IHRo
aXMgY29udHJhY3QuIFRoZXkgYXJlIHNlcGFyYXRlIG51bWJlcnMgb24KICAjIHB1cnBvc2U6IHRoaXMgY29udHJhY3QgY2FuIGJl
IHJldmlzZWQgKDEuMC4wIC0+IDEuMC4xKSB3aXRob3V0IGNoYW5naW5nCiAgIyB3aGF0IGEgY29tcG9uZW50IG11c3QgbG9vayBs
aWtlLgogIGNvbnRyYWN0X25hbWUgPSAiazktc3ZjLWNvbXBvbmVudCIsCiAgY29udHJhY3RfdmVyc2lvbiA9ICIxLjAuMCIsCiAg
c2NoZW1hX21ham9yID0gIjEiLAoKICAjIMKnNCDigJQgdGhlIGRpYWxlY3RzIGEgSzkgZW52ZWxvcGUgbWF5IGNhcnJ5LiBBIGZp
bGUgd2hvc2UgYm9keSBpcyBub3Qgb25lIG9mCiAgIyB0aGVzZSBpcyBub3QgYSBLOSBmaWxlLCB3aGF0ZXZlciBpdHMgc3VmZml4
IHNheXMuCiAgZGlhbGVjdCA9IHsKICAgICMgYEs5IWAgZW52ZWxvcGUgKyBOaWNrZWwgYm9keSBkZWNsYXJpbmcgYSBgcGVkaWdy
ZWVgLiBJbiBzY29wZSBoZXJlLgogICAgY29tcG9uZW50ID0gIms5LXN2Yy1jb21wb25lbnQiLAogICAgIyBObyBgSzkhYCBlbnZl
bG9wZSwgTmlja2VsIGJvZHksIG5vIHRvcC1sZXZlbCBgcGVkaWdyZWVgLiBJbXBvcnRlZCwgbmV2ZXIKICAgICMgZXhlY3V0ZWQu
IEluIHNjb3BlIGZvciDCpzExIG9ubHkuCiAgICBsaWJyYXJ5ID0gIms5LXN2Yy1saWJyYXJ5IiwKICAgICMgYEs5IWAgZW52ZWxv
cGUgKyBZQU1MIGJvZHkuIEdvdmVybmVkIGJ5CiAgICAjIDItcHJvdG9jb2xzL2s5LWNvb3JkaW5hdGlvbi9zcGVjL2FibmYvY29v
cmRpbmF0aW9uLWs5LWdyYW1tYXJfdjEuMS5hYm5mLAogICAgIyBOT1QgYnkgdGhpcyBjb250cmFjdC4gTmFtZWQgaGVyZSBzbyBh
IHZhbGlkYXRvciBjYW4gcm91dGUgaXQgaW5zdGVhZCBvZgogICAgIyBtaXNyZXBvcnRpbmcgaXQgYXMgYSBicm9rZW4gY29tcG9u
ZW50LgogICAgY29vcmRpbmF0aW9uID0gIms5LWNvb3JkaW5hdGlvbiIsCiAgfSwKCiAgIyDilIDilIAgwqc3IExlYXNoIHRheG9u
b215IOKAlCBDTE9TRUQgU0VUIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICMKICAjIE1hY2hpbmUtY2hlY2thYmxl
IGVudW1lcmF0aW9uIG9mIHRoZSB0aHJlZSBsZXZlbHMgaW4gYXNjZW5kaW5nIG9yZGVyIG9mCiAgIyB3aGF0IHRoZXkgcGVybWl0
LiBUaGlzIGxpc3QgSVMgdGhlIGNsb3NlZCBzZXQgdGhlIHByb3NlIHByb21pc2VzLCBhbmQgaXQKICAjIGxpdmVzIGluIHRoZSBz
YW1lIGZpbGUgYXMgdGhlIGBTZWN1cml0eUxldmVsYCBlbnVtIGl0IG1pcnJvcnMgc28gdGhlIHR3bwogICMgY2Fubm90IGRyaWZ0
IHNpbGVudGx5OyB0aGUgY29uZm9ybWFuY2Ugc3VpdGUgYXNzZXJ0cyB0aGV5IGFncmVlLgogIGxlYXNoX2xldmVscyA9IFsnS2Vu
bmVsLCAnWWFyZCwgJ0h1bnRdLAoKICAjIFRvdGFsIG9yZGVyIG92ZXIgdGhlIGNsb3NlZCBzZXQuIFVzZWQgZm9yIHRoZSBtb25v
dG9uaWNpdHkgcnVsZSAowqc3LjQpOiBhCiAgIyBob3N0IG1heSBlbmZvcmNlIGEgbGV2ZWwgU1RSSUNURVIgdGhhbiB0aGUgY29t
cG9uZW50IGRlY2xhcmVzLCBuZXZlciBsYXhlci4KICBsZXZlbF9yYW5rID0gZnVuIGwgPT4KICAgIGlmIGwgPT0gJ0tlbm5lbCB0
aGVuCiAgICAgIDAKICAgIGVsc2UgaWYgbCA9PSAnWWFyZCB0aGVuCiAgICAgIDEKICAgIGVsc2UKICAgICAgMiwKCiAgaXNfbGVh
c2ggPSBmdW4gdiA9PgogICAgc3RkLmFycmF5Lmxlbmd0aCAoc3RkLmFycmF5LmZpbHRlciAoZnVuIGwgPT4gbCA9PSB2KSBsZWFz
aF9sZXZlbHMpID09IDEsCgogICMgVGhlIGxlYXNoIGEgY29tcG9uZW50IERFQ0xBUkVTLiBGYWlsLWNsb3NlZDogYSBwZWRpZ3Jl
ZSB3aXRoIG5vIHJlYWRhYmxlCiAgIyBgc2VjdXJpdHkubGVhc2hgIHJhbmtzIGFzICdLZW5uZWwgaGVyZSwgYW5kIGlzIHJlamVj
dGVkIG91dHJpZ2h0IGJ5IHRoZQogICMgUGVkaWdyZWUgY29udHJhY3QgYmVsb3cuIFRoaXMgaGVscGVyIGV4aXN0cyBzbyBhIGhv
c3QgaGFuZGVkIGEgcGFydGlhbAogICMgcGVkaWdyZWUgY2Fubm90IGNyYXNoIG9uIGl0LgogIGxlYXNoX29mID0gZnVuIHBlZGln
cmVlID0+CiAgICBpZiBzdGQucmVjb3JkLmhhc19maWVsZCAic2VjdXJpdHkiIHBlZGlncmVlCiAgICAmJiBzdGQucmVjb3JkLmhh
c19maWVsZCAibGVhc2giIHBlZGlncmVlLnNlY3VyaXR5IHRoZW4KICAgICAgcGVkaWdyZWUuc2VjdXJpdHkubGVhc2gKICAgIGVs
c2UKICAgICAgJ0tlbm5lbCwKCiAgIyDilIDilIAgwqc4IENhcGFiaWxpdHkgbW9kZWwg4oCUIERFRkFVTFQtREVOWSDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIAKICAjCiAgIyDCpzguMSBDTE9TRUQgQ09SRSBTRVQuIEV4aGF1c3RpdmUgZm9yIHRoZSBjb3JlIG5hbWVzcGFj
ZS4gQWRkaW5nIG9yCiAgIyByZW1vdmluZyBhIG5hbWUgaGVyZSBpcyBhIE1BSk9SIGNoYW5nZSB0byB0aGlzIGNvbnRyYWN0Lgog
IGNvcmVfY2FwYWJpbGl0aWVzID0gWwogICAgImZzLnJlYWQiLAogICAgImZzLndyaXRlIiwKICAgICJuZXQuZmV0Y2giLAogICAg
InByb2Nlc3Muc3Bhd24iLAogICAgImNvbnRhaW5lci5ydW4iLAogICAgInNlY3JldC5yZWFkIiwKICAgICJkZXBsb3kuYXBwbHki
LAogICAgInJvbGxiYWNrLmFwcGx5IiwKICBdLAoKICAjIMKnOC4xIFJFU0VSVkVEIEVYVEVOU0lPTiBOQU1FU1BBQ0UuIE5vbi1j
b3JlIG5hbWVzIE1VU1QgYmUgIngtPHZlbmRvcj4uPHA+IgogICMgc28gdGhleSBjYW4gbmV2ZXIgY29sbGlkZSB3aXRoIGEgZnV0
dXJlIGNvcmUgbmFtZS4KICBleHRlbnNpb25fcHJlZml4ID0gRXh0ZW5zaW9uUHJlZml4LAoKICBpc19jb3JlID0gZnVuIG5hbWUg
PT4gc3RkLmFycmF5LmFueSAoZnVuIGMgPT4gYyA9PSBuYW1lKSBjb3JlX2NhcGFiaWxpdGllcywKCiAgIyBBIHdlbGwtZm9ybWVk
IGV4dGVuc2lvbjogc3RhcnRzIHdpdGggdGhlIHByZWZpeCBhbmQgaGFzIGF0IGxlYXN0IG9uZSAiLiIKICAjIGFmdGVyIHRoZSB2
ZW5kb3Igc2VnbWVudCwgaS5lLiAieC12ZW5kb3Iuc29tZXRoaW5nIiwgbmV2ZXIgYmFyZSAieC12ZW5kb3IiLgogIGlzX2V4dGVu
c2lvbiA9IGZ1biBuYW1lID0+CiAgICBzdGQuc3RyaW5nLmxlbmd0aCBuYW1lID4gc3RkLnN0cmluZy5sZW5ndGggRXh0ZW5zaW9u
UHJlZml4CiAgICAmJiBzdGQuc3RyaW5nLnN1YnN0cmluZyAwIChzdGQuc3RyaW5nLmxlbmd0aCBFeHRlbnNpb25QcmVmaXgpIG5h
bWUgPT0gRXh0ZW5zaW9uUHJlZml4CiAgICAmJiBzdGQuYXJyYXkubGVuZ3RoIChzdGQuc3RyaW5nLnNwbGl0ICIuIiBuYW1lKSA+
PSAyLAoKICBDYXBhYmlsaXR5ID0KICAgIHN0ZC5jb250cmFjdC5mcm9tX3ByZWRpY2F0ZSAoZnVuIG5hbWUgPT4KICAgICAgaXNf
Y29yZSBuYW1lIHx8IGlzX2V4dGVuc2lvbiBuYW1lCiAgICApLAoKICAjIEFuIGV4cGxpY2l0IGFsbG93LWxpc3QuIERFRkFVTFQt
REVOWSBpcyBleHByZXNzZWQgYnkgdGhlIGVtcHR5IGdyYW50OiBpdAogICMgcGVybWl0cyBub3RoaW5nLCBhbmQgIm5vdGhpbmci
IGlzIHRoZSBjb3JyZWN0IGFuc3dlciBmb3IgYW4gYWJzZW50IGdyYW50LgogIENhcGFiaWxpdHlHcmFudCA9IEFycmF5IENhcGFi
aWxpdHksCgogIGRlZmF1bHRfZ3JhbnQgPSBbXSwKCiAgcGVybWl0cyA9IGZ1biBncmFudCBuYW1lID0+IHN0ZC5hcnJheS5hbnkg
KGZ1biBnID0+IGcgPT0gbmFtZSkgZ3JhbnQsCgogIGRlbmllZCA9IGZ1biBncmFudCByZXF1ZXN0ZWQgPT4KICAgIHN0ZC5hcnJh
eS5maWx0ZXIgKGZ1biByID0+ICEocGVybWl0cyBncmFudCByKSkgcmVxdWVzdGVkLAoKICBncmFudGVkX29rID0gZnVuIGdyYW50
IHJlcXVlc3RlZCA9PgogICAgc3RkLmFycmF5Lmxlbmd0aCAoZGVuaWVkIGdyYW50IHJlcXVlc3RlZCkgPT0gMCwKCiAgIyDCpzgu
NCBERVJJVkVEIFJFUVVJUkVNRU5UUyDigJQgdGhlIHJ1bGUgdGhhdCBtYWtlcyB0aGUgZ3JhbnQgbG9hZC1iZWFyaW5nLgogICMK
ICAjIEEgc2VjdXJpdHkgZmxhZyBpcyBhIFJFUVVFU1QgZm9yIGEgY2FwYWJpbGl0eSwgYW5kIGEgcmVxdWVzdCB0aGUgZ3JhbnQK
ICAjIGRvZXMgbm90IGNvdmVyIGlzIGEgY29udHJhZGljdGlvbiBpbnNpZGUgdGhlIHBlZGlncmVlLCBub3QgYSBwcmVmZXJlbmNl
LgogICMgYGFsbG93X25ldHdvcmsgPSB0cnVlYCB3aXRoIGFuIGVtcHR5IGdyYW50IGlzIHRoZXJlZm9yZSBJTlZBTElELCBub3QK
ICAjIG1lcmVseSB1bndpc2U6IHRoZSBjb21wb25lbnQgYXNrcyBmb3IgdGhlIG5ldHdvcmsgd2hpbGUgZ3JhbnRpbmcgaXRzZWxm
CiAgIyBub3RoaW5nLiBUaGlzIFNUUkVOR1RIRU5TIHRoZSBwcmUtIzEwNTggc3RhdGUsIHdoZXJlIHRoZSBmbGFncyBhbmQgdGhl
CiAgIyBncmFudCB3ZXJlIHR3byB1bnJlbGF0ZWQgb3BpbmlvbnMgaW4gdGhlIHNhbWUgYmxvY2suCiAgcmVxdWlyZWRfY2FwYWJp
bGl0aWVzID0gZnVuIHNlY3VyaXR5ID0+CiAgICAoCiAgICAgIGlmIHN0ZC5yZWNvcmQuaGFzX2ZpZWxkICJhbGxvd19uZXR3b3Jr
IiBzZWN1cml0eQogICAgICAmJiBzZWN1cml0eS5hbGxvd19uZXR3b3JrIHRoZW4KICAgICAgICBbIm5ldC5mZXRjaCJdCiAgICAg
IGVsc2UKICAgICAgICBbXQogICAgKQogICAgQCAoCiAgICAgIGlmIHN0ZC5yZWNvcmQuaGFzX2ZpZWxkICJhbGxvd19maWxlc3lz
dGVtX3dyaXRlIiBzZWN1cml0eQogICAgICAmJiBzZWN1cml0eS5hbGxvd19maWxlc3lzdGVtX3dyaXRlIHRoZW4KICAgICAgICBb
ImZzLndyaXRlIl0KICAgICAgZWxzZQogICAgICAgIFtdCiAgICApCiAgICBAICgKICAgICAgaWYgc3RkLnJlY29yZC5oYXNfZmll
bGQgImFsbG93X3N1YnByb2Nlc3MiIHNlY3VyaXR5CiAgICAgICYmIHNlY3VyaXR5LmFsbG93X3N1YnByb2Nlc3MgdGhlbgogICAg
ICAgIFsicHJvY2Vzcy5zcGF3biJdCiAgICAgIGVsc2UKICAgICAgICBbXQogICAgKSwKCiAgIyBXaGF0IHRoZSBncmFudCBmYWls
cyB0byBjb3Zlci4gRW1wdHkgaWZmIHRoZSBwZWRpZ3JlZSBpcyBzZWxmLWNvbnNpc3RlbnQuCiAgZ3JhbnRfZGVmaWNpdCA9IGZ1
biBncmFudCBzZWN1cml0eSA9PgogICAgZGVuaWVkIGdyYW50IChyZXF1aXJlZF9jYXBhYmlsaXRpZXMgc2VjdXJpdHkpLAoKICAj
IOKUgOKUgCDCpzkgSHVudCBwcmVjb25kaXRpb25zIOKAlCBBTEwgRklWRSwgQUxXQVlTIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICMKICAjIE93bmVyIGRpcmVjdGl2
ZSAyMDI2LTA2LTAzLCByZXN0YXRlZCBhbmQgTk9UIFJFTEFYRUQgYnkgdGhpcyBjb250cmFjdDoKICAjIEh1bnQgcmVxdWlyZXMg
YWxsIGZpdmUsIGFsd2F5cy4gVGhlcmUgaXMgbm8gY29uZmlndXJhYmxlIHN1YnNldCwgYW5kIGEKICAjIHZhbGlkIHNpZ25hdHVy
ZSBhbG9uZSBpcyBub3Qgc3VmZmljaWVudC4gUmVwcm9kdWNlZCBmcm9tIGxlYXNoLm5jbAogICMgdmVyYmF0aW0gc28gdGhlIHR3
byBjYW5ub3QgZHJpZnQ7IHRoZSBjb25mb3JtYW5jZSBzdWl0ZSBhc3NlcnRzIGVxdWFsaXR5LgogIGh1bnRfcHJlY29uZGl0aW9u
cyA9IFsKICAgICJzaWduYXR1cmUiLAogICAgInBvbGljeSIsCiAgICAic2FuZGJveCIsCiAgICAiZHJ5X3J1biIsCiAgICAiY2Fw
YWJpbGl0eV9ncmFudCIsCiAgXSwKCiAgIyBUaGUgaG9zdCBzdXBwbGllcyBvbmUgQm9vbCBvZiBFVklERU5DRSBwZXIgcHJlY29u
ZGl0aW9uLiBFdmlkZW5jZSBpcwogICMgcnVudGltZSBmYWN0LCBub3QgYSBzdGF0aWMgY29tcG9uZW50IGZpZWxkIOKAlCB3aGlj
aCBpcyB3aHkgYGNoZWNrX2xldmVsYAogICMgaW4gbGVhc2gubmNsIGNhbiBuZXZlciBhdXRob3Jpc2UgSHVudCBvbiBpdHMgb3du
LgogICMgSG9zdC1zaWRlLCBhbmQgZGVsaWJlcmF0ZWx5IENMT1NFRCB1bmxpa2UgdGhlIGNvbXBvbmVudC1mYWNpbmcgcmVjb3Jk
cwogICMgYWJvdmU6IMKnOS4yIHNheXMgdGhlIGhvc3Qgc3VwcGxpZXMgb25lIEJvb2xlYW4gb2YgZXZpZGVuY2UgcGVyCiAgIyBw
cmVjb25kaXRpb24sIHNvIGEgbWlzc3BlbHQgZXZpZGVuY2UgZmllbGQgbXVzdCBiZSBhbiBlcnJvciByYXRoZXIgdGhhbiBhCiAg
IyBzaWxlbnRseSBpZ25vcmVkIHByZWNvbmRpdGlvbi4gwqc1LjUncyBvcGVubmVzcyBpcyBhYm91dCBhICpjb21wb25lbnQncyoK
ICAjIGZpZWxkcy4KICBIdW50RXZpZGVuY2UgPSB7CiAgICBzaWduYXR1cmUgfCBCb29sLAogICAgcG9saWN5IHwgQm9vbCwKICAg
IHNhbmRib3ggfCBCb29sLAogICAgZHJ5X3J1biB8IEJvb2wsCiAgICBjYXBhYmlsaXR5X2dyYW50IHwgQm9vbCwKICB9LAoKICAj
IMKnOS4yIFRoZSBnYXRlLiBJZGVudGljYWwgc2VtYW50aWNzIHRvIGxlYXNoLm5jbCBgYXV0aG9yaXplX2h1bnRgLCBhbmQKICAj
IGRlbGliZXJhdGVseSBzbzogYSBob3N0IGltcGxlbWVudGluZyB0aGlzIGZpbGUgYW5kIGEgaG9zdCBpbXBsZW1lbnRpbmcKICAj
IGxlYXNoLm5jbCBtdXN0IHJlYWNoIHRoZSBzYW1lIHZlcmRpY3Qgb24gdGhlIHNhbWUgZXZpZGVuY2UuCiAgYXV0aG9yaXplX2h1
bnQgPSBmdW4gZXZpZGVuY2UgPT4KICAgIGxldCB1bm1ldCA9CiAgICAgIChpZiBldmlkZW5jZS5zaWduYXR1cmUgdGhlbiBbXSBl
bHNlIFsic2lnbmF0dXJlIl0pCiAgICAgIEAgKGlmIGV2aWRlbmNlLnBvbGljeSB0aGVuIFtdIGVsc2UgWyJwb2xpY3kiXSkKICAg
ICAgQCAoaWYgZXZpZGVuY2Uuc2FuZGJveCB0aGVuIFtdIGVsc2UgWyJzYW5kYm94Il0pCiAgICAgIEAgKGlmIGV2aWRlbmNlLmRy
eV9ydW4gdGhlbiBbXSBlbHNlIFsiZHJ5X3J1biJdKQogICAgICBAIChpZiBldmlkZW5jZS5jYXBhYmlsaXR5X2dyYW50IHRoZW4g
W10gZWxzZSBbImNhcGFiaWxpdHlfZ3JhbnQiXSkKICAgIGluCiAgICBpZiBzdGQuYXJyYXkubGVuZ3RoIHVubWV0ID09IDAgdGhl
bgogICAgICB7CiAgICAgICAgcGVybWl0dGVkID0gdHJ1ZSwKICAgICAgICBlbmZvcmNlZF9sZXZlbCA9ICdIdW50LAogICAgICAg
IHVubWV0X3ByZWNvbmRpdGlvbnMgPSBbXSwKICAgICAgfQogICAgZWxzZQogICAgICB7CiAgICAgICAgcGVybWl0dGVkID0gZmFs
c2UsCiAgICAgICAgZW5mb3JjZWRfbGV2ZWwgPSAnWWFyZCwKICAgICAgICByZWFzb24gPQogICAgICAgICAgIkh1bnQgcmVxdWly
ZXMgYWxsIGZpdmUgcHJlY29uZGl0aW9uczsgdW5tZXQ6ICIKICAgICAgICAgICsrIHN0ZC5zdHJpbmcuam9pbiAiLCAiIHVubWV0
LAogICAgICAgIHVubWV0X3ByZWNvbmRpdGlvbnMgPSB1bm1ldCwKICAgICAgfSwKCiAgIyDilIDilIAgwqcxMCBTaWduYXR1cmUg
c2VtYW50aWNzIOKAlCBQUkVTRU5DRSBJUyBOT1QgVkVSSUZJQ0FUSU9OIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gAogICMKICAjIEEgYHNpZ25hdHVyZWAgYmxvY2sgaW4gYSBwZWRpZ3JlZSBpcyBhIENMQUlNLiBSZWFkaW5nIGl0IHByb3ZlcyB0
aGUgZmlsZQogICMgc2F5cyBpdCB3YXMgc2lnbmVkLiBJdCBkb2VzIG5vdCBwcm92ZSB0aGUgZmlsZSB3YXMgc2lnbmVkLCBhbmQg
aXQgZG9lcyBub3QKICAjIHByb3ZlIHRoZSBzaWduYXR1cmUgY292ZXJzIHRoZSBieXRlcyBhYm91dCB0byBiZSBleGVjdXRlZC4K
ICBzaWduYXR1cmVfY2hlY2tzID0gWydOb3RfUnVuLCAnUGFzc2VkLCAnRmFpbGVkXSwKICBzaWduYXR1cmVfdmVyZGljdHMgPSBb
J0Fic2VudCwgJ1ByZXNlbnRfVW52ZXJpZmllZCwgJ1ZlcmlmaWVkLCAnUmVqZWN0ZWRdLAoKICAjIMKnMTAuMiDigJQgdGhlIG9u
bHkgbWFwcGluZyBhIGNvbmZvcm1pbmcgaW1wbGVtZW50YXRpb24gbWF5IG1ha2UuCiAgIyAgIG5vIGJsb2NrICAgICAgICAgICAg
ICAgICAtPiAnQWJzZW50ICAgICAgICAgICAgIChub3RoaW5nIHdhcyBjbGFpbWVkKQogICMgICBibG9jaywgdmVyaWZpZXIgcGFz
c2VkICAgLT4gJ1ZlcmlmaWVkICAgICAgICAgICAoY3J5cHRvZ3JhcGhpYyBmYWN0KQogICMgICBibG9jaywgdmVyaWZpZXIgcmVq
ZWN0ZWQgLT4gJ1JlamVjdGVkICAgICAgICAgICAoY3J5cHRvZ3JhcGhpYyBmYWN0KQogICMgICBibG9jaywgbm8gdmVyaWZpZXIg
cmFuICAgLT4gJ1ByZXNlbnRfVW52ZXJpZmllZCAobGV4aWNhbCBmYWN0IE9OTFkpCiAgIwogICMgTm90ZSB3aGF0IGlzIGFic2Vu
dCBmcm9tIHRoYXQgdGFibGU6IHRoZXJlIGlzIG5vIGlucHV0IHRoYXQgdHVybnMKICAjICdOb3RfUnVuIGludG8gJ1ZlcmlmaWVk
LiBBbiBpbXBsZW1lbnRhdGlvbiBjYW5ub3QgaW5mZXIgdmVyaWZpY2F0aW9uIGZyb20KICAjIHByZXNlbmNlLCBhbmQgYSB2YWxp
ZGF0b3IgdGhhdCByZXBvcnRzICdWZXJpZmllZCB3aXRob3V0IGhhdmluZyBydW4gYQogICMgdmVyaWZpZXIgaXMgbm9uLWNvbmZv
cm1pbmcgKMKnMTAuMykuCiAgc2lnbmF0dXJlX3ZlcmRpY3QgPSBmdW4gaGFzX2Jsb2NrIGNoZWNrID0+CiAgICBpZiBoYXNfYmxv
Y2sgPT0gZmFsc2UgdGhlbgogICAgICAnQWJzZW50CiAgICBlbHNlIGlmIGNoZWNrID09ICdQYXNzZWQgdGhlbgogICAgICAnVmVy
aWZpZWQKICAgIGVsc2UgaWYgY2hlY2sgPT0gJ0ZhaWxlZCB0aGVuCiAgICAgICdSZWplY3RlZAogICAgZWxzZQogICAgICAnUHJl
c2VudF9VbnZlcmlmaWVkLAoKICAjIMKnMTAuNCDigJQgdGhlIEh1bnQgYHNpZ25hdHVyZWAgcHJlY29uZGl0aW9uIGlzIHNhdGlz
ZmlhYmxlIGJ5ICdWZXJpZmllZCBhbmQKICAjIGJ5IG5vdGhpbmcgZWxzZS4gUHJlc2VuY2UgeWllbGRzICdQcmVzZW50X1VudmVy
aWZpZWQsIHdoaWNoIGlzIGZhbHNlIGhlcmUuCiAgIyBUaGlzIGlzIHRoZSBsaW5lIHRoYXQgc3RvcHMgYSBsZXhpY2FsIGNoZWNr
IGZyb20gYmVjb21pbmcgYW4gZXhlY3V0aW9uCiAgIyBsaWNlbmNlLCBhbmQgaXQgaXMgdGhlIHJlYXNvbiB0aGlzIGNvbnRyYWN0
IGNhbm5vdCBiZSByZXBsYWNlZCBieSBhIGdyZXAuCiAgaHVudF9zaWduYXR1cmVfZXZpZGVuY2UgPSBmdW4gdmVyZGljdCA9PiB2
ZXJkaWN0ID09ICdWZXJpZmllZCwKCiAgIyBUaGUgc2lnbmF0dXJlIGJsb2NrIGEgY29tcG9uZW50IE1BWSBjYXJyeS4gRXZlcnkg
ZmllbGQgYnV0IGBhbGdvcml0aG1gIGlzCiAgIyBvcHRpb25hbCBhdCB0aGUgQ09OVFJBQ1QgbGV2ZWwsIGJlY2F1c2UgwqcxMC4x
IG1ha2VzIHByZXNlbmNlIGEgcGVyLWxlYXNoCiAgIyBydWxlIHJhdGhlciB0aGFuIGEgdW5pdmVyc2FsIG9uZTogJ0tlbm5lbCBh
bmQgJ1lhcmQgY29tcG9uZW50cyBhcmUKICAjIG9yZGluYXJpbHkgdW5zaWduZWQsIGFuZCB0aGF0IGlzIGNvcnJlY3QgcmF0aGVy
IHRoYW4gYSBkZWZlY3QuCiAgU2lnbmF0dXJlID0gewogICAgYWxnb3JpdGhtIHwgU3RyaW5nIHwgZGVmYXVsdCA9ICJFZDI1NTE5
IiwKICAgIHB1YmxpY19rZXkgfCBTdHJpbmcgfCBvcHRpb25hbCwKICAgIHNpZ25hdHVyZSB8IFN0cmluZyB8IG9wdGlvbmFsLAog
ICAgcGF5bG9hZF9oYXNoIHwgU3RyaW5nIHwgb3B0aW9uYWwsCiAgICBzaWduZWRfYXQgfCBTdHJpbmcgfCBvcHRpb25hbCwKICAg
IGtleV9pZCB8IFN0cmluZyB8IGRlZmF1bHQgPSAicHJpbWFyeSIsCiAgICAjIMKnNS41IOKAlCB1bmtub3duIGZpZWxkcyBhcmUg
UEVSTUlUVEVEOyBzZWUgdGhlIGAuLmAgYmxvY2sgYWJvdmUgYE1ldGFkYXRhYC4KICAgICMgQSBob3N0IHRoYXQgcmVhZHMgYHNp
Z25hdHVyZS5wdWJsaWNfa2V5YCBNVVNUIE5PVCBiZSB0aGUgcmVhc29uIGEgZnV0dXJlCiAgICAjIGBjb3VudGVyX3NpZ25hdHVy
ZWAgZmllbGQgaXMgcmVqZWN0ZWQuCiAgICAuLgogIH0sCgogICMg4pSA4pSAIMKnNiBUaGUgY29tcG9uZW50IHBlZGlncmVlLCB2
MSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAjCiAgIyBGaWVsZC1mb3ItZmllbGQgdGhpcyBpcyB0aGUgc2hh
cGUgdGhlIGVzdGF0ZSdzIGAuazkubmNsYCBjb21wb25lbnRzCiAgIyBhY3R1YWxseSBjYXJyeSAoYC5tYWNoaW5lX3JlYWRhYmxl
L3N2Yy9rOS90ZW1wbGF0ZS0qLms5Lm5jbGApLCB3aXRoIHR3bwogICMgbm9ybWF0aXZlIHRpZ2h0ZW5pbmdzOiBgY29tcG9uZW50
X3R5cGVgIGlzIFJFUVVJUkVEICjCpzYuMiksIGFuZCB0aGUKICAjIHNlY3VyaXR5IGZsYWdzIG11c3QgYmUgcGFpZCBmb3IgaW4g
dGhlIGNhcGFiaWxpdHkgZ3JhbnQgKMKnOC40KS4KICAjCiAgIyDilIDilIAgVEhFIGAuLmAgVEFJTCwgQU5EIFdIWSBFVkVSWSBD
T01QT05FTlQtRkFDSU5HIFJFQ09SRCBIRVJFIEhBUyBPTkUg4pSA4pSACiAgIwogICMgwqc1LjUncyB0YWJsZSBlbmRzIHdpdGgg
IlVua25vd24gZmllbGRzIGFueXdoZXJlIHwgUEVSTUlUVEVELiBBIHJlYWRlciBTSE9VTEQKICAjIHJlcG9ydCB0aGVtIGFuZCBN
VVNUIE5PVCBjb25zdWx0IHRoZW0gdG8gcmVsYXggYW55IHJlcXVpcmVtZW50IG9mIMKnOCBvciDCpzkuIgogICMgVGhhdCBpcyBu
b3JtYXRpdmUgcHJvc2UsIGFuZCBieSB0aGlzIGZpbGUncyBvd24gZmlyc3QgcnVsZSB0aGUgcHJvc2Ugd2luczoKICAjIHdoZXJl
IHRoZSB0d28gZGlzYWdyZWUsIHRoaXMgZmlsZSBpcyB0aGUgYnVnLgogICMKICAjIFRoZXkgZGlzYWdyZWVkIHVudGlsIDIwMjYt
MTAtMDUuIEEgTmlja2VsIHJlY29yZCBjb250cmFjdCBpcyBDTE9TRUQgYnkKICAjIGRlZmF1bHQg4oCUIHRoZSBzaGFycCBlZGdl
IGlzIHJlY29yZGVkIGluIE5pY2tlbCdzIG93biBpbnRlZ3JhdGlvbiBzdWl0ZSwKICAjIGNvcmUvdGVzdHMvaW50ZWdyYXRpb24v
aW5wdXRzL2NvbnRyYWN0cy9yZWNvcmRfY29udHJhY3RfZXh0cmFfZmllbGQubmNsLAogICMgd2hpY2ggYXNzZXJ0cyBgRXZhbEVy
cm9yOjpCbGFtZUVycm9yYCB3aXRoIHRoZSBtZXNzYWdlICJleHRyYSBmaWVsZCIgYW5kCiAgIyBhZHZpc2VzIGFwcGVuZGluZyBg
LCAuLmAuIFNvIGEgY29tcG9uZW50IGNhcnJ5aW5nIGEgbGVnaXRpbWF0ZSBleHRlbnNpb24KICAjIGZpZWxkIHdhcyBibGFtZWQg
YnkgdGhpcyBmaWxlIHdoaWxlIMKnNS41IHBlcm1pdHRlZCB0aGUgZmllbGQuIFRoZSBzaXgKICAjIGAubWFjaGluZV9yZWFkYWJs
ZS9jb250cmFjdGlsZXMvKi8qLms5Lm5jbGAgY29tcG9uZW50cyBhcmUgdGhlIGxpdmUgY2FzZQogICMgKHRoZXkga2VlcCBgc2Vt
YW50aWNzYCwgYGNvbnRyYWN0aWxlX3ZlcmJgLCBgdGllcmAsIGBhdXRob3JpdHlgLAogICMgYHZhcmlhbmNlX3NjaGVtYWAsIGBl
eGVjdXRpb25gLCBgZmFpbHVyZV9tb2RlX2RlZmVuc2VzYCBpbiB0aGUgcGVkaWdyZWU7CiAgIyBgcHJvYmVfc2NvcGVgLCBgcHJv
YmVfa2luZHNfKmAsIGBhbGxvd19maWxlc3lzdGVtX3dyaXRlX2NvbmRpdGlvbmFsYCBpbgogICMgc2VjdXJpdHk7IGBwYWlyZWRf
eGZpbGVgLCBgcGFpcmVkX3J1bm5lcmAgaW4gbWV0YWRhdGEpLCBhbmQKICAjIGAyLXByb3RvY29scy9heGVsL2NvbmZpZy8qLms5
Lm5jbGAga2VlcCB0aGVpciBwYXlsb2FkIGF0IHRvcCBsZXZlbC4KICAjCiAgIyBPcGVuaW5nIHRoZXNlIGZpdmUgcmVjb3JkcyBp
cyBhIENPTkZPUk1BTkNFIGZpeCwgbm90IGEgY29udHJhY3QgcmV2aXNpb246CiAgIyB0aGUgc3BlY2lmaWVkIGNvbnRyYWN0ICh0
aGUgcHJvc2UpIG5ldmVyIGNoYW5nZWQsIHNvIGBjb250cmFjdF92ZXJzaW9uYAogICMgc3RheXMgMS4wLjAuIEl0IGRvZXMgbm90
IHdlYWtlbiDCpzggb3Igwqc5IGVpdGhlciDigJQgwqc1LjUncyBvd24gbGFzdCBjbGF1c2UKICAjIGZvcmJpZHMgdGhhdCwgYW5k
IHRoZSB2YWxpZGF0b3IgZW5mb3JjZXMgdGhlIGNhcGFiaWxpdHkgYXJpdGhtZXRpYyBvdmVyIHRoZQogICMgZXh0cmFjdGVkIGZh
Y3RzIHdoYXRldmVyIGFuIGV4dGVuc2lvbiBmaWVsZCBjbGFpbXMgKEs5LVMwMDcsIEs5LVMwMDgpLgogICMKICAjIFRoZSBwb3Np
dGl2ZSBjb250cm9sIGB0b29scy9maXh0dXJlcy92YWxpZC9leHRlbnNpb24tZmllbGRzLms5Lm5jbGAgZXhpc3RzCiAgIyBzbyB0
aGlzIGNhbm5vdCBzaWxlbnRseSByZWdyZXNzOiBpdCBmYWlscyBhdCBMMiB0aGUgbW9tZW50IGFueSBvZiB0aGVzZQogICMgcmVj
b3JkcyBjbG9zZXMgYWdhaW4uCgogIE1ldGFkYXRhID0gewogICAgbmFtZSB8IFN0cmluZywKICAgIHZlcnNpb24gfCBTdHJpbmcg
fCBkZWZhdWx0ID0gIjAuMC4wIiwKICAgIGRlc2NyaXB0aW9uIHwgU3RyaW5nIHwgb3B0aW9uYWwsCiAgICBhdXRob3IgfCBTdHJp
bmcgfCBvcHRpb25hbCwKICAgICMgwqc1LjUg4oCUIHNlZSB0aGUgYmxvY2sgY29tbWVudCBhYm92ZS4gVGhlIGVzdGF0ZSdzIGNv
bnRyYWN0aWxlcyBhZGQKICAgICMgYHBhaXJlZF94ZmlsZWAgLyBgcGFpcmVkX3J1bm5lcmAgaGVyZS4KICAgIC4uCiAgfSwKCiAg
U2VjdXJpdHkgPSB7CiAgICAjIMKnNyDigJQgY2xvc2VkIHNldC4gQW4gdW5rbm93biBMRUFTSCBUQUcgaXMgYSBjb250cmFjdCB2
aW9sYXRpb24sIG5vdCBhCiAgICAjIHdhcm5pbmc7IGFuIHVua25vd24gRklFTEQgaW4gdGhpcyBibG9jayBpcyDCpzUuNSdzIGJ1
c2luZXNzLgogICAgbGVhc2ggfCBTZWN1cml0eUxldmVsLAogICAgdHJ1c3RfbGV2ZWwgfCBTdHJpbmcgfCBkZWZhdWx0ID0gInVu
c2V0IiwKICAgIGFsbG93X25ldHdvcmsgfCBCb29sIHwgZGVmYXVsdCA9IGZhbHNlLAogICAgYWxsb3dfZmlsZXN5c3RlbV93cml0
ZSB8IEJvb2wgfCBkZWZhdWx0ID0gZmFsc2UsCiAgICBhbGxvd19zdWJwcm9jZXNzIHwgQm9vbCB8IGRlZmF1bHQgPSBmYWxzZSwK
ICAgICMgwqcxMC4xIOKAlCBSRVFVSVJFRCB0byBiZSB0cnVlIHdoZW4gbGVhc2ggPT0gJ0h1bnQuIFRoZSB2YWxpZGF0b3IgZW5m
b3JjZXMKICAgICMgdGhlIGltcGxpY2F0aW9uOyB0aGlzIGNvbnRyYWN0IGNhbm5vdCwgYmVjYXVzZSBpdCBpcyBhIGNyb3NzLWZp
ZWxkIHJ1bGUuCiAgICBzaWduYXR1cmVfcmVxdWlyZWQgfCBCb29sIHwgZGVmYXVsdCA9IGZhbHNlLAogICAgIyDCpzguMyDigJQg
dGhlIGV4cGxpY2l0IGdyYW50LiBEZWZhdWx0LWRlbnk6IGFic2VudCBtZWFucyBlbXB0eS4KICAgIGNhcGFiaWxpdGllcyB8IENh
cGFiaWxpdHlHcmFudCB8IGRlZmF1bHQgPSBbXSwKICAgICMgwqc1LjUg4oCUIHVua25vd24gZmllbGRzIGFyZSBQRVJNSVRURUQs
IGFuZCB0aGUgcHJvc2UgbmFtZXMgdGhpcyBibG9jaydzIG93bgogICAgIyBleGFtcGxlczogInRoZSBlc3RhdGUncyBjb250cmFj
dGlsZXMgdXNlIGBwcm9iZV9zY29wZWAgYW5kCiAgICAjIGBhdXRob3Jpc2VkX3Byb2Jlc19vbmx5YCIuIE5vIGNvbmZvcm1pbmcg
cmVhZGVyIG1heSBsZXQgb25lIG9mIHRoZW0KICAgICMgd2Vha2VuIMKnOCBvciDCpzkg4oCUIHRoZSBncmFudCBhYm92ZSBpcyB3
aGF0IGEgaG9zdCBlbmZvcmNlcy4KICAgIC4uCiAgfSwKCiAgUGVkaWdyZWUgPSB7CiAgICAjIMKnNS4yIOKAlCBhIG51bWVyaWMg
ZG90LXRyaXBsZSB3aG9zZSBtYWpvciBzZWdtZW50IGVxdWFscyBgc2NoZW1hX21ham9yYC4KICAgICMgQSBjb21wb25lbnQgZnJv
bSBhbm90aGVyIG1ham9yIGlzIG5vdCAib2xkZXIiOyBpdCBpcyB1bnJlYWRhYmxlLCBhbmQKICAgICMgbXVzdCBiZSByZWZ1c2Vk
IHJhdGhlciB0aGFuIGd1ZXNzZWQgYXQgKMKnNS40KS4KICAgIHNjaGVtYV92ZXJzaW9uIHwgc3RkLmNvbnRyYWN0LmZyb21fcHJl
ZGljYXRlIChpc19zZW12ZXJfb2Ygc2NoZW1hX21ham9yKSwKICAgICMgwqc2LjIg4oCUIFJFUVVJUkVEOiB3aGF0IHRoaXMgY29t
cG9uZW50IElTLiBBIHRlbXBsYXRlIHBsYWNlaG9sZGVyIGlzIG5vdAogICAgIyBhIHZhbHVlOyB0aGUgY2Fub25pY2FsIHZhbGlk
YXRvciByZWplY3RzICJUT0RPIiBoZXJlIGF0IEwxLgogICAgY29tcG9uZW50X3R5cGUgfCBTdHJpbmcsCiAgICBzZWN1cml0eSB8
IFNlY3VyaXR5LAogICAgbWV0YWRhdGEgfCBNZXRhZGF0YSwKICAgICMgwqc2LjUg4oCUIGFkdmlzb3J5IHRvIGEgcmVhZGVyLCBt
YW5kYXRvcnkgdG8gZGVjbGFyZS4gQSAnSHVudCBjb21wb25lbnQKICAgICMgd2l0aCBhbiBlbXB0eSBzaWRlX2VmZmVjdHMgbGlz
dCBjbGFpbXMgZnVsbCBzeXN0ZW0gYWNjZXNzIGFuZCBkZXNjcmliZXMKICAgICMgbm9uZSBvZiBpdCwgd2hpY2ggdGhlIHZhbGlk
YXRvciByZWplY3RzIGF0IEwxLgogICAgd2FybmluZ3MgfCBBcnJheSBTdHJpbmcgfCBkZWZhdWx0ID0gW10sCiAgICBzaWRlX2Vm
ZmVjdHMgfCBBcnJheSBTdHJpbmcgfCBkZWZhdWx0ID0gW10sCiAgICAjIMKnMTAuMSDigJQgdGhlIHNpZ25hdHVyZSBjbGFpbS4g
UHJlc2VuY2UgaXMgcGVyLWxlYXNoOyBzZWUgU2lnbmF0dXJlIGFib3ZlLgogICAgc2lnbmF0dXJlIHwgU2lnbmF0dXJlIHwgb3B0
aW9uYWwsCiAgICAjIMKnNS41IOKAlCB1bmtub3duIGZpZWxkcyBhcmUgUEVSTUlUVEVELiBUaGlzIGlzIHRoZSBsaW5lIE1JR1JB
VElPTi0xMDU4IE0xCiAgICAjIHR1cm5lZCBvbjogdGhlIGNvbnRyYWN0aWxlIGZhbWlseSBrZWVwcyBpdHMgb3duIHZvY2FidWxh
cnkgaW4gdGhlIHBlZGlncmVlCiAgICAjIChgc2VtYW50aWNzYCwgYGNvbnRyYWN0aWxlX3ZlcmJgLCBgdGllcmAsIGBhdXRob3Jp
dHlgLCBgdmFyaWFuY2Vfc2NoZW1hYCwKICAgICMgYGV4ZWN1dGlvbmAsIGBmYWlsdXJlX21vZGVfZGVmZW5zZXNgKSwgYW5kIG5v
dGhpbmcgaW4gdGhpcyBmaWxlIG1heSBmb3JjZQogICAgIyB0aG9zZSBuYW1lcyBvdXQgb2YgaXQuCiAgICAuLgogIH0sCgogICMg
VGhlIHdob2xlIGNvbXBvbmVudDogdGhlIHBlZGlncmVlIHBsdXMgdGhlIG9wdGlvbmFsIE5pY2tlbCBwYXlsb2FkLgogICMgYGNv
bmZpZ2AsIGByZWNpcGVzYCBhbmQgYHZhbGlkYXRpb25gIHN0YXkgb3BlbiBvbiBwdXJwb3NlIOKAlCB0aGV5IGFyZSB0aGUKICAj
IGNvbXBvbmVudCdzIG93biBidXNpbmVzcyDigJQgYnV0IMKnNi43IG1ha2VzIG9uZSB0aGluZyBub24tbmVnb3RpYWJsZTogYQog
ICMgbm9uLWVtcHR5IGByZWNpcGVzYCBibG9jayBpcyBhbiBleGVjdXRpb24gc3VyZmFjZSBhbmQgdGhlcmVmb3JlIGZvcmNlcwog
ICMgJ0h1bnQuIFRoZSB2YWxpZGF0b3IgZW5mb3JjZXMgdGhhdDsgdGhpcyBjb250cmFjdCBvbmx5IHNoYXBlcyB0aGUgYmxvY2tz
LgogIENvbXBvbmVudCA9IHsKICAgIHBlZGlncmVlIHwgUGVkaWdyZWUsCiAgICAjIEFuIG9wZW4gcmVjb3JkOiBhbnkgZmllbGRz
LCBhbnkgdmFsdWVzLiBUaGVzZSB0aHJlZSBibG9ja3MgYXJlIHRoZQogICAgIyBjb21wb25lbnQncyBvd24gYnVzaW5lc3MgYW5k
IHRoZSBjb250cmFjdCBkZWxpYmVyYXRlbHkgZG9lcyBub3Qgc2hhcGUKICAgICMgdGhlbSDigJQgwqc2LjcncyBgcmVjaXBlc2At
Zm9yY2VzLSdIdW50IHJ1bGUgaXMgZW5mb3JjZWQgYnkgdGhlIHZhbGlkYXRvcgogICAgIyBvdmVyIHRoZSBleHRyYWN0ZWQgZmFj
dHMsIG5vdCBieSBhIHR5cGUgaGVyZS4KICAgICMKICAgICMgVHdvIG5hbWVzIHdlcmUgdHJpZWQgYW5kIHJlamVjdGVkIGJ5IE5p
Y2tlbCBiZWZvcmUgdGhpcyBvbmU6IGBSZWNvcmRgCiAgICAjIGFuZCB0aGVuIGBBbnlgLiBOZWl0aGVyIGV4aXN0czsgdGhlIGR5
bmFtaWMgdHlwZSBpcyBgRHluYC4gQm90aCBmYWlsdXJlcwogICAgIyB3ZXJlIGludmlzaWJsZSBsb2NhbGx5IOKAlCBubyBuaWNr
ZWwgYmluYXJ5IGlzIG9idGFpbmFibGUgaW4gdGhlIHNhbmRib3gKICAgICMgdGhhdCB3cm90ZSB0aGlzIGZpbGUg4oCUIGFuZCBi
b3RoIG1hZGUgZXZlcnkgTDIgdmVyZGljdCBkb3duc3RyZWFtIHZvaWQsCiAgICAjIGJlY2F1c2UgYSBjb250cmFjdCB0aGF0IGRv
ZXMgbm90IHR5cGVjaGVjayBjYW5ub3QganVkZ2UgYW55dGhpbmcuIFRoYXQKICAgICMgaXMgd2h5IGs5LWNvbnRyYWN0aWxlLnlt
bCBub3cgdHlwZWNoZWNrcyB0aGlzIGZpbGUgYXMgaXRzIG93biBuYW1lZCBzdGVwCiAgICAjIGJlZm9yZSB0aGUgZml4dHVyZXMg
cnVuLgogICAgY29uZmlnIHwgeyBfIDogRHluIH0gfCBvcHRpb25hbCwKICAgIHJlY2lwZXMgfCB7IF8gOiBEeW4gfSB8IG9wdGlv
bmFsLAogICAgdmFsaWRhdGlvbiB8IHsgXyA6IER5biB9IHwgb3B0aW9uYWwsCiAgICAjIMKnNS41IOKAlCB1bmtub3duIGZpZWxk
cyBhcmUgUEVSTUlUVEVEIGF0IHRvcCBsZXZlbCB0b28sIHdoaWNoIGlzIHRoZSBjYXNlCiAgICAjIE1JR1JBVElPTi0xMDU4IE00
IHJlY29yZGVkIGZvciB3aG9ldmVyIGZpcnN0IHJhbiB0aGUgY29ycHVzIGF0IEwyOgogICAgIyBgMi1wcm90b2NvbHMvYXhlbC9j
b25maWcvKi5rOS5uY2xgIGtlZXAgdGhlaXIgcGF5bG9hZCAoYGNpYCwgYGxvY2FsX2RldmAsCiAgICAjIGBxdWFsaXR5YDsgYG1l
dGFkYXRhLms5Lm5jbGA6IGBwcm9qZWN0YCwgYHRlY2hfc3RhY2tgLCBgZGVwbG95bWVudGAsCiAgICAjIGBmZWF0dXJlc2AsIGBz
dGF0dXNgKSBiZXNpZGUgYHBlZGlncmVlYC4KICAgIC4uCiAgfSwKCiAgIyDilIDilIAgwqcxMSBMaWJyYXJ5IGRpYWxlY3Qg4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgIwogICMgQSBsaWJy
YXJ5IGlzIGltcG9ydGVkOyBpdCBpcyBuZXZlciBleGVjdXRlZCBhcyBhIGNvbXBvbmVudCBhbmQgbmV2ZXIKICAjIGNhcnJpZXMg
YW4gZW52ZWxvcGUuIFRoZSBjb250cmFjdCBpdCBtdXN0IHNhdGlzZnkgaXMgdGhlIG5lZ2F0aXZlIG9uZToKICAjIG5vIHBlZGln
cmVlLCBubyBsZWFzaCBjbGFpbSwgbm8gZXhlY3V0aW9uIGxpY2VuY2Ugb2YgYW55IGtpbmQuCiAgaXNfbGlicmFyeSA9IGZ1biBs
aWIgPT4KICAgICEoc3RkLnJlY29yZC5oYXNfZmllbGQgInBlZGlncmVlIiBsaWIpCiAgICAmJiAhKHN0ZC5yZWNvcmQuaGFzX2Zp
ZWxkICJsZWFzaCIgbGliKSwKfQo=

idempotence

idempotent: yes

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-N001 K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 13 conforming, 5 grandfathered (layer all, contract v1.0.0)

hyperpolymath and others added 7 commits October 5, 2026 04:47
MIGRATION-1058 M2 offered two outcomes: (a) rename the twelve
3-practice/session-management-standards/*/*/PROTOCOL.k9 stubs to
PROTOCOL.yaml, or (b) give them a K9 envelope and a registered dialect.
Ruling: (a). They are plain YAML session-management contracts that no K9
host loads; (b) would invent a dialect to preserve a naming collision.

- git mv all 12 PROTOCOL.k9 -> PROTOCOL.yaml (contents otherwise unchanged)
- add MPL-2.0 SPDX headers to the 11 that lacked one: *.yaml is inside
  .githooks/validate-spdx.sh's scope, the .k9 suffix was not
- shrink .machine_readable/k9-contract-debt.txt: 17 -> 5 entries
- repoint the scorecard's dead 1-formats/k9/actions/validate/validate-k9.sh
  path at 1-formats/k9/tools/k9-validate.sh; re-grade S1 as pass on the
  extension-reservation rule with an executable check; refresh the M1-M4
  and S4 suffix/line-count references
- update README Protocol File Contract, substantial-completion CHECKLIST,
  K9-CONTRACT-SPEC 4.2 (also fixes its "migration item M4" -> M2),
  MIGRATION-1058 M2 (ruling recorded), and the k9-contractile CI comment
- regenerate REGISTRY.a2ml (source_hash covers the home) and the derived
  COMPLIANCE-DASHBOARD.adoc; the regeneration also clears 3 pre-existing
  registry drifts (1-formats/k9, 2-protocols/axel, form-fill-provenance)

Clears K9-E005 x12 and K9-E004 x11; no session-management path is in the
hook's violation list any more, stale-ledger is 0, and the 8 remaining
violations are the pre-existing contractile/Axel items owned by #A/#C/#D.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
The six contractile components imported `../k9/template-hunt.k9.ncl`,
which does not exist (there is no k9/ subdirectory under
.machine_readable/contractiles/), so K9-S013 fired and the pedigree a
reviewer read was not the one a host would evaluate. They now merge
`base.pedigree_schema` from ../_base.ncl and declare the §5.5 core:
schema_version, `component_type = "contractile:<verb>"`, semantics and
security (the §8.4 capabilities that pay for each allow_* flag).

Leash discipline is unchanged: adjust and dust are 'Yard (config-only
substrate, §7.3 caps); bust, intend, must and trust are 'Hunt. The four
Hunt components gain the §6.5/§9 material they need to be evaluated —
signature_required, a signature block (verdict 'Present_Unverified, per
§10.2/§10.4; not yet authorised to run) and 3 irreducible side_effects.
variance_schema is marked `not_exported`: its fields are contract
declarations with no definitions, which Nickel's export refuses to
serialize.

Naming: the `contractile:` component_type prefix is the sole tie between
the contractile family (must/trust/dust/intend) and K9's execution triad
(must/just/nickel). The K9 contract never names a contractile verb, so
DEED translation renames nothing.

Ref #1058

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Two paragraphs of K9-CONTRACT-SPEC still described the six contractiles as
broken, and one of them named the wrong migration item:

* §11.2 claimed all six carried a pedigree "and no envelope"; the envelope was
  already line 1 of all six when that was checked against the tree, so K9-S012
  never had a live instance. The paragraph described the pre-envelope revision
  and is now marked resolved, pointing at what actually remained (component_type,
  the §8.4 grant, and the §6.5/§9 Hunt material).
* §11.4 claimed all six imported "../k9/template-hunt.k9.ncl" and were a live
  K9-S013 instance. The import now resolves to ../_base.ncl, so the paragraph is
  recorded as fixed rather than live.

MIGRATION-1058 gains "M1 — resolved (2026-10-05)" in the shape M2/M3/M4 used:
the three corrections (envelope already present, the import's real source, the
ledger's entries already removed), the naming resolution stated in full (the
`contractile:` component_type prefix is the entire tie between the contractiles
family and K9's execution triad, so DEED translation renames nothing), the
'Yard request-vs-permission reading for adjust/dust, and the L2 caveat this
item does not close: §5.5 permits the contractiles' extension fields but the
contract's record contracts are closed by default, so the corpus-at-L2 item
(#F/M7) needs a `..` tail on Component/Pedigree/Security.

Ref #1058 (M1 · #A).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…ity (#1058)

The note recorded in 47751ee named "top-level variance_schema" as an extra
field on Component. Reading the six files' structure rather than their
reports: nothing is top-level but `pedigree`, and every contractile field is
inside it — pedigree.semantics/contractile_verb/tier/authority/
variance_schema/execution/failure_mode_defenses, and
security.probe_scope/probe_kinds_*/allow_filesystem_write_conditional. An L2
pass would blame Pedigree and Security, not Component (Component is M4's note,
for components that keep a payload at top level). Naming the fields correctly
matters to whoever picks up #F/M7 and has to make the blame go away.

Ref #1058 (M1 · #A).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
§5.5's table ends with "Unknown fields anywhere | PERMITTED". The
machine-readable contract did not implement that: Component, Pedigree,
Metadata, Security and Signature in k9_contract.ncl were plain Nickel
record contracts, which are CLOSED by default, so any component carrying a
legitimate extension field was blamed with "extra field" — the sharp edge
Nickel records in its own suite as
core/tests/integration/inputs/contracts/record_contract_extra_field.ncl.

The live cases are the six `.machine_readable/contractiles/*/*.k9.ncl`
components (pedigree.tier/authority/semantics/contractile_verb/
variance_schema/execution/failure_mode_defenses, security.probe_scope/
probe_kinds_*/allow_filesystem_write_conditional, metadata.paired_xfile/
paired_runner) and the two `2-protocols/axel/config/*.k9.ncl` files, which
keep their payload at top level. Both were recorded as M7's problem by
MIGRATION-1058 M1 and M4 — this is that fix.

The five records now take a `, ..` tail. By the contract's own first rule
— the prose wins and the file is the bug — this is a conformance fix, not
a contract revision, so `contract_version` stays 1.0.0. It relaxes nothing
in §8 or §9: §5.5 forbids consulting an unknown field to grant access, and
the validator's capability arithmetic still runs over the extracted facts.
HuntEvidence stays closed on purpose (host-side evidence, §9.2).

New positive control `tools/fixtures/valid/extension-fields.k9.ncl`, shaped
like a contractile: extension fields at four levels plus a declaration-only
`variance_schema` marked `not_exported`, so L2 exercises `nickel export`
too, not only the typecheck. It fails the moment any of the tails is
removed, which is what nothing in the suite could do before. Suite is now
6 positive / 21 negative; the self-test's keyword-scan label (hardcoded
count) follows.

CI: the corpus step now sets K9_VALIDATE_LAYER=all, so the whole corpus is
checked at L2 where the pinned binary is installed. The pre-commit hook
keeps its L1 default — a hook that fails on a laptop without a toolchain is
a hook people bypass — and ledger entries stay advisory at either layer.
This is MIGRATION-1058 M7's first step: the five grandfathered files are
reported, not failed, and still need their own items (M3, M5).

Verification here is L1-only by construction: no nickel binary is obtainable
in this environment (release-asset host TLS-refused; MIGRATION-1058 §L2
records the limitation). `--self-test` all assertions passed; `--fixtures`
6 positive, 21 negative; the hook is clean at L1 and reports 5 grandfathered
at L2. The L2 verdict itself is CI's to give, which is the point of raising
the layer there.

Ref #1058 (M1 · #A follow-up, M4 · #D follow-up, M7 · #F started).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
`source_hash` is sha256 over `git ls-files -s <home>`, so two homes moved:

* `1-formats/k9/` — the new positive control
  `tools/fixtures/valid/extension-fields.k9.ncl`;
* `2-protocols/axel/` — M4's pedigree fix (`leash` moved under
  `pedigree.security`), which was cherry-picked onto this branch with the
  release-pre-flight scorecard but not with a registry regeneration.

`bash scripts/build-registry.sh --check` now passes, as do
`build-scorecards.sh --check --strict` and a link-rot diff against the
pre-change tree (the two `{contract-file}` findings on K9-CONTRACT-SPEC
predate this branch).

Ref #1058.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
`nickel format --check` has failed on this file in ci-pipeline.yml since it
landed — on main (`a41f369`) as much as on this branch, which the Nickel job's
annotations show. No `nickel` binary is obtainable in this environment, so a
temporary CI step printed the formatter's output and this commit applies it
byte-for-byte (sha256
d68f75cb5662bd2af9b219203b43e6ecd84270a15612b8bb5018bc7e98608c7b, verified
idempotent by a second pass). The step is not in the tree: this commit is the
whole of the change.

Nothing semantic changes: continuation-operator indentation (`||`, `&&`, `@`,
`++`) moves under its operator, `in` gets its own line, one comment header loses
a blank line. The formatter did NOT touch the §5.5 `..` tails or any comment
added by this branch, which is itself evidence that the record-contract syntax
is canonical Nickel. `--self-test` still passes, so `contract_version` and
`schema_major` still mirror the validator.

Ref #1058.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
@hyperpolymath
hyperpolymath force-pushed the arena/01a10a3b-standards branch from 44f30e6 to 42bef07 Compare October 5, 2026 04:48
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Autopilot could not be updated. Open Coding to check access and billing.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37265105561

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ok   extension-fields.k9.ncl
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)

K9 corpus conformance (L2)

[validate-k9] debt .machine_readable/svc/k9/examples/setup-repo.k9.ncl (fail) — K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-hunt.k9.ncl (fail) — K9-S003 K9-S005 K9-S007 K9-S009 K9-S010 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-kennel.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt .machine_readable/svc/k9/template-yard.k9.ncl (fail) — K9-S003 K9-S005 (grandfathered; touching it makes it blocking)
[validate-k9] debt rhodium-standard-repositories/rsr-compliance-checklist.k9.ncl (fail) — K9-N001 K9-S004 K9-S005 K9-S014 (grandfathered; touching it makes it blocking)
[validate-k9] 13 conforming, 5 grandfathered (layer all, contract v1.0.0)

@sonarqubecloud

sonarqubecloud Bot commented Oct 5, 2026

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit aa1c4dd into main Oct 5, 2026
59 of 66 checks passed
@hyperpolymath
hyperpolymath deleted the arena/01a10a3b-standards branch October 5, 2026 04:49
hyperpolymath added a commit that referenced this pull request Oct 5, 2026
…ormatted

`source_hash` covers every tracked file in a home, so `nickel format` on
`1-formats/k9/spec/contract/k9_contract.ncl` moved the `1-formats/k9/` hash
again — one commit after the earlier regeneration. Registry Verify caught it on
main (`aa1c4dd`), which is the check doing its job.

`bash scripts/build-registry.sh --check` passes again; the only changed line is
the `1-formats/k9/` source_hash. Scorecards and the compliance dashboard were
already in sync.

Follow-up to #1149 (M1 · #A, M7 · #F).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 5, 2026
The #1149 squash (M1 contractiles + M2 PROTOCOL.k9 rename) touched 9 files
under 1-formats/k9/ but shipped the home's source_hash from before those
edits, so origin/main is red on "Registry + topology in sync" and on the
Justfile validate chain (registry-check is a hard dependency there).

`just registry`: one hash line changes; TOPOLOGY.adoc is unchanged.
`build-registry.sh --check` and `build-scorecards.sh --check --strict` both
green after.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
hyperpolymath added a commit that referenced this pull request Oct 5, 2026
…1149 follow-up) (#1151)

Follow-up to #1149 (merged as `aa1c4dd`), which landed one commit too
early: `nickel format` on `1-formats/k9/spec/contract/k9_contract.ncl`
moved the `1-formats/k9/` `source_hash` **after** the registry had been
regenerated, so `Registry Verify` failed on main.

`source_hash` is `sha256(git ls-files -s <home>)`, so the formatted
contract — not just the new fixture — is part of the hash. This
regenerates `.machine_readable/REGISTRY.a2ml`; the only changed line is
that one hash.

```
bash scripts/build-registry.sh --check                     → OK
bash scripts/build-scorecards.sh --check --strict          → OK (dashboard in sync)
1-formats/k9/tools/k9-validate.sh --self-test              → all assertions passed
K9_VALIDATE_LAYER=all bash .githooks/validate-k9.sh        → 13 conforming, 5 grandfathered
```

Refs: #1058 (M1 · #A, M7 · #F).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>

Copy link
Copy Markdown
Owner Author

The must naming-collision resolution — stated, not implied

Added after merge to satisfy the issue's second ask (#1058), which the merged body above does not carry.

Ruling. The K9 contract never names a contractile verb. A contractile component is an ordinary K9 component whose component_type begins contractile: — component_type = "contractile:<verb>", e.g. "contractile:must". That prefix is the entire tie between the contractiles family (must/trust/dust/intend) and K9's execution triad (must/just/nickel); it is the only name K9 machinery ever sees. DEED translation renames nothing this specification depends on, and the contractile family keeps its verbs.

Consequently no .k9.ncl file, contract rule, or validator branch is keyed on a bare verb, and the collision cannot recur as a resolution-order question in any consumer.

Where it lives in the tree: 1-formats/k9/spec/MIGRATION-1058.adoc, §M1 → "Naming resolution, stated rather than implied" (commit 5eba67d, merged in aa1c4dd).

Adjacent decisions recorded in the same section: adjust/dust are 'Yard requesting fs.write + process.spawn (the leash is the cap, so these record the request); bust/intend/must/trust are 'Hunt with placeholder signature claims, so §10.2 keeps them 'Present_Unverified and §10.4 leaves them unauthorised to run until the signing ceremony replaces the placeholder key.

hyperpolymath added a commit that referenced this pull request Oct 5, 2026
Resolve conflicts by accepting main branch changes for:
- REGISTRY.a2ml (hash updates from #1151, #1149)
- k9-contract-debt.txt (ledger updates)
- k9_contract.ncl (template file references)

This incorporates all changes from main into the PR branch.
hyperpolymath added a commit that referenced this pull request Oct 6, 2026
<!--
SPDX-License-Identifier: CC-BY-SA-4.0
Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
-->
## Summary

This turns `K9-SVC Contractile Validation` green on `main`.

#1154 removed the `..` tails from the five component-facing records in
`1-formats/k9/spec/contract/k9_contract.ncl` (`Component`, `Pedigree`,
`Security`, `Metadata`, `Signature`), and deleted the comments that
explained them. Nickel record contracts are closed by default, so the
contract again rejected extension fields that SPEC §5.5 permits
("Unknown fields anywhere | PERMITTED"). As a result the positive
control `tools/fixtures/valid/extension-fields.k9.ncl` failed K9-N001 at
L2, which made main red.

**Owner ruling D310** (standards#787, 2026-10-06): `K9.Component` is an
**open** record. This PR restores the tails and their rationale exactly
as #1149 wrote them. It keeps #1154's one real improvement, the
`.k9.ncl.in` template wording. `HuntEvidence` stays **closed** (§9.2
host evidence, where a misspelt field must be an error), and its comment
saying so is restored.

Closes #1165

## Type of change

- [x] 🐛 Bug fix (non-breaking change that fixes an issue): contract
conformance to §5.5; `contract_version` stays 1.0.0, because the prose
never changed.
- [ ] ✨ New feature: no
- [ ] 💥 Breaking change: no. This only widens acceptance to what §5.5
already permits.
- [ ] 🕳️ Soundness fix: not a checker false-negative. It fixes a
false-*positive* rejection.
- [ ] 📖 Documentation: comments only, restored with the code they
explain
- [ ] 🧹 Refactor: no
- [ ] ⚡ Performance: no
- [ ] 🔧 Build / CI / tooling: no workflow change

## 📌 New pins

Head SHA: **51321ad504550233854297a892e420d81e3635b8**. This PR adds or
changes no action pins, `actions.lock` entries, lockfiles or container
digests.

## How has this been verified?

Run locally with `nickel 1.17.0`. CI pins 1.18.0.
- `nickel typecheck 1-formats/k9/spec/contract/k9_contract.ncl` → rc 0
- `1-formats/k9/tools/k9-validate.sh --strict --fixtures fixtures` →
`fixtures: 6 positive, 21 negative (0 needing nickel), 0 failure(s)`
- **The control can fail.** With main's contract (`git show
origin/main:…`) swapped back in, the same command gives `ERROR K9-N001
[L2] fixtures/valid/extension-fields.k9.ncl: … extra fields
failure_mode_defenses, execution` → `1 failure(s)`, the exact CI error
on main.

**#1165 acceptance item 3** asks that the fix not open the contract
wholesale. The tails admit only *unknown names*. Known fields keep their
contracts, as the negatives that still fail show:
- `L2-K9-N001-wrong-field-type` (a declared field with a wrong type,
rejected at L2)
- `L2-K9-N001-two-segment-version`
- `L1-K9-S004-unknown-leash` (an unknown tag in the closed
`SecurityLevel` set)
- `HuntEvidence` remains closed.

§5.5's last clause (an unknown field never relaxes §8/§9) is enforced by
the validator's capability arithmetic, which this PR leaves unchanged
(K9-S007/S008 negatives pass).

## Checklist

- [x] My commits are **signed**: `git log --format=%G?` → `G`.
- [x] I ran the project's own checks/tests locally and they pass: the
pre-commit suite and `k9-validate.sh --strict --fixtures`, as above.
- [x] SPDX: no new files; the existing MPL-2.0 header is untouched.
- [x] Docs are updated, and no public claim overstates the code. The
restored comments describe the restored behaviour.
- [x] No soundness hole: see item 3 above.

## Notes for reviewers

- #1154 was titled "Pr 1148 fixed" with an empty template, so its
removal of the tails did not look deliberate. D310 now settles the
direction.
- Local nickel is 1.17.0 against CI's 1.18.0. CI is the authority.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01D6JVLvmCeSFGcY6jSNesbL

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant