kyyn-core 0.1.18

Core vocabulary for kyyn: registry, links, query AST, plugin and validation contracts for typed, git-backed knowledge bases.
Documentation
# kyyn-core

Core vocabulary for [kyyn](https://github.com/drshade/kyyn): the registry
(kinds, fields, roles, affordances), the universal link grammar, the
serializable query AST and typed builder, the source-plugin contract, and the
validation protocol a KB's schema crate speaks.

A KB's `schema/` crate depends on this; the engine and the schema meet only
through these types.

## Schema authoring

Rust remains the canonical schema language. Derive `KyynKind` on stored
record structs and `KyynType` on nested structs or enums; the derives generate
the existing `Registry` vocabulary rather than a second schema format:

```rust
#[derive(serde::Serialize, serde::Deserialize, kyyn_core::KyynKind)]
#[kyyn(kind = "todo", storage = "facts/todos/{id}.ron")]
struct Todo {
    id: String,
    #[kyyn(role = "title")]
    title: String,
    #[kyyn(link(allowed = ["todo"]))]
    blocked_by: Option<kyyn_core::link::Link>,
    #[kyyn(markdown)]
    notes: String,
}
```

`kyyn_schema!` assembles an explicit ordered kind list with the KB's roles,
queries, and optional custom-validation hook. Generic registry validation
always runs before custom findings are appended. Meaning Rust cannot infer —
Markdown rendering, roles, link policy and storage — must be explicit; an
ambiguous field is a compile error. Implement `KyynType` or `KyynKind`
manually for a representation outside the deliberately small derive surface.

Kind storage remains subject to Registry's existing ownership boundary: it
must be a relative path under `facts/` and may not contain `..`. `KyynKind`
reports that invariant at compile time; it does not introduce a macro-only
layout rule. For semantic annotations, do not shadow the standard `String`,
`Option`, `Vec`, or Kyyn `Link` names with unrelated types: early annotation
diagnostics identify those spellings before Rust resolves their definitions.

```rust,ignore
kyyn_core::kyyn_schema! {
    kinds: [Charter, Todo, SelfContext],
    roles: roles(),
    queries: queries(),
    custom_validate: validate::custom,
}
```

The optional custom hook has the same inputs as the protocol validator and
returns only its additional findings:

```rust,ignore
fn custom(
    entries: &[(String, String)],
    systems: &[&str],
) -> Vec<kyyn_core::violation::Violation> {
    for record in kyyn_core::schema::custom_records::<Todo>(entries) {
        // Typed cross-record/domain checks; generic Registry validation
        // already owns routing and parse findings.
        let todo = record.value;
    }
    Vec::new()
}
```

Schema `build.rs` files use the companion `kyyn-schema-build` crate to emit
the source hash consumed by `kyyn_schema!`; the hashing algorithm is shared
rather than copied into each KB.