v0.99.2
Added
-
SynapseAgentnow presents the zero-config machine identity by default, so
every verb that connects — send, listen, arm, queries, the bridges, and any
embedding application — signs its registration with the same
trust-on-first-use key. Previously onlyarmandwaitsigned, and arming
a name locked its holder out of every other verb under that name (refused
signature missing; the 2026-07-10 directed-delivery incident class). An
explicitidentity_key_pathwins over the default,machine_identity=False
opts a deliberately unsigned agent out, and a core-only installation
degrades to the unsigned path with a one-time warning. The test suite runs
on a session-isolated throwaway key. -
synapse git-claim --diff-basenow narrows safe tracked modifications to
function or type scopes using local tree-sitter grammars for Python,
JavaScript/JSX, TypeScript/TSX, Rust, and Go. Canonical.synapse-symbol
descendants reuse the hub's existing path ancestry rule, so separate symbols
can coexist without a wire change while class, file, and directory claims stay
conservative ancestors. Old and new diff sides are both mapped; incomplete,
unsupported, unsafe, add/delete/rename, or non-textual evidence widens to the
whole file. The optionalsemanticextra installs individual upstream grammar
wheels with no runtime download;tools/semantic_diff_claims.py, path filters,
committed-head comparisons, owner-only JSON evidence, and owning
test/generated companions expose the same local-first decision trail. -
synapse fleet-scorecardnow composes the existing durable causality spans,
opt-in accounting, advisory live-claim contention, evidence-only reliability,
and optional benchmark history into one atomic owner-only JSON bundle. With
the optionalotelextra it pushes the same projection to the collector's
standard trace and metric endpoints, fails visibly on either signal, and
keeps historical benchmark backfill outside the current-gauge claim. -
MCP-first onboarding now includes identity-safe
synapse mcpdefaults, real
synapse_inboxandsynapse_statustools, a secret-free.mcp.jsontemplate,
a dedicated PyPI/registry console entry, validated official-registry metadata,
and client-specific setup guidance for Claude Code, Codex, Cursor, and generic
stdio hosts. The guide keeps provider wake delivery separate from MCP tool
discovery and excludes arbitrary local shell-command locking from the adapter. -
synapse who,synapse status, andsynapse doctornow expose a durable
per-identity mailbox pending count. Mailbox clients acknowledge every accepted
live or replayed directed frame; the hub validates the logical recipient,
journals a monotonicmailbox_watermark, restores it after restart, and reports
unavailability instead of a false zero without a durable store. The count is
explicitly receiver transport state, not evidence that a model processed work. -
synapse arm install --identity NAME [--start]now productizes the permanent
waiter as a focused Linux systemd user-service path. It writes only the arm
template, enables the exactsystemd-escapeinstance on request, uses mailbox
replay plusRestart=always, accepts remote URIs and protected token files,
refuses persistent raw-token exposure, reports systemd failures as nonzero,
and gives an honest WSL recommendation outside Linux. -
The hub now detects a dark seat when an identity owns an unexpired claim or
assigned non-terminal board task without a fresh exact-identity-rxwaiter.
After a bounded grace it broadcasts one machine-readabledark_seat_alert
per continuous episode with affected work and the explicit permanent-arm
remedy; recovery re-arms detection without changing work authority. -
The React cockpit now incrementally renders
/receipts.jsonand
/operator-actions.jsonin a compact Audit inspector tab. Strict typed
parsers, monotonic sequence cursors, de-duplication, and bounded retention
keep the two durable histories distinct;404, failure, empty-present, and
stale last-good states remain explicit. The production browser harness now
uses a real temporary event store and proves a dashboard message receipt plus
a journalled governed operator action in the built cockpit. -
The React cockpit command palette now exposes the dashboard's governed task
declaration and task-update routes alongside operator messaging. Focused
forms validate task IDs, dependencies, statuses, and notes; update IDs come
from the live board but remain explicit-entry capable. A shared strict
{action, status, detail, ok}parser fails closed on malformed or
success-shaped non-2xx responses, and the production browser gate proves a
parent/dependent declaration plus recorded update through a real hub. -
A dedicated, path-filtered
clients-cockpitworkflow now gates the strict
TypeScript build, full Vitest coverage thresholds, the production Vite
bundle, and a Chromium acceptance run against a real local hub and dashboard.
The browser gate covers wrong and correct bearer handling, authenticated
operator messaging, lock-on-401, service-worker cache discipline, and
axe-core accessibility in both themes at desktop and phone widths. Failure
traces use only a disposable test bearer. The root CI/preflight guard also
fails closed when the workflow loses a required gate or the npm v3 lockfile
drifts frompackage.jsonor loses registry integrity metadata. -
Every domain exception now derives from
synapse_channel.core.errors.SynapseErrorand carries a stable
machine-readablecode, so boundary layers (CLI, A2A bridge, MCP server,
embedding applications) can classify failures without matching on message
text. Each class keeps its historical built-in base through multiple
inheritance — every pre-existingexcept ValueError/RuntimeError/
PermissionErrorclause keeps catching exactly what it caught before. The
full class-to-code map is frozen by a registry test, and an AST drift gate
refuses any future*Errorclass that does not join the taxonomy. -
Every generated systemd user unit (hub, presence, wake listener) and its
checked-indeploy/*.servicetemplate now carries a sandbox block:
ProtectSystem=strict+ProtectHome=read-onlywith narrow, code-derived
ReadWritePaths(~/synapse; clients also~/.local/share/synapsefor the
trust-on-first-use key),PrivateTmp,NoNewPrivileges,UMask=0077,
namespace/realtime/SUID restrictions, and per-roleLimitNOFILE(65536 hub,
4096 listeners). One shared module owns the block, tests pin the deploy
templates to the renderers and pin the writable roots to the real storage
modules, and the install paths create the writable directories up front.
Directives that fail under a user manager (ProtectClock,
ProtectKernelModules,PrivateDevices,CapabilityBoundingSet) are
deliberately absent and test-forbidden. Measured on a live workstation the
block moves a service from 9.8 (UNSAFE) to 7.4 (MEDIUM) in
systemd-analyze security --user.
Changed
-
Stale-recipient liveness warnings and the matching
synapse whoannotations
are now enabled by default for a bare hub. The existing
--warn-stale-recipientsspelling remains accepted, while
--no-warn-stale-recipientsprovides an explicit compatibility opt-out.
Directed messages remain delivered and journalled; the default change makes a
present-but-deaf recipient visible to the sender instead of silently waiting. -
cli_a2a_interopnow has a direct module-owned test surface covering parser
defaults and overrides, live endpoint-URL and host/port receipt flows through
the production HTTP bridge, operator-file output, invalid endpoints, and
refused connections. -
cli_a2a_typesnow has a direct module-owned runtime and strict-typing test
surface. The tests pin every callable alias's result contract, exercise real
async, card, bridge, and store factories, accept the production A2A defaults,
and reject a factory returning the wrong type. -
core.handlers.offeringsnow has a direct module-owned test surface covering
capability normalization, private malformed-offer and quota rejection,
resource aliases, journal persistence, idempotency memory, and broadcasts
with or without a journal. -
core.hub_httpnow has a direct module-owned test surface covering response
construction, bearer-versus-query token precedence, opt-in authorization,
WebSocket-path fallthrough, private rejection, and the production Prometheus
and health payloads. -
core.state_scopesnow has a direct module-owned test surface covering empty
state, self and same-owner exclusions, disjoint paths and worktrees,
whole-worktree contention, and deterministic first-conflict selection.
Fixed
-
Fleet-scorecard history loading now stays at the CLI feature edge instead of
importingbenchmark.trendupward from the coordination kernel. Core accepts
a minimal structural benchmark-run contract and preserves the existing JSON
and metric shapes, restoring the package-decomposition boundary without an
allowlist exception. -
Public security, protocol, glossary, staged-profile documentation, and the
paranoid operator checklist now distinguish shipped opt-in controls from the
remaining operator and external validation work. The evidence map pins the
live team-secure, paranoid, identity/ACL, message-auth, signed-event/mTLS,
federation, encryption, private-channel, and trust-graph boundaries.
Federation lifecycle clocks are described as POSIX epoch time, and
wire-version documentation now reflects the shipped version-2
negotiate-down-and-warn path. -
The built React cockpit can now unlock a read-gated dashboard without putting
its bearer in a URL. The server permits only files accepted by the existing
cockpit-dist containment and content-type validator to load before read
authentication; every live feed, history/proof/causality request, and
operator write uses one authenticated fetch adapter. The bearer lives only
in the tab'ssessionStorage; a401clears it and removes the whole live
presentation before the unlock veil returns. The service worker bypasses
every credential-bearing request and caches only the token-free shell. The
production build also keeps fonts as same-origin assets instead of
CSP-blockeddata:URLs. Loopback read-only and loopback operator dashboards
retain their existing open-read posture. The 634-line React app shell was
reduced below 500 lines by extracting the auth-bound feed lifecycle instead
of growing a godfile.
Documentation
ARCHITECTURE.mdis rewritten to describe the shipped system instead of the
early prototype: the real module families, the default-on ownership keystone
(ambient-identity refusal, hub-authoritative ownership lease, trust-on-first-use
key pinning), the conflict-free multi-hub merge slice with its
authority-never-merges boundary, and the stated scale ceiling. The previous
revision still claimed the package had no CRDT slice and no cryptographic
agent identity, which the 0.98–0.99 tree contradicts (external audit finding,
2026-07-10).