Initial project import
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# 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?
|
||||
Reference in New Issue
Block a user