Skip to main content

Architecture

Botfather's design has one constraint: SLAW instances stay sovereign. Everything else follows from that.

Botfather push model: every SLAW instance initiates outbound HTTPS connections to the tower. No inbound ports are opened on desktops. The sovereignty boundary keeps work content on the instance.

The push model

Every connection originates from a SLAW instance. Instances push outbound over HTTPS; the tower never initiates a connection into the instance network. This means instances work behind NAT, VPN, or corporate proxies without firewall exceptions.

Four message types flow instance → tower:

MessageFrequencyPurpose
enroll / enroll/pollStartupSelf-register; poll until approved; receive API key
heartbeat~60 sLiveness signal + summary counts and spend
sync~60 s, only when deltas existEntity upserts and cost/run fact events
manifestNightly or on demandFull reconciliation checksum

The heartbeat response is the back-channel: the tower delivers directives to the instance (for example, set_limits to enforce an enterprise budget ceiling) without ever opening an inbound connection.

The sovereignty boundary

The Reporter module inside each SLAW instance decides what to emit before anything leaves.

Synced to towerStays on the instance
Squad and agent names, roles, statusAgent adapter configuration and secrets
Issue titles and statusesIssue bodies and comments
Token counts and cost telemetryRun logs and output
Instance health and enrollment stateSkill definition content

Issue titles are included by default so admins can see what the fleet is working on. Set reportIssueTitles: false in the instance config to send only IDs and statuses.

Enrollment and the startup gate

Instances enroll themselves — there is no pre-shared secret to distribute to users. The flow:

  1. On startup, the instance sends POST /api/ingest/v1/enroll with its machine identity; no token required
  2. The instance appears as pending in the tower's Approval Queue
  3. An admin approves it, or an auto-approve rule matches (for example, any machine matching *-ENG-*)
  4. The instance polls, receives a per-instance API key, and moves to active
  5. The SLAW startup gate unlocks; the app becomes usable

Until the instance is active, the SLAW UI shows a blocking enrollment gate. A configured botfather.url signals that the enterprise expects enrollment. Already-enrolled instances continue to work if the tower goes offline (fail-open for enrolled); never-enrolled instances stay gated until approval.

The Reporter module

The Reporter is a sidecar module inside the existing SLAW instance (server/src/services/botfather/reporter.ts). It is not a separate process — it rides the process lifecycle and reuses the existing database connection. All errors are logged and swallowed; a Reporter failure cannot affect the SLAW instance.

The Reporter spools unsent batches to disk when the tower is unreachable (default cap: 50 MB / 14 days), then drains them in order once connectivity returns. Because cost facts already live in the instance's own database, even a dropped spool is recoverable via the nightly manifest reconciliation.

Next steps