v0.94.0
Added
-
The cockpit grew from a read-only viewer into a query surface: the
activity spine is brushable from mouse and keyboard (arrows seed and
move the window, brackets resize), a brushed window correlates the
panels, hovered events carry an inspector, log rows hop to their
causal cone through the causality feed, the spine consumes the
hub-attested event tail (real sequences and timestamps instead of
poll-quantised derivation), a capped board renders "N of M tasks" —
never a page masquerading as the whole plan — and the fonts are
self-hosted so the page loads without third-party requests. -
Three new dashboard feeds off the durable stores, closing the cockpit's
server-side asks:/events.json?since=SEQ&limit=N(the raw event-log
tail past a cursor in the exact multihub snapshot shape — real
sequences and timestamps instead of poll-quantised derivation),
/causality.json?seq=N|task=ID&direction=causes|effects(one causality
query in the CLI's exact--jsonshape, withtask=IDresolving to
the task's most recent recorded event), and/federation.json
(imported peerings with provenance and ceremony fingerprints; namespace
outcomes are hub-runtime state and ship absent with the reason stated).
The event-store flag is now named--feeds-dbwith--reliability-db
kept as the same flag's original name, and--cockpit-dist DIRserves
a built cockpit single-page app read-only under/cockpit/with path
traversal and unrecognised suffixes refused. -
synapse hub --board-task-cap N— bound the tasks served per board
snapshot, because a long-running fleet's full board eventually
outgrows a websocket frame (field-observed around a thousand tasks).
Live tasks are kept ahead of terminal ones, the newestupdated_at
wins inside each class when trimming, the reply carriestotal_tasks
andtruncated, and thereadyid list always stays complete. The
default serves the full board unchanged; the ledger itself is never
trimmed — the cap bounds one reply, not the plan.
Fixed
- The docs workflow retries its GitHub Pages deployment once after a
five-minute wait: the Pages backend intermittently refuses a first
attempt with "Deployment failed, try again later" and accepts a
delayed retry, which previously cost a manual rerun on almost every
push. The job fails only when both attempts fail. synapse locknow waits (bounded) for the hub's release confirmation
before exiting. The release frame itself is fire-and-forget and the
hub persists the release before broadcasting the grant, so previously
a follow-up step could read the event log — or contend for the lease —
before the release landed; the process now exits only after the lease
is durably gone. A hub that never confirms costs only the bounded
wait, with the lease TTL remaining the backstop.
Security
- The chat backend client refuses a
base_urlwhose scheme is not
http/httpsat construction — afile://or custom scheme smuggled
in through configuration is aValueError, not a silently opened
request. - Bandit now gates CI: the lint job runs
bandit -r src -c pyproject.toml(it was configured but never invoked). Every prior
finding was triaged in place: one unparsed suppression fixed (bandit
1.9 reads# nosec B603 B607, not the comma form), the placeholder-only
SQL construction and status-string/argv false positives annotated with
their reasons, and the subprocess imports documented as fixed-argv
surfaces.