[{"data":1,"prerenderedAt":2397},["ShallowReactive",2],{"navigation_docs":3,"-use-cases-audit-recipes":529,"-use-cases-audit-recipes-surround":2392},[4,30,80,128,308,440,499],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Start","\u002Fstart","1.start",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Learn","\u002Flearn","2.learn",[35,40,45,50,55,60,65,70,75],{"title":36,"path":37,"stem":38,"icon":39},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":46,"path":47,"stem":48,"icon":49},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":51,"path":52,"stem":53,"icon":54},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":56,"path":57,"stem":58,"icon":59},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":61,"path":62,"stem":63,"icon":64},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":66,"path":67,"stem":68,"icon":69},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":71,"path":72,"stem":73,"icon":74},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":76,"path":77,"stem":78,"icon":79},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":81,"path":82,"stem":83,"children":84,"page":29},"CLI","\u002Fcli","3.cli",[85,88,93,98,103,108,113,118,123],{"title":36,"path":86,"stem":87,"icon":44},"\u002Fcli\u002Foverview","3.cli\u002F0.overview",{"title":89,"path":90,"stem":91,"icon":92},"init","\u002Fcli\u002Finit","3.cli\u002F1.init","i-lucide-wand-sparkles",{"title":94,"path":95,"stem":96,"icon":97},"map","\u002Fcli\u002Fmap","3.cli\u002F2.map","i-lucide-radar",{"title":99,"path":100,"stem":101,"icon":102},"Rules","\u002Fcli\u002Frules","3.cli\u002F3.rules","i-lucide-list-checks",{"title":104,"path":105,"stem":106,"icon":107},"Scoring","\u002Fcli\u002Fscoring","3.cli\u002F4.scoring","i-lucide-gauge",{"title":109,"path":110,"stem":111,"icon":112},"CI","\u002Fcli\u002Fci","3.cli\u002F5.ci","i-lucide-git-pull-request",{"title":114,"path":115,"stem":116,"icon":117},"doctor","\u002Fcli\u002Fdoctor","3.cli\u002F6.doctor","i-lucide-stethoscope",{"title":119,"path":120,"stem":121,"icon":122},"telemetry","\u002Fcli\u002Ftelemetry","3.cli\u002F7.telemetry","i-lucide-bar-chart-3",{"title":124,"path":125,"stem":126,"icon":127},"agents","\u002Fcli\u002Fagents","3.cli\u002F8.agents","i-lucide-bot",{"title":129,"path":130,"stem":131,"children":132,"page":29},"Integrate","\u002Fintegrate","4.integrate",[133,137,220],{"title":36,"path":134,"stem":135,"icon":136},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[142,145,175,200],{"title":36,"path":143,"stem":144,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":146,"path":147,"stem":148,"children":149,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[150,155,160,165,170],{"title":151,"path":152,"stem":153,"icon":154},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F02.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F03.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F04.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F05.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"children":179,"page":29},"Cloud or Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fhybrid","4.integrate\u002Fadapters\u002Fhybrid",[180,185,190,195],{"title":181,"path":182,"stem":183,"icon":184},"Grafana Loki","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Floki","4.integrate\u002Fadapters\u002Fhybrid\u002F01.loki","i-simple-icons-grafana",{"title":186,"path":187,"stem":188,"icon":189},"ClickHouse","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fclickhouse","4.integrate\u002Fadapters\u002Fhybrid\u002F02.clickhouse","i-simple-icons-clickhouse",{"title":191,"path":192,"stem":193,"icon":194},"OTLP","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fotlp","4.integrate\u002Fadapters\u002Fhybrid\u002F03.otlp","i-simple-icons-opentelemetry",{"title":196,"path":197,"stem":198,"icon":199},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fhyperdx","4.integrate\u002Fadapters\u002Fhybrid\u002F04.hyperdx","i-custom-hyperdx",{"title":201,"path":202,"stem":203,"children":204,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[205,210,215],{"title":206,"path":207,"stem":208,"icon":209},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":211,"path":212,"stem":213,"icon":214},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":216,"path":217,"stem":218,"icon":219},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":221,"path":222,"stem":223,"children":224,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[225,229,234,239,244,249,254,259,264,269,274,279,284,289,293,298,303],{"title":36,"path":226,"stem":227,"icon":228},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":230,"path":231,"stem":232,"icon":233},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":235,"path":236,"stem":237,"icon":238},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":240,"path":241,"stem":242,"icon":243},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":245,"path":246,"stem":247,"icon":248},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":250,"path":251,"stem":252,"icon":253},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":255,"path":256,"stem":257,"icon":258},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":260,"path":261,"stem":262,"icon":263},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":265,"path":266,"stem":267,"icon":268},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":270,"path":271,"stem":272,"icon":273},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":275,"path":276,"stem":277,"icon":278},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":280,"path":281,"stem":282,"icon":283},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":285,"path":286,"stem":287,"icon":288},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":290,"path":291,"stem":292,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":294,"path":295,"stem":296,"icon":297},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":299,"path":300,"stem":301,"icon":302},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":304,"path":305,"stem":306,"icon":307},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":309,"path":310,"stem":311,"children":312,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[313,316,321,350,377,409,430,435],{"title":36,"path":314,"stem":315,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":317,"path":318,"stem":319,"icon":320},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":322,"icon":323,"path":324,"stem":325,"children":326,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[327,330,335,340,345],{"title":36,"path":328,"stem":329,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":331,"path":332,"stem":333,"icon":334},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":336,"path":337,"stem":338,"icon":339},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":341,"path":342,"stem":343,"icon":344},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":346,"path":347,"stem":348,"icon":349},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":351,"icon":352,"path":353,"stem":354,"children":355,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[356,359,364,369,373],{"title":36,"path":357,"stem":358,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":360,"path":361,"stem":362,"icon":363},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":365,"path":366,"stem":367,"icon":368},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":370,"path":371,"stem":372,"icon":320},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":374,"path":375,"stem":376,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[383,386,391,396,401,405],{"title":36,"path":384,"stem":385,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":387,"path":388,"stem":389,"icon":390},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":392,"path":393,"stem":394,"icon":395},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":397,"path":398,"stem":399,"icon":400},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":402,"path":403,"stem":404,"icon":379},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":406,"path":407,"stem":408,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":346,"icon":107,"path":410,"stem":411,"children":412,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[413,416,421,426],{"title":36,"path":414,"stem":415,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":417,"path":418,"stem":419,"icon":420},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":422,"path":423,"stem":424,"icon":425},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":427,"path":428,"stem":429,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":431,"path":432,"stem":433,"icon":434},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":436,"path":437,"stem":438,"icon":439},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":441,"path":442,"stem":443,"children":444,"page":29},"Extend","\u002Fextend","6.extend",[445,449,454,459,463,468,472,476,480,484,489,494],{"title":36,"path":446,"stem":447,"icon":448},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":450,"path":451,"stem":452,"icon":453},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":455,"path":456,"stem":457,"icon":458},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":460,"path":461,"stem":462,"icon":453},"Diagnostics channel","\u002Fextend\u002Fdiagnostics-channel","6.extend\u002F11.diagnostics-channel",{"title":464,"path":465,"stem":466,"icon":467},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":406,"path":469,"stem":470,"icon":471},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":473,"path":474,"stem":475,"icon":448},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":477,"path":478,"stem":479,"icon":434},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":481,"path":482,"stem":483,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":485,"path":486,"stem":487,"icon":488},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":490,"path":491,"stem":492,"icon":493},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":495,"path":496,"stem":497,"icon":498},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":427,"path":500,"stem":501,"children":502,"page":29},"\u002Freference","7.reference",[503,508,511,516,520,525],{"title":504,"path":505,"stem":506,"icon":507},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":374,"path":509,"stem":510,"icon":107},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":512,"path":513,"stem":514,"icon":515},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":517,"path":518,"stem":519,"icon":379},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":521,"path":522,"stem":523,"icon":524},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":526,"path":527,"stem":528,"icon":434},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"id":530,"title":531,"body":532,"description":2381,"extension":2382,"links":2383,"meta":2388,"navigation":2389,"path":407,"seo":2390,"stem":408,"__hash__":2391},"docs\u002F5.use-cases\u002F4.audit\u002F06.recipes.md","Recipes & Reference",{"type":533,"value":534,"toc":2374},"minimark",[535,552,557,1165,1174,1178,1477,1480,1484,1859,1869,1873,1889,2135,2149,2160,2164,2364,2370],[536,537,538,539,543,544,547,548,551],"p",{},"Pick the recipe that matches your sink, drop it in, and you have a tamper-evident audit log. Each recipe composes the same primitives (",[540,541,542],"code",{},"auditOnly",", ",[540,545,546],{},"signed",", optional ",[540,549,550],{},"await: true",") over different drains.",[553,554,556],"h2",{"id":555},"audit-logs-on-disk","Audit logs on disk",[558,559,560,766],"code-group",{},[561,562,568],"pre",{"className":563,"code":564,"filename":565,"language":566,"meta":567,"style":567},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { auditOnly, signed } from 'evlog'\nimport { createFsDrain } from 'evlog\u002Ffs'\n\nnitro.hooks.hook('evlog:drain', auditOnly(\n  signed(createFsDrain({ dir: '.audit', maxFiles: 30 }), { strategy: 'hash-chain' }),\n  { await: true },\n))\n","Input — server\u002Fplugins\u002Fevlog.ts","typescript","",[540,569,570,609,630,637,673,742,760],{"__ignoreMap":567},[571,572,575,579,583,587,590,593,596,599,602,606],"span",{"class":573,"line":574},"line",1,[571,576,578],{"class":577},"s7zQu","import",[571,580,582],{"class":581},"sMK4o"," {",[571,584,586],{"class":585},"sTEyZ"," auditOnly",[571,588,589],{"class":581},",",[571,591,592],{"class":585}," signed",[571,594,595],{"class":581}," }",[571,597,598],{"class":577}," from",[571,600,601],{"class":581}," '",[571,603,605],{"class":604},"sfazB","evlog",[571,607,608],{"class":581},"'\n",[571,610,612,614,616,619,621,623,625,628],{"class":573,"line":611},2,[571,613,578],{"class":577},[571,615,582],{"class":581},[571,617,618],{"class":585}," createFsDrain",[571,620,595],{"class":581},[571,622,598],{"class":577},[571,624,601],{"class":581},[571,626,627],{"class":604},"evlog\u002Ffs",[571,629,608],{"class":581},[571,631,633],{"class":573,"line":632},3,[571,634,636],{"emptyLinePlaceholder":635},true,"\n",[571,638,640,643,646,649,651,655,658,661,664,666,668,670],{"class":573,"line":639},4,[571,641,642],{"class":585},"nitro",[571,644,645],{"class":581},".",[571,647,648],{"class":585},"hooks",[571,650,645],{"class":581},[571,652,654],{"class":653},"s2Zo4","hook",[571,656,657],{"class":585},"(",[571,659,660],{"class":581},"'",[571,662,663],{"class":604},"evlog:drain",[571,665,660],{"class":581},[571,667,589],{"class":581},[571,669,586],{"class":653},[571,671,672],{"class":585},"(\n",[571,674,676,679,681,684,686,689,693,696,698,701,703,705,708,710,714,716,719,721,723,726,728,730,733,735,737,739],{"class":573,"line":675},5,[571,677,678],{"class":653},"  signed",[571,680,657],{"class":585},[571,682,683],{"class":653},"createFsDrain",[571,685,657],{"class":585},[571,687,688],{"class":581},"{",[571,690,692],{"class":691},"swJcz"," dir",[571,694,695],{"class":581},":",[571,697,601],{"class":581},[571,699,700],{"class":604},".audit",[571,702,660],{"class":581},[571,704,589],{"class":581},[571,706,707],{"class":691}," maxFiles",[571,709,695],{"class":581},[571,711,713],{"class":712},"sbssI"," 30",[571,715,595],{"class":581},[571,717,718],{"class":585},")",[571,720,589],{"class":581},[571,722,582],{"class":581},[571,724,725],{"class":691}," strategy",[571,727,695],{"class":581},[571,729,601],{"class":581},[571,731,732],{"class":604},"hash-chain",[571,734,660],{"class":581},[571,736,595],{"class":581},[571,738,718],{"class":585},[571,740,741],{"class":581},",\n",[571,743,745,748,751,753,757],{"class":573,"line":744},6,[571,746,747],{"class":581},"  {",[571,749,750],{"class":691}," await",[571,752,695],{"class":581},[571,754,756],{"class":755},"sfNiH"," true",[571,758,759],{"class":581}," },\n",[571,761,763],{"class":573,"line":762},7,[571,764,765],{"class":585},"))\n",[561,767,772],{"className":768,"code":769,"filename":770,"language":771,"meta":567,"style":567},"language-jsonl shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\"audit\":{\"action\":\"invoice.refund\",\"actor\":{\"type\":\"user\",\"id\":\"usr_42\"},\"target\":{\"type\":\"invoice\",\"id\":\"inv_889\"},\"outcome\":\"success\",\"version\":1,\"idempotencyKey\":\"ak_8f3c4b2a1e5d6f7c\",\"prevHash\":null,\"hash\":\"3f2c8e1a...\"}}\n{\"audit\":{\"action\":\"user.update\",\"actor\":{\"type\":\"user\",\"id\":\"usr_42\"},\"target\":{\"type\":\"user\",\"id\":\"usr_99\"},\"outcome\":\"success\",\"version\":1,\"idempotencyKey\":\"ak_5e7d8f9a0b1c2d3e\",\"prevHash\":\"3f2c8e1a...\",\"hash\":\"9a1b4d7c...\"}}\n","Output — .audit\u002F2026-04-24.ndjson","jsonl",[540,773,774,977],{"__ignoreMap":567},[571,775,776,778,781,785,787,790,792,796,798,800,802,805,807,809,811,814,816,818,820,823,825,827,829,832,834,836,838,841,843,845,847,850,852,855,857,860,862,864,866,868,870,872,874,877,879,881,883,885,887,889,891,894,896,898,900,903,905,907,909,912,914,916,918,921,923,925,928,930,932,935,937,939,941,944,946,948,950,953,955,958,960,963,965,967,969,972,974],{"class":573,"line":574},[571,777,688],{"class":581},[571,779,780],{"class":581},"\"",[571,782,784],{"class":783},"spNyl","audit",[571,786,780],{"class":581},[571,788,789],{"class":581},":{",[571,791,780],{"class":581},[571,793,795],{"class":794},"sBMFI","action",[571,797,780],{"class":581},[571,799,695],{"class":581},[571,801,780],{"class":581},[571,803,804],{"class":604},"invoice.refund",[571,806,780],{"class":581},[571,808,589],{"class":581},[571,810,780],{"class":581},[571,812,813],{"class":794},"actor",[571,815,780],{"class":581},[571,817,789],{"class":581},[571,819,780],{"class":581},[571,821,822],{"class":712},"type",[571,824,780],{"class":581},[571,826,695],{"class":581},[571,828,780],{"class":581},[571,830,831],{"class":604},"user",[571,833,780],{"class":581},[571,835,589],{"class":581},[571,837,780],{"class":581},[571,839,840],{"class":712},"id",[571,842,780],{"class":581},[571,844,695],{"class":581},[571,846,780],{"class":581},[571,848,849],{"class":604},"usr_42",[571,851,780],{"class":581},[571,853,854],{"class":581},"},",[571,856,780],{"class":581},[571,858,859],{"class":794},"target",[571,861,780],{"class":581},[571,863,789],{"class":581},[571,865,780],{"class":581},[571,867,822],{"class":712},[571,869,780],{"class":581},[571,871,695],{"class":581},[571,873,780],{"class":581},[571,875,876],{"class":604},"invoice",[571,878,780],{"class":581},[571,880,589],{"class":581},[571,882,780],{"class":581},[571,884,840],{"class":712},[571,886,780],{"class":581},[571,888,695],{"class":581},[571,890,780],{"class":581},[571,892,893],{"class":604},"inv_889",[571,895,780],{"class":581},[571,897,854],{"class":581},[571,899,780],{"class":581},[571,901,902],{"class":794},"outcome",[571,904,780],{"class":581},[571,906,695],{"class":581},[571,908,780],{"class":581},[571,910,911],{"class":604},"success",[571,913,780],{"class":581},[571,915,589],{"class":581},[571,917,780],{"class":581},[571,919,920],{"class":794},"version",[571,922,780],{"class":581},[571,924,695],{"class":581},[571,926,927],{"class":712},"1",[571,929,589],{"class":581},[571,931,780],{"class":581},[571,933,934],{"class":794},"idempotencyKey",[571,936,780],{"class":581},[571,938,695],{"class":581},[571,940,780],{"class":581},[571,942,943],{"class":604},"ak_8f3c4b2a1e5d6f7c",[571,945,780],{"class":581},[571,947,589],{"class":581},[571,949,780],{"class":581},[571,951,952],{"class":794},"prevHash",[571,954,780],{"class":581},[571,956,957],{"class":581},":null,",[571,959,780],{"class":581},[571,961,962],{"class":794},"hash",[571,964,780],{"class":581},[571,966,695],{"class":581},[571,968,780],{"class":581},[571,970,971],{"class":604},"3f2c8e1a...",[571,973,780],{"class":581},[571,975,976],{"class":581},"}}\n",[571,978,979,981,983,985,987,989,991,993,995,997,999,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028,1030,1032,1034,1036,1038,1040,1042,1044,1046,1048,1050,1052,1054,1056,1058,1060,1062,1064,1066,1068,1070,1072,1074,1076,1078,1080,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1128,1130,1132,1134,1136,1138,1140,1142,1144,1146,1148,1150,1152,1154,1156,1158,1161,1163],{"class":573,"line":611},[571,980,688],{"class":581},[571,982,780],{"class":581},[571,984,784],{"class":783},[571,986,780],{"class":581},[571,988,789],{"class":581},[571,990,780],{"class":581},[571,992,795],{"class":794},[571,994,780],{"class":581},[571,996,695],{"class":581},[571,998,780],{"class":581},[571,1000,1001],{"class":604},"user.update",[571,1003,780],{"class":581},[571,1005,589],{"class":581},[571,1007,780],{"class":581},[571,1009,813],{"class":794},[571,1011,780],{"class":581},[571,1013,789],{"class":581},[571,1015,780],{"class":581},[571,1017,822],{"class":712},[571,1019,780],{"class":581},[571,1021,695],{"class":581},[571,1023,780],{"class":581},[571,1025,831],{"class":604},[571,1027,780],{"class":581},[571,1029,589],{"class":581},[571,1031,780],{"class":581},[571,1033,840],{"class":712},[571,1035,780],{"class":581},[571,1037,695],{"class":581},[571,1039,780],{"class":581},[571,1041,849],{"class":604},[571,1043,780],{"class":581},[571,1045,854],{"class":581},[571,1047,780],{"class":581},[571,1049,859],{"class":794},[571,1051,780],{"class":581},[571,1053,789],{"class":581},[571,1055,780],{"class":581},[571,1057,822],{"class":712},[571,1059,780],{"class":581},[571,1061,695],{"class":581},[571,1063,780],{"class":581},[571,1065,831],{"class":604},[571,1067,780],{"class":581},[571,1069,589],{"class":581},[571,1071,780],{"class":581},[571,1073,840],{"class":712},[571,1075,780],{"class":581},[571,1077,695],{"class":581},[571,1079,780],{"class":581},[571,1081,1082],{"class":604},"usr_99",[571,1084,780],{"class":581},[571,1086,854],{"class":581},[571,1088,780],{"class":581},[571,1090,902],{"class":794},[571,1092,780],{"class":581},[571,1094,695],{"class":581},[571,1096,780],{"class":581},[571,1098,911],{"class":604},[571,1100,780],{"class":581},[571,1102,589],{"class":581},[571,1104,780],{"class":581},[571,1106,920],{"class":794},[571,1108,780],{"class":581},[571,1110,695],{"class":581},[571,1112,927],{"class":712},[571,1114,589],{"class":581},[571,1116,780],{"class":581},[571,1118,934],{"class":794},[571,1120,780],{"class":581},[571,1122,695],{"class":581},[571,1124,780],{"class":581},[571,1126,1127],{"class":604},"ak_5e7d8f9a0b1c2d3e",[571,1129,780],{"class":581},[571,1131,589],{"class":581},[571,1133,780],{"class":581},[571,1135,952],{"class":794},[571,1137,780],{"class":581},[571,1139,695],{"class":581},[571,1141,780],{"class":581},[571,1143,971],{"class":604},[571,1145,780],{"class":581},[571,1147,589],{"class":581},[571,1149,780],{"class":581},[571,1151,962],{"class":794},[571,1153,780],{"class":581},[571,1155,695],{"class":581},[571,1157,780],{"class":581},[571,1159,1160],{"class":604},"9a1b4d7c...",[571,1162,780],{"class":581},[571,1164,976],{"class":581},[536,1166,1167,1168,1170,1171,1173],{},"Each line's ",[540,1169,952],{}," matches the previous line's ",[540,1172,962],{},". Tampering with any row breaks the chain forward of that point — a verifier replays the hashes and reports the first mismatch.",[553,1175,1177],{"id":1176},"audit-logs-to-a-dedicated-axiom-dataset","Audit logs to a dedicated Axiom dataset",[558,1179,1180,1347,1415],{},[561,1181,1183],{"className":563,"code":1182,"filename":565,"language":566,"meta":567,"style":567},"import { auditOnly } from 'evlog'\nimport { createAxiomDrain } from 'evlog\u002Faxiom'\n\nnitro.hooks.hook('evlog:drain', createAxiomDrain({ dataset: 'logs' }))\nnitro.hooks.hook('evlog:drain', auditOnly(\n  createAxiomDrain({ dataset: 'audit', apiKey: process.env.AXIOM_AUDIT_API_KEY }),\n))\n",[540,1184,1185,1203,1223,1227,1271,1297,1343],{"__ignoreMap":567},[571,1186,1187,1189,1191,1193,1195,1197,1199,1201],{"class":573,"line":574},[571,1188,578],{"class":577},[571,1190,582],{"class":581},[571,1192,586],{"class":585},[571,1194,595],{"class":581},[571,1196,598],{"class":577},[571,1198,601],{"class":581},[571,1200,605],{"class":604},[571,1202,608],{"class":581},[571,1204,1205,1207,1209,1212,1214,1216,1218,1221],{"class":573,"line":611},[571,1206,578],{"class":577},[571,1208,582],{"class":581},[571,1210,1211],{"class":585}," createAxiomDrain",[571,1213,595],{"class":581},[571,1215,598],{"class":577},[571,1217,601],{"class":581},[571,1219,1220],{"class":604},"evlog\u002Faxiom",[571,1222,608],{"class":581},[571,1224,1225],{"class":573,"line":632},[571,1226,636],{"emptyLinePlaceholder":635},[571,1228,1229,1231,1233,1235,1237,1239,1241,1243,1245,1247,1249,1251,1253,1255,1258,1260,1262,1265,1267,1269],{"class":573,"line":639},[571,1230,642],{"class":585},[571,1232,645],{"class":581},[571,1234,648],{"class":585},[571,1236,645],{"class":581},[571,1238,654],{"class":653},[571,1240,657],{"class":585},[571,1242,660],{"class":581},[571,1244,663],{"class":604},[571,1246,660],{"class":581},[571,1248,589],{"class":581},[571,1250,1211],{"class":653},[571,1252,657],{"class":585},[571,1254,688],{"class":581},[571,1256,1257],{"class":691}," dataset",[571,1259,695],{"class":581},[571,1261,601],{"class":581},[571,1263,1264],{"class":604},"logs",[571,1266,660],{"class":581},[571,1268,595],{"class":581},[571,1270,765],{"class":585},[571,1272,1273,1275,1277,1279,1281,1283,1285,1287,1289,1291,1293,1295],{"class":573,"line":675},[571,1274,642],{"class":585},[571,1276,645],{"class":581},[571,1278,648],{"class":585},[571,1280,645],{"class":581},[571,1282,654],{"class":653},[571,1284,657],{"class":585},[571,1286,660],{"class":581},[571,1288,663],{"class":604},[571,1290,660],{"class":581},[571,1292,589],{"class":581},[571,1294,586],{"class":653},[571,1296,672],{"class":585},[571,1298,1299,1302,1304,1306,1308,1310,1312,1314,1316,1318,1321,1323,1326,1328,1331,1333,1336,1339,1341],{"class":573,"line":744},[571,1300,1301],{"class":653},"  createAxiomDrain",[571,1303,657],{"class":585},[571,1305,688],{"class":581},[571,1307,1257],{"class":691},[571,1309,695],{"class":581},[571,1311,601],{"class":581},[571,1313,784],{"class":604},[571,1315,660],{"class":581},[571,1317,589],{"class":581},[571,1319,1320],{"class":691}," apiKey",[571,1322,695],{"class":581},[571,1324,1325],{"class":585}," process",[571,1327,645],{"class":581},[571,1329,1330],{"class":585},"env",[571,1332,645],{"class":581},[571,1334,1335],{"class":585},"AXIOM_AUDIT_API_KEY ",[571,1337,1338],{"class":581},"}",[571,1340,718],{"class":585},[571,1342,741],{"class":581},[571,1344,1345],{"class":573,"line":762},[571,1346,765],{"class":585},[561,1348,1353],{"className":1349,"code":1350,"filename":1351,"language":1352,"meta":567,"style":567},"language-kusto shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","['audit']\n| where audit.action == \"invoice.refund\"\n| summarize count() by audit.outcome, bin(_time, 1h)\n","Output — Axiom query","kusto",[540,1354,1355,1369,1387],{"__ignoreMap":567},[571,1356,1357,1360,1362,1364,1366],{"class":573,"line":574},[571,1358,1359],{"class":585},"[",[571,1361,660],{"class":581},[571,1363,784],{"class":604},[571,1365,660],{"class":581},[571,1367,1368],{"class":585},"]\n",[571,1370,1371,1374,1377,1380,1382,1384],{"class":573,"line":611},[571,1372,1373],{"class":585},"| ",[571,1375,1376],{"class":712},"where",[571,1378,1379],{"class":585}," audit.action == ",[571,1381,780],{"class":581},[571,1383,804],{"class":604},[571,1385,1386],{"class":581},"\"\n",[571,1388,1389,1391,1394,1397,1400,1403,1406,1409,1412],{"class":573,"line":632},[571,1390,1373],{"class":585},[571,1392,1393],{"class":712},"summarize",[571,1395,1396],{"class":653}," count()",[571,1398,1399],{"class":712}," by",[571,1401,1402],{"class":585}," audit.outcome, ",[571,1404,1405],{"class":653},"bin",[571,1407,1408],{"class":585},"(_time, ",[571,1410,1411],{"class":712},"1h",[571,1413,1414],{"class":585},")\n",[561,1416,1419],{"className":1349,"code":1417,"filename":1418,"language":1352,"meta":567,"style":567},"['audit']\n| where audit.outcome == \"denied\"\n| summarize count() by audit.actor.id, audit.action\n| order by count_ desc\n","Output — denials by actor",[540,1420,1421,1433,1449,1462],{"__ignoreMap":567},[571,1422,1423,1425,1427,1429,1431],{"class":573,"line":574},[571,1424,1359],{"class":585},[571,1426,660],{"class":581},[571,1428,784],{"class":604},[571,1430,660],{"class":581},[571,1432,1368],{"class":585},[571,1434,1435,1437,1439,1442,1444,1447],{"class":573,"line":611},[571,1436,1373],{"class":585},[571,1438,1376],{"class":712},[571,1440,1441],{"class":585}," audit.outcome == ",[571,1443,780],{"class":581},[571,1445,1446],{"class":604},"denied",[571,1448,1386],{"class":581},[571,1450,1451,1453,1455,1457,1459],{"class":573,"line":632},[571,1452,1373],{"class":585},[571,1454,1393],{"class":712},[571,1456,1396],{"class":653},[571,1458,1399],{"class":712},[571,1460,1461],{"class":585}," audit.actor.id, audit.action\n",[571,1463,1464,1466,1469,1471,1474],{"class":573,"line":639},[571,1465,1373],{"class":585},[571,1467,1468],{"class":712},"order",[571,1470,1399],{"class":712},[571,1472,1473],{"class":585}," count_ ",[571,1475,1476],{"class":712},"desc\n",[536,1478,1479],{},"Splitting datasets means the audit dataset can have a longer retention (7y), tighter access controls, and a separate billing line — without touching the rest of your pipeline.",[553,1481,1483],{"id":1482},"audit-logs-in-postgres","Audit logs in Postgres",[558,1485,1486,1739],{},[561,1487,1489],{"className":563,"code":1488,"filename":565,"language":566,"meta":567,"style":567},"import { auditOnly } from 'evlog'\nimport type { DrainContext } from 'evlog'\n\nconst postgresAudit = async (ctx: DrainContext) => {\n  await db.insert(auditEvents).values({\n    id: ctx.event.audit!.idempotencyKey,\n    timestamp: new Date(ctx.event.timestamp),\n    payload: ctx.event,\n  }).onConflictDoNothing()\n}\n\nnitro.hooks.hook('evlog:drain', auditOnly(postgresAudit, { await: true }))\n",[540,1490,1491,1509,1531,1535,1568,1598,1624,1654,1670,1686,1692,1697],{"__ignoreMap":567},[571,1492,1493,1495,1497,1499,1501,1503,1505,1507],{"class":573,"line":574},[571,1494,578],{"class":577},[571,1496,582],{"class":581},[571,1498,586],{"class":585},[571,1500,595],{"class":581},[571,1502,598],{"class":577},[571,1504,601],{"class":581},[571,1506,605],{"class":604},[571,1508,608],{"class":581},[571,1510,1511,1513,1516,1518,1521,1523,1525,1527,1529],{"class":573,"line":611},[571,1512,578],{"class":577},[571,1514,1515],{"class":577}," type",[571,1517,582],{"class":581},[571,1519,1520],{"class":585}," DrainContext",[571,1522,595],{"class":581},[571,1524,598],{"class":577},[571,1526,601],{"class":581},[571,1528,605],{"class":604},[571,1530,608],{"class":581},[571,1532,1533],{"class":573,"line":632},[571,1534,636],{"emptyLinePlaceholder":635},[571,1536,1537,1540,1543,1546,1549,1552,1556,1558,1560,1562,1565],{"class":573,"line":639},[571,1538,1539],{"class":783},"const",[571,1541,1542],{"class":585}," postgresAudit ",[571,1544,1545],{"class":581},"=",[571,1547,1548],{"class":783}," async",[571,1550,1551],{"class":581}," (",[571,1553,1555],{"class":1554},"sHdIc","ctx",[571,1557,695],{"class":581},[571,1559,1520],{"class":794},[571,1561,718],{"class":581},[571,1563,1564],{"class":783}," =>",[571,1566,1567],{"class":581}," {\n",[571,1569,1570,1573,1576,1578,1581,1583,1586,1588,1590,1593,1595],{"class":573,"line":675},[571,1571,1572],{"class":577},"  await",[571,1574,1575],{"class":585}," db",[571,1577,645],{"class":581},[571,1579,1580],{"class":653},"insert",[571,1582,657],{"class":691},[571,1584,1585],{"class":585},"auditEvents",[571,1587,718],{"class":691},[571,1589,645],{"class":581},[571,1591,1592],{"class":653},"values",[571,1594,657],{"class":691},[571,1596,1597],{"class":581},"{\n",[571,1599,1600,1603,1605,1608,1610,1613,1615,1617,1620,1622],{"class":573,"line":744},[571,1601,1602],{"class":691},"    id",[571,1604,695],{"class":581},[571,1606,1607],{"class":585}," ctx",[571,1609,645],{"class":581},[571,1611,1612],{"class":585},"event",[571,1614,645],{"class":581},[571,1616,784],{"class":585},[571,1618,1619],{"class":581},"!.",[571,1621,934],{"class":585},[571,1623,741],{"class":581},[571,1625,1626,1629,1631,1634,1637,1639,1641,1643,1645,1647,1650,1652],{"class":573,"line":762},[571,1627,1628],{"class":691},"    timestamp",[571,1630,695],{"class":581},[571,1632,1633],{"class":581}," new",[571,1635,1636],{"class":653}," Date",[571,1638,657],{"class":691},[571,1640,1555],{"class":585},[571,1642,645],{"class":581},[571,1644,1612],{"class":585},[571,1646,645],{"class":581},[571,1648,1649],{"class":585},"timestamp",[571,1651,718],{"class":691},[571,1653,741],{"class":581},[571,1655,1657,1660,1662,1664,1666,1668],{"class":573,"line":1656},8,[571,1658,1659],{"class":691},"    payload",[571,1661,695],{"class":581},[571,1663,1607],{"class":585},[571,1665,645],{"class":581},[571,1667,1612],{"class":585},[571,1669,741],{"class":581},[571,1671,1673,1676,1678,1680,1683],{"class":573,"line":1672},9,[571,1674,1675],{"class":581},"  }",[571,1677,718],{"class":691},[571,1679,645],{"class":581},[571,1681,1682],{"class":653},"onConflictDoNothing",[571,1684,1685],{"class":691},"()\n",[571,1687,1689],{"class":573,"line":1688},10,[571,1690,1691],{"class":581},"}\n",[571,1693,1695],{"class":573,"line":1694},11,[571,1696,636],{"emptyLinePlaceholder":635},[571,1698,1700,1702,1704,1706,1708,1710,1712,1714,1716,1718,1720,1722,1725,1727,1729,1731,1733,1735,1737],{"class":573,"line":1699},12,[571,1701,642],{"class":585},[571,1703,645],{"class":581},[571,1705,648],{"class":585},[571,1707,645],{"class":581},[571,1709,654],{"class":653},[571,1711,657],{"class":585},[571,1713,660],{"class":581},[571,1715,663],{"class":604},[571,1717,660],{"class":581},[571,1719,589],{"class":581},[571,1721,586],{"class":653},[571,1723,1724],{"class":585},"(postgresAudit",[571,1726,589],{"class":581},[571,1728,582],{"class":581},[571,1730,750],{"class":691},[571,1732,695],{"class":581},[571,1734,756],{"class":755},[571,1736,595],{"class":581},[571,1738,765],{"class":585},[561,1740,1745],{"className":1741,"code":1742,"filename":1743,"language":1744,"meta":567,"style":567},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","SELECT id, timestamp, payload->'audit'->>'action' AS action,\n       payload->'audit'->>'outcome' AS outcome\nFROM audit_events\nWHERE id = 'ak_8f3c4b2a1e5d6f7c';\n\n--          id          |       timestamp       |     action      | outcome\n-- ---------------------+-----------------------+-----------------+---------\n--  ak_8f3c4b2a1e5d6f7c | 2026-04-24 10:23:45.6 | invoice.refund  | success\n","Output — audit_events row","sql",[540,1746,1747,1786,1812,1820,1839,1843,1849,1854],{"__ignoreMap":567},[571,1748,1749,1752,1755,1757,1760,1763,1765,1767,1769,1772,1774,1776,1778,1781,1784],{"class":573,"line":574},[571,1750,1751],{"class":712},"SELECT",[571,1753,1754],{"class":585}," id, ",[571,1756,1649],{"class":783},[571,1758,1759],{"class":585},", payload",[571,1761,1762],{"class":581},"->",[571,1764,660],{"class":581},[571,1766,784],{"class":604},[571,1768,660],{"class":581},[571,1770,1771],{"class":581},"->>",[571,1773,660],{"class":581},[571,1775,795],{"class":604},[571,1777,660],{"class":581},[571,1779,1780],{"class":712}," AS",[571,1782,1783],{"class":712}," action",[571,1785,741],{"class":585},[571,1787,1788,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809],{"class":573,"line":611},[571,1789,1790],{"class":585},"       payload",[571,1792,1762],{"class":581},[571,1794,660],{"class":581},[571,1796,784],{"class":604},[571,1798,660],{"class":581},[571,1800,1771],{"class":581},[571,1802,660],{"class":581},[571,1804,902],{"class":604},[571,1806,660],{"class":581},[571,1808,1780],{"class":712},[571,1810,1811],{"class":585}," outcome\n",[571,1813,1814,1817],{"class":573,"line":632},[571,1815,1816],{"class":712},"FROM",[571,1818,1819],{"class":585}," audit_events\n",[571,1821,1822,1825,1828,1830,1832,1834,1836],{"class":573,"line":639},[571,1823,1824],{"class":712},"WHERE",[571,1826,1827],{"class":585}," id ",[571,1829,1545],{"class":581},[571,1831,601],{"class":581},[571,1833,943],{"class":604},[571,1835,660],{"class":581},[571,1837,1838],{"class":585},";\n",[571,1840,1841],{"class":573,"line":675},[571,1842,636],{"emptyLinePlaceholder":635},[571,1844,1845],{"class":573,"line":744},[571,1846,1848],{"class":1847},"sHwdD","--          id          |       timestamp       |     action      | outcome\n",[571,1850,1851],{"class":573,"line":762},[571,1852,1853],{"class":1847},"-- ---------------------+-----------------------+-----------------+---------\n",[571,1855,1856],{"class":573,"line":1656},[571,1857,1858],{"class":1847},"--  ak_8f3c4b2a1e5d6f7c | 2026-04-24 10:23:45.6 | invoice.refund  | success\n",[536,1860,1861,1862,1864,1865,1868],{},"The deterministic ",[540,1863,934],{}," makes retries safe — duplicate inserts collapse via ",[540,1866,1867],{},"ON CONFLICT DO NOTHING",". Without it, a transient network blip during a retry would create a duplicate audit row, which is exactly what you don't want.",[553,1870,1872],{"id":1871},"testing-audits","Testing audits",[536,1874,1875,1878,1879,543,1882,1885,1886,695],{},[540,1876,1877],{},"mockAudit()"," captures every audit event on emit — from standalone ",[540,1880,1881],{},"audit()",[540,1883,1884],{},"log.audit()",", and ",[540,1887,1888],{},"log.set({ audit })",[561,1890,1892],{"className":563,"code":1891,"language":566,"meta":567,"style":567},"import { mockAudit } from 'evlog'\n\nit('refunds the invoice and records an audit', async () => {\n  const captured = mockAudit()\n\n  await refundInvoice({ id: 'inv_889' }, { actor: { type: 'user', id: 'u1' } })\n\n  captured.assertAudit({\n    action: 'invoice.refund',\n    target: { type: 'invoice', id: 'inv_889' },\n    outcome: 'success',\n  })\n\n  captured.restore()\n})\n",[540,1893,1894,1913,1917,1942,1957,1961,2024,2028,2042,2057,2090,2105,2111,2116,2128],{"__ignoreMap":567},[571,1895,1896,1898,1900,1903,1905,1907,1909,1911],{"class":573,"line":574},[571,1897,578],{"class":577},[571,1899,582],{"class":581},[571,1901,1902],{"class":585}," mockAudit",[571,1904,595],{"class":581},[571,1906,598],{"class":577},[571,1908,601],{"class":581},[571,1910,605],{"class":604},[571,1912,608],{"class":581},[571,1914,1915],{"class":573,"line":611},[571,1916,636],{"emptyLinePlaceholder":635},[571,1918,1919,1922,1924,1926,1929,1931,1933,1935,1938,1940],{"class":573,"line":632},[571,1920,1921],{"class":653},"it",[571,1923,657],{"class":585},[571,1925,660],{"class":581},[571,1927,1928],{"class":604},"refunds the invoice and records an audit",[571,1930,660],{"class":581},[571,1932,589],{"class":581},[571,1934,1548],{"class":783},[571,1936,1937],{"class":581}," ()",[571,1939,1564],{"class":783},[571,1941,1567],{"class":581},[571,1943,1944,1947,1950,1953,1955],{"class":573,"line":639},[571,1945,1946],{"class":783},"  const",[571,1948,1949],{"class":585}," captured",[571,1951,1952],{"class":581}," =",[571,1954,1902],{"class":653},[571,1956,1685],{"class":691},[571,1958,1959],{"class":573,"line":675},[571,1960,636],{"emptyLinePlaceholder":635},[571,1962,1963,1965,1968,1970,1972,1975,1977,1979,1981,1983,1986,1988,1991,1993,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2016,2018,2020,2022],{"class":573,"line":744},[571,1964,1572],{"class":577},[571,1966,1967],{"class":653}," refundInvoice",[571,1969,657],{"class":691},[571,1971,688],{"class":581},[571,1973,1974],{"class":691}," id",[571,1976,695],{"class":581},[571,1978,601],{"class":581},[571,1980,893],{"class":604},[571,1982,660],{"class":581},[571,1984,1985],{"class":581}," },",[571,1987,582],{"class":581},[571,1989,1990],{"class":691}," actor",[571,1992,695],{"class":581},[571,1994,582],{"class":581},[571,1996,1515],{"class":691},[571,1998,695],{"class":581},[571,2000,601],{"class":581},[571,2002,831],{"class":604},[571,2004,660],{"class":581},[571,2006,589],{"class":581},[571,2008,1974],{"class":691},[571,2010,695],{"class":581},[571,2012,601],{"class":581},[571,2014,2015],{"class":604},"u1",[571,2017,660],{"class":581},[571,2019,595],{"class":581},[571,2021,595],{"class":581},[571,2023,1414],{"class":691},[571,2025,2026],{"class":573,"line":762},[571,2027,636],{"emptyLinePlaceholder":635},[571,2029,2030,2033,2035,2038,2040],{"class":573,"line":1656},[571,2031,2032],{"class":585},"  captured",[571,2034,645],{"class":581},[571,2036,2037],{"class":653},"assertAudit",[571,2039,657],{"class":691},[571,2041,1597],{"class":581},[571,2043,2044,2047,2049,2051,2053,2055],{"class":573,"line":1672},[571,2045,2046],{"class":691},"    action",[571,2048,695],{"class":581},[571,2050,601],{"class":581},[571,2052,804],{"class":604},[571,2054,660],{"class":581},[571,2056,741],{"class":581},[571,2058,2059,2062,2064,2066,2068,2070,2072,2074,2076,2078,2080,2082,2084,2086,2088],{"class":573,"line":1688},[571,2060,2061],{"class":691},"    target",[571,2063,695],{"class":581},[571,2065,582],{"class":581},[571,2067,1515],{"class":691},[571,2069,695],{"class":581},[571,2071,601],{"class":581},[571,2073,876],{"class":604},[571,2075,660],{"class":581},[571,2077,589],{"class":581},[571,2079,1974],{"class":691},[571,2081,695],{"class":581},[571,2083,601],{"class":581},[571,2085,893],{"class":604},[571,2087,660],{"class":581},[571,2089,759],{"class":581},[571,2091,2092,2095,2097,2099,2101,2103],{"class":573,"line":1694},[571,2093,2094],{"class":691},"    outcome",[571,2096,695],{"class":581},[571,2098,601],{"class":581},[571,2100,911],{"class":604},[571,2102,660],{"class":581},[571,2104,741],{"class":581},[571,2106,2107,2109],{"class":573,"line":1699},[571,2108,1675],{"class":581},[571,2110,1414],{"class":691},[571,2112,2114],{"class":573,"line":2113},13,[571,2115,636],{"emptyLinePlaceholder":635},[571,2117,2119,2121,2123,2126],{"class":573,"line":2118},14,[571,2120,2032],{"class":585},[571,2122,645],{"class":581},[571,2124,2125],{"class":653},"restore",[571,2127,1685],{"class":691},[571,2129,2131,2133],{"class":573,"line":2130},15,[571,2132,1338],{"class":581},[571,2134,1414],{"class":585},[536,2136,2137,2138,2141,2142,2145,2146,645],{},"Prefer ",[540,2139,2140],{},"assertAudit()"," when a missing audit should fail the test with a readable message. Use ",[540,2143,2144],{},"toIncludeAuditOf()"," when you need a boolean inside ",[540,2147,2148],{},"expect(...)",[536,2150,2151,2152,2155,2156,2159],{},"Always call ",[540,2153,2154],{},"captured.restore()"," in an ",[540,2157,2158],{},"afterEach"," (or wrap with a fixture) so a failing assertion never leaks into the next test.",[553,2161,2163],{"id":2162},"api-reference","API Reference",[2165,2166,2167,2183],"table",{},[2168,2169,2170],"thead",{},[2171,2172,2173,2177,2180],"tr",{},[2174,2175,2176],"th",{},"Symbol",[2174,2178,2179],{},"Kind",[2174,2181,2182],{},"Notes",[2184,2185,2186,2199,2212,2224,2240,2252,2265,2278,2294,2311,2324,2339,2351],"tbody",{},[2171,2187,2188,2194,2196],{},[2189,2190,2191],"td",{},[540,2192,2193],{},"AuditFields",[2189,2195,822],{},[2189,2197,2198],{},"Reserved field on the wide event",[2171,2200,2201,2206,2209],{},[2189,2202,2203],{},[540,2204,2205],{},"defineAuditAction(name, opts?)",[2189,2207,2208],{},"factory",[2189,2210,2211],{},"Typed action registry, infers target shape",[2171,2213,2214,2219,2221],{},[2189,2215,2216],{},[540,2217,2218],{},"defineAuditCatalog(prefix, map)",[2189,2220,2208],{},[2189,2222,2223],{},"Bundle of typed audit actions sharing a prefix",[2171,2225,2226,2231,2234],{},[2189,2227,2228],{},[540,2229,2230],{},"log.audit(fields)",[2189,2232,2233],{},"method",[2189,2235,2236,2237,2239],{},"Sugar over ",[540,2238,1888],{}," + force-keep",[2171,2241,2242,2247,2249],{},[2189,2243,2244],{},[540,2245,2246],{},"log.audit.deny(reason, fields)",[2189,2248,2233],{},[2189,2250,2251],{},"Records a denied action",[2171,2253,2254,2259,2262],{},[2189,2255,2256],{},[540,2257,2258],{},"audit(fields)",[2189,2260,2261],{},"function",[2189,2263,2264],{},"Standalone for scripts \u002F jobs",[2171,2266,2267,2272,2275],{},[2189,2268,2269],{},[540,2270,2271],{},"withAudit({ action, target })(fn)",[2189,2273,2274],{},"wrapper",[2189,2276,2277],{},"Auto-emit success \u002F failure \u002F denied",[2171,2279,2280,2285,2288],{},[2189,2281,2282],{},[540,2283,2284],{},"auditDiff(before, after)",[2189,2286,2287],{},"helper",[2189,2289,2290,2291],{},"Redact-aware JSON Patch for ",[540,2292,2293],{},"changes",[2171,2295,2296,2300,2303],{},[2189,2297,2298],{},[540,2299,1877],{},[2189,2301,2302],{},"test util",[2189,2304,2305,2306,2308,2309],{},"Capture audits on emit; ",[540,2307,2140],{}," or ",[540,2310,2144],{},[2171,2312,2313,2318,2321],{},[2189,2314,2315],{},[540,2316,2317],{},"auditEnricher(opts?)",[2189,2319,2320],{},"enricher",[2189,2322,2323],{},"Auto-fill request \u002F runtime \u002F tenant context",[2171,2325,2326,2331,2333],{},[2189,2327,2328],{},[540,2329,2330],{},"auditOnly(drain, { await? })",[2189,2332,2274],{},[2189,2334,2335,2336,2338],{},"Routes only events with an ",[540,2337,784],{}," field",[2171,2340,2341,2346,2348],{},[2189,2342,2343],{},[540,2344,2345],{},"signed(drain, opts)",[2189,2347,2274],{},[2189,2349,2350],{},"Generic integrity wrapper (hmac \u002F hash-chain)",[2171,2352,2353,2358,2361],{},[2189,2354,2355],{},[540,2356,2357],{},"auditRedactPreset",[2189,2359,2360],{},"config",[2189,2362,2363],{},"Strict PII for audit events",[536,2365,2366,2367,2369],{},"Everything ships from the main ",[540,2368,605],{}," entrypoint.",[2371,2372,2373],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":567,"searchDepth":611,"depth":611,"links":2375},[2376,2377,2378,2379,2380],{"id":555,"depth":611,"text":556},{"id":1176,"depth":611,"text":1177},{"id":1482,"depth":611,"text":1483},{"id":1871,"depth":611,"text":1872},{"id":2162,"depth":611,"text":2163},"File system, Axiom, and Postgres recipes for audit logs, plus mockAudit for tests and the full API reference.","md",[2384,2387],{"label":402,"icon":379,"to":403,"color":2385,"variant":2386},"neutral","subtle",{"label":138,"icon":136,"to":143,"color":2385,"variant":2386},{},{"title":406,"icon":79},{"title":531,"description":2381},"d4tHcUb1EpoUIrMkf-DJ-DPvE575KpxoUq7BH9zzato",[2393,2395],{"title":402,"path":403,"stem":404,"description":2394,"icon":379,"children":-1},"Integrity, redact presets, GDPR vs append-only, retention windows, and the most common pitfalls when shipping audit logs to production.",{"title":36,"path":414,"stem":415,"description":2396,"icon":39,"children":-1},"Wide-event telemetry for CLIs and automation — evlog's one-event-per-run model for tools on user machines, with privacy-safe flags, consent, outbox, and auto-generated disclosure.",1786045668814]