You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Federation-bundle exchange over the network, replacing the out-of-band
file copy while keeping the trust decision with the operator: a hub
started with --federation-offer FILE serves its own operator-authored
bundle material over the ordinary websocket surface (token-gated,
re-read per request so rotated material republishes without a
restart); synapse federation fetch URI --out FILE pulls it, prints
the fingerprint block, and never imports; synapse federation offer FILE validates the offering side's material and prints the identical
block, so both operators compare like for like out-of-band before the
explicit federation import --confirmed-by (whose --source records
the fetch URI as the peering's provenance). The bundle fingerprint is
a SHA-256 over the whole canonical bundle, so an in-path alteration of
any policy content — namespaces and scope grants as much as keys and
pins — changes the value the operators read to each other; there is no
trust-on-first-use. Two new wire message types
(federation_offer_request/federation_offer); every transport
failure fails the fetch closed with nothing written.
synapse cross-repo --watch --notify-cmd CMD runs an operator command
whenever the coordination facts — live claims joined to the graph and
provable version conflicts — change between two consecutive watch
refreshes, with the delta on stdin (+ fact appeared, - fact
cleared) and the scanned root in SYNAPSE_CROSS_REPO_ROOT. Fires on
transitions only (never on the baseline refresh or a steady state);
the command is shlex-split and run without a shell, and a failing or
hanging sink is reported without stopping the watch. The sink is
generic by design — a desktop notifier, synapse send, or anything
else — keeping the scanner decoupled from any live hub.
synapse benchmark --trend STORE.db appends each finished scorecard
to a local SQLite history and renders per-metric sparkline trend
lines across every stored run — first and latest values, the observed
range, and the series shape — so a slow regression no single --compare gate trips stays visible. Host or package context changes
between consecutive runs (CPU model, governor, version) are annotated
as explicit breaks rather than silently connected; unlike --compare, a differing CPU model is annotated, not refused, since a
history legitimately spans upgrades. The JSON document gains a trend object, and the flag composes with --results and --compare.
Version-conflict detection now compares direct-URL requirements in the
one case the conservative model can honestly claim: two references to
the same base URL pinned at two hex revisions of which neither
prefixes the other are provably two different commits and conflict;
identical revisions overlap. Every other URL shape — different bases,
branch or tag revisions (mutable), revision-less URLs, or a URL
against a version range — remains uncompared, exactly as before.
synapse cross-repo --suggest-resolution turns each detected version
conflict into actionable advice: for every provably conflicting
package it intersects all consumers' declared ranges (the same bounded
interval model detection uses, so the two never disagree) and names
which single repository's declaration is the odd one out, with the
range the remaining consumers reconcile at. When no single declaration
is the outlier the advice says the constraints split into mutually
disjoint camps; declarations outside the bounded model are listed as
unassessed. Advisory text only — nothing rewrites a manifest. The
JSON report gains a resolutions list; the flag does not combine
with --watch or --dot.
synapse causality health flags three lifecycle-anomaly shapes in the
coordination-causality graph: orphaned claims (a claim is its task's
last recorded event), dangling dependencies (a declared depends_on
whose task never completed — the same completion predicate the
dependency-edge derivation uses), and stale claims (claimed, never
released, silent longer than --stale-after seconds, default 3600).
Ages are measured against the log's own final timestamp, never the
wall clock, so a report is deterministic and replayable; exit 1
signals at least one anomaly, and every signal is an operator hint
derived from recorded events, not a verdict.
Federated causality queries gain --dot: the answer renders as a
Graphviz digraph with one cluster per hub, so an edge inside a cluster
is same-hub causality and an edge crossing cluster boundaries is a federation edge — coloured and labelled with its basis. The rendered
edges are the query's induced subgraph (every merged-graph edge whose
endpoints both belong to the answer), now also carried in the JSON
output as edges; the queried node is double-bordered and a
counterfactual's unsupported descendants are dashed. --dot requires --peer and excludes --json.
synapse causality otel gains three projection controls: --service-name NAME overrides the service.name resource on the
exported spans so several hubs can share one observability tenant; --filter TASK_ID (repeatable) projects only the named tasks' traces,
refusing a task the log does not record, keeping cross-task links into
excluded tasks (the deterministic ids resolve against any export that
carried the other task) and counting the exclusions in the summary;
and an event recording the task lifecycle's failure terminal
(failed) — or a task whose final recorded status is it — now
projects OpenTelemetry span status ERROR, making failed
coordination visible in trace viewers. Everything else stays UNSET: the log records progress, not success verdicts. The JSON
span records carry the new status and filtered_out_tasks fields.
synapse causality otel --watch re-projects and re-exports every --interval seconds until --count ticks ran (0 = until Ctrl-C) —
live coordination observability on a fixed cadence. The store is
reread each tick, so newly recorded events appear in the next export,
and the deterministic span ids make re-exports idempotent on the
collector side; a failing tick stops the watch with its exit code.
Fixed
A2ATaskEvents.has_subscribers reports whether a live local
subscription is registered for a task, so a publisher can sequence an
update after a subscriber is known to be listening instead of racing
the registration — the race a slow CI runner exposed in the
subscription lifecycle test, which now synchronises on it.
Security
The hub federation gate now denies a frame signed with a peered key whose
live certificate pin fails to resolve to a single peered domain (reason peer_domain_unresolved), matching the existing refusal of a peered key
on a connection with no pinnable certificate. Previously such a frame —
a stale or foreign certificate, credentials split across peerings, or an
ambiguous pair two peerings both claim — degraded to local processing
with only an operator warning. A frame signed with an unpeered key still
takes the local path unchanged, and the misconfiguration diagnosis is
still logged for the operator.
Documentation
New README "Security posture" section: the loopback-first default and
the opt-in, deny-by-default runtime controls (connect and per-message
authentication, Ed25519 signature trust, mTLS pins, ACL policy,
paranoid mode) alongside the supply-chain gates (two-layer gitleaks,
hash-locked CI toolchain, SHA-pinned actions, digest-pinned images,
per-push pip-audit, CodeQL, Scorecard). The stale "Known limitations"
bullet claiming no signature trust, ACL enforcement, or mTLS trust
bundle exists is corrected to what actually remains out of scope: no
key exchange or automatic trust distribution, and declared (not
cryptographic) per-agent identity.