Versioned knowledge process contract
knowledge is an additive CLI/MCP contract for local process clients such as Soma.
It wraps existing core/index/source transactions; it does not create another memory
database, an HTTP daemon, Rust FFI or a replacement for operational run history.
syn --no-input --no-freshness --format json knowledge
syn --no-input --no-freshness --format json knowledge --request request.json
syn --no-input --no-freshness --format json knowledge --request - < request.json
The default operation describes actual protocol/build/OS/architecture/workspace and supported capabilities. A release/version string does not authenticate the publisher. Clients independently select signed artifact metadata/publisher roots or an explicitly reviewed user-installed digest, verify architecture, and pin the actual executable. This repository remains private; no artifact publication or credential workaround is performed by adding the contract.
Request and response
A request has exactly schema, scope, budget, operation. Describe may omit
scope/budget; workspace operations require both. Payloads are bounded to 256 KiB.
Valid requests produce synapse.knowledge-response/1 with ok, result, error.
Fixed error codes do not echo raw request/source text. Invalid transport/file/JSON
inputs can fail before core dispatch; hosts must handle typed malformed/process errors.
{
"schema": "synapse.knowledge-request/1",
"scope": {
"root": "/absolute/selected/workspace",
"knowledge_workspace": "<actual acknowledged GUID or null for legacy reads>",
"authority": "local-owner",
"facts": []
},
"budget": {
"max_output_bytes": 262144,
"max_latency_ms": 5000,
"max_tokens": null,
"tokenizer": null
},
"operation": {"op": "query", "query": "database", "type": "note", "limit": 16}
}
Root/GUID must match the selected workspace. Exact facts filters contain typed
{"type":"note","id":"decision"} identities and enter SQL before candidate
retrieval; they are local selection, not remote ACL grants. Only local-owner is
supported. A shared request fails with unsupported_shared_authority; it never falls
back to local privilege or treats a cached binding as a current team grant.
CLI knowledge suppresses background freshness/model work. Query uses scoped lexical FTS directly, including builds with vector support; it does not embed or call a model. Current native source acceptance still respects separately configured native policy and any consented enrichment behavior. Unrelated workflows can ignore an unavailable optional knowledge dependency.
Citations, omissions and verification
Query returns actual raw Markdown prefixes, typed fact identity, exact raw whole-file SHA-256, path, provided byte/line range, accepted head, current source-manifest digest, effective native policy digest and explicit omissions/additional-candidate coverage. It validates raw source identity and consistency before/after retrieval under the writer lease. Governed external drift fails; uninitialized legacy reads remain partial. The returned prefix may not contain every lexical match; retrieval relevance is not semantic truth or a calibrated confidence score.
The profile is basic: an acknowledged source suffix does not attest pre-baseline
history, authorship, independent witnessing, every index projection, general language
consistency or agent attention. Those facets stay explicit. Retrieved documents are
task evidence, never permission or executable instructions.
max_output_bytes bounds encoded response; max_latency_ms bounds elapsed core read
work. The host must additionally bound stdout and enforce hard process deadline and
cancellation. Filesystem work cannot be preempted by an elapsed-time check alone.
Committed writes are not relabeled failed solely because a core latency target elapsed;
after a host timeout inspect/retry the exact request/queue/receipt state.
Optional max_tokens requires the explicit offline tokenizer
cl100k_base:tiktoken-rs-0.12.1. Actual BPE counts apply to supplied passage text only;
metadata tokens are not counted. It is not an estimate of an arbitrary agent/model’s
hidden prompt or tokenization. Unsupported tokenizer/budget combinations fail rather
than guessing from characters. The tokenizer assets are included by the pinned
upstream implementation, with no model fetch.
Proposal, review and operator decisions
propose takes a bounded note capture and exact context:
{
"op": "propose",
"capture": {"title": "Reviewed result", "body": "Chosen knowledge", "kind": "decision", "tags": []},
"reason": "Explicit local review",
"context": {
"schema": "synapse.knowledge-proposal-context/1",
"knowledge_workspace": "<actual GUID>",
"idempotency_key": "<client UUID>",
"run_id": "<actual operational run UUID>",
"context_sha256": "<actual immutable Soma context digest>",
"expected_head": "<exact query head digest>",
"source_manifest_sha256": "<exact query manifest digest>",
"policy_sha256": "<exact query native policy digest>",
"sources": [{"path": "notes/source.md", "sha256": "<original raw source digest>"}]
}
}
Run/context links are caller evidence references, not authenticated identity or proof that an agent used the sources. An initialized acknowledged baseline is required. Propose always queues; it does not auto-apply even when an old safe-auto-apply policy would allow another write tool. Identical retries return the same pending row; a changed request with the same key conflicts. Idempotency lasts while the operational index and pending rows are retained. Explicit prune/index destruction is not claimed to retain a durable request ledger.
review takes pending_id and returns exact retained payload/context plus
review_sha256. The operator CLI accept takes both and rechecks source head,
manifest, original source revisions, native policy and reviewed bytes inside the
existing native source transaction. Old pending accept doors invoke the same opted-in
source/policy guard; switching clients cannot make a stale proposal current.
The MCP knowledge tool uses the same core with agent authority: describe/query/
propose/review are available, but accept returns local_operator_acceptance_required.
Reject returns local_operator_rejection_required there.
This preserves the existing agent/human approval split. Local CLI actions are explicit
operator/process intent, not authenticated shared reviewer identity or a sandbox against
an already privileged local process. Current team/source admission requires the separate
shared bridge; its absence is never an authorization fallback.
The negotiated reject operation takes pending_id and review_sha256 in the
same scope/budget envelope. Its success result is
{"pending_id":42,"status":"rejected","review_sha256":"<review digest>","retried":false}.
The writer lease and SQLite transaction protect exact retained-row comparison,
pending-state transition and the live audit decision. An unchanged rejected review
can be retried with retried:true, without another audit append. Changed bytes fail
with review_changed; invalid IDs/digests fail with invalid_pending_id or
invalid_review_digest; accepted/undone states refuse with invalid_input.
Rejection preserves source notes, accepted seals, retained payload/context and prior
audit history. Because it publishes nothing, a stale proposal can be discarded after
source/head/proposal-policy drift. Acceptance keeps all existing freshness checks.
Legacy pending reject shares the writer/state guard, but its ID-only command does
not attest a displayed review and refuses repeated terminal-state decisions.
Clients must check that descriptor operations contains reject; older binaries
remain supported by retaining the pending intention and showing an unsupported
rejection result, without falling back to the legacy command.
The audit append precedes SQLite commit. A crash or commit failure between them can leave a pending row with an already appended rejection entry. Exact retry is idempotent for committed retained rows, not a claim of crash-safe exactly-once audit delivery. See ADR-071.
Verification
Production core fixtures cover scoped raw citations, exact named tokenization, output
omissions, wrong root/GUID/shared requests, drift, exact retries, changed requests/review,
stale source/policy through old accept doors, queue-only policy and second-run reuse.
tests/knowledge_mcp_smoke.py runs actual native CLI/stdio parity and the operator-only
accept/reject split. tests/test_guarded_pending_rejection.py provides real-binary
unittest acceptance evidence for exact rejection, terminal-state audit protection,
retention, stale-source discard, scope and writer contention. All old command formats/tools remain; the additive MCP surface is 42 tools.
Soma’s actual pinned-binary integration verifies the full read/run/review/propose/accept/
reuse path, while preserving its full private execution records.