
Research
/Security News
Popular npm Packages in the keyv and Cacheable Namespaces Compromised in Active Supply Chain Attack
Popular npm packages keyv and cacheable compromised.
positif-ai
Advanced tools
Positif — Agent Switchboard: security-first inter-agent control plane (sbd) for agent fleets
sbd)Positif (
positif.ai) is the canonical product name.sbdis the CLI, andswitchboard/POSITIF_*remain the stable technical namespace (package, env vars,pos1.token prefix,/opt/positif-*paths, thepositif.serviceunit). Those identifiers stay put — renaming them is a separate, box-coordinated migration — but the product you're reading about is Positif.Status:
0.5.0pre-alpha. This repository is release-preparation work, not a stable v1 release. Public distribution and release publication still require human release authorization.
The security-first agent control plane — the governance + routing layer for a multi-agent fleet. Not "another orchestrator": it authenticates the caller (tailnet whois), enforces a metadata-only policy, dedupes, routes (explicit / by capability), brokers loop-guarded handoff between agents, rate-limits, and audits every decision — then gets out of the data path. It does not own memory (that is Bourdon) and does not execute work (that is the agents); it governs who can reach whom, with what, and proves it happened.
Sibling to Bourdon in one ecosystem — Bourdon = what the fleet knows, Positif = who's online + what's in flight. They meet at exactly one MCP boundary.
Lives on the always-on switchboard host (service data under /var/lib/positif),
mirroring Bourdon's layout. Port 7600 (Bourdon = 7500).
sbd is a FastMCP server exposing one secure tool, dispatch(target, payload),
over streamable-HTTP bound to the tailnet IP. The HTTP transport is deliberate:
it's what makes whois-gated auth real — the caller's peer IP comes from the
live request and tailscaled turns it into an authoritative node identity.
Dispatch state machine (core/dispatch.py):
trusted | tainted (caller may self-declare tainted)(caller, target) table, metadata only, never the
payload; tainted is forbidden from sensitive targets
(write/spend/prod/privileged)(intent → target) decision but
does not route (the event log is the training set)acp → drives hermes acp; http →
POSTs to an HTTP worker, ready for a local assistant / *-automations worker)A per-caller token-bucket rate limit runs before forwarding (caps cost/DoS
from a runaway or compromised caller). Observability: the health MCP tool and
sbd stats aggregate the event log over a default 7-day window (per-target
counts, deny rate, latency p50/p95). Use --all-time only when an operator
intentionally needs the full retained dataset.
Routing is explicit-target today. The classifier is scaffolded and learning from day one.
Hermes is delegated to over the Zed Agent Client Protocol (newline-delimited
JSON-RPC over stdio) — the Bourdon-aware path. core/acp_client.py spawns
hermes acp --accept-hooks, runs initialize → session/new → session/prompt,
accumulates agent_message_chunk text, auto-answers any session/request_permission
(else the turn deadlocks), and returns on stopReason: end_turn.
core/ db schema.sql whois policy policy_studio idempotency classifier classifier_pipeline cards acp_client dispatch server
default_data/ packaged policy + card seeds used by installed `sbd init`
cli/ main.py (sbd serve | init | policy-lint | policy-diff | policy-simulate | ...)
data/ editable mirror/override seeds for source-tree operators
deploy/ positif.service
scripts/ smoke_dispatch.py tests/ test_dispatch.py
Draft feature notes live at:
docs/features/README.mddocs/features/policy-simulator.mddocs/features/policy-change-studio.mddocs/features/dry-run-dispatch.mddocs/features/agent-registry.mddocs/features/audit-reporting.mddocs/features/classifier-promotion.mddocs/features/sandbox-manager.mddocs/features/retention-automation.mddocs/features/presence-heartbeat.mddocs/features/release-readiness.mddocs/features/release-evidence.mddocs/features/ha-durability.mddocs/features/render-surfaces.mddocs/features/operator-tui.mdsbd render emits JSON Render flat specs for those operator surfaces. This is
the renderer-ready contract for operator clients, not a release authorization
path:
sbd render command-center --db /var/lib/positif/positif.db
sbd render agent-detail --db /var/lib/positif/positif.db
sbd render audit --db /var/lib/positif/positif.db --window-days 7
sbd render audit-detail --db /var/lib/positif/positif.db --window-days 7
sbd render retention --db /var/lib/positif/positif.db
sbd render release --root /opt/positif-src
Every database-backed render surface requires explicit --db; release is the
only render surface that may run from --root without a database path.
Heartbeat probes update bounded agent presence metadata without dispatching work:
sbd heartbeat --db /var/lib/positif/positif.db --target hermes --timeout-ms 1500
sbd heartbeat --db /var/lib/positif/positif.db --all --timeout-ms 1500
sbd agents --db /var/lib/positif/positif.db --stale-after 300 --json
Release evidence packs collect local review artifacts without authorizing,
tagging, publishing, or deploying anything. The manifest always records
release_authorized: false:
sbd release-evidence --root /opt/positif-src --output /var/lib/positif/release-evidence
sbd release-evidence --root /opt/positif-src --output /var/lib/positif/release-evidence --run-checks --force
HA durability checks start with local SQLite backup and read-only restore validation only. Phase A is local backup/restore; Phase B is a future second-node dry run; Phase C is Litestream/B2/NATS or other external replication only after separate third-party review. This feature adds no B2, NATS, Litestream config, credentials, bucket names, endpoints, or external replication calls:
sbd backup --db /var/lib/positif/positif.db --output /var/lib/positif/backups
sbd restore-check --backup /var/lib/positif/backups/positif-20260630T000000Z.sqlite --root /opt/positif-src --json
sbd durability-report --db /var/lib/positif/positif.db --backup-dir /var/lib/positif/backups --json
Policy Change Studio reviews candidate policy JSON before seeding. Lint, diff, and simulation are review-only: they do not mutate the live database, do not log events, do not claim idempotency rows, and do not call target transports.
sbd policy-lint --policy ./policy.candidate.json
sbd policy-diff --db /var/lib/positif/positif.db --policy ./policy.candidate.json --json
sbd policy-simulate --db /var/lib/positif/positif.db --policy ./policy.candidate.json --caller-node pc.example.ts.net --target hermes --payload "diagnose" --provenance trusted --json
Classifier promotion reporting and assist-mode recommendations stay advisory.
classifier-report reads shadow prediction metadata, while classifier-assist
returns a target only when the caller is already policy-authorized for that
target. Primary classifier routing remains out of scope.
sbd classifier-report --db /var/lib/positif/positif.db --window-days 7 --json
sbd classifier-assist --db /var/lib/positif/positif.db --intent "review this patch" --caller-node pc.example.ts.net --provenance trusted --json
An optional local Ink renderer lives in tui/ for the same surfaces:
npm --prefix tui ci
npm --prefix tui test
npm --prefix tui run build
node tui/dist/index.js --surface command-center --db /var/lib/positif/positif.db
node tui/dist/index.js --surface agents --db /var/lib/positif/positif.db --status error
node tui/dist/index.js --surface release --root /opt/positif-src --once
The TUI supports command-center, agents, agent-detail, audit,
audit-detail, metrics, retention, and release JSON Render specs. It is
read-only: it does not dispatch, prune, mutate policy, generate release
evidence, authorize release, call external services, or emit analytics.
# on the box
/opt/positif-venv/bin/python -m pip install -e /opt/positif-src
openssl rand -base64 32 > /var/lib/positif/handoff.secret
chown switchboard:switchboard /var/lib/positif/handoff.secret
chmod 600 /var/lib/positif/handoff.secret
sbd init --db /var/lib/positif/positif.db # schema + seed policy + cards
sbd serve --transport http --host 127.0.0.1 --port 7600 --db /var/lib/positif/positif.db
# in another shell (on the box, so whois resolves a real tailnet node):
/opt/positif-venv/bin/python scripts/smoke_dispatch.py
# add --yes-live only when you intentionally want to spawn the target agent:
/opt/positif-venv/bin/python scripts/smoke_dispatch.py --yes-live
Wire a coding agent as an MCP client by pointing it at
http://127.0.0.1:7600/mcp/.
Positif bounds and redacts operator-facing metadata before storage or export.
event_log.intent and event_log.error are stored as short redacted strings, and
sbd events / sbd training re-apply the same bounds when reading older rows.
Stats, metrics, classifier accuracy, and training export default to the last 7
days; pass --all-time for an explicit full retained read.
Retention is manual, not automatic during dispatch:
sbd retention-report --db /var/lib/positif/positif.db --events-days 30 --idempotency-hours 24 --json
sbd prune --db /var/lib/positif/positif.db --events-days 30 --idempotency-hours 24 --batch-size 1000
The default policy keeps audit events for 30 days and idempotency cache rows for 24 hours. Prune deletes in bounded batches so operators can run it from cron or systemd timers without putting cleanup work on the request path.
Reviewed systemd templates are included at deploy/positif-prune.service and
deploy/positif-prune.timer. A human operator must review and install them on
the target host before enabling the timer.
100.64.0.0/10) before whois is even consulted, so a
loopback/proxy/public peer can't be mistaken for a fleet node. Default-deny on
unknown caller / unknown target / no policy row (a targeted deny overrides a
broader allow).tainted (untrusted-origin) dispatches are denied from privileged targets at
ingress, and are additionally bounded to non-destructive tools.sbd runs as the
switchboard user, and the Hermes it drives runs as that same unprivileged
user with its own private HERMES_HOME (/var/lib/positif/hermes-home —
config + Anthropic key, no Slack tokens). A compromise of sbd or its Hermes
yields only the switchboard user: it cannot read /root, touch system files,
or escalate. The gateway's separate root Hermes instance is untouched.
deploy/preflight.sh refuses to start unless the HERMES_HOME is present,
private, and switchboard-owned (and hermes is root-owned); an in-code argv
allowlist in acp_client is the second barrier on the spawn.event_log.tool_audit,
preserved even on error/timeout turns). compute (the default for Hermes;
forced for tainted; can be narrowed-to via max_capability) is an allowlist
— only read/search/fetch/think pass; edit/delete/move/execute and any
absent/unknown kind are denied. Verified: under compute, Hermes was
denied a file edit and a dangerous rm at the gate, while Bourdon MCP tools +
Q&A still work. Truly benign commands (e.g. whoami) auto-run in Hermes and skip
the gate — but since Hermes now runs unprivileged, even those can't read
/root, touch system files, or escalate, so the residual is contained.provenance and max_capability normalize
and resolve any typo/casing to the more restrictive branch, never the privileged
one. A cap can only narrow.codex exec --skip-git-repo-check without
--dangerously-bypass-approvals-and-sandbox, is marked compute, and is a
review/reasoning node rather than an autonomous writer. A future write-capable
Codex runner must be a separate, explicitly named card.sbd-hermes, sbd-coder, and sbd-codex execution must go through
exact root-owned wrapper commands before code enables it. Broad sudo is not
acceptable. Until that runner exists, preflight enforces private
switchboard-owned homes/workspaces for the seeded agents.sbd heartbeat never dispatches
payloads, never runs prompts, and never creates agent work sessions. CLI probes
check only configured filesystem paths, ACP probes stay session-free, and HTTP
probes use only explicit card health URLs with enforced timeouts. Probe errors
are bounded and redacted before storage.Authorization: Bearer pos1.<payload>.<hmac> tokens signed with
POSITIF_HANDOFF_SECRET_FILE (default deploy path:
/var/lib/positif/handoff.secret). Unsigned X-SBD-* headers are ignored
by default; set POSITIF_ALLOW_LEGACY_HANDOFF=1 only for a temporary compatibility
window. Handoff tokens authenticate metadata only; payload bodies are never used
to derive or validate handoff identity.Second-node dry runs, Litestream/B2 durability, capability-match + semantic
routing as primary, NATS, brokered agent-to-agent handoff, a second sbd to
kill the SPOF. Litestream, B2, NATS, and other external replication services
require separate third-party review before implementation.
RADLAB LLC, a Wyoming limited liability company · BUSL-1.1
FAQs
Positif — Agent Switchboard: security-first inter-agent control plane (sbd) for agent fleets
The pypi package positif-ai receives a total of 231 weekly downloads. As such, positif-ai popularity was classified as not popular.
We found that positif-ai demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Popular npm packages keyv and cacheable compromised.

Security News
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.

Security News
/Company News
Socket has joined the new Composer and Packagist sponsorship program as a launch sponsor, supporting the team that keeps PHP's package ecosystem secure.