Skip to content

v0.99.6

Choose a tag to compare

@github-actions github-actions released this 14 Jul 05:54

Added

  • OpenCode 1.17.20 is now a pinned Participant Fabric and IDE bridge. A
    reversible project/global adapter owns one local-stdio Synapse MCP entry and
    one fail-closed native mutation plugin; strict ownership, bounded race-aware
    file updates, token-file persistence, and uninstall preservation keep existing
    OpenCode configuration outside its scope. Exact-version headless JSONL and
    authenticated HTTP API participants, cancellation, remote attach delivery,
    and an ACP protocol-v1 handshake are covered by isolated real-process tests.
    The focused CI lane verifies the official OpenCode archive and extracted
    binary hashes before exercising adapter lifecycle, claimed/denied native
    writes, local turns, authenticated server access, and package contents.

  • The experimental VS Code/Cursor client now consumes a bounded strict editor
    wire projection with version negotiation, stale-last-good state, fail-closed
    mutations, bounded reconnect/backoff, and safe identity/auth close handling.
    Claims and releases use canonical Git/workspace roots plus deterministic
    per-file task IDs, so multi-root workspaces and two files held by one identity
    remain distinct. Gutter projections require the exact canonical worktree and
    path; stale credential reads cannot restore an older configuration; switching
    hub or identity clears the previous projection; and terminal authentication or
    seat-ownership refusals wait for an operator change instead of retrying. Focused
    coverage is enforced above 95%, while a real VS Code
    Extension Development Host exercises two independent token-gated hubs,
    per-hub SecretStorage, configuration reconnects, identical relative paths in
    two real Git roots, exact claims, and exact releases. Runtime, timer, protocol,
    scope, and test-harness responsibilities
    remain split below the documented Godfile threshold.

  • synapse hub --secure is the strict multi-seat production umbrella: it
    composes the --team-secure trust profile and the --paranoid exposed-hub
    profile, then bounds per-agent (100/s, burst 20), per-host (500/s, burst 100),
    and per-host connection (10) flood limits. Missing operator material fails
    closed before any socket binds, listing every absent input in one aggregate
    error; a stricter positive limit is preserved and a rate, burst, or
    connection cap above a preset ceiling is refused; startup prints one
    consolidated report of the composed gates, effective limits, and the controls
    the preset genuinely does not compose. It generates no credentials and enables
    no metrics surface. See Secure mode.

  • --message-auth-key-file and --metrics-token-file read hub secrets from
    owner-only (chmod 600) files instead of argv, so a per-message HMAC key or
    metrics bearer token is not exposed in the process list. The key file carries
    one KEY_ID:SECRET:SENDER[,SENDER...] entry per line (# comments allowed)
    and merges with argv keys for rotation; an explicit --metrics-token wins
    over its file, mirroring --token/--token-file. The loader refuses a group-
    or world-readable file and reports problems by flag and path, never by content.

Security

  • Human-readable chat, channel, hub-query, mailbox, routing, resource-bid,
    federation-relay, peer-hub, capability-directory, outbound-MCP, workflow,
    event-query, memory-recall, accounting, acknowledgement, and Participant
    Fabric output now renders ANSI, OSC, carriage-return, newline, bidi, and other
    control characters as visible escape notation before they reach a terminal.
    Copyable operator commands shell-quote terminal-safe values, bind long-option
    values with =, and terminate positional options with --. Generated shell
    wrappers, git hooks, and systemd units use the same option boundary; custom
    shell providers must be bare command names. This closes command-substitution,
    option capture, and shell-function injection paths in setup, doctor, locks,
    federation exchange, SQLCipher guidance, claim helpers, fleet-init, and
    automatic waiter, provider, hook, and service-start flows.
  • Headless Claude turns now disable built-in tools, ambient MCP servers, skills,
    plugins, hooks, browser integration, and customisations explicitly while also
    selecting plan permission mode. Unsupported older CLIs fail closed rather than
    accepting a bus prompt with weaker local execution policy.
  • The hub rejects a non-finite (nan, inf) --rate, --burst, --host-rate,
    or --host-burst at the argument parser for every run: nan previously passed
    every downstream comparison and then built no limiter at all, so a hub could
    appear rate-limited while enforcing nothing. --secure additionally rejects a
    non-finite value and holds each burst to its own ceiling.
  • The exposure guard now runs before the durable event store is constructed, so
    a refused unauthenticated non-loopback bind leaves no database file on disk.
  • SECURITY.md distinguishes host ingress from container-network reachability:
    same-network containers reach the hub container-to-container regardless of the
    host publish flags. The shipped docker-compose.yml now attaches the hub to a
    dedicated single-service network so both audiences are bounded.
  • The --secure report no longer copies the paranoid profile's
    "compose --team-secure" missing-hook line, which the umbrella already
    enforces; genuinely uncomposed controls (at-rest encryption, mutual TLS, …)
    stay listed.

Documentation

  • SECURITY.md now explains the container image bind posture that external
    audits kept re-flagging: the in-container 0.0.0.0 bind is required for
    port publishing, the exposure guard refuses startup with InsecureBindError
    on an unauthenticated non-loopback bind, and the shipped compose file pairs
    a loopback-only publish with a dedicated network and the explicit
    --insecure-off-loopback opt-out. The Dockerfile comment now states the
    refusal instead of understating it as a warning, and documentation-accuracy
    regressions pin both surfaces.

  • Secure mode documents the file-backed secret flags and
    the burst ceilings, and its production example delivers every secret from an
    owner-only file instead of expanding it into argv.

  • synapse a2a-serve --allow-origin ORIGIN restricts browser requests to an
    opt-in allow-list of exact web origins (scheme://host[:port], or null),
    repeatable for several. A request whose Origin header is not listed is
    refused 403 on every route — the public agent card included — before
    authentication; a non-browser client sends no Origin and is unaffected, and
    with no list configured the check is a no-op. Hardens the loopback bridge
    against DNS rebinding and drive-by browser requests.

Fixed

  • Failed headless provider turns no longer copy raw CLI stderr or process-start
    exception text into relayable or durable results. Claude, Codex, Gemini, Grok,
    Kimi, and Ollama now expose only the exit status plus a bounded safe
    classification; unknown diagnostics are withheld. Gemini's binary-health row
    also states that account entitlement was not probed, while a recognised retired
    consumer-account failure points operators to Antigravity or an eligible
    enterprise/API-key configuration.

  • synapse git-init now stores staged-claim identity, hub URI, and the optional
    token-file path in Git's official per-worktree config. Linked worktrees can
    therefore use different exact seat identities without overwriting one another;
    migration removes the old shared values only after the current worktree is
    configured and refuses unsafe core.worktree / core.bare=true layouts with
    an explicit repair instead of guessing.

  • The MCP guide now reflects the live official-registry state: SYNAPSE CHANNEL
    is active there, while a newer server.json remains only a prepared update
    until the immutable registry record exposes that exact version.

  • Path-based claim enforcement now rejects symlink loops and broken path
    components consistently on Python 3.10–3.13 while retaining support for
    valid paths whose final file or directory does not exist yet.