Initial Commit
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
# Capability Spec Delta: api-logger-worker-proxy (api-logger-worker-proxy)
|
||||
|
||||
**Package**: `@suaveplan/api-logger-worker-proxy`
|
||||
**Status**: PROPOSED
|
||||
|
||||
> Every requirement below carries a `**Verified by:**` line at authoring time.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Proxy preserves LoggerLike surface with plugin pre-tagging
|
||||
|
||||
The package SHALL expose `createLoggerProxyClient(port, { plugin: { name, version } })` returning a `WorkerProxyOf<LoggerLike>`. Every emitted record SHALL carry the plugin's `name` and `version` as pre-tagged fields per design doc §5.1. Every log level (`trace`, `debug`, `info`, `warn`, `error`, `fatal`) MUST round-trip through the proxy.
|
||||
|
||||
#### Scenario: every level round-trips with plugin tags
|
||||
|
||||
- **WHEN** the worker calls `log.info({ msg: "x" })`
|
||||
- **THEN** the main-side stub sink receives a record with `plugin === { name, version }` AND `msg === "x"` AND `level === "info"`
|
||||
|
||||
**Verified by:** `src/client/client.test.ts::"every level round-trips with plugin tags"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Batched send flushes on size, idle, or error level
|
||||
|
||||
The package SHALL batch outbound log records. A batch SHALL flush when ANY of three conditions hold: (a) `maxBatchSize` records buffered (default 100); (b) `flushIntervalMs` elapsed since the first buffered record (default 50); (c) the record's level is `error` or `fatal` (immediate flush). Buffered records MUST persist across the immediate flush — flushing for an `error` record does NOT discard lower-level records buffered before it.
|
||||
|
||||
#### Scenario: batch flushes at max size
|
||||
|
||||
- **WHEN** 100 records are buffered
|
||||
- **THEN** the batch is sent on the next microtask
|
||||
|
||||
#### Scenario: error level flushes immediately AND preserves earlier records
|
||||
|
||||
- **WHEN** 5 `info` records are buffered AND a `log.error(...)` is called
|
||||
- **THEN** the batch flushes within 1 microtask AND the main side receives all 6 records in order
|
||||
|
||||
**Verified by:** `src/batching/batching.test.ts::"batch flushes at max size"` AND `src/batching/batching.test.ts::"error flushes immediately and preserves earlier records"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Backpressure drops records and emits a counter rather than throwing
|
||||
|
||||
The package SHALL enforce a bounded outstanding-batch budget per port. When the budget is exhausted, new records MUST be dropped silently AND a `LOGGER_PROXY_BACKPRESSURE_DROP` counter MUST be incremented. The proxy MUST NOT throw on log calls — logging is best-effort by design, and an application MUST NOT break because the log sink is slow.
|
||||
|
||||
#### Scenario: over-budget records drop without throwing
|
||||
|
||||
- **WHEN** the stub sink is paused AND 10000 records are emitted
|
||||
- **THEN** no exception is thrown AND `LOGGER_PROXY_BACKPRESSURE_DROP` counter is incremented above 0
|
||||
|
||||
**Verified by:** `src/batching/backpressure.test.ts::"over-budget records drop without throwing"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Control channel can disable and re-enable worker logs
|
||||
|
||||
The package SHALL accept `disable` and `enable` messages on the control channel from the main process. After `disable`, every level method on the worker side MUST become a no-op (records discarded without buffer or batch). After `enable`, normal flow resumes. The main host calls `disable` during plugin shutdown so a worker that is being torn down stops producing records after the main-side sink has been disposed (per design doc §5.5 disposal-in-reverse-order).
|
||||
|
||||
#### Scenario: disable makes level methods no-op
|
||||
|
||||
- **WHEN** the main sends `disable` AND the worker subsequently calls `log.info(...)`
|
||||
- **THEN** no record reaches the main-side sink AND no batch is queued
|
||||
|
||||
#### Scenario: enable restores normal flow
|
||||
|
||||
- **WHEN** the main sends `enable` after a prior `disable`
|
||||
- **THEN** subsequent `log.info(...)` calls reach the sink normally
|
||||
|
||||
**Verified by:** `src/control-channel/control-channel.test.ts::"disable makes level methods no-op"` AND `src/control-channel/control-channel.test.ts::"enable restores normal flow"`
|
||||
Reference in New Issue
Block a user