Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


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 json is always machine-clean and unstyled.

Workspace lifecycle

CommandWhat 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 infoWorkspace 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 contextPrint 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 reindexRebuild the SQLite index from the Markdown source of truth. Idempotent.
syn doctorRead-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 explicit syn embed --all (FTS-only until then): SYN-251. Declared pattern (regex) field constraints are parsed but not yet enforced (needs a regex dep + 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 at DATE (YYYY-MM-DD or RFC-3339), using the SQL:2011 closed-open [x-valid-from, x-valid-until) interval. Facts with no x-valid-* stamps always pass. Applies in every mode (FTS and hybrid); local-only (conflicts with --all). Composes with syn 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 blame use), 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 link rows for mentions that resolve to existing entities (surfaced by syn graph);
  • queues a create_entity_from_ner proposal 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

VariableEffect
SYNAPSE_LANGLocale override (en, pt-BR). Same as --lang.
SYNAPSE_PLAINAny non-empty value forces raw, unstyled output (same as --plain).
SYNAPSE_NO_COLOR / NO_COLORDrop ANSI colour, keep structure. TERM=dumb does the same.
SYNAPSE_AGENTMark the caller as an AI agent: implies --plain and --no-input (no styling, no prompts).
SYNAPSE_PROFILEPath to the global self-identity profile.toml (overrides the default location; used by tests + advanced setups).
SYNAPSE_NO_FRESHNESSAny non-empty value silences the freshness advisory for the invocation.
SYNAPSE_ENRICHMENT_MODEOverride [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_CACHEOverride 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

CodeMeaning
0success
1user error (validation, not found)
2internal bug (panic caught)
64usage error (bad clap args)
65data format error (frontmatter, YAML)
74I/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/; syn finds it walking up from cwd.

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.