All commands accept these global flags:
--format text|json,--verbose,--lang <locale>, and (v0.6) the output/automation set:--plain/--raw(raw, unstyled output),--no-color(drop colour, keep structure),--quiet/-q(suppress non-essential lines),--no-input/--yes(never prompt: for CI/agents). Locale precedence:--lang→SYNAPSE_LANG→ system locale →en. Output is rich by default on a TTY (tables, panels, the unicode graph tree, progress, the mascot) and degrades to plain bytes on a pipe /--plain/NO_COLOR;--format jsonis always machine-clean and unstyled.
Workspace lifecycle
| Command | What it does |
|---|---|
syn setup [--force] | Guided global config + self-identity (v0.6, BR-14): locale, output format, then your profile: name, birthdate, profession, employers: saved to a global profile.toml. Non-TTY falls back to defaults and skips identity (never blocks). |
syn init [PATH] [--with-config] | Initialise a workspace. Refuses to overwrite. Runs the guided setup inline on a fresh interactive machine, then seeds the self: true person from your profile (employers become entity(kind=org) linked employed-by). Offers the one-time ~2.5 GB model download. --with-config seeds .synapse/config.toml. |
syn info | Workspace summary: counts per type, total. Stable JSON shape with --format json. |
syn digest [--days N] | “Your week in the graph” (SYN-222): recent activity (created/updated/AI-applied) + a “needs your attention” list (pending to review, untagged notes, disconnected entities, dangling links). Deterministic: no model. --format json for cron/scripts. |
syn context | Print the workspace’s self-describing vocabulary (SYN-311): entity types + their indexed/identity fields, link relations, reserved x-* keys, write-proposal payload shapes, enrichment sources, search modes. --format json mirrors the MCP synapse://capabilities resource: read it before proposing to avoid an invalid kind/rel/key. |
syn reindex | Rebuild the SQLite index from the Markdown source of truth. Idempotent. |
syn doctor | Read-only consistency audit. Exits non-zero on errors. |
Entities
The six types share add | list | show | rm (except task, which adds done).
syn project
syn project add "Display Name" [--desc TEXT] [--status active|paused|concluded|archived] [--priority low|medium|high]
syn project list [--status STATUS]
syn project show <slug>
syn project rm <slug> [--force]
syn person
syn person add "Full Name" [--email X] [--org SLUG] [--job-title "Tech Lead"]
syn person link <person-slug> --project <project-slug> --role <free-form>
syn person list
syn person show <slug>
syn person rm <slug> [--force]
--job-title (cargo formal) is not the same as --role in the link command (papel funcional naquele projeto). See BR-4.4.
syn entity
syn entity add "Name" [--kind vendor|customer|internal|partner] [--contact STR]
syn entity list
syn entity show <slug>
syn entity rm <slug> [--force]
syn api
syn api add "Name" [--base-url URL] [--auth none|apikey|basic|oauth2|jwt|mtls] [--status production|staging|deprecated] [--owner <person-slug>]
syn api list [--status STATUS]
syn api show <slug>
syn api rm <slug> [--force]
syn task
syn task add "Title" [--project SLUG] [--owner SLUG] [--api SLUG] [--due ISO-DATE] [--status open|in_progress|blocked|concluded] [--tag T]...
syn task done <id>
syn task list [--status STATUS]
syn task show <id>
syn task rm <id> [--force]
IDs are auto-assigned: <project>-NNN when scoped, t-NNN otherwise. done stamps closed_at.
syn note
syn note add "Title" [--kind decision|runbook|meeting|snippet|reference] [--project SLUG] [--tag T]...
syn note list
syn note show <slug>
syn note rm <slug> [--force]
Custom entity types (SYN-234 / ADR-028)
Beyond the six built-ins you can define your own types in
.synapse/types.toml (book, meeting, decision, client, …) without
a code change. A type is a closed core (a small whitelist of indexed,
queryable fields) plus an open frontmatter bag validated on read.
# .synapse/types.toml
schema_version = "1.0"
[types.book]
display = "Book"
store_dir = "books" # folder under the workspace root
indexed = ["author", "year", "isbn"] # ≤ 16; these become bindable query keys
identity = ["isbn"] # SYN-254: a capture matching these on an
# existing book is flagged as a duplicate
# and routed to the gate (⊆ indexed)
[types.book.fields.author]
type = "string"
required = true
[types.book.fields.year]
type = "int" # string | int | float | bool | date | ref | list
# SYN-248: per-kind policy (covers built-ins too, which are reserved above).
[policy.person]
decay = false # profile: current-state, never flagged by `syn stale`
syn types lists every registered type (built-ins + yours). Manage instances
with the generic dispatcher (the built-in commands stay for the six core
types):
syn new --type <kind> "Title" [-f key=value]... [--tag T]... [--id SLUG]
syn ls --type <kind> [--status S] [--as-of DATE]
syn show --type <kind> <id>
syn rm --type <kind> <id> [--force]
syn new --type book "Dune" -f author="Frank Herbert" -f year=1965 --tag scifi
syn ls --type book
syn show --type book dune
Field values are passed as repeatable -f key=value pairs (static clap
cannot synthesise a typed flag per runtime-defined field). Each value is
coerced to its declared type and validated on write; a missing required
field or a type mismatch is rejected. Custom-typed entities are reindexed,
FTS-searchable (syn search, MCP search_everything), countable via the
query tool (incl. filter.field over an indexed field), and can be link
endpoints (MCP link_entity).
Current limitations (honest). Custom types are first-class for create / read / list / remove / search (incl.
--type <custom>, SYN-259) / link /update_status/ supersession. The remaining gap is insertion-time semantic embeddings: custom entities are embedded by an explicitsyn embed --all(FTS-only until then): SYN-251. Declaredpattern(regex) field constraints are parsed but not yet enforced (needs aregexdep + ADR; deferred).
Search and graph
syn search <query> [--type <kind>] [--tag T] [--owner SLUG] [--limit N] [--near <slug>] # --type: built-in|custom (SYN-259); --near: graph-distance rerank (SYN-255)
[--semantic | --no-vector] [--as-of DATE] [--grade] [--all]
syn graph project|person|api <slug> [--rel RELATION]
graph walks the materialised links table. search behaviour depends on whether the semantic layer is present:
- Minimal core build (
--no-default-features --features mcp) or models not downloaded yet: plain FTS5, BM25-ranked. The query takes FTS5 syntax (title:foo,"phrase"). - Default build, models present: the default is hybrid: FTS5 + vector similarity + graph-neighbourhood fused with Reciprocal Rank Fusion (k=60). The query is natural language. Flags:
--semantic: vector similarity only (best for “find conceptually similar”, needs an embedded workspace).--no-vector: FTS + graph only; skips the embedding step and its cold-start.--grade: after searching, prompt per hit (relevant? [y/N/skip]) and append the judgments to.synapse/search-labels.ndjson(for v0.6 ranking tuning). Requires an interactive terminal; conflicts with--all.--as-of DATE: valid-time filter (SYN-223 / ADR-027): keep only facts true in the world atDATE(YYYY-MM-DDor RFC-3339), using the SQL:2011 closed-open[x-valid-from, x-valid-until)interval. Facts with nox-valid-*stamps always pass. Applies in every mode (FTS and hybrid); local-only (conflicts with--all). Composes withsyn at <ref>: see the time-travel section.--all: fan out across every federated workspace (plain FTS, not hybrid).
syn search "the firebase feature flag" # hybrid (default)
syn search --semantic "auth and sessions" # vector-only
syn search --no-vector "checkout-v2" # FTS + graph, no model load
Filters (
--type/--tag/--owner) apply in every mode. When the models haven’t been downloaded yet (or the workspace is un-embedded), hybrid search degrades gracefully to FTS+graph rather than failing, and never triggers a download.
Trust-weighted ranking (SYN-250 / ADR-029). The hybrid ranker multiplies each hit’s relevance by its deterministic trust score (the same curve
syn stale/syn blameuse), bounded to[0.5, 1.0]: a decayed or low-confidence AI fact sinks beneath an equally-relevant fresher one, but trust never fully suppresses a strong textual match. Human-authored facts carry no penalty (full weight).
Embeddings (syn embed)
The semantic layer ships in the default binary (opt-out, SYN-168): to drop it, build a minimal core binary with --no-default-features --features mcp. The ~2.5 GB of local models are not bundled; syn embed --all (or syn embed <slug>) is the explicit consent step that downloads them on first use (the other consent path is answering “yes” to the syn init onboarding prompt).
syn embed --all # download (on first use) + embed every entity; skips rows whose content + model already match
syn embed <slug> # (re-)embed one entity
syn embed --check # show cache state (entities, embedded, current vs stale model, models_ready): read-only, never downloads
syn embed --reset-cache # drop every vector + meta row; next --all re-embeds from scratch
syn embed --force # with --all/<slug>: re-embed even when the content hash matches
Writes already embed automatically at insertion time once the models are present (see Insertion-time enrichment below), so syn embed --all is mainly for backfilling an existing workspace the first time you populate the cache, or after switching embedding_model. --check is the quick way to see whether the index is populated and on which model; its output (text and JSON) carries a models_ready field: false means the models haven’t been downloaded yet, and --check reports it without triggering a download.
Insertion-time enrichment (BR-13)
On the default (semantic) binary, once the models are present, every write (project add, note add, an accepted MCP proposal, …) runs a synchronous pipeline inside the transaction: it embeds the entity, runs NER, and links mentions. You don’t call anything: it just happens.
If the models haven’t been downloaded yet, the write still succeeds: enrichment is skipped gracefully with a one-time note (“semantic models not downloaded yet: write saved without embedding. Run syn embed --all…”), and the write never triggers a download. Models are pulled only on explicit consent: answering “yes” to the syn init onboarding prompt (a TTY-only prompt; non-interactive syn init just prints a one-line breadcrumb and never blocks), or running syn embed --all. Once present, the pipeline:
- writes the vector to
entities_vec(so the entity is immediately searchable semantically); - creates typed
linkrows for mentions that resolve to existing entities (surfaced bysyn graph); - queues a
create_entity_from_nerproposal in the pending queue for a mention that does not resolve yet: accepting it (syn pending accept <id>) materialises the new entity (BR-12.3: nothing is created without your sign-off).
Control it with [enrichment] mode in config (off / heuristic / heuristic+ner) or the SYNAPSE_ENRICHMENT_MODE env var per invocation (e.g. SYNAPSE_ENRICHMENT_MODE=off syn project add … for a fast write that skips the model). See CONFIGURATION.md.
Tags
syn tag list # tags with counts (desc)
syn tag rename <old> <new> # rewrites every entity's frontmatter and the index
syn tag merge <source> <target>
Workspaces and federation
syn ws list # every workspace ever seen
syn ws show <id|name> # full row + SYNAPSE.md
syn ws include <id|name> # opt this workspace into cross-workspace queries (BR-12.4)
syn ws exclude <id|name> # remove from the federated pool
syn ws forget <id|name> # remove from the registry (folder is left intact)
syn ws gc # sweep registry rows whose root has been deleted
syn ws topic add|rm <value> # curate SYNAPSE.md topics
syn ws tag add|rm <value> # curate SYNAPSE.md tags
syn ws edit [name] # open SYNAPSE.md in $EDITOR
syn ws refresh [name] # re-read SYNAPSE.md from disk and refresh the registry cache
syn ws freshness on|off <name> # toggle the per-workspace freshness advisory (SYN-93)
Federation is opt-in (default off). See ADR-010 and the Privacy gate section in MCP.md.
Workspace maintenance
syn reindex # rebuild the SQLite index from the source-of-truth Markdown
syn watch [--debounce-ms 250] # auto-reindex on filesystem change (SYN-65)
syn doctor # audit consistency
syn open <slug> [--no-reindex] # open an entity in $EDITOR, reindex after exit (SYN-70)
syn export --as json [--out FILE] # dump every entity + link as JSON (SYN-67)
syn export --as html --out DIR/ # render a static site (SYN-66)
syn config get|set|unset <key> [val] # workspace-scoped TOML knobs (SYN-69)
--as (not --format) avoids colliding with the global --format text|json flag.
syn import (SYN-228)
The honest inverse of syn export --as obsidian: import a Markdown vault as
governed proposals (BR-12.3: nothing touches the workspace until you accept):
syn import --from <PATH> # a .md file, or a directory walked recursively
Each .md becomes a queued capture_fact proposal. A note with YAML
frontmatter keeps its type (when it names a registered kind, else note),
title, tags, and scalar fields; a frontmatter-less note (plain Obsidian
markdown) becomes a note whose title is its first # heading (or the
filename) and whose body is the whole file. Review with syn pending list,
then syn pending accept --all. The contract is deliberately Markdown + YAML
frontmatter (the format Synapse itself emits) not a reverse-engineered
external schema, so it round-trips your own export.
Uninstall
syn uninstall # remove the binary (asks in tty; --force to skip)
syn uninstall --purge # also delete the global config
syn uninstall --everything # also delete the workspaces registry
Workspace folders are never touched: your Markdown belongs to you.
Destructive prompts
Every <type> rm asks for confirmation in a TTY. Non-TTY runs require --force; running in a script without it now fails loudly rather than deleting silently (SYN-71).
Pending proposals (SYN-60..62, SYN-92)
The MCP server enqueues every write proposal here instead of touching the workspace. Review and apply with:
syn pending list # currently-pending proposals
syn pending list --all # include accepted + rejected
syn pending show <id> # full payload + reason + source
syn pending accept <id> # apply (via Workspace::tx) and mark accepted
syn pending accept 1 3 5 # accept several at once (each applies atomically)
syn pending accept --all # batch-approve every pending proposal (SYN-185)
syn pending reject <id> # mark rejected; row kept for audit
syn pending reject <id> --prune # delete the row instead of keeping it
syn pending reject --all # batch-reject everything (add --prune to delete)
See BR-12.3: MCP must never write without explicit human confirmation. The pending queue is per-workspace, lives in .synapse/index.db, and the row id is monotonic per workspace.
Undo an accepted decision (syn undo, SYN-287 / ADR-039)
syn undo <id> # reverse a previously accepted decision (same id as `pending list --all`)
It reverses a capture_fact create (removes the entity), a link_entity
(deletes the edge), and an update_status (restores the prior status from a
pre-image captured at accept time, SYN-292): all on a just-accepted,
uncommitted write, no git commit required. It refuses (with guidance to
revert via git) for supersessions, custom-typed creates, and batches, and
refuses if the fact was changed after the decision (the conflict guard never
clobbers later work). Every undo is atomic and is
itself recorded on the audit trail (the original accepted entry is never
deleted). undo is a human corrective action and is CLI-only by design, it is deliberately not an MCP tool, so the agent can’t erase its own accepted
history (the agent proposes, the human disposes: ADR-022/039).
Ambient capture (syn capture)
syn capture "Why we picked PKCE for auth" # the one-liner: drop a thought in seconds as a raw note (SYN-221)
echo "Why we picked PKCE" | syn capture # …or pipe stdin; a bare TTY opens $EDITOR
syn capture --from-git # seed people (commit authors) + a project (the repo) from git, as proposals (SYN-220)
syn capture --from-git ~/code/myproj # …from a specific repo; --max N caps the authors proposed
syn capture "<text>" is the promoted capture path (SYN-221): zero schema at the moment of capture; it queues a raw note, and the AI can later propose the typed/linked version (deferred structuring). Everything still goes through the pending queue (BR-12.3).
Governance, audit & forensics
This is the differentiated surface: prove what the AI changed, when, and on
whose behalf, and undo it. All of it reads the source-of-truth Markdown, the
x-ai-* provenance frontmatter, and git.
syn blame <slug> # AI provenance lineage: who/what touched the entity, when, on whose behalf (SYN-240)
syn diff <slug> [--since <ref>] # per-field before/after of an entity since a git ref (SYN-240)
syn changes --since <rfc3339> [--limit N] # what changed since an instant: audit decisions + per-field deltas (SYN-256)
syn timeline <slug> # walk the git history of one entity (SYN-121)
syn connections <slug> [--hops N] [--max-nodes N] [--semantic] # ego graph as JGF (SYN-244); --semantic adds explainable mutual-kNN edges (SYN-245)
syn stale [--limit N] # AI facts whose trust score has decayed: advisory (SYN-224)
syn types # list registered entity types (built-ins + types.toml; SYN-234)
Time travel (SYN-122). Query the workspace as of any git ref: what you knew at commit R:
syn at <ref> -- search <query> # search the workspace as it was at <ref>
syn at <ref> -- show <type> <id> # show an entity as it was at <ref>
Bitemporal (SYN-223 / ADR-027). Two orthogonal time axes, each a separate filter, composable:
- Transaction-time: what we knew at commit R:
syn at <ref>(above). - Valid-time: what was true in the world at date D:
--as-of D.
syn search <query> --as-of 2025-01-01 # what was true on that date (current history)
syn at <ref> -- search <query> --as-of 2025-01-01 # "using only what we knew at <ref>, what was true on D"
Valid-time comes from the x-valid-from / x-valid-until frontmatter keys
(closed-open [from, until)); facts without them always pass.
Supersession (ADR-027 / ADR-031). A captured fact carrying
x-supersedes: <id> closes the superseded fact’s interval as an append, never a delete: the older fact gets an x-valid-until (when it stopped being
true) plus an x-invalidated-at belief stamp (when we learned it). Three
deterministic rules: new-after-old closes the predecessor, older-than-known
is born already-expired, disjoint keeps both. The captured fact also carries
x-recorded-at (belief-time it entered the store). Built-in F1 only for now;
custom-type close + temporal replay are v0.10. --as-of filters the current
history; at <ref> reconstructs the tree at a commit.
Field corrections are bitemporal too (SYN-315 / ADR-046). An update_status
is an in-place, single-field edit, not a whole-fact supersession. It records
valid-time at the field level: the prior value is appended to the entity’s
x-field-history frontmatter, so syn ls <type> --as-of <before> reconstructs
the pre-correction status while the entity itself stays visible on both sides of
the correction. The history lives in the Markdown, so syn reindex rebuilds it
(disposable, verify-honest).
Audit trail (syn audit). The append-only .synapse/audit.ndjson:
syn audit list [--all] # recent entries (newest first); --all includes archived months
syn audit show <id> # one entry by its pending id
syn audit verify # re-hash each row's payload vs the recorded payload_sha256 (SYN-135)
# : exits 65 on any mismatch; the tamper-evidence check
syn audit replay <id> [--execute] # replay an accepted proposal: visual diff by default
syn audit prune <YYYY-MM> # delete archive months older than DATE (live log untouched)
syn audit stale # cross-workspace ranking of stalled open commitments (SYN-123)
Portable receipts (syn provenance, SYN-247). A signed, self-verifying
proof of an entity’s provenance that anyone can check without Synapse:
syn provenance export <slug> [--out FILE] # signed receipt (ed25519)
syn provenance verify <FILE> # verify a receipt's signature; needs no workspace access
See PROVENANCE.md, AUDITABILITY.md, and IDENTITY.md for the data model behind these.
Provable non-corruption (syn verify, SYN-263 / ADR-035).
Prove the AI memory was not silently corrupted: reproducible, signed,
offline. Runs the runtime invariants and emits a verdict; --format json
emits the full signed synapse.verify-report/1 (an in-toto Statement signed
with your ed25519 identity):
syn verify # text report: per-invariant pass/fail + trust-root caveat
syn verify --format json # the signed synapse.verify-report/1 report
syn verify --deep # also INV-4 (replay the governed decision journal, SYN-266) + INV-13 (logical contradictions, SYN-316)
syn verify --rebuild # attestation: on INV-1 mismatch, list EVERY diverging fact (SYN-269)
syn verify --since <file> # also INV-12: prove history is an append-only extension of a witness (SYN-270)
Offline consistency proof (syn audit witness + verify --since, SYN-269 /
ADR-037). syn audit witness
emits a tiny ed25519-signed checkpoint of the audit history (git HEAD +
per-author segment prefixes + count); publish it. Later, syn verify --since <witness> proves the current history only ever extended it (HEAD descends
from the witnessed commit and every witnessed segment prefix is byte-stable) so a force-push or mid-log rewrite is caught offline, without a remote. A
published witness lets a third party hold you to your history.
syn audit witness [--out FILE] # signed witness checkpoint (default .synapse/audit/witness.json)
Rebuild attestation (--rebuild, SYN-269). Makes the claim your memory is
a reproducible build of your files literally checkable: a from-scratch rebuild
of the index is compared to the live index, and on any mismatch the signed
report names the specific diverging facts (diffoscope-style ± <type> <id>),
not just the first, so you see exactly where the index stopped being a faithful
build. A clean run is the signed attestation itself (binds git_ref +
inputs_hash). A hosted store structurally cannot offer this.
The invariants: INV-1 reindex fixpoint (the index is a reproducible build
of the Markdown: a from-scratch in-memory rebuild yields the same canonical
dump; the keystone), INV-2 audit payload integrity, INV-3 history
integrity (hash-chain + signed checkpoint), INV-5 no silent overwrite
(supersession closes its predecessor). With --deep, INV-4 also replays
the governed decision journal in a scratch workspace to check it applies
cleanly and deterministically (SYN-266 / ADR-036):
a journal-integrity check, not store reconstruction (Synapse is
state-based; reconstruction is INV-1 + git syn at), and INV-13 runs a
deterministic logical-contradiction sweep (SYN-316): no overlapping
valid-time values for one field (x-field-history), no supersession cycle, no
inverted interval. It guards logical coherence, catching contradictions
introduced by a direct Markdown edit that bypasses the gate: the one class
INV-1 (storage coherence) and the propose-time gate (SYN-242) cannot see.
Deterministic and model-free (no NLI/judgement). INV-8 (stored-receipt round-trip) is
checks native stored receipt signatures in governed workspaces. Missing or unsigned receipts report skipped; invalid evidence fails. Legacy export-on-demand receipts do not create coverage. Independent signer trust/identity require opt-in v2 inputs. Exit codes: 0 no checked invariant failed (skips may remain), 1 an invariant was violated. The report always prints the trust-root caveat: tamper-evident,
not tamper-proof: a lone local clone cannot detect its own owner’s rewrite
without a witness. MCP counterpart: the verify tool.
--from-git (ADR-025) inverts the capture value-timing: a fresh workspace seeds itself from the repo’s history (authors → people, repo → project, with contributor memberships), as queued proposals (BR-12.3), bot-filtered and idempotent. Review and apply the lot with syn pending accept --all.
Freshness advisory
The workspace freshness signal (SYN-93 / SYN-93b, ADR-011) is advisory, never blocking. Phase 2 adds a bounded (3s) network git ls-refs probe of origin to catch commits you haven’t fetched yet; any network/auth/timeout failure is silent (status unreachable, previous state retained). Three escape hatches:
SYNAPSE_NO_FRESHNESS=1 syn info # silence for this invocation
syn info --no-freshness # same effect
syn ws freshness off <name> # per-workspace, persisted
Globally disable in config:
[freshness]
enabled = false
MCP
syn mcp # starts the stdio MCP server (feature-gated, default-on)
24 tools across local read / federation / maintenance / audit / integrity / write
proposals. Reads include search_knowledge (hybrid, optional type filter),
search_everything (SYN-226: hybrid RRF over all kinds incl. custom,
no type filter), query (structured aggregation incl. filter.field over a
custom indexed field), get_entity, get_entities, list_by_type,
project_graph, workspace_overview, recent_changes. All of these now
reach custom types (SYN-234). Writes go through the pending queue
(BR-12.3): capture_fact (creates a built-in or custom-typed entity),
link_entity (any registered kind as an endpoint), update_status,
propose_batch, plus the workspace-manifest tools. See MCP.md
for client wiring.
Agent assets (v0.6, SYN-175 / SYN-184)
The binary carries the agent-facing assets and emits them on demand, so they never drift from the release that ships them.
syn skill install [--dir PATH] [--force] # write the Claude Agent Skill (SKILL.md) to ~/.claude/skills/synapse-second-brain/
syn agents init [--dir PATH] [--force] # write an llms.txt (cwd by default) orienting any AI agent
syn plugin install [--dir PATH] [--force] # scaffold a Claude Code plugin: plugin.json + skill + .mcp.json + a SessionStart hook
All three refuse to overwrite without --force and honour --format json.
Environment variables
| Variable | Effect |
|---|---|
SYNAPSE_LANG | Locale override (en, pt-BR). Same as --lang. |
SYNAPSE_PLAIN | Any non-empty value forces raw, unstyled output (same as --plain). |
SYNAPSE_NO_COLOR / NO_COLOR | Drop ANSI colour, keep structure. TERM=dumb does the same. |
SYNAPSE_AGENT | Mark the caller as an AI agent: implies --plain and --no-input (no styling, no prompts). |
SYNAPSE_PROFILE | Path to the global self-identity profile.toml (overrides the default location; used by tests + advanced setups). |
SYNAPSE_NO_FRESHNESS | Any non-empty value silences the freshness advisory for the invocation. |
SYNAPSE_ENRICHMENT_MODE | Override [enrichment] mode per invocation (off / heuristic / heuristic+ner). Use off for a fast write that skips the model. Honoured on the default (semantic) build; ignored on a minimal core build. |
SYNAPSE_MODEL_CACHE | Override where embedding/NER models are cached. Default is the platform cache dir + /synapse/models. Honoured on the default (semantic) build; ignored on a minimal core build. |
Output and exit codes
| Code | Meaning |
|---|---|
0 | success |
1 | user error (validation, not found) |
2 | internal bug (panic caught) |
64 | usage error (bad clap args) |
65 | data format error (frontmatter, YAML) |
74 | I/O error (disk, database) |
--format json returns canonical, byte-stable JSON on every read command: list, show, tag list, pending list|show, ws list|show, at … show, plus search/info/doctor/graph/audit/cv, and machine-readable errors carry {error, kind, exit_code} on stderr (SYN-188/189/204). Text mode is rich by default on a TTY (colour, ✓/▲ glyphs, tables, entity panels, the unicode graph tree, progress spinners/bars, the graph-constellation mascot); it degrades to plain bytes on a pipe and is fully suppressed by --plain/--raw/SYNAPSE_PLAIN, while --no-color/NO_COLOR/TERM=dumb drop only colour and --quiet/-q drops non-essential lines (ADR-019/021).
Conventions worth knowing
- Slugs are kebab-case ASCII, derived automatically. Renaming is a separate command (
<type> rename old new), not an edit. - Frontmatter round-trips preserve field order; safe to edit by hand without producing noisy diffs.
- Writes are all-or-nothing: filesystem + index commit together, rollback together (BR-6.1).
- A workspace is any folder whose ancestors contain
.synapse/;synfinds it walking up fromcwd.
syn commit-verify --roster <JSON>
Verifies raw Git HEAD SSHSIG bytes in the git namespace against explicitly
pinned local signing keys. Emits synapse.commit-verification/1 JSON and exits
nonzero for unsigned, unsupported, invalid, unknown or ineligible signatures.
The same pure core serves MCP commit_verify. A compatible roster array keeps
v1 behavior. A synapse.commit-roster/1 object additionally requires an explicit
--roster-sha256 (roster_sha256 in MCP) selected outside the mutable workspace.
It emits v2 with revision/pin/freshness and rejects missing/wrong pins, stale
snapshots, future signing claims and unsigned/unknown signatures.
--require-current additionally requires current key eligibility; historical
administrative revocation can preserve a prior valid signature. Reported
compromised_at invalidates signatures at or after its onset. Neither profile
establishes team authority or an independently trusted historical timestamp.
Roster entries have issuer, subject, OpenSSH public_key, Unix-second
not_before/expires_at and optional revoked_at/compromised_at. Signing-time validity and
current_key_valid are separate. Author names/emails do not establish identity;
commit time is signer-controlled, and current team membership needs independent
revalidation. OpenPGP and alternate SHA256 commit headers are explicitly unsupported.
A roster supplied by a caller is a local trust decision, not an authority-issued
binding. The snapshot includes schema, bounded revision, observed_at/expires_at
Unix seconds and unique signers; its normative SHA-256 prefixes fixed-order JSON
with synapse.commit-roster/1 and NUL. Unobserved offline revocations remain
unknown. See ADR-055/064 and the CI test generating actual Git/OpenSSH commits.
The official Git configuration documents
gpg.format=ssh; verification uses the normative git SSHSIG namespace.
Governed source suffix: syn state
This is separate from native v1 syn verify: current Markdown remains the
content source, while the optional governed suffix preserves complete accepted
before/after manifests and retrievable raw images. Previous history is unknown.
syn state baseline --reason 'adopt reviewed current knowledge' \
--acknowledge-unknown-history --acknowledge-plaintext-retention
syn state verify
syn state witness --key-dir /private/existing-identity > /independent/state-witness.json
syn state verify --since /independent/state-witness.json --trusted-key '<pinned public key>'
syn state reconcile --expected-parent '<reviewed head SHA256>' --reason 'reviewed external API update'
syn state receipt '<accepted event ID>'
These commands return native JSON objects in both output modes. Verify exits
nonzero if uninitialized, damaged, missing retained images or source is
Unattested. Reindex cannot turn external edits into accepted history. A
reconciliation records the previous accepted state and actual observed state
separately; a stale expected parent denies it. Mutation IDs are stable during
recovery, and Workspace::tx_with_event_id supports caller request IDs without
repeating an accepted ID’s effects; retrieve original evidence with receipt.
Baseline/reconcile accept optional --context <JSON> containing actor_claim
(issuer/subject/device_key), proposal/rule/context SHA-256 values and a reason.
These are explicit claims until authority/receipts verify them. No password,
token, private key or raw prompt belongs in context/reason. Witness export needs
an existing signing key, and verification needs a separately trusted pin; its
embedded key alone does not establish trust. Preserve the witness independently.
Scope covers regular Markdown recursively outside .git/.synapse components;
symlinks/unportable paths and exceeded budgets deny instead of silently skipping.
Retained deleted images are plaintext private history with no automatic GC; use
filesystem encryption/access controls. Purging an image loses reconstruction
coverage. The framework does not publish raw images or commitments externally.
See ADR-057 for normative bytes, budgets and
adversary/platform boundaries.
MCP counterparts: state_baseline, state_verify, state_reconcile,
state_witness, state_receipt. Each calls the same core as the CLI. State verify
reports tool error when uninitialized or Unattested; field attribution remains
explicitly unverified without authority-issued receipts. These tools do not
claim general natural-language consistency, trusted timestamps or team authority.
Native receipts and explicit assurance profiles (SYN-325)
syn state receipt-policy --input <policy.json> [--expected-policy <active-digest>]
syn state signed-receipt <event_id>
syn state witness --key-dir <existing-key-directory> --include-receipts > <independently-retained-witness.json>
syn state verify --profile strict-local --trust <reviewed-trust.json> --trust-sha256 <independent-digest> --since <retained-witness.json> --trusted-key <independent-key-pin>
syn state verify --profile basic
syn state verify --profile strict-team
Without --profile, the existing synapse.governed-state/1 source report stays
available. Explicit profiles use synapse.state-assurance/2; passed is the
selected policy verdict. Basic can succeed with absent/unsigned receipts and
explicit gaps (strict_requirements_met:false). Strict-local requires matching
source/images, all receipts from the limited baseline, independently pinned key
validity/freshness and a v2 witness covering the exact selected tip/receipt set.
A prefix-only witness or old v1 source-only witness is partial, not sufficient.
Strict-team additionally requires independently selected current issuer roots,
exact resource scope and fresh complete actor/device observations supplied with
--team <reviewed-team-inputs.json>. Every retained native receipt must match
its original issuer/source seal and event-specific admission, with an independent
v3 witness covering both receipt and original seal sets. Missing, stale, copied
or untrusted inputs fail; a local key alone does not establish team authority.
A successful historical verdict grants no current publication permission.
Configure signing before baseline; no back-signing of unsigned history. Policy
JSON contains schema synapse.receipt-write-policy/1, profile strict_local, an
absolute existing key_dir, a reviewed public trust snapshot and its normative
trust_sha256. Snapshot schema is synapse.local-receipt-trust/1: revision,
observed_at/expires_at and unique keys with public_key, not_before/not_after,
revoked_at and compromised_at. Times are integer Unix seconds, end exclusive;
nullable timing fields remain explicit null. Digest is SHA-256 of its schema
plus NUL and fixed-order compact JSON. No auto-generated/trusted signer is used.
An explicit expected public policy digest permits key rotation/trust refresh; prior receipts and public trust revisions stay retained. A wrong prior digest, missing key, permissive Unix private-key mode or invalid/stale signing trust blocks before source installation. Losing the active policy pointer cannot silently downgrade retained strict configuration. Private key paths are local configuration only, never exported in receipts; bearer/private bytes never enter source, evidence or logs.
Native receipts bind full transition/context/source digests and public signing policy; independently retained v2 witnesses additionally bind the ordered exact receipt set. Verification-at-claimed-time is distinct from current key approval: a later administrative revocation can preserve earlier evidence; compromise at or before that claim invalidates it. The clock remains signer-controlled and no offline verifier can know an unobserved revocation. Receipt validity is not semantic truth, organizational authority or a trusted historical timestamp.
MCP counterparts state_receipt_policy and state_signed_receipt share the CLI
core. state_verify accepts profile/trust/trust_sha256; state_witness accepts
include_receipts and optional include_shared_seals (v3 requires receipt coverage).
Team verification accepts the typed team input shared with CLI. Failed selected profiles return tool error plus inspectable
JSON; the native signed-receipt result is an object with nullable receipt.
See ADR-058.
Scoped offline authority evidence (SYN-326)
syn state binding-verify --bundle <signed-bundle.json> --trust <reviewed-issuer-roots.json> --trust-sha256 <independent-digest> --expect <selected-identity-and-scope.json> [--claimed-at <epoch-microseconds>]
The bundle contains signed binding and snapshot only. Root review/digest and
expected authentication issuer, tenant/subject UUIDs, device/fingerprint and exact
organization/workspace/project/knowledge GUID are selected separately. The current
governed workspace must match that GUID; otherwise the report fails. No access,
refresh, M2M, password or private key belongs in these files. Account API identity
is not represented as OIDC without such an adapter.
state_binding_verify is the MCP counterpart with bundle/trust/trust_sha256/expect
and optional claimed_at. It reports an inspectable object and tool error for failed
signature, root pin, identity/scope, revoked/compromised/expired or partial selected-key
evidence. Claimed/observed/root times here are Unix microseconds, distinct from native
source receipt seconds. Signatures and exact canonical schemas live in the shared
pure synapse-evidence Rust package; ADR-059
defines the contract and independent fixtures.
A passing synapse.binding-verification/1 proves this scoped identity observation;
source_integrity_checked:false requires separate state verification and
shared_acceptance:unknown_without_online_event_bound_admission requires fresh
SYN-231 admission. It neither changes source/pending data nor makes strict-team
verification pass. Snapshot writer/key activity is an observed point, not evidence
of unobserved later revocations or new action authority.
Historical shared admission (SYN-231 component)
syn state admission-verify --bundle <grant-binding-snapshot.json> --trust <reviewed-roots.json> --trust-sha256 <independent-digest> --expect <selected-reviewer-change-policy.json>
MCP state_admission_verify takes bundle/trust/trust_sha256/expect and uses the
same core. The bundle contains admission, reviewer binding and fresh selected-key
snapshot. Independently selected expect contains reviewer, exact change and policy.
The actual governed GUID must match. Missing/stale/wrong-scope evidence denies.
The verdict authenticates a historical authority decision;
source_installation_verified:false and
new_operation_authority:requires_current_online_decision state its limits.
This does not enable strict-team writes or replace the prepare/sign/commit host
protocol, source receipts, search/citation ACL or independent witness. See ADR-060.
Scoped contradiction diagnostics (SYN-319)
syn contradictions [--fact note/api-contract] [--fact api/catalog] [--limit 50] [--proposal operation.json] [--assessment advisory.json]
MCP contradictions {request:{facts:[],limit:50,proposal:null,assessment:null}}
uses the same core. Each fact is {type,id}. Report schema is
synapse.contradiction-diagnostics/1; typed exact findings include stable rule
IDs, finding digests, fact/field/interval references, indexed paths and exact
checked scope. Omitted diagnostics/counts and unavailable checks are explicit.
Cycles resolve the full indexed reference graph before scope filtering. Bare
supersession targets must resolve to one globally unique fact ID; ambiguous
targets now deny acceptance instead of invalidating a row chosen by query order.
Unambiguous cross-type targets continue working. No source is changed by this verb.
An empty result is clear only within the checked structured classes. General prose/unindexed semantics stay unknown. Structured native proposal flips are a separate comparison, never an automatic review. Optional external assessment JSON names model_revision, rubric_revision, evaluation_revision, classification (contradiction/entailment/unknown), confidence and abstained. It is explicitly caller-asserted; this binary does not claim to run that model. Abstention requires unknown class and null confidence. Confidence cannot approve a write, change a rule or create an exact invariant result. See ADR-062 and SYN-323 model evaluation.
Versioned knowledge process API
knowledge describes actual build/protocol capabilities or takes bounded versioned
request JSON through --request <file|->. Query/propose/review share the MCP knowledge
tool. Acceptance and exact-review rejection are explicit operator CLI actions; the
MCP agent door refuses both. Legacy rejection refuses terminal rows without adding
a contradictory audit entry.
See request shapes, scopes, budgets, citations and proof limits.
syn --format json knowledge
syn --no-input --no-freshness --format json knowledge --request request.json
syn shared-source --input <JSON> [--operator-bridge]
Request schema 1 shares typed metadata/operator dispatch with MCP shared_source.
The MCP agent can describe public configuration; operator actions deny there.
Native bootstrap/exact pending acceptance requires a separate current signing
host through the bounded two-frame stdin/stdout bridge. No token/private key is
accepted. Shared content requires a fresh scope read proof; old local/automatic
write doors cannot publish without the exact host seal. This protocol foundation
is documented in SHARED_SOURCE; real Soma issuer/Keychain and
full strict-team composition remain separate acceptance work.
Team inputs use schema synapse.team-assurance-inputs/1, public trust and its
independent trust_sha256, selected scope and unique actors containing
external expected binding expectations and current signed snapshot objects.
Authority timestamps use microseconds; existing local source observation and
local trust timestamps remain seconds. Historical device eligibility is assessed
at original issuer permit issuance, not the source preparation clock. Later
administrative revocation preserves preceding decisions while
currently_approved:false prevents confusing history with current permission.
Use syn state witness --include-receipts --include-shared-seals --key-dir <independent-key-directory> and independently retain the resulting v3 witness
and its separately selected public key. No retroactive receipts or team history
are fabricated for a local/unsigned baseline.
Standard evidence exchange: syn state attest
state attest is a separate opt-in in-toto Statement v1 export; native report
formats and defaults remain available. The subject hashes exact exported native
evidence artifact bytes. Basic/strict assurance, originals, selected public
trust/witness inputs, skipped checks and excluded surfaces are preserved.
syn state attest --profile basic
syn state attest --profile strict-local --trust <reviewed-trust.json> \
--trust-sha256 <independent-digest> --since <witness.json> \
--trusted-key <independent-witness-key> --dsse-key-dir <private-export-key-dir> \
--artifact-output <new-file-outside-source.json>
syn state envelope-verify --input <dsse.json> --trusted-key <independent-export-key> \
--artifact <exact-optional-subject-artifact.json>
The optional DSSE export key signs only the outer statement. Independent envelope
verification reports signature and subject integrity; native source verification
is not rerun and current publication authority is not granted. A failed native
policy still exports its honest statement and exits non-zero. Artifact output
cannot overwrite an existing file or modify the source. MCP state_attest and
state_envelope_verify use the same cores; no MCP private-key path exists.
See the versioned predicate.
Scoped advisory decisions (SYN-323)
syn decisions --fact note/a --fact note/b [--provider rules|HOST_ALIAS] reads an exact bounded source subset and emits synapse.source-decision-diagnostics/1. MCP decisions accepts {request:{facts:[{type:"note",id:"a"},{type:"note",id:"b"}],provider:"rules"}} through the same core. There are 42 MCP tools.
Source read authorization, accepted revision integrity, deterministic contradictions, topic, API version, environment and validity precede inference. Pairs are evaluated in both directions because entailment is directional. Unknown/truncated context or exhausted budgets produces abstention. The default rules baseline recognizes identical text and abstains from arbitrary prose. Models never approve or mutate memory.
See provider configuration and reproducible evaluation. Local NLI and Jev are opt-in experiments; the initial EN/PT benchmark failed its recall gate. No model download, Python runtime or hosted credentials are required by default.
Revisioned source acquisition (SYN-335)
syn sources --request '{"connector":"docs","document_id":"catalog","cursor":null,"notification_revision":null,"cancelled":false}' polls one exact host-configured document. --request - reads bounded JSON from stdin; MCP sources takes the same object in request and calls the same core. It returns current revision/digest/access provenance or an explicit no-content unavailable/denied result. It never creates accepted notes or publishes upstream patches.
See configuration, access mapping and adapter coverage. Git/Markdown and opt-in GitHub are implemented; other tools remain separately tracked adapters. There are 42 MCP tools.
Scoped source impact (SYN-327)
The same sources request accepts an optional operation (absent means {"op":"read"}). observe reconciles current source revision and returns only authorized matching dependencies; review pins a proposal ID; suggest_patch requires that reviewed ID and expected_revision, and returns an unpublished suggestion. queue creates an exact source-linked native note proposal; accept requires explicit CLI operator action, pending ID, exact review digest and a fresh matching upstream read. Generic pending accept and MCP cannot bypass that source check. Current adapters always refuse publish, including requests with reviewer consent.
See evolution states, dependency mapping and acceptance limits. Accepted historical local annotations do not establish current upstream truth; current upstream passages are served through fresh source acquisition.