Skip to content

v0.99.36

Choose a tag to compare

@github-actions github-actions released this 01 Oct 18:01

Changed

  • Document per-host connection budgets for large terminal fleets, including
    transient CLI connections, close code 4015, and explicit 100-terminal sizing.

  • Refresh compatible hash-locked Python workflow cohorts, the cockpit test/build
    lock, Ruff hooks and the CodeQL action commit. CI uses Node 22.23.3 and the
    Python 3.13.15 slim container digest. The accepted MCP SDK 1.30.0 and historical
    hub fixtures remain pinned to their exercised compatibility contracts.

Added

  • Explicit durable hub inbox pages for remote CLI and MCP readers, with exact
    recipient filtering, mailbox ACLs, bounded journal scans, independent
    endpoint and identity cursors, and unavailable results for unsupported hubs.

  • Real SQLite recovery regressions for damaged atomic-operation rows, settled
    evidence outbox bindings, invalid operation and AEF identities, and cleanup
    refusals before or after commit. Independent database reads and reopen/replay
    checks preserve the distinction between a rejected write and durable success.

  • Recipient-granted private cross-hub attachment metadata and chunk reads (wire
    version six). --attachment-recipient-policy binds verified recipient hubs to
    exact scopes, digests and finite expiries, reloads owner-only permissions on
    every request and composes them with live peer trust before storage lookup.
    Invalid or revoked grants, expired content and malformed requests share one
    private refusal. The Python peer transport checks the named source, negotiates
    version six and validates bounded responses. Local attachment permissions,
    quotas, session-bound uploads and reference retention remain in force.

