Pular para o conteúdo

Kover Connector Protocol

kover specs/kover/protocol.kmd

Profile do protocolo de conectores do Koder Kover. NÃO é um wire format novo: é um perfil (namespace `kover.*` + schema de payload) sobre `specs/ipc/protocol.kmd` (JSON-RPC 2.0) reusando os schemas de telemetria de `instrumentation-contract.kmd` e o formato de erro de `errors/user-facing-messages.kmd`. Define as categorias de informação, tipos, metadados, e a operação bidirecional (ativo = request/response, passivo = notification) que um programa implementa para ser observável e controlável pelo Kover.

Quando esta spec se aplica

Triggers primários

Todos os triggers

Corpo da especificação

Spec — Kover Connector Protocol (profile v0.1)

This spec defines the Kover connector profile. It is a profile, not a new protocol: the wire format, framing, transports, discovery, and capability advertisement are exactly specs/ipc/protocol.kmd (JSON-RPC 2.0). This document adds (a) the kover.* method namespace, (b) the typed payload schema per information category, and (c) the bidirectional contract. Every rule R* is testable; tests T* at the end.

Scope

Applies to any program that wants to be observed and/or driven by Koder Kover. Two implementation paths:

  • Koder components get the profile from the SDK (engines/sdk/koder_kit for Dart, engines/sdk/go for Go) — built-in, no per-component code (reuse-first; RFC-001 §4 D-protocol-5).
  • External programs implement the public profile directly, or are observed without a connector (external resource sampling + capture + OS-input; see scenario-dsl.kmd T2).

R1 — Transport & framing are inherited, not redefined

R1.1 — The connector MUST speak specs/ipc/protocol.kmd verbatim: JSON-RPC 2.0, newline-delimited, over the platform transport (Unix socket / named pipe / intent). Kover MUST NOT define a second framing.

R1.2 — A Kover connector MUST answer the standard IPC capabilities query and MUST include "kover" in its advertised capability set, with a kover_profile semver (this doc's version).

R2 — Bidirectional contract

R2.1 — Active (Kover → program): Kover issues JSON-RPC requests; the program answers with a response. Used to pull info and send commands (kover.snapshot, kover.query, kover.command).

R2.2 — Passive (program → Kover): the program emits JSON-RPC notifications (no id) that Kover did not solicit. Used to push unsolicited info (kover.emit with a category payload, R3).

R2.3 — A connector MUST support passive emission; active handling is SHOULD (a program may be push-only). A push-only connector still advertises kover with active=false in its capability descriptor.

R3 — Information categories (the taxonomy)

R3.1 — Every payload carries a category from this closed enum, each with a typed schema:

categoryDirectionSchema source
logpassiveinstrumentation-contract.kmd C1 (verbatim)
metricpassiveinstrumentation-contract.kmd C2 (verbatim)
tracepassiveinstrumentation-contract.kmd C3/C4 (verbatim)
errorpassiveR4 (reuses errors/user-facing-messages.kmd ID)
eventpassive{ name, ts, attrs } — UI/app lifecycle events
resourcepassive{ pid, ts, cpu_pct, rss_bytes, disk_io, gpu_pct? } (R5)
inputactive+passivescenario-dsl.kmd input record schema
media-refpassive{ kind: screen|video|audio, ref, ts_range } → object ref (R6 of capture.kmd)

R3.2 — log/metric/trace MUST NOT define new schemas — they are the instrumentation-contract schemas. A Kover connector that already instruments via instrumentation-contract simply forwards those events; it does not re-encode them. (One telemetry schema for the whole Stack.)

R3.3 — Every payload carries minimum metadata: category, ts (RFC3339 UTC ms), source (program slug or pid), and session_id (the Kover run). Trace correlation uses trace_id from the telemetry context (C3), not a Kover-private id.

R4 — Error identity reuses the Stack format

R4.1 — An error payload's identity is the existing <PRODUCT>-<CATEGORY>-<CODE>-<SEQ> from errors/user-facing-messages.kmd (e.g. KRUZE-UI-503-001). Kover MUST NOT mint a parallel "ERR-…" scheme.

R4.2 — Required fields of an error payload: error_id (R4.1), ts, severity (fatal|error|warn), title (humanised, from the product registry), detail (technical), trace_id (if in a trace). PII redaction per capture.kmd R-redact / instrumentation-contract C5 applies before emit.

R5 — Resource category

R5.1 — resource samples carry { pid, ts, cpu_pct, rss_bytes, disk_read_bytes, disk_write_bytes } as required, and gpu_pct/vram_bytes as optional best-effort (GPU portability is not guaranteed across vendor/OS — RFC-001 §9 D-4).

R5.2 — resource for external programs Kover launched is produced by Kover's own sampler (L1), not by a connector — the program need not cooperate to be resource-monitored.

R5.3 — On Koder Kodix, resource and process-lifecycle event payloads MAY originate from the ambient daemon (kover-RFC-001 §7.3) composing platform sources (Kolide window/input feed + procfs/cgroups + an exec-notify hook), not from any per-program connector. Ambient sourcing is off by default and gated per kover-RFC-001 §7.3 D-daemon-3 + capture.kmd R-consent.3.

R6 — Versioning & forward-compat

R6.1 — Unknown category values or unknown payload fields MUST be ignored by the receiver (forward-compat), never fatal. The capability kover_profile semver governs negotiation; minor bumps are additive.

Test cases

#CheckSeverity
T1A connector advertises kover in capabilities with a kover_profile semver.hard
T2A passive log emission validates byte-for-byte against instrumentation-contract C1 (no second schema).hard
T3An error payload's error_id matches ^[A-Z0-9]{2,8}-[A-Z]{2}-\d+-\d{3}$ (the Stack error-ID grammar).hard
T4An active kover.command request gets a JSON-RPC response or a JSON-RPC error with koder_error_id.hard
T5A receiver given an unknown category ignores it without erroring (R6.1).hard
T6A push-only connector (active=false) still delivers passive emissions end to end.soft
T7resource samples for an externally-launched program arrive even though that program implements no connector (R5.2).hard

Non-goals

  • Wire format / transport / discovery — owned by specs/ipc/protocol.kmd.
  • Telemetry schemas — owned by instrumentation-contract.kmd.
  • Capture byte storage & formats — owned by capture.kmd.
  • Input record/replay semantics — owned by scenario-dsl.kmd.

Open questions

  1. Should kover.* live in the same IPC socket as a host app's main IPC, or a dedicated Kover socket? Lean: dedicated, to keep the collection hot-path off the app's primary channel (mirrors the koder-x↔kolide sub-protocol precedent in ipc/protocol.kmd). Decide at the Go SDK impl (KOVER-002).
  2. Capability descriptor exact shape (active, categories[], kover_profile) — finalise against the IPC capabilities schema.

Referências