// SPDX-License-Identifier: CC-BY-SA-4.0
= K9 SVC Specification
:subtitle: Self-Validating Components for Multi-Architecture Permanence
:author: hyperpolymath
:revnumber: 1.0.0
:revdate: 2026-06-03
:toc: left
:toclevels: 3
:icons: font
:source-highlighter: rouge
:sectnums:

== Abstract

This specification defines the `.k9` file format—a Self-Validating Component (SVC)
architecture designed to replace passive, opaque file types with active,
self-validating, and environment-aware components.

The format operates via the **must-just-nickel** triad: environment detection (must),
task orchestration (Just), and typed validation (Nickel).

[IMPORTANT]
.Naming hazard — keep these distinct
====
K9's execution triad is *must / just / nickel*. It is *not* the contractiles
family *must / trust / dust / intend*, which is a separate estate concept. The
word `must` appears in both and means different things; never conflate them.
====

== Status

[cols="1,2"]
|===
|Standard ID |`application/vnd.k9+nickel`
|Version |1.0.0
|Stability |Stable
|Magic Number |`K9!` (`\x4B\x39\x21`)
|===

== Problem Statement

Traditional file formats are **passive containers**. They rely entirely on external
host applications to interpret, validate, and deploy their content.

This creates several failure modes:

[horizontal]
Bit Rot:: Data survives but the logic to interpret it dies, especially on
specialized environments like Minix, ASICs, or Edge nodes.

Platform Lock-in:: Files require specific applications (MS Office, Adobe, etc.)
to function, creating vendor dependencies.

Silent Corruption:: Invalid data isn't detected until runtime failure, often
after critical decisions have been made.

Deprecation Treadmill:: Formats evolve, old versions become unreadable, and
migration is manual and error-prone.

== Solution: The Active Pedigree

The `.k9` format introduces **agency as a document property**.

By embedding the must-just-nickel triad, a `.k9` file carries its own
"digestive system." It doesn't just store data—it stores the contracts
(Nickel) to validate it and the recipes (Just) to deploy it.

=== The Dogfooding Principle

A `.k9` repository is "Alpha-Ready." This means the repository uses its own
format to manage itself. The build system, the MIME registration, and the
documentation are all generated by the `.k9` components within the repo.

If the file can't "eat its own config," it refuses to run.

== Technical Architecture

=== Layer Model

[cols="1,2,3,3"]
|===
|Level |Name |Component |Function

|L1
|The Scent
|Magic Number + MIME
|OS/kernel-level recognition

|L2
|The Brain
|Nickel Contracts
|Logical integrity and security enforcement

|L3
|The Muscle
|Just Recipes
|Multi-platform deployment (ASIC to PC)

|L4
|The Pack
|SVC Interface
|Living document / dogfooding lifecycle
|===

=== L1: The Scent (Identity)

Every `.k9` file begins with a magic number for immediate kernel identification:

[source]
----
Offset: 0x00
Value:  0x4B 0x39 0x21 (ASCII: "K9!")
----

MIME registration uses Freedesktop XML on Linux/Minix and UTI plists on macOS.

=== L2: The Brain (Nickel Contracts)

Nickel provides typed, functional configuration. Key contracts:

[source,nickel]
----
let SecurityLevel = [| 'Kennel, 'Yard, 'Hunt |] in
let Architecture = [| 'Linux, 'Minix, 'MacOS, 'Android, 'PC, 'ASIC |] in

K9Pedigree = {
  metadata | Metadata,
  target | Target,
  security | Security,
  validation | Validation,
  recipes | Recipes,
}
----

All data must pass these contracts before deployment.

=== L3: The Muscle (Just Orchestration)

Just recipes handle environment-specific deployment:

[source,just]
----
deploy:
    @if command -v podman >/dev/null 2>&1; then \
        just deploy-podman; \
    else \
        just deploy-native; \
    fi
----

Podman-first deployment prevents host pollution while supporting native fallback.

== Security Model

=== The Leash System (Normative)

To prevent abuse, `.k9` mandates tiered execution levels. These are NORMATIVE:
an implementation MUST enforce them. The canonical encoding is `leash.ncl`.

[cols="1,2,3",options="header"]
|===
|Level |Name |Rule

|`'Kennel`
|Data-only
|No evaluation of any kind. Read/parse/display only. Safe to open anywhere.

|`'Yard`
|Contract-eval-only
|Nickel contract evaluation permitted. NO filesystem access, NO network, NO
 subprocess. Pure, side-effect-free.

|`'Hunt`
|Controlled execution
|Triad execution permitted — but ONLY when all five Hunt preconditions hold
 (below). Any unmet precondition refuses execution and downgrades to `'Yard`.
|===

==== Hunt preconditions — all five, always

Owner directive (2026-06-03): Hunt requires *all five* of the following,
*always*. There is no configurable subset, and a valid signature alone is
NOT sufficient (this is the normative change from the alpha).

[cols="1,4",options="header"]
|===
|Precondition |Meaning

|`signature` |A valid Ed25519 signature over the payload hash.
|`policy` |An explicit policy decision of `allow`.
|`sandbox` |An isolation sandbox is in force for the run.
|`dry_run` |A dry-run plan was produced (and reviewed).
|`capability_grant` |Every requested capability is explicitly granted (default-deny; see Capability Model).
|===

The gate is `authorize_hunt(evidence)` in `leash.ncl`: it permits `'Hunt` iff
all five evidence flags are true, and otherwise returns `permitted = false`,
`enforced_level = 'Yard`, and the exact list of unmet preconditions (which the
receipt records).

=== Dependability Collapse Prevention

**Dependability Collapse** occurs when security mitigations become so heavy
that users bypass them entirely, or the system fails its primary function.

K9 prevents this through:

[horizontal]
Contract Isolation:: Even if a Just recipe is compromised, it can only act
on resources explicitly granted by the Nickel contracts.

Fail-Fast Validation:: Invalid components refuse to execute rather than
proceeding with corrupt data.

Sandboxed Evaluation:: Nickel evaluation is functionally pure—no side effects
until explicitly permitted.

=== Threat Model

[cols="1,2,2"]
|===
|Threat |Vector |Mitigation

|Malicious Payload
|Crafted `.k9` with hostile Just recipe
|`'Hunt` level requires signed handshake

|Interop Monoculture
|Single Nickel vulnerability affects all platforms
|Contract isolation limits blast radius

|Complexity Exhaustion
|Validation too heavy for Edge/ASIC
|`'Kennel` mode for constrained environments
|===

== Capability Model (Normative)

K9 is *default-deny*: a component is granted *no* capability unless it is
explicitly listed in its pedigree `policy.capabilities`. The leash checks the
grant before any Hunt-level action; an action needing an ungranted capability
is refused even at `'Hunt`. The canonical encoding is `capabilities.ncl`.

=== Closed core capabilities

The core capability set is *closed and exhaustive*. Adding or removing a core
capability is a breaking (MAJOR) change.

[cols="2,4",options="header"]
|===
|Capability |Grants

|`fs.read` |Read named filesystem paths.
|`fs.write` |Write named filesystem paths.
|`net.fetch` |Outbound network fetch to named hosts.
|`process.spawn` |Spawn a child process.
|`container.run` |Run a container image.
|`secret.read` |Read a named secret.
|`deploy.apply` |Apply a deployment.
|`rollback.apply` |Apply a rollback.
|===

=== Reserved extension namespace

Non-core capabilities MUST be namespaced `x-<vendor>.<path>` (e.g.
`x-acme.gpu.alloc`) so they can never collide with a future core name. Core
names (no `x-` prefix) are reserved to this specification.

== The Active Pedigree (Seven Sections)

v1.0.0 restructures the pedigree (`pedigree.ncl`) into seven explicit, named
sections. Two are new in v1.0.0: *recovery_recipe* and *docs_rationale*.

[cols="1,2,4",options="header"]
|===
|# |Section |Purpose

|1 |`metadata` |Identity: name, version, breed, magic number.
|2 |`validation_contract` |What MUST pass first: checksum, the contract files to evaluate, fail-closed flag.
|3 |`policy` |Leash level + capability grant (default-deny) + target environment.
|4 |`deploy_recipe` |install / validate / deploy / migrate.
|5 |`recovery_recipe` |*(new)* rollback / recover / verify-recovery / backup. A deploy is only as safe as its rollback.
|6 |`signature` |Cryptographic provenance (Ed25519, key id, signed payload hash).
|7 |`docs_rationale` |*(new)* human summary + rationale, and the single soft A2ML cross-reference (below).
|===

== Evidence and Receipts

Every K9 run emits a *receipt*: the attested record of what the component did
and was permitted to do — component identity, contract result, enforced leash
level, capabilities granted/denied, signatures checked, dry-run plan, deploy
result, rollback result, policy decision, and (on failure) the reason.

The receipt is *canonical in A2ML* as the `a2ml/k9-receipt` profile, with a
*lossless JSON projection*. Both live under `receipt/`:

* `receipt/PROFILE.a2ml` — the canonical schema (an A2ML profile).
* `receipt/receipt.schema.json` — the lossless JSON projection.

Because the receipt's `component` block uses the A2ML base record vocabulary
(hash + provenance), a receipt is hash-pinned and attributable and cannot
desync from the artefact it describes. K9 is a *consumer* of A2ML here
(dependency direction K9 → A2ML); A2ML core ships only neutral primitives and
names no consumer.

== A2ML Cross-Reference (one soft field)

The pedigree carries exactly *one* soft cross-reference into A2ML:
`docs_rationale.a2ml_ref`. It points at an A2ML rationale/runbook artefact (a
repo-relative path, URI, or A2ML record id). It is *soft*: a dangling reference
is a WARNING, never a hard validation failure. This is the only A2ML bridge
field in the pedigree — K9 remains an independent foundation and does not
otherwise depend on A2ML.

[NOTE]
====
Naming hazard (restated): the soft reference and the runbook are about K9's
*must / just / nickel* triad, never the contractiles *must / trust / dust /
intend* family. Keep them distinct in all prose and tooling.
====

== Repository Requirements

To be listed as a conforming `.k9` repository:

[cols="1,3"]
|===
|File |Purpose

|`pedigree.ncl`
|Root Nickel file: the seven-section pedigree (metadata, validation_contract,
 policy, deploy_recipe, recovery_recipe, signature, docs_rationale)

|`leash.ncl`
|Leash modes + the normative `authorize_hunt` five-precondition gate

|`capabilities.ncl`
|Closed core capability set + reserved extension namespace (default-deny)

|`receipt/`
|Receipt schema: `a2ml/k9-receipt` profile + lossless JSON projection

|`justfile`
|Cookbook containing `install`, `validate`, `deploy`, `rollback`, `recover` recipes

|`must`
|Bootstrap script ensuring triad executes on target architecture

|`README.adoc`
|Human-readable entry point with bash bootstrap command

|`SPEC.adoc`
|This specification document (optional but recommended)
|===

== Path to MIME Recognition

=== Linux (Freedesktop)

[source,xml]
----
<mime-type type="application/vnd.k9+nickel">
  <comment>K9 Self-Validating Component</comment>
  <magic priority="50">
    <match value="K9!" type="string" offset="0"/>
  </magic>
  <glob pattern="*.k9"/>
</mime-type>
----

Location: `/usr/share/mime/packages/k9.xml`

=== macOS (UTI)

[source,xml]
----
<key>UTTypeIdentifier</key>
<string>org.k9-svc.component</string>
<key>public.mime-type</key>
<string>application/vnd.k9+nickel</string>
----

=== Minix

Static mapping in `/etc/mime.types`:

[source]
----
application/vnd.k9+nickel    k9
----

== Philosophy

The `.k9` format treats documents as **Living Entities**.

Where the MS Office suite locks data into proprietary silos, K9 liberates it.
Whether being read by a human via AsciiDoc or deployed to an ASIC via Just,
the integrity of the data remains absolute.

[quote]
A `.k9` file is not a document you open; it is a component you unleash.

== Appendix: The Triad in Detail

=== Must (Environment Shim)

POSIX shell script that:

1. Detects OS and architecture
2. Identifies edge/constrained environments
3. Ensures Nickel and Just are installed
4. Exports environment variables to the triad

=== Just (Task Runner)

Recipes for:

- MIME registration (`register-user`, `register-system`)
- Validation (`validate`, `validate-all`)
- Deployment (`deploy`, `deploy-podman`, `deploy-native`)
- Dogfooding (`dogfood`)

=== Nickel (Validation Engine)

Contracts for:

- Component metadata (name, version, breed)
- Target environment (OS, architecture, edge mode)
- Security level (Kennel/Yard/Hunt)
- Self-validation (checksum, pedigree version)
- Deployment recipes (install, validate, deploy, migrate)

== References

* https://nickel-lang.org[Nickel Language]
* https://just.systems[Just Task Runner]
* https://specifications.freedesktop.org/shared-mime-info-spec/[Freedesktop MIME Spec]
* https://developer.apple.com/documentation/uniformtypeidentifiers[Apple UTI Documentation]

== License

SPDX-License-Identifier: MPL-2.0