Fixed

  • Spend requests classify an interrupted WebSocket handshake as a transport
    failure, allowing callers to retry within their existing bounded budget and
    refuse unavailable owners without granting unconfirmed reservations.

  • Journal-free hubs release the private SQLite forwarding connection when
    its ledger is retired. Journal-backed connections remain owned by the event
    store, preserving forwarding state across hub restarts.

  • Bound outbound socket writes and isolate unread peers with finite close/abort cleanup.
    Directed and private-channel chat receipts and retry deduplication now require
    completed recipient or waiter writes; failed writes remain durable and retryable. The JavaScript SDK
    waits for the prior socket close event before reconnecting the same identity.

  • Manual release verifies exact-confirmation support before sending a mutation.
    Unsupported, malformed or missing probes refuse without releasing the claim;
    an existing exact receipt is recovered without replay. Published 0.48.0 and
    0.99.27 hubs require a matching upgrade for this CLI workflow.

  • Deadlock socket tests correlate claim grants with the requested task and
    holder before sending dependent waits. An unrelated claim broadcast no
    longer satisfies another holder's setup barrier; wait and deadlock behavior
    is unchanged.

  • Failed event-store initialization closes the acquired SQLite or SQLCipher
    connection across schema setup, backfill, caller interruption and replay
    validation. Retaining an exception traceback no longer retains failed-open
    WAL handles. Incompatible databases still refuse startup without discarding
    events; cleanup is not an atomic schema-migration guarantee.

  • One-shot sends distinguish confirmed delivery (0), explicit negative
    receipts (1) and missing confirmation (3), including receiptless older
    hubs. The receipt timeout bounds send and confirmation together, rejects
    nonfinite deadlines and never triggers automatic retransmission. Receipt
    matching checks the hub sender, original target, message identity and boolean
    verdict; unknown output preserves the identity for journal correlation.

  • Manual release bounds the complete send/reply exchange and returns exit 3
    for a missing acknowledgement instead of reporting a refusal. A retained
    operation key and semantic SHA-256 digest support exact read-only durable
    confirmation, including after restart, without another release. Python and
    JavaScript clients expose the optional query. Legacy replies and corrupt or
    missing journal proofs remain unknown. The non-blocking Git hook reports
    release requested and joins its connection cleanup rather than claiming
    confirmed release from a send alone.

  • Durable dashboard feeds return a fixed private HTTP 503 for storage,
    builder and JSON-encoding failures instead of exposing internal paths or
    disconnecting the request. Live events, receipts and operator-actions
    channels use the same fixed detail. Explicit causality refusal types
    preserve authored 400/404 messages and ValueError compatibility; the
    next request can observe a repaired store on the same dashboard server.

  • Task causal-parent validation uses an explicit authored refusal type while
    preserving ValueError compatibility and existing validation reasons.
    Unexpected parser faults return fixed private errors without changing the
    board or consuming a retry key. CLI failures keep interpreter diagnostics
    and tracebacks out of caller output.

  • MCP inbox and advisory storage failures return fixed diagnostics instead of
    system exception text. Failed cursor writes retain the original cursor and
    repeatable messages; tool sessions remain usable after a failure. Explicitly
    typed missing-store input refusals retain their authored text. Unexpected
    database and key-file details remain in server logs.

  • Governed identity storage failures keep exception text out of operator
    responses and audit details. Pin reclaim, enrolment, rotation and revocation
    retain existing authority and live holders until persistence succeeds.
    Dashboard receipts now include the declared identity-enrolment events,
    keeping approval, failed application and successful application distinct.

  • Shared-plan journal failures privately report rollback without exposing
    storage exception text. Declaration, re-declaration, update and progress
    preserve their prior state and allow a retry after storage recovery;
    diagnostic tracebacks remain in server logs.

  • Git claim timeouts remain unknown (CLI exit 3) instead of reporting denial.
    CLI and MCP wait with finite configurable deadlines and confirm exact live
    leases through a correlated state snapshot. --confirm-only / confirm_only
    recover without replaying a mutation or renewing a lease; verified fences
    persist for later release and hook processes. Older hubs without the optional
    snapshot request-id echo leave uncertain claims unknown.

  • Python clients, CLI queries, and dashboard observers accept hub responses up
    to a finite 8 MiB instead of disconnecting on accumulated boards above the
    WebSocket library's 1 MiB default. Oversized responses still close with code
    1009, including an authored diagnostic for local receive-size refusals.

  • Peer attachment transports refuse plaintext connections outside loopback and
    require verified server certificates or an exact live certificate pin before
    registration. Source reads now require a successful bounded private audit write;
    the owner ledger retains the latest 256 decisions across restarts without content.

  • F02 spend ledger: findings from an independent correctness review and its
    follow-up
    (SCPN-PHASE-ORCHESTRATOR/codex-01a0eea6, 2026-09-30). Enforcement
    is still not activated.

    • Exact arithmetic. Amounts, exposures, sums, signs and comparisons used
      the default Decimal context (28 digits). A small fixed fee could therefore be
      rounded away at admission, status could report a non-zero headroom for a
      full pool, and a settlement's overrun flag could disagree with the ledger.
      • Quantities now have a bounded exact domain: at most 30 digits, at most 18
        decimals, and a magnitude below 10**19.
      • Every public ledger method runs in a context that traps rounding, so it
        refuses instead of rounding. This holds whatever the caller's ambient
        context is.
      • A ledger row outside the domain, possible from 0.99.35, makes evaluation
        fail closed. So does a malformed or out-of-order event.
    • Expiry at the use boundary. usable_grant now needs now and accepts a
      min_remaining_seconds margin for clock skew. An expired grant, including
      a replayed or queried one, is not usable to start work. Its exposure still
      counts until it is settled or reconciled.
    • Quota windows. A reservation's idempotency scope and record now include
      the configured window.
      • A new window has its own keys and its own settled usage.
      • Unresolved exposure from earlier windows still counts.
      • The unit, billing surface, account or tax basis cannot change while
        reservations are unresolved.
      • Ledger schema 2. A 0.99.35 ledger (schema 1) is migrated when first
        opened: each stored answer is re-keyed to the window it was decided in, so
        a retry after the upgrade replays it instead of granting twice. A record
        that cannot be matched or read refuses the ledger unchanged, and the
        refused open closes its connection.
      • A 0.99.35 grant, which carries no window, belongs to the window of the
        configuration in effect when it was recorded.

Security

  • The GitHub App development lock uses PyJWT 2.15.1, removing the
    pre-verification JWT payload recursion denial of service (GHSA-42vr-xj54-vc7v).

Artifact checksums (SHA-256)

5a16dde22da41db93ed5f7f5eb5c5d4e58fc2e66beb63de9b4090c5eae3e0db8  synapse_channel-0.99.36-py3-none-any.whl
0191f5da96ac1044566463cad45b7c9da44f6ad725e3ef4f2e52efc507754866  synapse_channel-0.99.36.tar.gz
663d8389d335ef0745f2177a2073618aeb8a86641ddbced795be62fa506f594b  synapse-channel-v0.99.36-sbom.cdx.json