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