3.9 KiB
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 }ANDmsg === "x"ANDlevel === "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
inforecords are buffered AND alog.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_DROPcounter 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
disableAND the worker subsequently callslog.info(...) - THEN no record reaches the main-side sink AND no batch is queued
Scenario: enable restores normal flow
- WHEN the main sends
enableafter a priordisable - 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"