Files
peardata/docs/PROTOCOL.md
T
Raven Scott f604d210c3
CI / test (push) Successful in 1m1s
Release rolling / release (push) Successful in 7m12s
Add process view
2026-07-19 15:41:35 -04:00

199 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Protocol
Wire contract for PearData P2P RPC. Source of truth: `shared/protocol.js`, `shared/schema.js`, `shared/metrics.js`.
## Identity
| Constant | Value |
|----------|-------|
| Protocol id | `peardata/rpc` |
| Protocol version | `1` |
| Invite prefix | `pd1.` |
| Default role | `viewer` |
Bump `PROTOCOL_VERSION` on breaking argument/result shapes.
## Roles
| Role | Rank | Typical access |
|------|------|----------------|
| `viewer` | 1 | Read metrics, subscribe, list alerts |
| `operator` | 2 | Ack/silence alerts, run jobs, set alert config |
| `admin` | 3 | Mint invites, revoke peers, export snapshot |
Auth modes at handshake: public key (viewer), capability token / `pd1.` invite, admin seed proof, allowlist.
## Methods
### Session
| Method | Role | Notes |
|--------|------|-------|
| `handshake` | viewer | Negotiate version + elevate role |
| `ping` | viewer | Hot |
| `getServerInfo` | viewer | Agent metadata |
| `getAuthStatus` | viewer | Peer role / auth mode |
| `setDisplayName` | viewer | Label for audit / UI |
### Node
| Method | Role | Result |
|--------|------|--------|
| `getNodeInfo` | viewer | Hostname, CPUs, charts, sample interval |
| `getHealth` | viewer | `{ status, score, checks }` |
### Metrics discovery & query
| Method | Role | Args | Result |
|--------|------|------|--------|
| `listContexts` | viewer | — | Context catalog |
| `getContext` | viewer | `{ id }` | Charts in context |
| `listCharts` | viewer | — | agent-style chart map |
| `getChart` | viewer | `{ id }` | Chart summary |
| `queryData` | viewer | `{ chart, after, before, points, group, tier }` | Time series |
| `getWeights` | viewer | see below | Metric Correlations / alert weights |
| `queryLogs` | viewer* | see below | Anomaly / audit / journal lines |
| `listProcesses` | viewer | sort / filter / q / limit | Live Linux `/proc` process table |
| `getAllMetrics` | viewer | `{ format: json\|prometheus\|shell }` | Latest export |
\* `queryLogs` method role is viewer so anomaly search works for all dialers; **audit** and **journal** sources require **admin** inside the handler.
`after` / `before`: absolute unix seconds, or relative (negative = relative to `before`/`now`), agent-style.
#### `getWeights`
Scores charts for [Metric Correlations](../user-guide/metric-correlations.md) (or legacy alert weights when no highlight window).
| Arg | Notes |
|-----|--------|
| `method` | `volume` \| `ks2` \| `anomaly-rate` \| `value` \| `alerts` |
| `after` / `before` | Highlight window |
| `baseline_after` / `baseline_before` | Optional baseline (default 4× preceding highlight) |
| `points`, `time_group`, `contexts`, `charts`, `dimensions`, `limit`, `timeout` | Same as REST |
REST parity: `GET /api/v*/weights`. Engine: `server/services/weights.js`.
#### `queryLogs`
| Arg | Notes |
|-----|--------|
| `source` | `journal` (default) \| `anomaly` \| `audit` — desktop prefers journal for admins |
| `q` | Case-insensitive substring |
| `since` / `until` | Absolute ms/sec or relative (`-1h`) |
| `priority` / `unit` | Journal filters |
| `limit` / `cursor` | Cap (≤2000) + pagination offset |
Journal is **enabled by default** on Linux (`PEARDATA_JOURNAL=0` to disable). Installer grants `systemd-journal` to the agent user. REST: `GET /api/v*/logs`. Engine: `server/services/logs.js`. UI: [user-guide/logs.md](../user-guide/logs.md).
#### `listProcesses`
| Arg | Notes |
|-----|--------|
| `sort` | `cpu` (default) \| `rss` \| `pid` \| `name` \| `io` \| `threads` \| `age` \| `fds` \| `state` |
| `order` | `desc` (default) \| `asc` |
| `filter` | `all` \| `running` \| `sleeping` \| `zombie` \| `stopped` \| `highcpu` \| `highmem` \| `hasio` \| `kernel` \| `user` |
| `q` | Substring over pid / name / cmdline / user / cgroup |
| `limit` / `offset` | Cap ≤2000 |
| `pid` | Optional — return one process with detail fields (fds, exe, cwd, …) |
Linux `/proc` only. Rates need two samples (~450ms cache). REST: `GET /api/v*/processes`. UI: [user-guide/processes.md](../user-guide/processes.md).
### Live subscriptions
| Method | Role | Args |
|--------|------|------|
| `subscribeMetrics` | viewer | `{ charts: string[]\|['*'], intervalMs }` |
| `unsubscribeMetrics` | viewer | — |
| `subscribeAnomalies` | viewer | — |
| `unsubscribeAnomalies` | viewer | — |
### Anomalies & alerts
| Method | Role | Notes |
|--------|------|-------|
| `listAnomalies` | viewer | Recent events |
| `listAlerts` / `getAlert` | viewer | State + config |
| `setAlertConfig` | operator | Upsert threshold |
| `ackAlert` | operator | Clear until next breach |
| `silenceAlert` | operator | Disable temporarily |
### Jobs
| Method | Role | Known jobs |
|--------|------|------------|
| `listJobs` | viewer | — |
| `runJob` | operator | `collectOnce`, `snapshot`, `gcBuffers` (prune) |
| `cancelJob` | operator | By job id |
### Data Manager (retention / storage)
| Method | Role | Notes |
|--------|------|-------|
| `getStorageInfo` | viewer | Disk usage, memory rings, warm sample stats, effective retention |
| `getRetentionConfig` | viewer | Current policy (`retention.json`; default warm age **1 year**) |
| `setRetentionConfig` | admin | Update hot/warm rings, age rotate, disk budget, auto-prune |
| `pruneHistory` | admin | `{ dryRun?, beforeMs? }` — delete warm points past retention |
UI: [user-guide/settings.md](../user-guide/settings.md) → **Data**. Job alias: `runJob({ name: 'gcBuffers' })` runs the same prune path.
### HyperDB / peer links
| Method | Role | Notes |
|--------|------|-------|
| `getDbInfo` | viewer | DB + discovery keys, swarm flag, remotes |
| `listPeerLinks` | viewer | Linked peers from HyperDB |
| `linkPeer` | admin | Upsert link; open remote bee + optional swarm join |
| `unlinkPeer` | admin | Remove link |
| `getFleetHealth` | viewer | Parent rollup (when `PEARDATA_PARENT=1`) |
| `listChildPeers` | viewer | Dialed child agents |
See [STORAGE-HYPERDB.md](./STORAGE-HYPERDB.md).
### Admin
| Method | Role |
|--------|------|
| `mintInvite` | admin |
| `listPeers` | admin |
| `revokePeer` | admin |
| `exportSnapshot` | admin |
## Pushes (server → client)
| Event | Payload |
|-------|---------|
| `push:metrics` | `{ samples: MetricSample[] }` |
| `push:anomaly` | `AnomalyEvent` |
| `push:alert` | Alert transition |
| `push:health` | `HealthSnapshot` |
| `push:job` | `JobRecord` |
| `push:system` | Generic notices |
## Errors
Handlers throw `Error` with `.code`:
| Code | Meaning |
|------|---------|
| `PERMISSION_DENIED` | Role too low |
| `RATE_LIMIT_EXCEEDED` | RPM exceeded |
| `INVALID_ARGS` | Schema failure |
| `NOT_CONNECTED` | Client-side |
| `CAPABILITY_*` | Invite/token issues |
## Versioning policy
1. Additive methods/fields: no version bump if old clients ignore unknowns.
2. Rename/remove/change meaning: bump `PROTOCOL_VERSION`; reject or compat-negotiate in handshake.
3. REST API versions (`v1`/`v2`/`v3`) are independent of RPC version but share the store.
## Example session
```text
client → handshake { clientName, clientVersion, capability? }
server → { role, protocolVersion, auth }
client → subscribeMetrics { charts: ['*'], intervalMs: 1000 }
server → push:metrics { samples: [...] } # ~1 Hz
client → queryData { chart: 'system.cpu', after: -300, points: 300 }
```