Request Lifecycle
How a request actually flows through the components in
Architecture, using validate_knowledge — the most
involved tool — as the walkthrough. Simpler tools follow the same shape
with fewer steps.
validate_knowledge with a fresh json_data payload
- Transport.
server.pyreads a JSON-RPCtools/callrequest from stdin and dispatches it to the wrappedvalidate_knowledgehandler. - Middleware. The composed stack runs first:
require_fieldschecks that a required argument isn't missing; ifsession_idwere given instead,require_session/require_open_sessionwould resolve and check it before the handler ever runs. - Parsing. The handler parses
json_datainto aKnowledgeStructureviacks-core. Acks.SerializationErrorhere short-circuits into a structuredinvalid_jsonerror — nothing downstream runs. - Extension resolution. Any requested
extensionsnames are resolved tocks-coreConstraintobjects. An unrecognized name short-circuits into anunknown_extensionerror. If the structure contains aVerificationRecord, theverification_recordextension is force-added regardless of what was requested — see Extension Model. - Provenance check — before any session is registered. The structure
is checked for
VerificationRecordobjects and their HMAC signatures, using a throwaway, unregisteredRuntimeSessionrather thanruntime.create_session(). This ordering matters:create_sessionpersists immediately, and if it ran before this check, a forged record would already be live and readable viaserialize_knowledge,query_subgraph, or an MCP Resource on the returnedsession_id— even though the response correctly reported it as invalid. See Security Model. - Branch on provenance result:
- Provenance OK: now
runtime.create_session()registers the session for real, aTransactionis opened, aValidateOperationis added and committed.cks-core's own validation pipeline runs inside that commit, producing the first layer of diagnostics. - Provenance failed: the operation runs once, straight through the executor, bypassing the transaction/commit pipeline entirely — core diagnostics are still collected for a complete report, but no session is registered and no version is created.
- Response assembly. Core diagnostics and provenance diagnostics are
combined;
validistrueonly if both passed.session_idis included only if a session actually exists (registered in step 6);version_idonly if a version actually committed. - Transport.
server.pyserializes the response dict back over stdout as the JSON-RPC result.
What's common to every tool
- Middleware runs before the handler body, so field/session checks never depend on the handler remembering to do them itself.
catch_unhandled_errorsis the outermost layer — any exception that escapes a handler becomes a structuredinternal_errorresponse, never a raw traceback reaching the LLM client (exceptasyncio.CancelledError, which must propagate for cooperative cancellation).- Mutating tools dry-run before they commit.
evolve_knowledge,merge_branch,merge_knowledge, andfork_sandboxall validate the prospective result — including provenance — before opening a transaction, for the same reason step 5 above runs beforecreate_session: a persisted version is trusted by every downstream reader, so nothing partially-invalid is ever allowed to become one. - Every committed change is observed twice.
observability.pysubscribes tocks-runtime's EventBus and logs structured events (SessionCreated,TransactionCommitted, ...) to stderr;telemetry.pyindependently aggregates per-tool call counts and latencies forget_metrics, from the same call.
See Architecture for what each component in this flow is responsible for, and Tools Reference for the request/response shape of every individual tool.