Skip to content

Propose: an additive client-side notation module (ckn) over the shipped verb surface #7

Description

@styk-tv

Summary

conceptkernel.org describes cklib as a notation-ready dispatch client, and Concept Kernel Notation — the nine strands χ · ρ · σ · α · γ · π · δ · φ ⟫ε — is published there as the canonical way to say what a kernel is and what to lay down in it. This proposes an additive module (working name ckn) that takes a CKN expression and assembles a construct on a live kernel by compiling it to the verbs that already ship in ck.js. Notation in, sealed construct out — no new transport, no new authority.

Motivation

Today an app or agent builds a multi-step construct by hand: a threaded sequence of create / link / transition / verify calls. A notation expression captures that same intent declaratively, in one form. A thin compiler closes the gap between the two without changing the surface beneath it — and gives every client (browser and Node) the same "one expression → one construct" surface.

Design sketch — grounded in the shipped surface

The module sits above ConceptKernel and composes only what ck.js already exposes:

Strand Compiles to (existing method)
χ / ρ — instances + properties k.create(type, body)
edges k.link(source, predicate, target)
τ — transitions k.transition(id, toState) (sealed-map gated server-side)
π — attestation k.verify(id) / k.provenance(id)
genome-plane declaration (new χ/ρ/σ/α/γ) k.propose(op, detail) ▸ k.vote(iri, value) ▸ k.apply(iri)

Declaring a new capability is a consented, multi-party act (propose ▸ vote ▸ apply), never a direct write — so the genome plane compiles to governance, and degrades honestly to gov_plane_unavailable where that plane isn't reachable, exactly like the existing _gov path.

The compiler's output is an ordered dispatch plan — a list of {verb, typed-payload} steps — not a graph. This preserves the invariant ck.js states in its own header: there is no RDF, quad store, or query engine on the client. The module adds notation sugar; it emits no query language and holds no authority of its own (pgCK remains the only authorization boundary — the handle is not).

Scope for a first slice

  • Instance plane first — buildable entirely on today's shipped verbs.
  • Genome plane gated — compiles to propose/vote/apply; honest degrade until reachable.
  • No client RDF — the AST is a dispatch plan, so the L1 store-not-graph invariant holds.

What I'm asking

  1. Does a notation compiler belong in cklib as an additive module — e.g. a notation subpath export beside the current . / ./client exports — keeping ck.js unchanged?
  2. Preferred module boundary and naming.
  3. Grammar scope for the first instance-plane slice.

I have a working reference implementation of this pipeline (parse → plan → assemble) validated end-to-end against a live kernel — an instance sealed with a real proof digest, sealed-map transitions, and re-verification — and I'm glad to contribute it or adapt it to whatever boundary the maintainers prefer.

Activity

  1. added
    enhancementNew feature or request
    questionFurther information is requested
    P1Priority 1 — this release
    on Jul 4, 2026
  2. styk-tv commented on Jul 4, 2026

    @styk-tv
    MemberAuthor

    Maintainer response — yes to the direction, as an additive ./notation subpath export, with the invariants as a hard acceptance bar. Answering the three in order.

    1. Does it belong in cklib? Yes — conditionally.

    A CKN→construct compiler is pure client-side compilation over cklib's own verb surface, so cklib is its natural home: every client (a browser page, a Node service, an agent harness, any consuming application) gets the "one expression → one construct" surface once, instead of each consumer re-implementing it. The deciding reason is coupling direction — the compiler emits payloads shaped to cklib's exact method contracts (create(type, body), link(source, predicate, target), transition(id, to_state), verify/provenance, propose/vote/apply). Those must version and be tested in lockstep with the surface they target; a separate package would perpetually chase our signatures. Co-location keeps them honest.

    It is "in" only if it holds the invariants that define this client — your sketch already commits to all of them, so I'm making them the bar:

    • Plan-emitter, not a graph. Output is an ordered [{verb, payload}] dispatch plan. No RDF, no quad store, no query language emitted — the L1 store-not-graph invariant in ck.js's own header stays true.
    • Zero authority. The compiler resolves / evaluates / traverses nothing; every step goes through ckp.dispatch and is governed server-side. pgCK stays the only authorization boundary; the plan is a proposal, the server still gates each step — decisive in the untrusted-JWT posture the client runs under.
    • ck.js unchanged. The module sits strictly above ConceptKernel, consuming only its public methods. No new core methods, no new transport.
    • Zero runtime deps, vendored / air-gapped, offline-testable. The parser pulls nothing into the bundle; compile() is pure (no I/O) so it tests without NATS, exactly like the existing smoke-*.mjs.
    • Separately importable. Core clients that never import it pay nothing at runtime. (In the OCI bundle the file lands at image root beside the others — a browser loads it only if it imports it — so keep it lean.)

    2. Module boundary + naming.

    • File: ck-notation.js — sibling to ck.js / ck-client.js / ck-store.js (keeps the ck-*.js convention).
    • Export: public subpath @conceptkernel/cklib/notation (beside . / ./client; not under ./internal — this is a first-class additive surface).
    • API — split compilation from execution:
      • compile(source) → plan — pure, I/O-free, inspectable (a caller can audit/authorize the plan before it runs).
      • assemble(handle, planOrSource) → results — runs the plan through a live ConceptKernel handle.
        That inspect-then-run split is what makes it both offline-testable and safe in untrusted contexts.
    • Ships as its own release cut, byte-verified, with package.json files/exports updated — not folded into the v1.5.4 scoring byte-set (features don't share a bundle).

    3. First-slice grammar scope — instance plane only.

    Exactly the strands that compile to already-shipped, ungated verbs:

    • χ / ρ (instances + properties) → create
    • edges → link
    • τ (transitions) → transition (sealed-map gated server-side; an illegal move already returns allowed)
    • π (attestation) → verify / provenance

    Defer the genome plane (σ/α/γ declaration → propose ▸ vote ▸ apply) to slice 2 — that plane's reachability is still gated, and the compiler should degrade honestly to gov_plane_unavailable there, mirroring the existing _gov path, rather than pretend. Ship the instance plane on today's verbs; add the genome plane when that plane is reliably reachable.

    On the contribution + sequencing

    Glad to take the reference pipeline (parse → plan → assemble) you mention. The gate is the usual bar: TDD (offline compile tests + a live-verified assemble path in the smoke-*.mjs style), zero deps, ck.js untouched, plan-emitter-only. Adapt it to ck-notation.js + compile/assemble and we're aligned. It's orthogonal to the scoring loop (blocks nothing, blocked by nothing), so it can proceed in parallel — but it lands as its own version cut after v1.5.4, not inside it.

  3. styk-tv commented on Jul 4, 2026

    @styk-tv
    MemberAuthor

    Reference implementation offered as #8 — framed as a suggestion in this direction, and handing authority to cklib: the module boundary, API, and grammar are yours to set. It's shaped to the three answers above (ck-notation.js · @conceptkernel/cklib/notation · compile/assemble split · instance plane only · genome plane deferred), holds the acceptance bar (plan-emitter, zero authority, ck.js untouched, zero-dep, offline-tested 27/27), and stages as its own cut — not folded into the scoring byte-set. Adapt, rewrite, or reject freely; downstream consumers will align to whatever cklib lands.

  4. added
    P2Priority 2 — soon
    and removed
    P1Priority 1 — this release
    on Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Priority 2 — soonenhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions