# Adapter Observer `adapter-observer` is an independent, read-only web service for adapter telemetry. It must never connect to 1C SQL, call write methods, modify `/data`, or be a runtime dependency of `adapter-1c-rest` or `adapter-1c-mcp`. ## Inputs and guarantees - It mounts REST and MCP Docker volumes at `/audit:ro` and `/mcp-audit:ro` and reads only rotated `adapter-audit.jsonl*` / `mcp-audit.jsonl*` files. - The source events contain public selector summaries, status/error, request correlation id, timings, and safe result summaries. They intentionally omit BSL text, raw SQL payloads, storage keys, and credentials. - A missing or malformed log is an Observer condition, never an adapter error. - The UI distinguishes `exception` from expected safe outcomes such as `blocked`, `unsupported`, and `invalid_argument`. ## Tabs - **Журнал запросов**: filterable individual REST events and their safe details. - **Аналитика**: p50/p95, slow method ranking, grouped non-OK fingerprints and evidence-based next actions. - **Покрытие**: contract for adding a future `metadata.adapter.audit` snapshot. ## Retry boundary Audit JSONL deliberately has no complete request payload. Do not reconstruct or guess it from selector summaries. A future replay button may repeat only a request captured by Observer itself with an explicit read-only allowlist. It must never replay a write request from logs. ## Deployment On `docker.cin.su`, inspect the existing REST container and volume first: ```text docker inspect adapter-1c-rest docker volume ls ``` Deploy only the Observer stack from `core/deploy/docker/adapter-observer`. It uses external volume `adapter-1c_adapter-1c-data` read-only and port 8031 by default. Do not run `down` against the adapter compose project. ```text docker compose --env-file .env -f compose.yaml up -d --build curl http://localhost:8031/health ``` ## Development contract When adapter telemetry changes, preserve backwards parsing: unknown fields are shown in event details; known metrics remain optional. Before adding a special visualization, record its input schema and add fixture JSONL tests. The general journal must continue working for unknown adapter methods. ## Key decisions for future agents 1. Keep Observer a separate Compose project, port, image and failure domain. Never add it as a dependency to REST/MCP and never restart those containers while deploying it. 2. The volumes are externally named `adapter-1c_adapter-1c-data` and `adapter-1c-mcp_adapter-1c-mcp-data` on `docker.cin.su`; Observer mounts them only as `/audit:ro` and `/mcp-audit:ro`. 3. Audit events are evidence, not replay payloads. The historical journal can link to an object by a public selector but cannot reconstruct omitted fields. 4. Treat job lifecycle statuses `accepted`, `running`, `done` and `cancelled` as operational state, not failures. Expected rejections are shown separately from adapter exceptions. 5. Retain both `duration_ms` (Observer-facing REST wall time) and optional result timings. Do not manufacture nested timings if the adapter did not return them; the first precise per-span waterfall requires an Observer-owned read-only proxy/session trace. ## Delivery plan ### Delivered MVP - Rotated REST JSONL reader, safe event details and filters. - p50/p95/max latency by method, error fingerprint grouping and guidance. - Read-only Docker deployment and health endpoint. - MCP-to-REST request correlation by `request_id`; absent REST pair is shown as a transport boundary, not a decoder failure. - A bounded read-only coverage refresh (`help.methods` and `metadata.adapter.audit`) stored in Observer's own state volume, with the latest 50 snapshots per base and a schema/method/count delta. - A best-effort background coverage snapshot every 900 seconds for `upo_test`. It has a 300-second minimum interval and must never affect UI availability. ### Next safe increments 1. Add an Observer-owned, read-only allowlist proxy. It can save complete *sanitized* read request payloads for user-initiated replay and form a true parent/child waterfall; no historical write replay. 2. Periodically invoke `metadata.adapter.audit` through that proxy and persist versioned coverage snapshots in an Observer-owned SQLite database. 3. Add regression screens: compare coverage/schema/method catalog before and after an adapter release, with an explicit `not comparable` state. 4. Add retention, export and role controls before exposing the journal outside the internal network. ### Explicit non-goals until separately approved - No replay of historical write, activation, repository or password operations. - No raw request/response capture solely to make replay convenient. - No automatic remediation, SQL optimization, Configurator launch or mutation. - No claim that a slow request is an adapter defect without repeated evidence. ### Items commonly forgotten in observability work - **Clock semantics:** preserve source UTC timestamp and Observer receive time; never compare durations across hosts as if clocks were synchronized. - **Asynchrony:** display job poll calls separately from end-to-end job time; polling volume must not dominate failure charts. - **Cardinality:** bound selector/error fingerprints so arbitrary object names cannot create an unbounded metrics index. - **Release correlation:** record Observer version and adapter health/method catalog snapshot beside each periodic coverage run. - **Availability:** health, disk/read errors and log rotation failures of Observer must appear in its own diagnostics, not as adapter failures. - **Retention and access:** define data lifetime, exported fields and viewer permissions before making port 8031 internet-facing or adding Caddy routes. ## Review checklist - Does a proposed feature work with omitted payload fields rather than guessing? - Does it classify expected rejection separately from exception/transport loss? - Does it preserve `request_id` and public selector provenance? - Is every newly persisted field redacted and bounded by retention? - Can the Observer be stopped without affecting adapter requests?