6.1 KiB
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:roand/mcp-audit:roand reads only rotatedadapter-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
exceptionfrom expected safe outcomes such asblocked,unsupported, andinvalid_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.auditsnapshot.
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:
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.
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
- 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.
- The volumes are externally named
adapter-1c_adapter-1c-dataandadapter-1c-mcp_adapter-1c-mcp-dataondocker.cin.su; Observer mounts them only as/audit:roand/mcp-audit:ro. - Audit events are evidence, not replay payloads. The historical journal can link to an object by a public selector but cannot reconstruct omitted fields.
- Treat job lifecycle statuses
accepted,running,doneandcancelledas operational state, not failures. Expected rejections are shown separately from adapter exceptions. - 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.methodsandmetadata.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
- 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.
- Periodically invoke
metadata.adapter.auditthrough that proxy and persist versioned coverage snapshots in an Observer-owned SQLite database. - Add regression screens: compare coverage/schema/method catalog before and
after an adapter release, with an explicit
not comparablestate. - 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_idand public selector provenance? - Is every newly persisted field redacted and bounded by retention?
- Can the Observer be stopped without affecting adapter requests?