CK.Project, CK.Lib.Py, and CK.Lib.Js
CK.Project -- Project Declaration
Purpose
A CK.Project declares the existence, scope, and configuration of a project -- a coherent collection of kernels under a shared domain. It answers: "What kernels exist, what domain do they serve, how are they stored, and how are users authenticated?"
CK.Project is a static kernel because it holds only declarations; it has no processor that executes actions at runtime. CK.Operator COMPOSES it to access project data.
| Property | Value |
|---|---|
| URN | ckp://Kernel#CK.Project:v1.0 |
| Type | static |
| Governance | STRICT |
| Archetype | Declarator |
Project Instance Structure
Each project is an instance stored at CK.Project/storage/instances/{hostname}/data.yaml. The hostname is the project's identity -- it determines DNS routing, namespace naming, and filer path prefixes.
# CK.Project instance: delvinator.tech.games
domain: tech.games
serving:
subdomain: delvinator
hostname: delvinator.tech.games
storage: volume
gateway:
parentRef:
name: multi-domain-gateway
namespace: gateway-system
backends:
nats:
endpoint: nats://nats.nats.svc:4222
wssEndpoint: wss://stream.tech.gamesRequired Fields
A conformant CK.Project instance MUST declare:
| Field | Type | Description |
|---|---|---|
domain | string | DNS domain for all kernels in the project |
serving.subdomain | string | Subdomain prefix; namespace derived as ck-{subdomain} |
storage | enum | Deployment method: volume, filer, or configmap |
gateway.parentRef.name | string | Kubernetes Gateway API gateway name |
gateway.parentRef.namespace | string | Gateway namespace |
AuthConfig
CK.Project instances MAY declare an auth block for OIDC identity provider configuration. Identity is a project-scoped concern: each project has its own realm, client, and access policies.
auth:
provider: keycloak # keycloak | none
instance: keycloak-name # Keycloak CR on cluster
realm: realm-name # Keycloak realm name
client_id: ck-web # OIDC public client
issuer_url: https://id.example.com/realms/realm-name
create_realm: false # true = operator creates realm via KeycloakRealmImport
redirect_uris: [] # REQUIRED if create_realm is true
web_origins: [] # REQUIRED if create_realm is trueTwo modes:
| Mode | Behaviour | Keycloak Permissions |
|---|---|---|
Reuse (create_realm: false) | Operator injects existing issuer URL into deployments, verifies OIDC endpoint | None (zero write) |
Create (create_realm: true) | Operator creates KeycloakRealmImport CR; Keycloak operator provisions realm | get, list, create on keycloakrealmimports |
On teardown, the KeycloakRealmImport is RETAINED. Identity outlives compute.
Auth Details
For the full authentication flow including JWT verification, token lifecycle, and grants enforcement, see Auth.
Ontology Publishing
Each project SHOULD publish a Layer 2 ontology importing CKP Layer 1:
id: https://example.org/ontology/v1/{project-name}
prefixes:
ckp: https://conceptkernel.org/ontology/v3.6/
bfo: http://purl.obolibrary.org/obo/BFO_
prov: http://www.w3.org/ns/prov#
proj: https://example.org/ontology/v1/
classes:
ProjectKernel:
is_a: ckp:Kernel
attributes:
project_name: { range: string, required: true }
kernel_count: { range: integer }CK.Project Conformance
| Criterion | Level |
|---|---|
CK.Project MUST declare domain, serving.subdomain, storage, gateway.parentRef | REQUIRED |
| Each project SHOULD publish a Layer 2 ontology | RECOMMENDED |
Project ontology.yaml MUST import CKP Layer 1 | REQUIRED |
If auth.provider is keycloak, realm, client_id, issuer_url MUST be present | REQUIRED |
If create_realm is true, redirect_uris and web_origins MUST be present | REQUIRED |
CK.Lib.Py -- Python Runtime
Purpose
CK.Lib.Py (conceptkernel on PyPI) is the canonical Python runtime library for CKP. Every Python-based Concept Kernel MUST use CK.Lib.Py (or a compatible implementation) to participate in the CKP ecosystem. The library codifies the CKP contract -- three-loop separation, instance lifecycle, PROV-O provenance, edge composition, RBAC -- as executable code.
| Property | Value |
|---|---|
| Package | conceptkernel on PyPI |
| Import | import cklib |
| Python | >= 3.11 |
| Dependencies | pyyaml, nats-py, httpx, pyjwt, fastapi, uvicorn |
| License | MIT |
Architecture
CK.Lib.Py implements the server-side CKP runtime. It runs on cluster nodes or local machines, connects to NATS via nats-py (native TCP or WSS), has filesystem access to storage/, and writes instances, proofs, and ledger entries.
CLUSTER / LOCAL MACHINE (Python, nats-py)
KernelProcessor -- ckp:Kernel
NatsKernelLoop -- ckp:NATSListening
instance.py -- ckp:InstanceManifest, ckp:SealedInstance
prov.py -- prov:Activity chain
actions.py -- ckp:Edge + ckp:RelationshipType18 Modules
| # | Module | Ontology Class | Purpose | Key Exports |
|---|---|---|---|---|
| 1 | processor.py | ckp:Kernel | Base class for all kernel processors | KernelProcessor |
| 2 | events.py | ckp:Action | Action handler decorator and typed event emission | on(), emit() |
| 3 | instance.py | ckp:InstanceManifest, ckp:SealedInstance | Instance lifecycle: create, seal, ledger, proof | create_instance(), seal_instance(), append_ledger() |
| 4 | ledger.py | ckp:LedgerEntry | Kernel-wide append-only JSONL action log | log_action(), read_ledger() |
| 5 | schema.py | ckp:SealedInstance validation | LinkML ontology.yaml loading and validation | load_schema(), validate_instance(), has_schema() |
| 6 | context.py | N/A | Three-loop-aware context builder | build_context() |
| 7 | capacity.py | N/A | Concurrency control via file-based capacity management | check_capacity(), acquire(), release() |
| 8 | occurrent.py | ckp:Occurrent (BFO:0000015) | Action substeps with PROV-O proof and hash chains | ActionOccurrent, StepRecord |
| 9 | edges.py | ckp:Edge, ckp:RelationshipType | Edge subscription materialisation for NATS | materialise_edge_subscriptions() |
| 10 | actions.py | ckp:Action, rbac.ttl | Action type resolution, composition, RBAC | resolve_action_type(), check_access(), get_effective_actions() |
| 11 | dispatch.py | ckp:EdgeCommunication | Local inter-kernel action dispatch and FIFO queue | send_action(), queue_action(), run_queue() |
| 12 | serve.py | ckp:WebServing, ckp:APIServing | FastAPI HTTP server wrapping @on handlers | KernelServer |
| 13 | auth.py | rbac.ttl | Keycloak JWT verification + API token fallback | CKAuth |
| 14 | urn.py | CKP URN scheme | CKP URN parser, validator, builder (17 entity types) | parse_urn(), validate_urn(), build_urn() |
| 15 | prov.py | prov:Activity | PROV-O session recording for any kernel | ProvChain, Session, verified_action() |
| 16 | execution.py | ckp:ProofRecord, ckp:ProofCheck | Multi-step execution proofs with hash chains | hash_step(), build_execution_proof(), verify_chain() |
| 17 | entities.py | N/A | In-memory entity store with code-based lookup | EntityManager |
| 18 | nats_loop.py | ckp:NATSListening | NATS subscriber loop implementing CK processing cycle | NatsKernelLoop |
KernelProcessor Base Class
KernelProcessor is the base class that every Python kernel subclasses. On construction it reads conceptkernel.yaml (CK loop), resolves paths, and prepares the handler dispatch table.
| Member | Kind | Description |
|---|---|---|
KernelProcessor(ck_dir=None) | constructor | Initialise; loads identity from conceptkernel.yaml |
.identity | property | Lazy-loaded parsed identity dict |
.name | property | metadata.name from identity |
.urn | property | metadata.urn from identity |
.kernel_type | property | qualities.type (e.g., node:hot) |
.governance | property | qualities.governance_mode |
.handle_message(msg) | method | Dispatch to @on handler; resolution: own -> built-in -> composed -> error |
.listen() | method | Start NatsKernelLoop subscriber (blocking) |
.serve(port=8901) | method | Start FastAPI HTTP server via KernelServer |
KernelProcessor.run() | classmethod | CLI entry point: --status, --listen, --serve, --action, --data |
NatsKernelLoop
The NATS processing cycle enforces three-loop separation at the message level:
- Connect to NATS (TCP or WSS)
- Subscribe to
input.{KernelName} - For each message:
- Parse headers (
Trace-Id,X-Kernel-ID,X-User-ID,Authorization) - Verify JWT if
Authorization: Bearerpresent; fallback to anonymous - RBAC grants check via
check_access() - Dispatch to
handler_fn(body)(supports sync and async handlers) - Write instance record to
storage/instances/i-{trace}-{ts}/message.json - Publish result to
result.{KernelName}with headers - Publish event to
event.{KernelName}
- Parse headers (
The handler returns data; the platform writes it. This is the three-loop contract in action.
Processor Pattern
from cklib import KernelProcessor, on, emit
class MyKernel(KernelProcessor):
@on("my.action")
def handle(self, data):
result = {"answer": 42}
return emit("ActionCompleted", result=result)
if __name__ == "__main__":
MyKernel.run()
# CLI modes: --status, --action, --listen, --serveCK.Lib.Py Conformance
| Criterion | Level |
|---|---|
| CK.Lib.Py MUST enforce three-loop separation | REQUIRED |
Handlers MUST NOT write to storage/ directly | REQUIRED |
| JWT verification MUST occur before handler dispatch | REQUIRED |
| PROV-O provenance MUST be generated for every instance | REQUIRED |
Edge composition MUST derive from conceptkernel.yaml declarations | REQUIRED |
| Kernel processors MUST output structured JSON logs to stdout | REQUIRED |
All 18 modules MUST be importable from the cklib package | REQUIRED |
CK.Lib.Js -- JavaScript Client
Purpose
CK.Lib.Js (@conceptkernel/cklib on npm) is the canonical JavaScript client library for CKP. It runs in browsers and Node.js environments, connecting to NATS via WebSocket Secure (WSS). CK.Lib.Js provides no filesystem access -- it is a pure messaging client.
The browser is an isolated client, like any CLI tool. It publishes action messages to input.* topics and subscribes to result.* and event.* topics. All mutations happen server-side in kernel processors. The client never reads or writes kernel filesystems.
| Property | Value |
|---|---|
| Package | @conceptkernel/cklib on npm |
| Main entry | ck-client.js |
| Type | ESM module |
| Dependencies | nats.ws ^1.30.3 |
| License | MIT |
12 Modules
| # | Module | Export Path | Ontology Grounding | Purpose |
|---|---|---|---|---|
| 1 | ck-client.js | . / ./client | ckp:NATSBrowserClient | Core NATS WSS client; connection, auth, send, subscribe |
| 2 | ck-page.js | ./page | ckp:InlineKernel | Page harness; auto-detects kernel, renders chrome |
| 3 | ck-bus.js | ./bus | ckp:EdgeCommunication | In-browser event bus for decoupled component communication |
| 4 | ck-kernel.js | ./kernel | -- | Kernel-specific CSS variables and theming |
| 5 | ck-registry.js | ./registry | ckp:Project | Kernel registry for multi-kernel page composition |
| 6 | ck-runtime.js | ./runtime | -- | Client-side runtime utilities |
| 7 | ck-materializer.js | ./materializer | -- | Client-side resource materialisation |
| 8 | ck-store.js | ./store | -- | Client-side state persistence (localStorage + server filer) |
| 9 | ck-shapes.js | ./shapes | sh:NodeShape | SHACL shape rendering and validation UI |
| 10 | ck-anim.js | ./anim | -- | Animation engine for kernel visualisations |
| 11 | ck-anim-grammar.js | (internal) | -- | Animation grammar parser |
| 12 | ck-sound.js | ./sound | -- | Web Audio API integration for kernel sound effects |
CKClient API
CKClient is the core NATS WSS client. It manages connection lifecycle, authentication escalation, and message send/receive.
const ck = new CKClient({
kernel: "Delvinator.Core",
wssEndpoint: "wss://stream.tech.games",
authEndpoint: "https://id.tech.games",
realm: "techgames",
clientId: "ck-web"
})| Method | Returns | Description |
|---|---|---|
connect() | Promise<boolean> | Connect to NATS WSS, auto-subscribe to result.{kernel} and event.{kernel} |
send(data) | Promise<string> | Publish to input.{kernel}; returns traceId |
login(username, password) | Promise<string> | Keycloak password grant; returns userId |
logout() | void | Downgrade to anonymous identity |
disconnect() | Promise<void> | Unsubscribe all, drain connection |
on(event, fn) | void | Subscribe to: "result", "event", "status", "error" |
off(event, fn) | void | Unsubscribe from event |
Authentication Lifecycle
- Anonymous connect: Generate
anon_{random_hex}identity, connect to WSS, subscribe to result/event topics - Login escalation: POST to Keycloak token endpoint (
grant_type=password), upgrade identity, attach JWT to all subsequent messages - Token refresh: Auto-refresh when access token is within 30 seconds of expiry. On failure, revert to anonymous
- Logout: Downgrade to anonymous identity without NATS reconnect
CKPage -- Web Console
CKPage is the unified page harness (console.html) that auto-detects the kernel from /ontology.yaml, connects NATS via CKClient, and renders the standard CKP chrome.
Three-panel layout:
| Panel | Width | Content |
|---|---|---|
| Action sidebar | 160px | Actions from kernel's spec.actions, NATS topics, message history |
| Parameter form | 280px | Per-action input fields, JSON preview, send button |
| Results | flex | NATS messages in chat, body, or envelope view |
For more on the web console, see Web Shell.
CK.Lib.Js Conformance
| Criterion | Level |
|---|---|
| CKClient MUST implement anonymous-first connection | REQUIRED |
| CKClient MUST include all specified NATS headers on every message | REQUIRED |
| Control data MUST reside in headers, not in body payloads | REQUIRED |
| Token refresh MUST occur automatically before expiry | REQUIRED |
| CKClient MUST handle NATS reconnection transparently | REQUIRED |
| CKPage MUST load from CK.Lib.Js on the CK volume, not from CDN at runtime | REQUIRED |