kcode-k1-terms 0.2.1

Canonical K1 terms text, digest, signature verification, and Axum endpoint
Documentation
# Contract

## Public API

```rust
pub const REVISION: u64 = 1;

pub fn text() -> &'static str;
pub fn sha256() -> [u8; 32];
pub fn verify_acceptance(
    public_key: &[u8; 32],
    signature: &[u8; 64],
) -> Result<(), AcceptanceError>;
pub fn endpoint() -> axum::routing::MethodRouter;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum AcceptanceError {
    MalformedPublicKey,
    VerificationFailed,
}
```

`AcceptanceError` implements `Clone`, `Copy`, `Debug`, `Eq`, `PartialEq`, `Display`, and `std::error::Error`.

## Canonical bytes

`REVISION` is `1` for this unchanged approved terms text and its SHA-256 digest. It is the sole public revision owner for these canonical bytes.

`text()` returns the approved UTF-8 terms as one immutable static string. Paragraphs are separated by one LF blank line, and the final period is the final byte with no trailing LF. The terms are exactly 2,490 bytes.

Performance: Not yet benchmarked; it returns borrowed static storage in constant work with no package-owned allocation or I/O.

`sha256()` hashes exactly `text().as_bytes()` with SHA-256 and returns the 32 digest bytes. Any byte change creates a new digest and requires a new acceptance.

Performance: Not yet benchmarked; work is linear in the fixed 2,490-byte text, with a fixed 32-byte result and no package-owned heap allocation or I/O.

## Acceptance verification

`verify_acceptance()` performs strict Ed25519 verification directly over exactly `text().as_bytes()`. It does not verify a digest, prefix, serialization, JSON value, or wrapper. `MalformedPublicKey` means the supplied 32 bytes cannot decode as an Ed25519 public key. Every signature rejection is reported only as `VerificationFailed`.

Performance: Not yet benchmarked; it processes a fixed 32-byte key, 64-byte signature, and 2,490-byte message with at most one strict Ed25519 verification and no package-owned heap allocation or I/O.

## HTTP behavior

`endpoint()` constructs a pathless `MethodRouter` for the caller to mount. GET returns exactly the canonical text bytes with `Content-Type: text/plain; charset=utf-8`. HEAD uses Axum's ordinary GET-derived HEAD behavior: it succeeds with the same content type and no response body. The router does not accept or retain acceptance submissions.

Performance: Not yet benchmarked; it constructs one fixed pathless router, with Axum owning router and response allocations and no package-owned I/O.

Account persistence, registration, identity, authorization, and submission handling remain outside this API.