Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# @suaveplan/api-audit-stdout - Stdout `RequestAuditSink` for @suaveplan/api-host. Writes JSON-per-line audit records to a Writable (default process.stdout) with an HMAC-SHA-256 signature over canonical bytes. Implements the design-doc §12.5 audit-record shape, Zod-validated at the boundary, with bounded backpressure (maxQueueMs default 100ms), observable drop counter, and a once-per-minute warning throttle. OTel counters api.audit.records_total{sink=stdout,type,outcome} and api.audit.dropped_total{sink=stdout}. Server-tier — Bun + Node.
|
||||
|
||||
Stdout audit sink for `@suaveplan/api-host`. Writes JSON-per-line
|
||||
audit records to a `LineWriter` (default `process.stdout`) with an
|
||||
HMAC-SHA-256 signature appended as a `_hmac` field. Implements
|
||||
`RequestAuditSink` from `@suaveplan/api-host/request-pipeline`, so the
|
||||
host's request pipeline accepts the instance directly via its `audit`
|
||||
capability slot.
|
||||
|
||||
The record shape is the design-doc §12.5 canonical wire format —
|
||||
`ts`, `type`, `principal`, `tenant`, `request_id`, `trace_id`,
|
||||
`subject`, `outcome`, and a conditional `cause`. Each record is
|
||||
Zod-validated at the boundary before signing, so a malformed record
|
||||
never reaches the log pipeline.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [error-codes](./src/error-codes/error-codes.md) — This module declares the four stable error codes the stdout audit sink exposes to consumers. Every failure path inside…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — This module declares the four stable error codes the stdout audit sink exposes to consumers. Every failure path inside…
|
||||
- [hmac](./src/hmac/hmac.md) — This module produces the HMAC-SHA-256 tag attached to every audit line. Signing operates on a *canonical* byte represen…
|
||||
- [hmac](./src/hmac/hmac.md) — This module produces the HMAC-SHA-256 tag attached to every audit line. Signing operates on a *canonical* byte represen…
|
||||
- [instruments](./src/instruments/instruments.md) — This module owns the two counters the stdout sink emits at runtime, matching design doc §12.3's metric surface for the…
|
||||
- [instruments](./src/instruments/instruments.md) — This module owns the two counters the stdout sink emits at runtime, matching design doc §12.3's metric surface for the…
|
||||
- [options](./src/options/options.md) — This module owns the Zod schema and defaults for the scalar slice of `createStdoutAuditSink({...})`'s input. Validation…
|
||||
- [options](./src/options/options.md) — This module owns the Zod schema and defaults for the scalar slice of `createStdoutAuditSink({...})`'s input. Validation…
|
||||
- [schema](./src/schema/schema.md) — This module locks the wire shape of the JSON line the stdout sink writes. The shape is exactly what design doc §12.5 sp…
|
||||
- [schema](./src/schema/schema.md) — This module locks the wire shape of the JSON line the stdout sink writes. The shape is exactly what design doc §12.5 sp…
|
||||
- [sink](./src/sink/sink.md) — This module wires the schema, HMAC signer, instruments, and options into a `RequestAuditSink` implementation that write…
|
||||
- [sink](./src/sink/sink.md) — This module wires the schema, HMAC signer, instruments, and options into a `RequestAuditSink` implementation that write…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Modules
|
||||
|
||||
- [`./sink`](./src/sink/sink.md) — `createStdoutAuditSink`, the
|
||||
factory that ties everything together.
|
||||
- [`./schema`](./src/schema/schema.md) — `AuditRecord` Zod schema and
|
||||
boundary parser.
|
||||
- [`./hmac`](./src/hmac/hmac.md) — canonical bytes and HMAC-SHA-256
|
||||
signer / verifier.
|
||||
- [`./instruments`](./src/instruments/instruments.md) — OTel counters
|
||||
(`api.audit.records_total`, `api.audit.dropped_total`).
|
||||
- [`./options`](./src/options/options.md) — scalar option schema +
|
||||
defaults (`maxQueueMs = 100`, `warnThrottleMs = 60_000`).
|
||||
- [`./error-codes`](./src/error-codes/error-codes.md) —
|
||||
`AUDIT_STDOUT.*` registry (`INVALID_RECORD`, `WRITER_FAILED`,
|
||||
`QUEUE_FULL`, `INVALID_OPTIONS`).
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import { createStdoutAuditSink } from "@suaveplan/api-audit-stdout";
|
||||
|
||||
const sink = createStdoutAuditSink({
|
||||
hmacKey: new TextEncoder().encode(process.env["AUDIT_HMAC_KEY"]!),
|
||||
});
|
||||
|
||||
await sink.emit({
|
||||
at: "2026-05-26T10:00:00.000Z",
|
||||
requestId: "req_1",
|
||||
traceId: null,
|
||||
route: "/admin/plugin",
|
||||
plugin: "@core/admin",
|
||||
method: "POST",
|
||||
principal: { id: "u1", scopes: ["admin"] },
|
||||
tenantId: "t1",
|
||||
status: 200,
|
||||
outcome: "success",
|
||||
});
|
||||
```
|
||||
|
||||
## Drop policy
|
||||
|
||||
Backpressure is bounded by `maxQueueMs` (default 100ms). When the
|
||||
queue wait exceeds the bound the record is dropped, the
|
||||
`api.audit.dropped_total{sink,reason}` counter increments, and
|
||||
(subject to a once-per-`warnThrottleMs` throttle) a single warning is
|
||||
logged. Drops are NEVER silent.
|
||||
|
||||
Reference in New Issue
Block a user