[{"data":1,"prerenderedAt":8619},["ShallowReactive",2],{"navigation_docs":3,"-logging-audit":308,"-logging-audit-surround":8614},[4,35,80,124,212,292],{"title":5,"path":6,"stem":7,"children":8,"page":34},"Getting Started","\u002Fgetting-started","1.getting-started",[9,14,19,24,29],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-zap",{"title":25,"path":26,"stem":27,"icon":28},"Agent Skills","\u002Fgetting-started\u002Fagent-skills","1.getting-started\u002F4.agent-skills","i-lucide-sparkles",{"title":30,"path":31,"stem":32,"icon":33},"vs Other Loggers","\u002Fgetting-started\u002Fvs-other-loggers","1.getting-started\u002F5.vs-other-loggers","i-lucide-scale",false,{"title":36,"path":37,"stem":38,"children":39,"page":34},"Logging","\u002Flogging","2.logging",[40,45,50,55,60,65,70,75],{"title":41,"path":42,"stem":43,"icon":44},"Overview","\u002Flogging\u002Foverview","2.logging\u002F0.overview","i-lucide-list",{"title":46,"path":47,"stem":48,"icon":49},"Simple Logging","\u002Flogging\u002Fsimple-logging","2.logging\u002F1.simple-logging","i-lucide-terminal",{"title":51,"path":52,"stem":53,"icon":54},"Wide Events","\u002Flogging\u002Fwide-events","2.logging\u002F2.wide-events","i-lucide-layers",{"title":56,"path":57,"stem":58,"icon":59},"Structured Errors","\u002Flogging\u002Fstructured-errors","2.logging\u002F3.structured-errors","i-lucide-shield-alert",{"title":61,"path":62,"stem":63,"icon":64},"Client Logging","\u002Flogging\u002Fclient-logging","2.logging\u002F4.client-logging","i-lucide-monitor",{"title":66,"path":67,"stem":68,"icon":69},"AI SDK Integration","\u002Flogging\u002Fai-sdk","2.logging\u002F5.ai-sdk","i-simple-icons-vercel",{"title":71,"path":72,"stem":73,"icon":74},"Better Auth Integration","\u002Flogging\u002Fbetter-auth","2.logging\u002F6.better-auth","i-simple-icons-betterauth",{"title":76,"path":77,"stem":78,"icon":79},"Audit Logs","\u002Flogging\u002Faudit","2.logging\u002F7.audit","i-lucide-shield-check",{"title":81,"path":82,"stem":83,"children":84,"page":34},"Core Concepts","\u002Fcore-concepts","3.core-concepts",[85,90,95,100,105,109,114,119],{"title":86,"path":87,"stem":88,"icon":89},"Lifecycle","\u002Fcore-concepts\u002Flifecycle","3.core-concepts\u002F0.lifecycle","i-lucide-arrow-right-left",{"title":91,"path":92,"stem":93,"icon":94},"Configuration","\u002Fcore-concepts\u002Fconfiguration","3.core-concepts\u002F1.configuration","i-lucide-settings",{"title":96,"path":97,"stem":98,"icon":99},"Sampling","\u002Fcore-concepts\u002Fsampling","3.core-concepts\u002F2.sampling","i-lucide-filter",{"title":101,"path":102,"stem":103,"icon":104},"Typed Fields","\u002Fcore-concepts\u002Ftyped-fields","3.core-concepts\u002F3.typed-fields","i-simple-icons-typescript",{"title":106,"path":107,"stem":108,"icon":79},"Best Practices","\u002Fcore-concepts\u002Fbest-practices","3.core-concepts\u002F4.best-practices",{"title":110,"path":111,"stem":112,"icon":113},"Performance","\u002Fcore-concepts\u002Fperformance","3.core-concepts\u002F5.performance","i-lucide-gauge",{"title":115,"path":116,"stem":117,"icon":118},"Vite Plugin","\u002Fcore-concepts\u002Fvite-plugin","3.core-concepts\u002F6.vite-plugin","i-custom-vite",{"title":120,"path":121,"stem":122,"icon":123},"Auto-Redaction","\u002Fcore-concepts\u002Fredaction","3.core-concepts\u002F7.redaction","i-lucide-eye-off",{"title":125,"path":126,"stem":127,"children":128,"page":34},"Frameworks","\u002Fframeworks","4.frameworks",[129,133,138,143,148,153,158,163,168,173,178,183,188,193,197,202,207],{"title":41,"path":130,"stem":131,"icon":132},"\u002Fframeworks\u002Foverview","4.frameworks\u002F00.overview","i-lucide-layout-grid",{"title":134,"path":135,"stem":136,"icon":137},"Nuxt","\u002Fframeworks\u002Fnuxt","4.frameworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":139,"path":140,"stem":141,"icon":142},"Next.js","\u002Fframeworks\u002Fnextjs","4.frameworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":144,"path":145,"stem":146,"icon":147},"SvelteKit","\u002Fframeworks\u002Fsveltekit","4.frameworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":149,"path":150,"stem":151,"icon":152},"Nitro","\u002Fframeworks\u002Fnitro","4.frameworks\u002F04.nitro","i-custom-nitro",{"title":154,"path":155,"stem":156,"icon":157},"TanStack Start","\u002Fframeworks\u002Ftanstack-start","4.frameworks\u002F05.tanstack-start","i-custom-tanstack",{"title":159,"path":160,"stem":161,"icon":162},"NestJS","\u002Fframeworks\u002Fnestjs","4.frameworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":164,"path":165,"stem":166,"icon":167},"Express","\u002Fframeworks\u002Fexpress","4.frameworks\u002F07.express","i-simple-icons-express",{"title":169,"path":170,"stem":171,"icon":172},"Hono","\u002Fframeworks\u002Fhono","4.frameworks\u002F08.hono","i-simple-icons-hono",{"title":174,"path":175,"stem":176,"icon":177},"Fastify","\u002Fframeworks\u002Ffastify","4.frameworks\u002F09.fastify","i-simple-icons-fastify",{"title":179,"path":180,"stem":181,"icon":182},"Elysia","\u002Fframeworks\u002Felysia","4.frameworks\u002F10.elysia","i-custom-elysia",{"title":184,"path":185,"stem":186,"icon":187},"React Router","\u002Fframeworks\u002Freact-router","4.frameworks\u002F11.react-router","i-custom-reactrouter",{"title":189,"path":190,"stem":191,"icon":192},"Cloudflare Workers","\u002Fframeworks\u002Fcloudflare-workers","4.frameworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":194,"path":195,"stem":196,"icon":104},"Standalone","\u002Fframeworks\u002Fstandalone","4.frameworks\u002F13.standalone",{"title":198,"path":199,"stem":200,"icon":201},"Astro","\u002Fframeworks\u002Fastro","4.frameworks\u002F14.astro","i-simple-icons-astro",{"title":203,"path":204,"stem":205,"icon":206},"AWS Lambda","\u002Fframeworks\u002Faws-lambda","4.frameworks\u002F16.aws-lambda","i-custom-lambda",{"title":208,"path":209,"stem":210,"icon":211},"Custom Integration","\u002Fframeworks\u002Fcustom-integration","4.frameworks\u002F17.custom-integration","i-lucide-puzzle",{"title":213,"path":214,"stem":215,"children":216,"page":34},"Adapters","\u002Fadapters","6.adapters",[217,257,272],{"title":218,"path":219,"stem":220,"children":221,"page":34},"Cloud destinations","\u002Fadapters\u002Fcloud","6.adapters\u002F02.cloud",[222,227,232,237,242,247,252],{"title":223,"path":224,"stem":225,"icon":226},"Axiom","\u002Fadapters\u002Fcloud\u002Faxiom","6.adapters\u002F02.cloud\u002F01.axiom","i-custom-axiom",{"title":228,"path":229,"stem":230,"icon":231},"OTLP","\u002Fadapters\u002Fcloud\u002Fotlp","6.adapters\u002F02.cloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":233,"path":234,"stem":235,"icon":236},"PostHog","\u002Fadapters\u002Fcloud\u002Fposthog","6.adapters\u002F02.cloud\u002F03.posthog","i-simple-icons-posthog",{"title":238,"path":239,"stem":240,"icon":241},"Sentry","\u002Fadapters\u002Fcloud\u002Fsentry","6.adapters\u002F02.cloud\u002F04.sentry","i-simple-icons-sentry",{"title":243,"path":244,"stem":245,"icon":246},"Better Stack","\u002Fadapters\u002Fcloud\u002Fbetter-stack","6.adapters\u002F02.cloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":248,"path":249,"stem":250,"icon":251},"Datadog","\u002Fadapters\u002Fcloud\u002Fdatadog","6.adapters\u002F02.cloud\u002F06.datadog","i-simple-icons-datadog",{"title":253,"path":254,"stem":255,"icon":256},"HyperDX","\u002Fadapters\u002Fcloud\u002Fhyperdx","6.adapters\u002F02.cloud\u002F07.hyperdx","i-custom-hyperdx",{"title":258,"path":259,"stem":260,"children":261,"page":34},"Self-hosted","\u002Fadapters\u002Fself-hosted","6.adapters\u002F03.self-hosted",[262,267],{"title":263,"path":264,"stem":265,"icon":266},"File System","\u002Fadapters\u002Fself-hosted\u002Ffs","6.adapters\u002F03.self-hosted\u002F01.fs","i-lucide-hard-drive",{"title":268,"path":269,"stem":270,"icon":271},"NuxtHub","\u002Fadapters\u002Fself-hosted\u002Fnuxthub","6.adapters\u002F03.self-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":273,"path":274,"stem":275,"children":276,"page":34},"Building blocks","\u002Fadapters\u002Fbuilding-blocks","6.adapters\u002F04.building-blocks",[277,282,287],{"title":278,"path":279,"stem":280,"icon":281},"Pipeline","\u002Fadapters\u002Fbuilding-blocks\u002Fpipeline","6.adapters\u002F04.building-blocks\u002F01.pipeline","i-lucide-workflow",{"title":283,"path":284,"stem":285,"icon":286},"HTTP","\u002Fadapters\u002Fbuilding-blocks\u002Fhttp","6.adapters\u002F04.building-blocks\u002F02.http","i-lucide-globe",{"title":288,"path":289,"stem":290,"icon":291},"Custom Adapters","\u002Fadapters\u002Fbuilding-blocks\u002Fcustom","6.adapters\u002F04.building-blocks\u002F03.custom","i-lucide-code",{"title":293,"path":294,"stem":295,"children":296,"page":34},"Enrichers","\u002Fenrichers","7.enrichers",[297,300,304],{"title":41,"path":298,"stem":299,"icon":28},"\u002Fenrichers\u002Foverview","7.enrichers\u002F1.overview",{"title":301,"path":302,"stem":303,"icon":211},"Built-in","\u002Fenrichers\u002Fbuilt-in","7.enrichers\u002F2.built-in",{"title":305,"path":306,"stem":307,"icon":291},"Custom","\u002Fenrichers\u002Fcustom","7.enrichers\u002F3.custom",{"id":309,"title":76,"body":310,"description":8601,"extension":8602,"links":8603,"meta":8610,"navigation":8611,"path":77,"seo":8612,"stem":78,"__hash__":8613},"docs\u002F2.logging\u002F7.audit.md",{"type":311,"value":312,"toc":8573},"minimark",[313,331,378,383,409,438,451,455,462,469,473,476,784,2681,2684,2720,2730,2734,2743,3160,3191,3213,3217,3224,3232,3247,3252,3262,3438,3444,4007,4013,4373,4393,4397,4407,4514,4518,4536,4549,4675,4682,4727,4733,4762,4779,4998,5002,5005,5168,5204,5210,5874,5880,5886,5903,6946,6949,6986,6990,6994,6997,7071,7085,7107,7111,7118,7223,7256,7260,7263,7275,7287,7290,7293,7320,7323,7327,7399,7403,7407,7575,7584,7588,7796,7799,7803,8082,8092,8096,8102,8382,8386,8563,8569],[314,315,316,317,321,322,326,327,330],"p",{},"evlog's audit layer is ",[318,319,320],"strong",{},"not a parallel system",". Audit events are wide events with a reserved ",[323,324,325],"code",{},"audit"," field. Every existing primitive — drains, enrichers, redact, tail-sampling — applies as is. Enable audit logs by adding ",[318,328,329],{},"1 enricher + 1 drain wrapper + 1 helper",".",[332,333,336,339,364],"prompt",{":actions":334,"description":335,"icon":79},"[\"copy\",\"cursor\",\"windsurf\"]","Add an audit log to my app",[314,337,338],{},"Add a tamper-evident audit log to my app on top of evlog.",[340,341,342,346,349,352,355,358,361],"ul",{},[343,344,345],"li",{},"Identify my framework and follow its evlog integration pattern",[343,347,348],{},"Register auditEnricher() on the evlog:enrich hook (or in initLogger.enrichers)",[343,350,351],{},"Register a separate auditOnly(signed(createFsDrain({ dir: '.audit' }), { strategy: 'hash-chain' })) drain alongside my main drain",[343,353,354],{},"Use { await: true } on the audit drain so audit events are flushed before the response returns",[343,356,357],{},"Call log.audit({ action, actor, target, outcome, reason }) for every security-sensitive action (login, role change, refund, data export, deletion)",[343,359,360],{},"Audit events are force-kept past sampling and signed via hash-chain for tamper-evidence",[343,362,363],{},"Combine with the Better Auth integration so actor.id \u002F actor.email are automatic",[314,365,366,367,373,374],{},"Docs: ",[368,369,370],"a",{"href":370,"rel":371},"https:\u002F\u002Fwww.evlog.dev\u002Flogging\u002Faudit",[372],"nofollow","\nAdapters: ",[368,375,376],{"href":376,"rel":377},"https:\u002F\u002Fwww.evlog.dev\u002Fadapters\u002Foverview",[372],[379,380,382],"h2",{"id":381},"agent-skills","Agent skills",[314,384,385,386,391,392,395,396,399,400,405,406,330],{},"Install the evlog skill catalog so your assistant can follow ",[318,387,388],{},[323,389,390],{},"build-audit-logs"," end to end: written policy, framework wiring, ",[323,393,394],{},"withAudit"," \u002F ",[323,397,398],{},"log.audit",", denials, redaction, multi-tenant isolation, tamper-evident sinks, and grep-based review passes. If you use the file-system drain for audits or general logs, ",[318,401,402],{},[323,403,404],{},"analyze-logs"," teaches assistants to read NDJSON under ",[323,407,408],{},".evlog\u002Flogs\u002F",[410,411,417],"pre",{"className":412,"code":413,"filename":414,"language":415,"meta":416,"style":416},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx skills add https:\u002F\u002Fwww.evlog.dev\n","Terminal","bash","",[323,418,419],{"__ignoreMap":416},[420,421,424,428,432,435],"span",{"class":422,"line":423},"line",1,[420,425,427],{"class":426},"sBMFI","npx",[420,429,431],{"class":430},"sfazB"," skills",[420,433,434],{"class":430}," add",[420,436,437],{"class":430}," https:\u002F\u002Fwww.evlog.dev\n",[314,439,440,441,443,444,447,448,330],{},"See ",[368,442,25],{"href":26}," for the full list. Skill paths in the repo: ",[323,445,446],{},"skills\u002Fbuild-audit-logs",", ",[323,449,450],{},"skills\u002Fanalyze-logs",[379,452,454],{"id":453},"why-audit-logs","Why Audit Logs?",[314,456,457,458,461],{},"Compliance frameworks (SOC2, HIPAA, GDPR, PCI) require knowing ",[318,459,460],{},"who did what, on which resource, when, from where, with which outcome",". evlog covers this without a second logging library.",[463,464,465,468],"tip",{},[318,466,467],{},"An audit event is a fact about an intent, not a measurement of an operation."," A regular wide event answers \"how did this request behave?\" (latency, status, tokens). An audit event answers \"who tried to do what, and was it allowed?\". Same pipeline, different question — that's why the schema is reserved and the event is force-kept past sampling.",[379,470,472],{"id":471},"quickstart","Quickstart",[314,474,475],{},"You already use evlog. Add audit logs in three changes:",[410,477,482],{"className":478,"code":479,"filename":480,"language":481,"meta":416,"style":416},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { auditEnricher, auditOnly, signed } from 'evlog'\nimport { createAxiomDrain } from 'evlog\u002Faxiom'\nimport { createFsDrain } from 'evlog\u002Ffs'\n\nexport default defineNitroPlugin((nitro) => {\n  nitro.hooks.hook('evlog:enrich', auditEnricher())\n  nitro.hooks.hook('evlog:drain', createAxiomDrain())\n  nitro.hooks.hook('evlog:drain', auditOnly(\n    signed(createFsDrain({ dir: '.audit' }), { strategy: 'hash-chain' }),\n    { await: true },\n  ))\n})\n","server\u002Fplugins\u002Fevlog.ts","typescript",[323,483,484,524,545,566,573,605,639,667,695,751,769,775],{"__ignoreMap":416},[420,485,486,490,494,498,501,504,506,509,512,515,518,521],{"class":422,"line":423},[420,487,489],{"class":488},"s7zQu","import",[420,491,493],{"class":492},"sMK4o"," {",[420,495,497],{"class":496},"sTEyZ"," auditEnricher",[420,499,500],{"class":492},",",[420,502,503],{"class":496}," auditOnly",[420,505,500],{"class":492},[420,507,508],{"class":496}," signed",[420,510,511],{"class":492}," }",[420,513,514],{"class":488}," from",[420,516,517],{"class":492}," '",[420,519,520],{"class":430},"evlog",[420,522,523],{"class":492},"'\n",[420,525,527,529,531,534,536,538,540,543],{"class":422,"line":526},2,[420,528,489],{"class":488},[420,530,493],{"class":492},[420,532,533],{"class":496}," createAxiomDrain",[420,535,511],{"class":492},[420,537,514],{"class":488},[420,539,517],{"class":492},[420,541,542],{"class":430},"evlog\u002Faxiom",[420,544,523],{"class":492},[420,546,548,550,552,555,557,559,561,564],{"class":422,"line":547},3,[420,549,489],{"class":488},[420,551,493],{"class":492},[420,553,554],{"class":496}," createFsDrain",[420,556,511],{"class":492},[420,558,514],{"class":488},[420,560,517],{"class":492},[420,562,563],{"class":430},"evlog\u002Ffs",[420,565,523],{"class":492},[420,567,569],{"class":422,"line":568},4,[420,570,572],{"emptyLinePlaceholder":571},true,"\n",[420,574,576,579,582,586,589,591,595,598,602],{"class":422,"line":575},5,[420,577,578],{"class":488},"export",[420,580,581],{"class":488}," default",[420,583,585],{"class":584},"s2Zo4"," defineNitroPlugin",[420,587,588],{"class":496},"(",[420,590,588],{"class":492},[420,592,594],{"class":593},"sHdIc","nitro",[420,596,597],{"class":492},")",[420,599,601],{"class":600},"spNyl"," =>",[420,603,604],{"class":492}," {\n",[420,606,608,611,613,616,618,621,624,627,630,632,634,636],{"class":422,"line":607},6,[420,609,610],{"class":496},"  nitro",[420,612,330],{"class":492},[420,614,615],{"class":496},"hooks",[420,617,330],{"class":492},[420,619,620],{"class":584},"hook",[420,622,588],{"class":623},"swJcz",[420,625,626],{"class":492},"'",[420,628,629],{"class":430},"evlog:enrich",[420,631,626],{"class":492},[420,633,500],{"class":492},[420,635,497],{"class":584},[420,637,638],{"class":623},"())\n",[420,640,642,644,646,648,650,652,654,656,659,661,663,665],{"class":422,"line":641},7,[420,643,610],{"class":496},[420,645,330],{"class":492},[420,647,615],{"class":496},[420,649,330],{"class":492},[420,651,620],{"class":584},[420,653,588],{"class":623},[420,655,626],{"class":492},[420,657,658],{"class":430},"evlog:drain",[420,660,626],{"class":492},[420,662,500],{"class":492},[420,664,533],{"class":584},[420,666,638],{"class":623},[420,668,670,672,674,676,678,680,682,684,686,688,690,692],{"class":422,"line":669},8,[420,671,610],{"class":496},[420,673,330],{"class":492},[420,675,615],{"class":496},[420,677,330],{"class":492},[420,679,620],{"class":584},[420,681,588],{"class":623},[420,683,626],{"class":492},[420,685,658],{"class":430},[420,687,626],{"class":492},[420,689,500],{"class":492},[420,691,503],{"class":584},[420,693,694],{"class":623},"(\n",[420,696,698,701,703,706,708,711,714,717,719,722,724,726,728,730,732,735,737,739,742,744,746,748],{"class":422,"line":697},9,[420,699,700],{"class":584},"    signed",[420,702,588],{"class":623},[420,704,705],{"class":584},"createFsDrain",[420,707,588],{"class":623},[420,709,710],{"class":492},"{",[420,712,713],{"class":623}," dir",[420,715,716],{"class":492},":",[420,718,517],{"class":492},[420,720,721],{"class":430},".audit",[420,723,626],{"class":492},[420,725,511],{"class":492},[420,727,597],{"class":623},[420,729,500],{"class":492},[420,731,493],{"class":492},[420,733,734],{"class":623}," strategy",[420,736,716],{"class":492},[420,738,517],{"class":492},[420,740,741],{"class":430},"hash-chain",[420,743,626],{"class":492},[420,745,511],{"class":492},[420,747,597],{"class":623},[420,749,750],{"class":492},",\n",[420,752,754,757,760,762,766],{"class":422,"line":753},10,[420,755,756],{"class":492},"    {",[420,758,759],{"class":623}," await",[420,761,716],{"class":492},[420,763,765],{"class":764},"sfNiH"," true",[420,767,768],{"class":492}," },\n",[420,770,772],{"class":422,"line":771},11,[420,773,774],{"class":623},"  ))\n",[420,776,778,781],{"class":422,"line":777},12,[420,779,780],{"class":492},"}",[420,782,783],{"class":496},")\n",[785,786,787,1081,1384,1757,2068,2226],"code-group",{},[410,788,791],{"className":478,"code":789,"filename":790,"language":481,"meta":416,"style":416},"export default defineEventHandler(async (event) => {\n  const log = useLogger(event)\n  const user = await requireUser(event)\n  const invoice = await refundInvoice(getRouterParam(event, 'id'))\n\n  log.audit({\n    action: 'invoice.refund',\n    actor: { type: 'user', id: user.id, email: user.email },\n    target: { type: 'invoice', id: invoice.id },\n    outcome: 'success',\n    reason: 'Customer requested refund',\n  })\n\n  return { ok: true }\n})\n","Nuxt \u002F Nitro",[323,792,793,819,839,859,894,898,912,928,978,1012,1028,1044,1051,1056,1074],{"__ignoreMap":416},[420,794,795,797,799,802,804,807,810,813,815,817],{"class":422,"line":423},[420,796,578],{"class":488},[420,798,581],{"class":488},[420,800,801],{"class":584}," defineEventHandler",[420,803,588],{"class":496},[420,805,806],{"class":600},"async",[420,808,809],{"class":492}," (",[420,811,812],{"class":593},"event",[420,814,597],{"class":492},[420,816,601],{"class":600},[420,818,604],{"class":492},[420,820,821,824,827,830,833,835,837],{"class":422,"line":526},[420,822,823],{"class":600},"  const",[420,825,826],{"class":496}," log",[420,828,829],{"class":492}," =",[420,831,832],{"class":584}," useLogger",[420,834,588],{"class":623},[420,836,812],{"class":496},[420,838,783],{"class":623},[420,840,841,843,846,848,850,853,855,857],{"class":422,"line":547},[420,842,823],{"class":600},[420,844,845],{"class":496}," user",[420,847,829],{"class":492},[420,849,759],{"class":488},[420,851,852],{"class":584}," requireUser",[420,854,588],{"class":623},[420,856,812],{"class":496},[420,858,783],{"class":623},[420,860,861,863,866,868,870,873,875,878,880,882,884,886,889,891],{"class":422,"line":568},[420,862,823],{"class":600},[420,864,865],{"class":496}," invoice",[420,867,829],{"class":492},[420,869,759],{"class":488},[420,871,872],{"class":584}," refundInvoice",[420,874,588],{"class":623},[420,876,877],{"class":584},"getRouterParam",[420,879,588],{"class":623},[420,881,812],{"class":496},[420,883,500],{"class":492},[420,885,517],{"class":492},[420,887,888],{"class":430},"id",[420,890,626],{"class":492},[420,892,893],{"class":623},"))\n",[420,895,896],{"class":422,"line":575},[420,897,572],{"emptyLinePlaceholder":571},[420,899,900,903,905,907,909],{"class":422,"line":607},[420,901,902],{"class":496},"  log",[420,904,330],{"class":492},[420,906,325],{"class":584},[420,908,588],{"class":623},[420,910,911],{"class":492},"{\n",[420,913,914,917,919,921,924,926],{"class":422,"line":641},[420,915,916],{"class":623},"    action",[420,918,716],{"class":492},[420,920,517],{"class":492},[420,922,923],{"class":430},"invoice.refund",[420,925,626],{"class":492},[420,927,750],{"class":492},[420,929,930,933,935,937,940,942,944,947,949,951,954,956,958,960,962,964,967,969,971,973,976],{"class":422,"line":669},[420,931,932],{"class":623},"    actor",[420,934,716],{"class":492},[420,936,493],{"class":492},[420,938,939],{"class":623}," type",[420,941,716],{"class":492},[420,943,517],{"class":492},[420,945,946],{"class":430},"user",[420,948,626],{"class":492},[420,950,500],{"class":492},[420,952,953],{"class":623}," id",[420,955,716],{"class":492},[420,957,845],{"class":496},[420,959,330],{"class":492},[420,961,888],{"class":496},[420,963,500],{"class":492},[420,965,966],{"class":623}," email",[420,968,716],{"class":492},[420,970,845],{"class":496},[420,972,330],{"class":492},[420,974,975],{"class":496},"email",[420,977,768],{"class":492},[420,979,980,983,985,987,989,991,993,996,998,1000,1002,1004,1006,1008,1010],{"class":422,"line":697},[420,981,982],{"class":623},"    target",[420,984,716],{"class":492},[420,986,493],{"class":492},[420,988,939],{"class":623},[420,990,716],{"class":492},[420,992,517],{"class":492},[420,994,995],{"class":430},"invoice",[420,997,626],{"class":492},[420,999,500],{"class":492},[420,1001,953],{"class":623},[420,1003,716],{"class":492},[420,1005,865],{"class":496},[420,1007,330],{"class":492},[420,1009,888],{"class":496},[420,1011,768],{"class":492},[420,1013,1014,1017,1019,1021,1024,1026],{"class":422,"line":753},[420,1015,1016],{"class":623},"    outcome",[420,1018,716],{"class":492},[420,1020,517],{"class":492},[420,1022,1023],{"class":430},"success",[420,1025,626],{"class":492},[420,1027,750],{"class":492},[420,1029,1030,1033,1035,1037,1040,1042],{"class":422,"line":771},[420,1031,1032],{"class":623},"    reason",[420,1034,716],{"class":492},[420,1036,517],{"class":492},[420,1038,1039],{"class":430},"Customer requested refund",[420,1041,626],{"class":492},[420,1043,750],{"class":492},[420,1045,1046,1049],{"class":422,"line":777},[420,1047,1048],{"class":492},"  }",[420,1050,783],{"class":623},[420,1052,1054],{"class":422,"line":1053},13,[420,1055,572],{"emptyLinePlaceholder":571},[420,1057,1059,1062,1064,1067,1069,1071],{"class":422,"line":1058},14,[420,1060,1061],{"class":488},"  return",[420,1063,493],{"class":492},[420,1065,1066],{"class":623}," ok",[420,1068,716],{"class":492},[420,1070,765],{"class":764},[420,1072,1073],{"class":492}," }\n",[420,1075,1077,1079],{"class":422,"line":1076},15,[420,1078,780],{"class":492},[420,1080,783],{"class":496},[410,1082,1084],{"className":478,"code":1083,"filename":139,"language":481,"meta":416,"style":416},"import { withEvlog, useLogger } from '@\u002Flib\u002Fevlog'\n\nexport const POST = withEvlog(async (req, { params }) => {\n  const log = useLogger()\n  const user = await requireUser(req)\n  const invoice = await refundInvoice(params.id)\n\n  log.audit({\n    action: 'invoice.refund',\n    actor: { type: 'user', id: user.id, email: user.email },\n    target: { type: 'invoice', id: invoice.id },\n    outcome: 'success',\n    reason: 'Customer requested refund',\n  })\n\n  return Response.json({ ok: true })\n})\n",[323,1085,1086,1110,1114,1152,1165,1183,1206,1210,1222,1236,1280,1312,1326,1340,1346,1350,1377],{"__ignoreMap":416},[420,1087,1088,1090,1092,1095,1097,1099,1101,1103,1105,1108],{"class":422,"line":423},[420,1089,489],{"class":488},[420,1091,493],{"class":492},[420,1093,1094],{"class":496}," withEvlog",[420,1096,500],{"class":492},[420,1098,832],{"class":496},[420,1100,511],{"class":492},[420,1102,514],{"class":488},[420,1104,517],{"class":492},[420,1106,1107],{"class":430},"@\u002Flib\u002Fevlog",[420,1109,523],{"class":492},[420,1111,1112],{"class":422,"line":526},[420,1113,572],{"emptyLinePlaceholder":571},[420,1115,1116,1118,1121,1124,1127,1129,1131,1133,1135,1138,1140,1142,1145,1148,1150],{"class":422,"line":547},[420,1117,578],{"class":488},[420,1119,1120],{"class":600}," const",[420,1122,1123],{"class":496}," POST ",[420,1125,1126],{"class":492},"=",[420,1128,1094],{"class":584},[420,1130,588],{"class":496},[420,1132,806],{"class":600},[420,1134,809],{"class":492},[420,1136,1137],{"class":593},"req",[420,1139,500],{"class":492},[420,1141,493],{"class":492},[420,1143,1144],{"class":593}," params",[420,1146,1147],{"class":492}," })",[420,1149,601],{"class":600},[420,1151,604],{"class":492},[420,1153,1154,1156,1158,1160,1162],{"class":422,"line":568},[420,1155,823],{"class":600},[420,1157,826],{"class":496},[420,1159,829],{"class":492},[420,1161,832],{"class":584},[420,1163,1164],{"class":623},"()\n",[420,1166,1167,1169,1171,1173,1175,1177,1179,1181],{"class":422,"line":575},[420,1168,823],{"class":600},[420,1170,845],{"class":496},[420,1172,829],{"class":492},[420,1174,759],{"class":488},[420,1176,852],{"class":584},[420,1178,588],{"class":623},[420,1180,1137],{"class":496},[420,1182,783],{"class":623},[420,1184,1185,1187,1189,1191,1193,1195,1197,1200,1202,1204],{"class":422,"line":607},[420,1186,823],{"class":600},[420,1188,865],{"class":496},[420,1190,829],{"class":492},[420,1192,759],{"class":488},[420,1194,872],{"class":584},[420,1196,588],{"class":623},[420,1198,1199],{"class":496},"params",[420,1201,330],{"class":492},[420,1203,888],{"class":496},[420,1205,783],{"class":623},[420,1207,1208],{"class":422,"line":641},[420,1209,572],{"emptyLinePlaceholder":571},[420,1211,1212,1214,1216,1218,1220],{"class":422,"line":669},[420,1213,902],{"class":496},[420,1215,330],{"class":492},[420,1217,325],{"class":584},[420,1219,588],{"class":623},[420,1221,911],{"class":492},[420,1223,1224,1226,1228,1230,1232,1234],{"class":422,"line":697},[420,1225,916],{"class":623},[420,1227,716],{"class":492},[420,1229,517],{"class":492},[420,1231,923],{"class":430},[420,1233,626],{"class":492},[420,1235,750],{"class":492},[420,1237,1238,1240,1242,1244,1246,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278],{"class":422,"line":753},[420,1239,932],{"class":623},[420,1241,716],{"class":492},[420,1243,493],{"class":492},[420,1245,939],{"class":623},[420,1247,716],{"class":492},[420,1249,517],{"class":492},[420,1251,946],{"class":430},[420,1253,626],{"class":492},[420,1255,500],{"class":492},[420,1257,953],{"class":623},[420,1259,716],{"class":492},[420,1261,845],{"class":496},[420,1263,330],{"class":492},[420,1265,888],{"class":496},[420,1267,500],{"class":492},[420,1269,966],{"class":623},[420,1271,716],{"class":492},[420,1273,845],{"class":496},[420,1275,330],{"class":492},[420,1277,975],{"class":496},[420,1279,768],{"class":492},[420,1281,1282,1284,1286,1288,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1310],{"class":422,"line":771},[420,1283,982],{"class":623},[420,1285,716],{"class":492},[420,1287,493],{"class":492},[420,1289,939],{"class":623},[420,1291,716],{"class":492},[420,1293,517],{"class":492},[420,1295,995],{"class":430},[420,1297,626],{"class":492},[420,1299,500],{"class":492},[420,1301,953],{"class":623},[420,1303,716],{"class":492},[420,1305,865],{"class":496},[420,1307,330],{"class":492},[420,1309,888],{"class":496},[420,1311,768],{"class":492},[420,1313,1314,1316,1318,1320,1322,1324],{"class":422,"line":777},[420,1315,1016],{"class":623},[420,1317,716],{"class":492},[420,1319,517],{"class":492},[420,1321,1023],{"class":430},[420,1323,626],{"class":492},[420,1325,750],{"class":492},[420,1327,1328,1330,1332,1334,1336,1338],{"class":422,"line":1053},[420,1329,1032],{"class":623},[420,1331,716],{"class":492},[420,1333,517],{"class":492},[420,1335,1039],{"class":430},[420,1337,626],{"class":492},[420,1339,750],{"class":492},[420,1341,1342,1344],{"class":422,"line":1058},[420,1343,1048],{"class":492},[420,1345,783],{"class":623},[420,1347,1348],{"class":422,"line":1076},[420,1349,572],{"emptyLinePlaceholder":571},[420,1351,1353,1355,1358,1360,1363,1365,1367,1369,1371,1373,1375],{"class":422,"line":1352},16,[420,1354,1061],{"class":488},[420,1356,1357],{"class":496}," Response",[420,1359,330],{"class":492},[420,1361,1362],{"class":584},"json",[420,1364,588],{"class":623},[420,1366,710],{"class":492},[420,1368,1066],{"class":623},[420,1370,716],{"class":492},[420,1372,765],{"class":764},[420,1374,511],{"class":492},[420,1376,783],{"class":623},[420,1378,1380,1382],{"class":422,"line":1379},17,[420,1381,780],{"class":492},[420,1383,783],{"class":496},[410,1385,1387],{"className":478,"code":1386,"filename":169,"language":481,"meta":416,"style":416},"import type { EvlogVariables } from 'evlog\u002Fhono'\nimport { Hono } from 'hono'\n\nconst app = new Hono\u003CEvlogVariables>()\n\napp.post('\u002Finvoices\u002F:id\u002Frefund', async (c) => {\n  const log = c.get('log')\n  const user = await requireUser(c)\n  const invoice = await refundInvoice(c.req.param('id'))\n\n  log.audit({\n    action: 'invoice.refund',\n    actor: { type: 'user', id: user.id, email: user.email },\n    target: { type: 'invoice', id: invoice.id },\n    outcome: 'success',\n    reason: 'Customer requested refund',\n  })\n\n  return c.json({ ok: true })\n})\n",[323,1388,1389,1411,1431,1435,1461,1465,1500,1527,1545,1580,1584,1596,1610,1654,1686,1700,1714,1720,1725,1750],{"__ignoreMap":416},[420,1390,1391,1393,1395,1397,1400,1402,1404,1406,1409],{"class":422,"line":423},[420,1392,489],{"class":488},[420,1394,939],{"class":488},[420,1396,493],{"class":492},[420,1398,1399],{"class":496}," EvlogVariables",[420,1401,511],{"class":492},[420,1403,514],{"class":488},[420,1405,517],{"class":492},[420,1407,1408],{"class":430},"evlog\u002Fhono",[420,1410,523],{"class":492},[420,1412,1413,1415,1417,1420,1422,1424,1426,1429],{"class":422,"line":526},[420,1414,489],{"class":488},[420,1416,493],{"class":492},[420,1418,1419],{"class":496}," Hono",[420,1421,511],{"class":492},[420,1423,514],{"class":488},[420,1425,517],{"class":492},[420,1427,1428],{"class":430},"hono",[420,1430,523],{"class":492},[420,1432,1433],{"class":422,"line":547},[420,1434,572],{"emptyLinePlaceholder":571},[420,1436,1437,1440,1443,1445,1448,1450,1453,1456,1459],{"class":422,"line":568},[420,1438,1439],{"class":600},"const",[420,1441,1442],{"class":496}," app ",[420,1444,1126],{"class":492},[420,1446,1447],{"class":492}," new",[420,1449,1419],{"class":584},[420,1451,1452],{"class":492},"\u003C",[420,1454,1455],{"class":426},"EvlogVariables",[420,1457,1458],{"class":492},">",[420,1460,1164],{"class":496},[420,1462,1463],{"class":422,"line":575},[420,1464,572],{"emptyLinePlaceholder":571},[420,1466,1467,1470,1472,1475,1477,1479,1482,1484,1486,1489,1491,1494,1496,1498],{"class":422,"line":607},[420,1468,1469],{"class":496},"app",[420,1471,330],{"class":492},[420,1473,1474],{"class":584},"post",[420,1476,588],{"class":496},[420,1478,626],{"class":492},[420,1480,1481],{"class":430},"\u002Finvoices\u002F:id\u002Frefund",[420,1483,626],{"class":492},[420,1485,500],{"class":492},[420,1487,1488],{"class":600}," async",[420,1490,809],{"class":492},[420,1492,1493],{"class":593},"c",[420,1495,597],{"class":492},[420,1497,601],{"class":600},[420,1499,604],{"class":492},[420,1501,1502,1504,1506,1508,1511,1513,1516,1518,1520,1523,1525],{"class":422,"line":641},[420,1503,823],{"class":600},[420,1505,826],{"class":496},[420,1507,829],{"class":492},[420,1509,1510],{"class":496}," c",[420,1512,330],{"class":492},[420,1514,1515],{"class":584},"get",[420,1517,588],{"class":623},[420,1519,626],{"class":492},[420,1521,1522],{"class":430},"log",[420,1524,626],{"class":492},[420,1526,783],{"class":623},[420,1528,1529,1531,1533,1535,1537,1539,1541,1543],{"class":422,"line":669},[420,1530,823],{"class":600},[420,1532,845],{"class":496},[420,1534,829],{"class":492},[420,1536,759],{"class":488},[420,1538,852],{"class":584},[420,1540,588],{"class":623},[420,1542,1493],{"class":496},[420,1544,783],{"class":623},[420,1546,1547,1549,1551,1553,1555,1557,1559,1561,1563,1565,1567,1570,1572,1574,1576,1578],{"class":422,"line":697},[420,1548,823],{"class":600},[420,1550,865],{"class":496},[420,1552,829],{"class":492},[420,1554,759],{"class":488},[420,1556,872],{"class":584},[420,1558,588],{"class":623},[420,1560,1493],{"class":496},[420,1562,330],{"class":492},[420,1564,1137],{"class":496},[420,1566,330],{"class":492},[420,1568,1569],{"class":584},"param",[420,1571,588],{"class":623},[420,1573,626],{"class":492},[420,1575,888],{"class":430},[420,1577,626],{"class":492},[420,1579,893],{"class":623},[420,1581,1582],{"class":422,"line":753},[420,1583,572],{"emptyLinePlaceholder":571},[420,1585,1586,1588,1590,1592,1594],{"class":422,"line":771},[420,1587,902],{"class":496},[420,1589,330],{"class":492},[420,1591,325],{"class":584},[420,1593,588],{"class":623},[420,1595,911],{"class":492},[420,1597,1598,1600,1602,1604,1606,1608],{"class":422,"line":777},[420,1599,916],{"class":623},[420,1601,716],{"class":492},[420,1603,517],{"class":492},[420,1605,923],{"class":430},[420,1607,626],{"class":492},[420,1609,750],{"class":492},[420,1611,1612,1614,1616,1618,1620,1622,1624,1626,1628,1630,1632,1634,1636,1638,1640,1642,1644,1646,1648,1650,1652],{"class":422,"line":1053},[420,1613,932],{"class":623},[420,1615,716],{"class":492},[420,1617,493],{"class":492},[420,1619,939],{"class":623},[420,1621,716],{"class":492},[420,1623,517],{"class":492},[420,1625,946],{"class":430},[420,1627,626],{"class":492},[420,1629,500],{"class":492},[420,1631,953],{"class":623},[420,1633,716],{"class":492},[420,1635,845],{"class":496},[420,1637,330],{"class":492},[420,1639,888],{"class":496},[420,1641,500],{"class":492},[420,1643,966],{"class":623},[420,1645,716],{"class":492},[420,1647,845],{"class":496},[420,1649,330],{"class":492},[420,1651,975],{"class":496},[420,1653,768],{"class":492},[420,1655,1656,1658,1660,1662,1664,1666,1668,1670,1672,1674,1676,1678,1680,1682,1684],{"class":422,"line":1058},[420,1657,982],{"class":623},[420,1659,716],{"class":492},[420,1661,493],{"class":492},[420,1663,939],{"class":623},[420,1665,716],{"class":492},[420,1667,517],{"class":492},[420,1669,995],{"class":430},[420,1671,626],{"class":492},[420,1673,500],{"class":492},[420,1675,953],{"class":623},[420,1677,716],{"class":492},[420,1679,865],{"class":496},[420,1681,330],{"class":492},[420,1683,888],{"class":496},[420,1685,768],{"class":492},[420,1687,1688,1690,1692,1694,1696,1698],{"class":422,"line":1076},[420,1689,1016],{"class":623},[420,1691,716],{"class":492},[420,1693,517],{"class":492},[420,1695,1023],{"class":430},[420,1697,626],{"class":492},[420,1699,750],{"class":492},[420,1701,1702,1704,1706,1708,1710,1712],{"class":422,"line":1352},[420,1703,1032],{"class":623},[420,1705,716],{"class":492},[420,1707,517],{"class":492},[420,1709,1039],{"class":430},[420,1711,626],{"class":492},[420,1713,750],{"class":492},[420,1715,1716,1718],{"class":422,"line":1379},[420,1717,1048],{"class":492},[420,1719,783],{"class":623},[420,1721,1723],{"class":422,"line":1722},18,[420,1724,572],{"emptyLinePlaceholder":571},[420,1726,1728,1730,1732,1734,1736,1738,1740,1742,1744,1746,1748],{"class":422,"line":1727},19,[420,1729,1061],{"class":488},[420,1731,1510],{"class":496},[420,1733,330],{"class":492},[420,1735,1362],{"class":584},[420,1737,588],{"class":623},[420,1739,710],{"class":492},[420,1741,1066],{"class":623},[420,1743,716],{"class":492},[420,1745,765],{"class":764},[420,1747,511],{"class":492},[420,1749,783],{"class":623},[420,1751,1753,1755],{"class":422,"line":1752},20,[420,1754,780],{"class":492},[420,1756,783],{"class":496},[410,1758,1760],{"className":478,"code":1759,"filename":164,"language":481,"meta":416,"style":416},"import type { Request, Response } from 'express'\n\napp.post('\u002Finvoices\u002F:id\u002Frefund', async (req: Request, res: Response) => {\n  const log = req.log\n  const user = await requireUser(req)\n  const invoice = await refundInvoice(req.params.id)\n\n  log.audit({\n    action: 'invoice.refund',\n    actor: { type: 'user', id: user.id, email: user.email },\n    target: { type: 'invoice', id: invoice.id },\n    outcome: 'success',\n    reason: 'Customer requested refund',\n  })\n\n  res.json({ ok: true })\n})\n",[323,1761,1762,1788,1792,1835,1851,1869,1895,1899,1911,1925,1969,2001,2015,2029,2035,2039,2062],{"__ignoreMap":416},[420,1763,1764,1766,1768,1770,1773,1775,1777,1779,1781,1783,1786],{"class":422,"line":423},[420,1765,489],{"class":488},[420,1767,939],{"class":488},[420,1769,493],{"class":492},[420,1771,1772],{"class":496}," Request",[420,1774,500],{"class":492},[420,1776,1357],{"class":496},[420,1778,511],{"class":492},[420,1780,514],{"class":488},[420,1782,517],{"class":492},[420,1784,1785],{"class":430},"express",[420,1787,523],{"class":492},[420,1789,1790],{"class":422,"line":526},[420,1791,572],{"emptyLinePlaceholder":571},[420,1793,1794,1796,1798,1800,1802,1804,1806,1808,1810,1812,1814,1816,1818,1820,1822,1825,1827,1829,1831,1833],{"class":422,"line":547},[420,1795,1469],{"class":496},[420,1797,330],{"class":492},[420,1799,1474],{"class":584},[420,1801,588],{"class":496},[420,1803,626],{"class":492},[420,1805,1481],{"class":430},[420,1807,626],{"class":492},[420,1809,500],{"class":492},[420,1811,1488],{"class":600},[420,1813,809],{"class":492},[420,1815,1137],{"class":593},[420,1817,716],{"class":492},[420,1819,1772],{"class":426},[420,1821,500],{"class":492},[420,1823,1824],{"class":593}," res",[420,1826,716],{"class":492},[420,1828,1357],{"class":426},[420,1830,597],{"class":492},[420,1832,601],{"class":600},[420,1834,604],{"class":492},[420,1836,1837,1839,1841,1843,1846,1848],{"class":422,"line":568},[420,1838,823],{"class":600},[420,1840,826],{"class":496},[420,1842,829],{"class":492},[420,1844,1845],{"class":496}," req",[420,1847,330],{"class":492},[420,1849,1850],{"class":496},"log\n",[420,1852,1853,1855,1857,1859,1861,1863,1865,1867],{"class":422,"line":575},[420,1854,823],{"class":600},[420,1856,845],{"class":496},[420,1858,829],{"class":492},[420,1860,759],{"class":488},[420,1862,852],{"class":584},[420,1864,588],{"class":623},[420,1866,1137],{"class":496},[420,1868,783],{"class":623},[420,1870,1871,1873,1875,1877,1879,1881,1883,1885,1887,1889,1891,1893],{"class":422,"line":607},[420,1872,823],{"class":600},[420,1874,865],{"class":496},[420,1876,829],{"class":492},[420,1878,759],{"class":488},[420,1880,872],{"class":584},[420,1882,588],{"class":623},[420,1884,1137],{"class":496},[420,1886,330],{"class":492},[420,1888,1199],{"class":496},[420,1890,330],{"class":492},[420,1892,888],{"class":496},[420,1894,783],{"class":623},[420,1896,1897],{"class":422,"line":641},[420,1898,572],{"emptyLinePlaceholder":571},[420,1900,1901,1903,1905,1907,1909],{"class":422,"line":669},[420,1902,902],{"class":496},[420,1904,330],{"class":492},[420,1906,325],{"class":584},[420,1908,588],{"class":623},[420,1910,911],{"class":492},[420,1912,1913,1915,1917,1919,1921,1923],{"class":422,"line":697},[420,1914,916],{"class":623},[420,1916,716],{"class":492},[420,1918,517],{"class":492},[420,1920,923],{"class":430},[420,1922,626],{"class":492},[420,1924,750],{"class":492},[420,1926,1927,1929,1931,1933,1935,1937,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967],{"class":422,"line":753},[420,1928,932],{"class":623},[420,1930,716],{"class":492},[420,1932,493],{"class":492},[420,1934,939],{"class":623},[420,1936,716],{"class":492},[420,1938,517],{"class":492},[420,1940,946],{"class":430},[420,1942,626],{"class":492},[420,1944,500],{"class":492},[420,1946,953],{"class":623},[420,1948,716],{"class":492},[420,1950,845],{"class":496},[420,1952,330],{"class":492},[420,1954,888],{"class":496},[420,1956,500],{"class":492},[420,1958,966],{"class":623},[420,1960,716],{"class":492},[420,1962,845],{"class":496},[420,1964,330],{"class":492},[420,1966,975],{"class":496},[420,1968,768],{"class":492},[420,1970,1971,1973,1975,1977,1979,1981,1983,1985,1987,1989,1991,1993,1995,1997,1999],{"class":422,"line":771},[420,1972,982],{"class":623},[420,1974,716],{"class":492},[420,1976,493],{"class":492},[420,1978,939],{"class":623},[420,1980,716],{"class":492},[420,1982,517],{"class":492},[420,1984,995],{"class":430},[420,1986,626],{"class":492},[420,1988,500],{"class":492},[420,1990,953],{"class":623},[420,1992,716],{"class":492},[420,1994,865],{"class":496},[420,1996,330],{"class":492},[420,1998,888],{"class":496},[420,2000,768],{"class":492},[420,2002,2003,2005,2007,2009,2011,2013],{"class":422,"line":777},[420,2004,1016],{"class":623},[420,2006,716],{"class":492},[420,2008,517],{"class":492},[420,2010,1023],{"class":430},[420,2012,626],{"class":492},[420,2014,750],{"class":492},[420,2016,2017,2019,2021,2023,2025,2027],{"class":422,"line":1053},[420,2018,1032],{"class":623},[420,2020,716],{"class":492},[420,2022,517],{"class":492},[420,2024,1039],{"class":430},[420,2026,626],{"class":492},[420,2028,750],{"class":492},[420,2030,2031,2033],{"class":422,"line":1058},[420,2032,1048],{"class":492},[420,2034,783],{"class":623},[420,2036,2037],{"class":422,"line":1076},[420,2038,572],{"emptyLinePlaceholder":571},[420,2040,2041,2044,2046,2048,2050,2052,2054,2056,2058,2060],{"class":422,"line":1352},[420,2042,2043],{"class":496},"  res",[420,2045,330],{"class":492},[420,2047,1362],{"class":584},[420,2049,588],{"class":623},[420,2051,710],{"class":492},[420,2053,1066],{"class":623},[420,2055,716],{"class":492},[420,2057,765],{"class":764},[420,2059,511],{"class":492},[420,2061,783],{"class":623},[420,2063,2064,2066],{"class":422,"line":1379},[420,2065,780],{"class":492},[420,2067,783],{"class":496},[410,2069,2072],{"className":478,"code":2070,"filename":2071,"language":481,"meta":416,"style":416},"import { audit } from 'evlog'\n\naudit({\n  action: 'invoice.refund',\n  actor: { type: 'system', id: 'billing-worker' },\n  target: { type: 'invoice', id: 'inv_889' },\n  outcome: 'success',\n  reason: 'Auto-refund triggered by chargeback webhook',\n})\n","Standalone job",[323,2073,2074,2093,2097,2105,2120,2155,2189,2204,2220],{"__ignoreMap":416},[420,2075,2076,2078,2080,2083,2085,2087,2089,2091],{"class":422,"line":423},[420,2077,489],{"class":488},[420,2079,493],{"class":492},[420,2081,2082],{"class":496}," audit",[420,2084,511],{"class":492},[420,2086,514],{"class":488},[420,2088,517],{"class":492},[420,2090,520],{"class":430},[420,2092,523],{"class":492},[420,2094,2095],{"class":422,"line":526},[420,2096,572],{"emptyLinePlaceholder":571},[420,2098,2099,2101,2103],{"class":422,"line":547},[420,2100,325],{"class":584},[420,2102,588],{"class":496},[420,2104,911],{"class":492},[420,2106,2107,2110,2112,2114,2116,2118],{"class":422,"line":568},[420,2108,2109],{"class":623},"  action",[420,2111,716],{"class":492},[420,2113,517],{"class":492},[420,2115,923],{"class":430},[420,2117,626],{"class":492},[420,2119,750],{"class":492},[420,2121,2122,2125,2127,2129,2131,2133,2135,2138,2140,2142,2144,2146,2148,2151,2153],{"class":422,"line":575},[420,2123,2124],{"class":623},"  actor",[420,2126,716],{"class":492},[420,2128,493],{"class":492},[420,2130,939],{"class":623},[420,2132,716],{"class":492},[420,2134,517],{"class":492},[420,2136,2137],{"class":430},"system",[420,2139,626],{"class":492},[420,2141,500],{"class":492},[420,2143,953],{"class":623},[420,2145,716],{"class":492},[420,2147,517],{"class":492},[420,2149,2150],{"class":430},"billing-worker",[420,2152,626],{"class":492},[420,2154,768],{"class":492},[420,2156,2157,2160,2162,2164,2166,2168,2170,2172,2174,2176,2178,2180,2182,2185,2187],{"class":422,"line":607},[420,2158,2159],{"class":623},"  target",[420,2161,716],{"class":492},[420,2163,493],{"class":492},[420,2165,939],{"class":623},[420,2167,716],{"class":492},[420,2169,517],{"class":492},[420,2171,995],{"class":430},[420,2173,626],{"class":492},[420,2175,500],{"class":492},[420,2177,953],{"class":623},[420,2179,716],{"class":492},[420,2181,517],{"class":492},[420,2183,2184],{"class":430},"inv_889",[420,2186,626],{"class":492},[420,2188,768],{"class":492},[420,2190,2191,2194,2196,2198,2200,2202],{"class":422,"line":641},[420,2192,2193],{"class":623},"  outcome",[420,2195,716],{"class":492},[420,2197,517],{"class":492},[420,2199,1023],{"class":430},[420,2201,626],{"class":492},[420,2203,750],{"class":492},[420,2205,2206,2209,2211,2213,2216,2218],{"class":422,"line":669},[420,2207,2208],{"class":623},"  reason",[420,2210,716],{"class":492},[420,2212,517],{"class":492},[420,2214,2215],{"class":430},"Auto-refund triggered by chargeback webhook",[420,2217,626],{"class":492},[420,2219,750],{"class":492},[420,2221,2222,2224],{"class":422,"line":697},[420,2223,780],{"class":492},[420,2225,783],{"class":496},[410,2227,2231],{"className":2228,"code":2229,"filename":2230,"language":1362,"meta":416,"style":416},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"level\": \"info\",\n  \"service\": \"billing-api\",\n  \"method\": \"POST\",\n  \"path\": \"\u002Fapi\u002Finvoices\u002Finv_889\u002Frefund\",\n  \"status\": 200,\n  \"duration\": \"84ms\",\n  \"requestId\": \"a566ef91-7765-4f59-b6f0-b9f40ce71599\",\n  \"audit\": {\n    \"action\": \"invoice.refund\",\n    \"actor\": { \"type\": \"user\", \"id\": \"usr_42\", \"email\": \"demo@example.com\" },\n    \"target\": { \"type\": \"invoice\", \"id\": \"inv_889\" },\n    \"outcome\": \"success\",\n    \"reason\": \"Customer requested refund\",\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_8f3c4b2a1e5d6f7c\",\n    \"context\": {\n      \"requestId\": \"a566ef91-7765-4f59-b6f0-b9f40ce71599\",\n      \"ip\": \"203.0.113.7\",\n      \"userAgent\": \"Mozilla\u002F5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit\u002F537.36\"\n    }\n  }\n}\n","Output — wide event",[323,2232,2233,2237,2260,2280,2300,2320,2337,2357,2377,2389,2409,2473,2518,2537,2556,2572,2592,2605,2624,2644,2663,2669,2675],{"__ignoreMap":416},[420,2234,2235],{"class":422,"line":423},[420,2236,911],{"class":492},[420,2238,2239,2242,2245,2248,2250,2253,2256,2258],{"class":422,"line":526},[420,2240,2241],{"class":492},"  \"",[420,2243,2244],{"class":600},"level",[420,2246,2247],{"class":492},"\"",[420,2249,716],{"class":492},[420,2251,2252],{"class":492}," \"",[420,2254,2255],{"class":430},"info",[420,2257,2247],{"class":492},[420,2259,750],{"class":492},[420,2261,2262,2264,2267,2269,2271,2273,2276,2278],{"class":422,"line":547},[420,2263,2241],{"class":492},[420,2265,2266],{"class":600},"service",[420,2268,2247],{"class":492},[420,2270,716],{"class":492},[420,2272,2252],{"class":492},[420,2274,2275],{"class":430},"billing-api",[420,2277,2247],{"class":492},[420,2279,750],{"class":492},[420,2281,2282,2284,2287,2289,2291,2293,2296,2298],{"class":422,"line":568},[420,2283,2241],{"class":492},[420,2285,2286],{"class":600},"method",[420,2288,2247],{"class":492},[420,2290,716],{"class":492},[420,2292,2252],{"class":492},[420,2294,2295],{"class":430},"POST",[420,2297,2247],{"class":492},[420,2299,750],{"class":492},[420,2301,2302,2304,2307,2309,2311,2313,2316,2318],{"class":422,"line":575},[420,2303,2241],{"class":492},[420,2305,2306],{"class":600},"path",[420,2308,2247],{"class":492},[420,2310,716],{"class":492},[420,2312,2252],{"class":492},[420,2314,2315],{"class":430},"\u002Fapi\u002Finvoices\u002Finv_889\u002Frefund",[420,2317,2247],{"class":492},[420,2319,750],{"class":492},[420,2321,2322,2324,2327,2329,2331,2335],{"class":422,"line":607},[420,2323,2241],{"class":492},[420,2325,2326],{"class":600},"status",[420,2328,2247],{"class":492},[420,2330,716],{"class":492},[420,2332,2334],{"class":2333},"sbssI"," 200",[420,2336,750],{"class":492},[420,2338,2339,2341,2344,2346,2348,2350,2353,2355],{"class":422,"line":641},[420,2340,2241],{"class":492},[420,2342,2343],{"class":600},"duration",[420,2345,2247],{"class":492},[420,2347,716],{"class":492},[420,2349,2252],{"class":492},[420,2351,2352],{"class":430},"84ms",[420,2354,2247],{"class":492},[420,2356,750],{"class":492},[420,2358,2359,2361,2364,2366,2368,2370,2373,2375],{"class":422,"line":669},[420,2360,2241],{"class":492},[420,2362,2363],{"class":600},"requestId",[420,2365,2247],{"class":492},[420,2367,716],{"class":492},[420,2369,2252],{"class":492},[420,2371,2372],{"class":430},"a566ef91-7765-4f59-b6f0-b9f40ce71599",[420,2374,2247],{"class":492},[420,2376,750],{"class":492},[420,2378,2379,2381,2383,2385,2387],{"class":422,"line":697},[420,2380,2241],{"class":492},[420,2382,325],{"class":600},[420,2384,2247],{"class":492},[420,2386,716],{"class":492},[420,2388,604],{"class":492},[420,2390,2391,2394,2397,2399,2401,2403,2405,2407],{"class":422,"line":753},[420,2392,2393],{"class":492},"    \"",[420,2395,2396],{"class":426},"action",[420,2398,2247],{"class":492},[420,2400,716],{"class":492},[420,2402,2252],{"class":492},[420,2404,923],{"class":430},[420,2406,2247],{"class":492},[420,2408,750],{"class":492},[420,2410,2411,2413,2416,2418,2420,2422,2424,2427,2429,2431,2433,2435,2437,2439,2441,2443,2445,2447,2449,2452,2454,2456,2458,2460,2462,2464,2466,2469,2471],{"class":422,"line":771},[420,2412,2393],{"class":492},[420,2414,2415],{"class":426},"actor",[420,2417,2247],{"class":492},[420,2419,716],{"class":492},[420,2421,493],{"class":492},[420,2423,2252],{"class":492},[420,2425,2426],{"class":2333},"type",[420,2428,2247],{"class":492},[420,2430,716],{"class":492},[420,2432,2252],{"class":492},[420,2434,946],{"class":430},[420,2436,2247],{"class":492},[420,2438,500],{"class":492},[420,2440,2252],{"class":492},[420,2442,888],{"class":2333},[420,2444,2247],{"class":492},[420,2446,716],{"class":492},[420,2448,2252],{"class":492},[420,2450,2451],{"class":430},"usr_42",[420,2453,2247],{"class":492},[420,2455,500],{"class":492},[420,2457,2252],{"class":492},[420,2459,975],{"class":2333},[420,2461,2247],{"class":492},[420,2463,716],{"class":492},[420,2465,2252],{"class":492},[420,2467,2468],{"class":430},"demo@example.com",[420,2470,2247],{"class":492},[420,2472,768],{"class":492},[420,2474,2475,2477,2480,2482,2484,2486,2488,2490,2492,2494,2496,2498,2500,2502,2504,2506,2508,2510,2512,2514,2516],{"class":422,"line":777},[420,2476,2393],{"class":492},[420,2478,2479],{"class":426},"target",[420,2481,2247],{"class":492},[420,2483,716],{"class":492},[420,2485,493],{"class":492},[420,2487,2252],{"class":492},[420,2489,2426],{"class":2333},[420,2491,2247],{"class":492},[420,2493,716],{"class":492},[420,2495,2252],{"class":492},[420,2497,995],{"class":430},[420,2499,2247],{"class":492},[420,2501,500],{"class":492},[420,2503,2252],{"class":492},[420,2505,888],{"class":2333},[420,2507,2247],{"class":492},[420,2509,716],{"class":492},[420,2511,2252],{"class":492},[420,2513,2184],{"class":430},[420,2515,2247],{"class":492},[420,2517,768],{"class":492},[420,2519,2520,2522,2525,2527,2529,2531,2533,2535],{"class":422,"line":1053},[420,2521,2393],{"class":492},[420,2523,2524],{"class":426},"outcome",[420,2526,2247],{"class":492},[420,2528,716],{"class":492},[420,2530,2252],{"class":492},[420,2532,1023],{"class":430},[420,2534,2247],{"class":492},[420,2536,750],{"class":492},[420,2538,2539,2541,2544,2546,2548,2550,2552,2554],{"class":422,"line":1058},[420,2540,2393],{"class":492},[420,2542,2543],{"class":426},"reason",[420,2545,2247],{"class":492},[420,2547,716],{"class":492},[420,2549,2252],{"class":492},[420,2551,1039],{"class":430},[420,2553,2247],{"class":492},[420,2555,750],{"class":492},[420,2557,2558,2560,2563,2565,2567,2570],{"class":422,"line":1076},[420,2559,2393],{"class":492},[420,2561,2562],{"class":426},"version",[420,2564,2247],{"class":492},[420,2566,716],{"class":492},[420,2568,2569],{"class":2333}," 1",[420,2571,750],{"class":492},[420,2573,2574,2576,2579,2581,2583,2585,2588,2590],{"class":422,"line":1352},[420,2575,2393],{"class":492},[420,2577,2578],{"class":426},"idempotencyKey",[420,2580,2247],{"class":492},[420,2582,716],{"class":492},[420,2584,2252],{"class":492},[420,2586,2587],{"class":430},"ak_8f3c4b2a1e5d6f7c",[420,2589,2247],{"class":492},[420,2591,750],{"class":492},[420,2593,2594,2596,2599,2601,2603],{"class":422,"line":1379},[420,2595,2393],{"class":492},[420,2597,2598],{"class":426},"context",[420,2600,2247],{"class":492},[420,2602,716],{"class":492},[420,2604,604],{"class":492},[420,2606,2607,2610,2612,2614,2616,2618,2620,2622],{"class":422,"line":1722},[420,2608,2609],{"class":492},"      \"",[420,2611,2363],{"class":2333},[420,2613,2247],{"class":492},[420,2615,716],{"class":492},[420,2617,2252],{"class":492},[420,2619,2372],{"class":430},[420,2621,2247],{"class":492},[420,2623,750],{"class":492},[420,2625,2626,2628,2631,2633,2635,2637,2640,2642],{"class":422,"line":1727},[420,2627,2609],{"class":492},[420,2629,2630],{"class":2333},"ip",[420,2632,2247],{"class":492},[420,2634,716],{"class":492},[420,2636,2252],{"class":492},[420,2638,2639],{"class":430},"203.0.113.7",[420,2641,2247],{"class":492},[420,2643,750],{"class":492},[420,2645,2646,2648,2651,2653,2655,2657,2660],{"class":422,"line":1752},[420,2647,2609],{"class":492},[420,2649,2650],{"class":2333},"userAgent",[420,2652,2247],{"class":492},[420,2654,716],{"class":492},[420,2656,2252],{"class":492},[420,2658,2659],{"class":430},"Mozilla\u002F5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit\u002F537.36",[420,2661,2662],{"class":492},"\"\n",[420,2664,2666],{"class":422,"line":2665},21,[420,2667,2668],{"class":492},"    }\n",[420,2670,2672],{"class":422,"line":2671},22,[420,2673,2674],{"class":492},"  }\n",[420,2676,2678],{"class":422,"line":2677},23,[420,2679,2680],{"class":492},"}\n",[314,2682,2683],{},"That's it. The audit event:",[340,2685,2686,2689,2696,2703],{},[343,2687,2688],{},"Travels through the same wide-event pipeline as the rest of your logs.",[343,2690,2691,2692,2695],{},"Is ",[318,2693,2694],{},"always kept"," past tail sampling.",[343,2697,2698,2699,2702],{},"Goes to your main drain (Axiom) ",[318,2700,2701],{},"and"," to a dedicated, signed, append-only sink (FS journal).",[343,2704,2705,2706,447,2708,447,2711,2713,2714,2716,2717,330],{},"Carries ",[323,2707,2363],{},[323,2709,2710],{},"traceId",[323,2712,2630],{},", and ",[323,2715,2650],{}," automatically via ",[323,2718,2719],{},"auditEnricher",[463,2721,2722,2725,2726,2729],{},[318,2723,2724],{},"Why two drains?"," The main drain (Axiom, Datadog, ...) keeps audits next to the rest of your telemetry so dashboards and queries still work. The signed sink is your insurance: if the main drain has an outage, gets purged, or an admin quietly removes a row, the FS journal still holds the chain. Auditors want both — fast querying ",[2727,2728,2701],"em",{}," a tamper-evident artefact.",[379,2731,2733],{"id":2732},"the-audit-schema","The Audit Schema",[314,2735,2736,2739,2740,330],{},[323,2737,2738],{},"event.audit"," is a typed field on every wide event. Downstream queries filter on ",[323,2741,2742],{},"audit IS NOT NULL",[410,2744,2746],{"className":478,"code":2745,"language":481,"meta":416,"style":416},"interface AuditFields {\n  action: string                          \u002F\u002F 'invoice.refund'\n  actor: {\n    type: 'user' | 'system' | 'api' | 'agent'\n    id: string\n    displayName?: string\n    email?: string\n    \u002F\u002F For type === 'agent', mirrors evlog\u002Fai fields:\n    model?: string\n    tools?: string[]\n    reason?: string\n    promptId?: string\n  }\n  target?: { type: string, id: string, [k: string]: unknown }\n  outcome: 'success' | 'failure' | 'denied'\n  reason?: string\n  changes?: { before?: unknown, after?: unknown }\n  causationId?: string                    \u002F\u002F ID of the action that caused this one\n  correlationId?: string                  \u002F\u002F Shared by every action in one operation\n  version?: number                        \u002F\u002F Defaults to 1\n  idempotencyKey?: string                 \u002F\u002F Auto-derived; safe retries across drains\n  context?: {                             \u002F\u002F Filled by auditEnricher\n    requestId?: string\n    traceId?: string\n    ip?: string\n    userAgent?: string\n    tenantId?: string\n  }\n  signature?: string                      \u002F\u002F Set by signed({ strategy: 'hmac' })\n  prevHash?: string                       \u002F\u002F Set by signed({ strategy: 'hash-chain' })\n  hash?: string\n}\n",[323,2747,2748,2758,2771,2779,2819,2829,2839,2848,2853,2862,2874,2882,2891,2895,2939,2969,2977,3004,3016,3028,3041,3053,3065,3074,3084,3094,3104,3114,3119,3132,3145,3155],{"__ignoreMap":416},[420,2749,2750,2753,2756],{"class":422,"line":423},[420,2751,2752],{"class":600},"interface",[420,2754,2755],{"class":426}," AuditFields",[420,2757,604],{"class":492},[420,2759,2760,2762,2764,2767],{"class":422,"line":526},[420,2761,2109],{"class":623},[420,2763,716],{"class":492},[420,2765,2766],{"class":426}," string",[420,2768,2770],{"class":2769},"sHwdD","                          \u002F\u002F 'invoice.refund'\n",[420,2772,2773,2775,2777],{"class":422,"line":547},[420,2774,2124],{"class":623},[420,2776,716],{"class":492},[420,2778,604],{"class":492},[420,2780,2781,2784,2786,2788,2790,2792,2795,2797,2799,2801,2803,2805,2808,2810,2812,2814,2817],{"class":422,"line":568},[420,2782,2783],{"class":623},"    type",[420,2785,716],{"class":492},[420,2787,517],{"class":492},[420,2789,946],{"class":430},[420,2791,626],{"class":492},[420,2793,2794],{"class":492}," |",[420,2796,517],{"class":492},[420,2798,2137],{"class":430},[420,2800,626],{"class":492},[420,2802,2794],{"class":492},[420,2804,517],{"class":492},[420,2806,2807],{"class":430},"api",[420,2809,626],{"class":492},[420,2811,2794],{"class":492},[420,2813,517],{"class":492},[420,2815,2816],{"class":430},"agent",[420,2818,523],{"class":492},[420,2820,2821,2824,2826],{"class":422,"line":575},[420,2822,2823],{"class":623},"    id",[420,2825,716],{"class":492},[420,2827,2828],{"class":426}," string\n",[420,2830,2831,2834,2837],{"class":422,"line":607},[420,2832,2833],{"class":623},"    displayName",[420,2835,2836],{"class":492},"?:",[420,2838,2828],{"class":426},[420,2840,2841,2844,2846],{"class":422,"line":641},[420,2842,2843],{"class":623},"    email",[420,2845,2836],{"class":492},[420,2847,2828],{"class":426},[420,2849,2850],{"class":422,"line":669},[420,2851,2852],{"class":2769},"    \u002F\u002F For type === 'agent', mirrors evlog\u002Fai fields:\n",[420,2854,2855,2858,2860],{"class":422,"line":697},[420,2856,2857],{"class":623},"    model",[420,2859,2836],{"class":492},[420,2861,2828],{"class":426},[420,2863,2864,2867,2869,2871],{"class":422,"line":753},[420,2865,2866],{"class":623},"    tools",[420,2868,2836],{"class":492},[420,2870,2766],{"class":426},[420,2872,2873],{"class":496},"[]\n",[420,2875,2876,2878,2880],{"class":422,"line":771},[420,2877,1032],{"class":623},[420,2879,2836],{"class":492},[420,2881,2828],{"class":426},[420,2883,2884,2887,2889],{"class":422,"line":777},[420,2885,2886],{"class":623},"    promptId",[420,2888,2836],{"class":492},[420,2890,2828],{"class":426},[420,2892,2893],{"class":422,"line":1053},[420,2894,2674],{"class":492},[420,2896,2897,2899,2901,2903,2905,2907,2909,2911,2913,2915,2917,2919,2922,2925,2927,2929,2932,2934,2937],{"class":422,"line":1058},[420,2898,2159],{"class":623},[420,2900,2836],{"class":492},[420,2902,493],{"class":492},[420,2904,939],{"class":623},[420,2906,716],{"class":492},[420,2908,2766],{"class":426},[420,2910,500],{"class":492},[420,2912,953],{"class":623},[420,2914,716],{"class":492},[420,2916,2766],{"class":426},[420,2918,500],{"class":492},[420,2920,2921],{"class":496}," [",[420,2923,2924],{"class":593},"k",[420,2926,716],{"class":492},[420,2928,2766],{"class":426},[420,2930,2931],{"class":496},"]",[420,2933,716],{"class":492},[420,2935,2936],{"class":426}," unknown",[420,2938,1073],{"class":492},[420,2940,2941,2943,2945,2947,2949,2951,2953,2955,2958,2960,2962,2964,2967],{"class":422,"line":1076},[420,2942,2193],{"class":623},[420,2944,716],{"class":492},[420,2946,517],{"class":492},[420,2948,1023],{"class":430},[420,2950,626],{"class":492},[420,2952,2794],{"class":492},[420,2954,517],{"class":492},[420,2956,2957],{"class":430},"failure",[420,2959,626],{"class":492},[420,2961,2794],{"class":492},[420,2963,517],{"class":492},[420,2965,2966],{"class":430},"denied",[420,2968,523],{"class":492},[420,2970,2971,2973,2975],{"class":422,"line":1352},[420,2972,2208],{"class":623},[420,2974,2836],{"class":492},[420,2976,2828],{"class":426},[420,2978,2979,2982,2984,2986,2989,2991,2993,2995,2998,3000,3002],{"class":422,"line":1379},[420,2980,2981],{"class":623},"  changes",[420,2983,2836],{"class":492},[420,2985,493],{"class":492},[420,2987,2988],{"class":623}," before",[420,2990,2836],{"class":492},[420,2992,2936],{"class":426},[420,2994,500],{"class":492},[420,2996,2997],{"class":623}," after",[420,2999,2836],{"class":492},[420,3001,2936],{"class":426},[420,3003,1073],{"class":492},[420,3005,3006,3009,3011,3013],{"class":422,"line":1722},[420,3007,3008],{"class":623},"  causationId",[420,3010,2836],{"class":492},[420,3012,2766],{"class":426},[420,3014,3015],{"class":2769},"                    \u002F\u002F ID of the action that caused this one\n",[420,3017,3018,3021,3023,3025],{"class":422,"line":1727},[420,3019,3020],{"class":623},"  correlationId",[420,3022,2836],{"class":492},[420,3024,2766],{"class":426},[420,3026,3027],{"class":2769},"                  \u002F\u002F Shared by every action in one operation\n",[420,3029,3030,3033,3035,3038],{"class":422,"line":1752},[420,3031,3032],{"class":623},"  version",[420,3034,2836],{"class":492},[420,3036,3037],{"class":426}," number",[420,3039,3040],{"class":2769},"                        \u002F\u002F Defaults to 1\n",[420,3042,3043,3046,3048,3050],{"class":422,"line":2665},[420,3044,3045],{"class":623},"  idempotencyKey",[420,3047,2836],{"class":492},[420,3049,2766],{"class":426},[420,3051,3052],{"class":2769},"                 \u002F\u002F Auto-derived; safe retries across drains\n",[420,3054,3055,3058,3060,3062],{"class":422,"line":2671},[420,3056,3057],{"class":623},"  context",[420,3059,2836],{"class":492},[420,3061,493],{"class":492},[420,3063,3064],{"class":2769},"                             \u002F\u002F Filled by auditEnricher\n",[420,3066,3067,3070,3072],{"class":422,"line":2677},[420,3068,3069],{"class":623},"    requestId",[420,3071,2836],{"class":492},[420,3073,2828],{"class":426},[420,3075,3077,3080,3082],{"class":422,"line":3076},24,[420,3078,3079],{"class":623},"    traceId",[420,3081,2836],{"class":492},[420,3083,2828],{"class":426},[420,3085,3087,3090,3092],{"class":422,"line":3086},25,[420,3088,3089],{"class":623},"    ip",[420,3091,2836],{"class":492},[420,3093,2828],{"class":426},[420,3095,3097,3100,3102],{"class":422,"line":3096},26,[420,3098,3099],{"class":623},"    userAgent",[420,3101,2836],{"class":492},[420,3103,2828],{"class":426},[420,3105,3107,3110,3112],{"class":422,"line":3106},27,[420,3108,3109],{"class":623},"    tenantId",[420,3111,2836],{"class":492},[420,3113,2828],{"class":426},[420,3115,3117],{"class":422,"line":3116},28,[420,3118,2674],{"class":492},[420,3120,3122,3125,3127,3129],{"class":422,"line":3121},29,[420,3123,3124],{"class":623},"  signature",[420,3126,2836],{"class":492},[420,3128,2766],{"class":426},[420,3130,3131],{"class":2769},"                      \u002F\u002F Set by signed({ strategy: 'hmac' })\n",[420,3133,3135,3138,3140,3142],{"class":422,"line":3134},30,[420,3136,3137],{"class":623},"  prevHash",[420,3139,2836],{"class":492},[420,3141,2766],{"class":426},[420,3143,3144],{"class":2769},"                       \u002F\u002F Set by signed({ strategy: 'hash-chain' })\n",[420,3146,3148,3151,3153],{"class":422,"line":3147},31,[420,3149,3150],{"class":623},"  hash",[420,3152,2836],{"class":492},[420,3154,2828],{"class":426},[420,3156,3158],{"class":422,"line":3157},32,[420,3159,2680],{"class":492},[463,3161,3162,3167,3168,809,3171,447,3173,447,3176,3179,3180,3183,3184,3187,3188,3190],{},[318,3163,3164,3165,330],{},"Naming convention for ",[323,3166,2396],{}," Use ",[323,3169,3170],{},"noun.verb",[323,3172,923],{},[323,3174,3175],{},"user.invite",[323,3177,3178],{},"apiKey.revoke","). Past tense if the action already happened (",[323,3181,3182],{},"invoice.refunded","), present tense if ",[323,3185,3186],{},"withAudit()"," will resolve the outcome. Keep a small fixed dictionary in one file — auditors and SIEM rules query on ",[323,3189,2396],{},", so a typo is a missing alert.",[3192,3193,3194,3167,3197,3200,3201,3204,3205,3208,3209,3212],"warning",{},[318,3195,3196],{},"Don't fake the actor.",[323,3198,3199],{},"actor.type: 'system'"," for cron jobs, queue workers, and background tasks; ",[323,3202,3203],{},"actor.type: 'api'"," for machine-to-machine calls authenticated by a token; ",[323,3206,3207],{},"actor.type: 'agent'"," for AI tool calls. Logging a synthetic ",[323,3210,3211],{},"'user'"," for system actions is the single fastest way to fail an audit review.",[379,3214,3216],{"id":3215},"composition","Composition",[314,3218,3219,3220,3223],{},"Each layer is ",[318,3221,3222],{},"opt-in and replaceable",". Visually, the path of an audit event through your pipeline looks like this:",[410,3225,3230],{"className":3226,"code":3228,"language":3229,"meta":416},[3227],"language-text","  log.audit \u002F audit \u002F withAudit\n              │\n              ▼\n       set event.audit\n              │\n              ▼\n    force-keep tail-sample\n              │\n              ▼\n        auditEnricher\n              │\n              ▼\n   redact + auditRedactPreset\n              │\n   ┌──────────┴──────────┐\n   ▼                     ▼\n main drain         auditOnly(\n (Axiom \u002F            signed(\n  Datadog \u002F          fsDrain))\n  ...)\n","text",[323,3231,3228],{"__ignoreMap":416},[314,3233,3234,3235,447,3237,2713,3239,3242,3243,3246],{},"Every node except ",[323,3236,398],{},[323,3238,2719],{},[323,3240,3241],{},"auditOnly","\u002F",[323,3244,3245],{},"signed"," is shared with regular wide events.",[3248,3249,3251],"h3",{"id":3250},"helper","Helper",[314,3253,3254,3257,3258,3261],{},[323,3255,3256],{},"log.audit()"," is sugar over ",[323,3259,3260],{},"log.set({ audit: ... })"," plus tail-sample force-keep:",[410,3263,3265],{"className":478,"code":3264,"language":481,"meta":416,"style":416},"log.audit({\n  action: 'invoice.refund',\n  actor: { type: 'user', id: user.id },\n  target: { type: 'invoice', id: 'inv_889' },\n  outcome: 'success',\n})\n\n\u002F\u002F Strictly equivalent to:\nlog.set({ audit: { action: 'invoice.refund', \u002F* ... *\u002F, version: 1 } })\n",[323,3266,3267,3279,3293,3327,3359,3373,3379,3383,3388],{"__ignoreMap":416},[420,3268,3269,3271,3273,3275,3277],{"class":422,"line":423},[420,3270,1522],{"class":496},[420,3272,330],{"class":492},[420,3274,325],{"class":584},[420,3276,588],{"class":496},[420,3278,911],{"class":492},[420,3280,3281,3283,3285,3287,3289,3291],{"class":422,"line":526},[420,3282,2109],{"class":623},[420,3284,716],{"class":492},[420,3286,517],{"class":492},[420,3288,923],{"class":430},[420,3290,626],{"class":492},[420,3292,750],{"class":492},[420,3294,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313,3315,3317,3319,3321,3324],{"class":422,"line":547},[420,3296,2124],{"class":623},[420,3298,716],{"class":492},[420,3300,493],{"class":492},[420,3302,939],{"class":623},[420,3304,716],{"class":492},[420,3306,517],{"class":492},[420,3308,946],{"class":430},[420,3310,626],{"class":492},[420,3312,500],{"class":492},[420,3314,953],{"class":623},[420,3316,716],{"class":492},[420,3318,845],{"class":496},[420,3320,330],{"class":492},[420,3322,3323],{"class":496},"id ",[420,3325,3326],{"class":492},"},\n",[420,3328,3329,3331,3333,3335,3337,3339,3341,3343,3345,3347,3349,3351,3353,3355,3357],{"class":422,"line":568},[420,3330,2159],{"class":623},[420,3332,716],{"class":492},[420,3334,493],{"class":492},[420,3336,939],{"class":623},[420,3338,716],{"class":492},[420,3340,517],{"class":492},[420,3342,995],{"class":430},[420,3344,626],{"class":492},[420,3346,500],{"class":492},[420,3348,953],{"class":623},[420,3350,716],{"class":492},[420,3352,517],{"class":492},[420,3354,2184],{"class":430},[420,3356,626],{"class":492},[420,3358,768],{"class":492},[420,3360,3361,3363,3365,3367,3369,3371],{"class":422,"line":575},[420,3362,2193],{"class":623},[420,3364,716],{"class":492},[420,3366,517],{"class":492},[420,3368,1023],{"class":430},[420,3370,626],{"class":492},[420,3372,750],{"class":492},[420,3374,3375,3377],{"class":422,"line":607},[420,3376,780],{"class":492},[420,3378,783],{"class":496},[420,3380,3381],{"class":422,"line":641},[420,3382,572],{"emptyLinePlaceholder":571},[420,3384,3385],{"class":422,"line":669},[420,3386,3387],{"class":2769},"\u002F\u002F Strictly equivalent to:\n",[420,3389,3390,3392,3394,3397,3399,3401,3403,3405,3407,3410,3412,3414,3416,3418,3420,3423,3425,3428,3430,3432,3434,3436],{"class":422,"line":697},[420,3391,1522],{"class":496},[420,3393,330],{"class":492},[420,3395,3396],{"class":584},"set",[420,3398,588],{"class":496},[420,3400,710],{"class":492},[420,3402,2082],{"class":623},[420,3404,716],{"class":492},[420,3406,493],{"class":492},[420,3408,3409],{"class":623}," action",[420,3411,716],{"class":492},[420,3413,517],{"class":492},[420,3415,923],{"class":430},[420,3417,626],{"class":492},[420,3419,500],{"class":492},[420,3421,3422],{"class":2769}," \u002F* ... *\u002F",[420,3424,500],{"class":492},[420,3426,3427],{"class":623}," version",[420,3429,716],{"class":492},[420,3431,2569],{"class":2333},[420,3433,511],{"class":492},[420,3435,511],{"class":492},[420,3437,783],{"class":496},[314,3439,3440,3443],{},[323,3441,3442],{},"log.audit.deny(reason, fields)"," records AuthZ-denied actions — most teams forget to log denials, but they are exactly what auditors and security teams ask for:",[785,3445,3446,3626],{},[410,3447,3450],{"className":478,"code":3448,"filename":3449,"language":481,"meta":416,"style":416},"if (!user.canRefund(invoice)) {\n  log.audit.deny('Insufficient permissions', {\n    action: 'invoice.refund',\n    actor: { type: 'user', id: user.id },\n    target: { type: 'invoice', id: invoice.id },\n  })\n  throw createError({ status: 403, message: 'Forbidden' })\n}\n","Input",[323,3451,3452,3474,3500,3514,3546,3578,3584,3622],{"__ignoreMap":416},[420,3453,3454,3457,3459,3462,3464,3466,3469,3472],{"class":422,"line":423},[420,3455,3456],{"class":488},"if",[420,3458,809],{"class":496},[420,3460,3461],{"class":492},"!",[420,3463,946],{"class":496},[420,3465,330],{"class":492},[420,3467,3468],{"class":584},"canRefund",[420,3470,3471],{"class":496},"(invoice)) ",[420,3473,911],{"class":492},[420,3475,3476,3478,3480,3482,3484,3487,3489,3491,3494,3496,3498],{"class":422,"line":526},[420,3477,902],{"class":496},[420,3479,330],{"class":492},[420,3481,325],{"class":496},[420,3483,330],{"class":492},[420,3485,3486],{"class":584},"deny",[420,3488,588],{"class":623},[420,3490,626],{"class":492},[420,3492,3493],{"class":430},"Insufficient permissions",[420,3495,626],{"class":492},[420,3497,500],{"class":492},[420,3499,604],{"class":492},[420,3501,3502,3504,3506,3508,3510,3512],{"class":422,"line":547},[420,3503,916],{"class":623},[420,3505,716],{"class":492},[420,3507,517],{"class":492},[420,3509,923],{"class":430},[420,3511,626],{"class":492},[420,3513,750],{"class":492},[420,3515,3516,3518,3520,3522,3524,3526,3528,3530,3532,3534,3536,3538,3540,3542,3544],{"class":422,"line":568},[420,3517,932],{"class":623},[420,3519,716],{"class":492},[420,3521,493],{"class":492},[420,3523,939],{"class":623},[420,3525,716],{"class":492},[420,3527,517],{"class":492},[420,3529,946],{"class":430},[420,3531,626],{"class":492},[420,3533,500],{"class":492},[420,3535,953],{"class":623},[420,3537,716],{"class":492},[420,3539,845],{"class":496},[420,3541,330],{"class":492},[420,3543,888],{"class":496},[420,3545,768],{"class":492},[420,3547,3548,3550,3552,3554,3556,3558,3560,3562,3564,3566,3568,3570,3572,3574,3576],{"class":422,"line":575},[420,3549,982],{"class":623},[420,3551,716],{"class":492},[420,3553,493],{"class":492},[420,3555,939],{"class":623},[420,3557,716],{"class":492},[420,3559,517],{"class":492},[420,3561,995],{"class":430},[420,3563,626],{"class":492},[420,3565,500],{"class":492},[420,3567,953],{"class":623},[420,3569,716],{"class":492},[420,3571,865],{"class":496},[420,3573,330],{"class":492},[420,3575,888],{"class":496},[420,3577,768],{"class":492},[420,3579,3580,3582],{"class":422,"line":607},[420,3581,1048],{"class":492},[420,3583,783],{"class":623},[420,3585,3586,3589,3592,3594,3596,3599,3601,3604,3606,3609,3611,3613,3616,3618,3620],{"class":422,"line":641},[420,3587,3588],{"class":488},"  throw",[420,3590,3591],{"class":584}," createError",[420,3593,588],{"class":623},[420,3595,710],{"class":492},[420,3597,3598],{"class":623}," status",[420,3600,716],{"class":492},[420,3602,3603],{"class":2333}," 403",[420,3605,500],{"class":492},[420,3607,3608],{"class":623}," message",[420,3610,716],{"class":492},[420,3612,517],{"class":492},[420,3614,3615],{"class":430},"Forbidden",[420,3617,626],{"class":492},[420,3619,511],{"class":492},[420,3621,783],{"class":623},[420,3623,3624],{"class":422,"line":669},[420,3625,2680],{"class":492},[410,3627,3630],{"className":2228,"code":3628,"filename":3629,"language":1362,"meta":416,"style":416},"{\n  \"level\": \"warn\",\n  \"service\": \"billing-api\",\n  \"method\": \"POST\",\n  \"path\": \"\u002Fapi\u002Finvoices\u002Finv_889\u002Frefund\",\n  \"status\": 403,\n  \"duration\": \"12ms\",\n  \"requestId\": \"9c3f7d12-8a45-4e60-b8a9-1f0d4c5e6e7d\",\n  \"audit\": {\n    \"action\": \"invoice.refund\",\n    \"actor\": { \"type\": \"user\", \"id\": \"usr_intruder\" },\n    \"target\": { \"type\": \"invoice\", \"id\": \"inv_889\" },\n    \"outcome\": \"denied\",\n    \"reason\": \"Insufficient permissions\",\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_d12c3a4f5b6e7d8c\",\n    \"context\": {\n      \"requestId\": \"9c3f7d12-8a45-4e60-b8a9-1f0d4c5e6e7d\",\n      \"ip\": \"203.0.113.7\"\n    }\n  }\n}\n","Output — denied",[323,3631,3632,3636,3655,3673,3691,3709,3723,3742,3761,3773,3791,3836,3880,3898,3916,3930,3949,3961,3979,3995,3999,4003],{"__ignoreMap":416},[420,3633,3634],{"class":422,"line":423},[420,3635,911],{"class":492},[420,3637,3638,3640,3642,3644,3646,3648,3651,3653],{"class":422,"line":526},[420,3639,2241],{"class":492},[420,3641,2244],{"class":600},[420,3643,2247],{"class":492},[420,3645,716],{"class":492},[420,3647,2252],{"class":492},[420,3649,3650],{"class":430},"warn",[420,3652,2247],{"class":492},[420,3654,750],{"class":492},[420,3656,3657,3659,3661,3663,3665,3667,3669,3671],{"class":422,"line":547},[420,3658,2241],{"class":492},[420,3660,2266],{"class":600},[420,3662,2247],{"class":492},[420,3664,716],{"class":492},[420,3666,2252],{"class":492},[420,3668,2275],{"class":430},[420,3670,2247],{"class":492},[420,3672,750],{"class":492},[420,3674,3675,3677,3679,3681,3683,3685,3687,3689],{"class":422,"line":568},[420,3676,2241],{"class":492},[420,3678,2286],{"class":600},[420,3680,2247],{"class":492},[420,3682,716],{"class":492},[420,3684,2252],{"class":492},[420,3686,2295],{"class":430},[420,3688,2247],{"class":492},[420,3690,750],{"class":492},[420,3692,3693,3695,3697,3699,3701,3703,3705,3707],{"class":422,"line":575},[420,3694,2241],{"class":492},[420,3696,2306],{"class":600},[420,3698,2247],{"class":492},[420,3700,716],{"class":492},[420,3702,2252],{"class":492},[420,3704,2315],{"class":430},[420,3706,2247],{"class":492},[420,3708,750],{"class":492},[420,3710,3711,3713,3715,3717,3719,3721],{"class":422,"line":607},[420,3712,2241],{"class":492},[420,3714,2326],{"class":600},[420,3716,2247],{"class":492},[420,3718,716],{"class":492},[420,3720,3603],{"class":2333},[420,3722,750],{"class":492},[420,3724,3725,3727,3729,3731,3733,3735,3738,3740],{"class":422,"line":641},[420,3726,2241],{"class":492},[420,3728,2343],{"class":600},[420,3730,2247],{"class":492},[420,3732,716],{"class":492},[420,3734,2252],{"class":492},[420,3736,3737],{"class":430},"12ms",[420,3739,2247],{"class":492},[420,3741,750],{"class":492},[420,3743,3744,3746,3748,3750,3752,3754,3757,3759],{"class":422,"line":669},[420,3745,2241],{"class":492},[420,3747,2363],{"class":600},[420,3749,2247],{"class":492},[420,3751,716],{"class":492},[420,3753,2252],{"class":492},[420,3755,3756],{"class":430},"9c3f7d12-8a45-4e60-b8a9-1f0d4c5e6e7d",[420,3758,2247],{"class":492},[420,3760,750],{"class":492},[420,3762,3763,3765,3767,3769,3771],{"class":422,"line":697},[420,3764,2241],{"class":492},[420,3766,325],{"class":600},[420,3768,2247],{"class":492},[420,3770,716],{"class":492},[420,3772,604],{"class":492},[420,3774,3775,3777,3779,3781,3783,3785,3787,3789],{"class":422,"line":753},[420,3776,2393],{"class":492},[420,3778,2396],{"class":426},[420,3780,2247],{"class":492},[420,3782,716],{"class":492},[420,3784,2252],{"class":492},[420,3786,923],{"class":430},[420,3788,2247],{"class":492},[420,3790,750],{"class":492},[420,3792,3793,3795,3797,3799,3801,3803,3805,3807,3809,3811,3813,3815,3817,3819,3821,3823,3825,3827,3829,3832,3834],{"class":422,"line":771},[420,3794,2393],{"class":492},[420,3796,2415],{"class":426},[420,3798,2247],{"class":492},[420,3800,716],{"class":492},[420,3802,493],{"class":492},[420,3804,2252],{"class":492},[420,3806,2426],{"class":2333},[420,3808,2247],{"class":492},[420,3810,716],{"class":492},[420,3812,2252],{"class":492},[420,3814,946],{"class":430},[420,3816,2247],{"class":492},[420,3818,500],{"class":492},[420,3820,2252],{"class":492},[420,3822,888],{"class":2333},[420,3824,2247],{"class":492},[420,3826,716],{"class":492},[420,3828,2252],{"class":492},[420,3830,3831],{"class":430},"usr_intruder",[420,3833,2247],{"class":492},[420,3835,768],{"class":492},[420,3837,3838,3840,3842,3844,3846,3848,3850,3852,3854,3856,3858,3860,3862,3864,3866,3868,3870,3872,3874,3876,3878],{"class":422,"line":777},[420,3839,2393],{"class":492},[420,3841,2479],{"class":426},[420,3843,2247],{"class":492},[420,3845,716],{"class":492},[420,3847,493],{"class":492},[420,3849,2252],{"class":492},[420,3851,2426],{"class":2333},[420,3853,2247],{"class":492},[420,3855,716],{"class":492},[420,3857,2252],{"class":492},[420,3859,995],{"class":430},[420,3861,2247],{"class":492},[420,3863,500],{"class":492},[420,3865,2252],{"class":492},[420,3867,888],{"class":2333},[420,3869,2247],{"class":492},[420,3871,716],{"class":492},[420,3873,2252],{"class":492},[420,3875,2184],{"class":430},[420,3877,2247],{"class":492},[420,3879,768],{"class":492},[420,3881,3882,3884,3886,3888,3890,3892,3894,3896],{"class":422,"line":1053},[420,3883,2393],{"class":492},[420,3885,2524],{"class":426},[420,3887,2247],{"class":492},[420,3889,716],{"class":492},[420,3891,2252],{"class":492},[420,3893,2966],{"class":430},[420,3895,2247],{"class":492},[420,3897,750],{"class":492},[420,3899,3900,3902,3904,3906,3908,3910,3912,3914],{"class":422,"line":1058},[420,3901,2393],{"class":492},[420,3903,2543],{"class":426},[420,3905,2247],{"class":492},[420,3907,716],{"class":492},[420,3909,2252],{"class":492},[420,3911,3493],{"class":430},[420,3913,2247],{"class":492},[420,3915,750],{"class":492},[420,3917,3918,3920,3922,3924,3926,3928],{"class":422,"line":1076},[420,3919,2393],{"class":492},[420,3921,2562],{"class":426},[420,3923,2247],{"class":492},[420,3925,716],{"class":492},[420,3927,2569],{"class":2333},[420,3929,750],{"class":492},[420,3931,3932,3934,3936,3938,3940,3942,3945,3947],{"class":422,"line":1352},[420,3933,2393],{"class":492},[420,3935,2578],{"class":426},[420,3937,2247],{"class":492},[420,3939,716],{"class":492},[420,3941,2252],{"class":492},[420,3943,3944],{"class":430},"ak_d12c3a4f5b6e7d8c",[420,3946,2247],{"class":492},[420,3948,750],{"class":492},[420,3950,3951,3953,3955,3957,3959],{"class":422,"line":1379},[420,3952,2393],{"class":492},[420,3954,2598],{"class":426},[420,3956,2247],{"class":492},[420,3958,716],{"class":492},[420,3960,604],{"class":492},[420,3962,3963,3965,3967,3969,3971,3973,3975,3977],{"class":422,"line":1722},[420,3964,2609],{"class":492},[420,3966,2363],{"class":2333},[420,3968,2247],{"class":492},[420,3970,716],{"class":492},[420,3972,2252],{"class":492},[420,3974,3756],{"class":430},[420,3976,2247],{"class":492},[420,3978,750],{"class":492},[420,3980,3981,3983,3985,3987,3989,3991,3993],{"class":422,"line":1727},[420,3982,2609],{"class":492},[420,3984,2630],{"class":2333},[420,3986,2247],{"class":492},[420,3988,716],{"class":492},[420,3990,2252],{"class":492},[420,3992,2639],{"class":430},[420,3994,2662],{"class":492},[420,3996,3997],{"class":422,"line":1752},[420,3998,2668],{"class":492},[420,4000,4001],{"class":422,"line":2665},[420,4002,2674],{"class":492},[420,4004,4005],{"class":422,"line":2671},[420,4006,2680],{"class":492},[314,4008,4009,4010,716],{},"For non-request contexts (jobs, scripts, CLIs), use the standalone ",[323,4011,4012],{},"audit()",[785,4014,4015,4153],{},[410,4016,4019],{"className":478,"code":4017,"filename":4018,"language":481,"meta":416,"style":416},"import { audit } from 'evlog'\n\naudit({\n  action: 'cron.cleanup',\n  actor: { type: 'system', id: 'cron' },\n  target: { type: 'job', id: 'cleanup-stale-sessions' },\n  outcome: 'success',\n})\n","scripts\u002Fcleanup.ts",[323,4020,4021,4039,4043,4051,4066,4099,4133,4147],{"__ignoreMap":416},[420,4022,4023,4025,4027,4029,4031,4033,4035,4037],{"class":422,"line":423},[420,4024,489],{"class":488},[420,4026,493],{"class":492},[420,4028,2082],{"class":496},[420,4030,511],{"class":492},[420,4032,514],{"class":488},[420,4034,517],{"class":492},[420,4036,520],{"class":430},[420,4038,523],{"class":492},[420,4040,4041],{"class":422,"line":526},[420,4042,572],{"emptyLinePlaceholder":571},[420,4044,4045,4047,4049],{"class":422,"line":547},[420,4046,325],{"class":584},[420,4048,588],{"class":496},[420,4050,911],{"class":492},[420,4052,4053,4055,4057,4059,4062,4064],{"class":422,"line":568},[420,4054,2109],{"class":623},[420,4056,716],{"class":492},[420,4058,517],{"class":492},[420,4060,4061],{"class":430},"cron.cleanup",[420,4063,626],{"class":492},[420,4065,750],{"class":492},[420,4067,4068,4070,4072,4074,4076,4078,4080,4082,4084,4086,4088,4090,4092,4095,4097],{"class":422,"line":575},[420,4069,2124],{"class":623},[420,4071,716],{"class":492},[420,4073,493],{"class":492},[420,4075,939],{"class":623},[420,4077,716],{"class":492},[420,4079,517],{"class":492},[420,4081,2137],{"class":430},[420,4083,626],{"class":492},[420,4085,500],{"class":492},[420,4087,953],{"class":623},[420,4089,716],{"class":492},[420,4091,517],{"class":492},[420,4093,4094],{"class":430},"cron",[420,4096,626],{"class":492},[420,4098,768],{"class":492},[420,4100,4101,4103,4105,4107,4109,4111,4113,4116,4118,4120,4122,4124,4126,4129,4131],{"class":422,"line":607},[420,4102,2159],{"class":623},[420,4104,716],{"class":492},[420,4106,493],{"class":492},[420,4108,939],{"class":623},[420,4110,716],{"class":492},[420,4112,517],{"class":492},[420,4114,4115],{"class":430},"job",[420,4117,626],{"class":492},[420,4119,500],{"class":492},[420,4121,953],{"class":623},[420,4123,716],{"class":492},[420,4125,517],{"class":492},[420,4127,4128],{"class":430},"cleanup-stale-sessions",[420,4130,626],{"class":492},[420,4132,768],{"class":492},[420,4134,4135,4137,4139,4141,4143,4145],{"class":422,"line":641},[420,4136,2193],{"class":623},[420,4138,716],{"class":492},[420,4140,517],{"class":492},[420,4142,1023],{"class":430},[420,4144,626],{"class":492},[420,4146,750],{"class":492},[420,4148,4149,4151],{"class":422,"line":669},[420,4150,780],{"class":492},[420,4152,783],{"class":496},[410,4154,4156],{"className":2228,"code":4155,"filename":2230,"language":1362,"meta":416,"style":416},"{\n  \"level\": \"info\",\n  \"service\": \"billing-api\",\n  \"audit\": {\n    \"action\": \"cron.cleanup\",\n    \"actor\": { \"type\": \"system\", \"id\": \"cron\" },\n    \"target\": { \"type\": \"job\", \"id\": \"cleanup-stale-sessions\" },\n    \"outcome\": \"success\",\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_2b8e1f9d4c6a7b3e\"\n  }\n}\n",[323,4157,4158,4162,4180,4198,4210,4228,4272,4316,4334,4348,4365,4369],{"__ignoreMap":416},[420,4159,4160],{"class":422,"line":423},[420,4161,911],{"class":492},[420,4163,4164,4166,4168,4170,4172,4174,4176,4178],{"class":422,"line":526},[420,4165,2241],{"class":492},[420,4167,2244],{"class":600},[420,4169,2247],{"class":492},[420,4171,716],{"class":492},[420,4173,2252],{"class":492},[420,4175,2255],{"class":430},[420,4177,2247],{"class":492},[420,4179,750],{"class":492},[420,4181,4182,4184,4186,4188,4190,4192,4194,4196],{"class":422,"line":547},[420,4183,2241],{"class":492},[420,4185,2266],{"class":600},[420,4187,2247],{"class":492},[420,4189,716],{"class":492},[420,4191,2252],{"class":492},[420,4193,2275],{"class":430},[420,4195,2247],{"class":492},[420,4197,750],{"class":492},[420,4199,4200,4202,4204,4206,4208],{"class":422,"line":568},[420,4201,2241],{"class":492},[420,4203,325],{"class":600},[420,4205,2247],{"class":492},[420,4207,716],{"class":492},[420,4209,604],{"class":492},[420,4211,4212,4214,4216,4218,4220,4222,4224,4226],{"class":422,"line":575},[420,4213,2393],{"class":492},[420,4215,2396],{"class":426},[420,4217,2247],{"class":492},[420,4219,716],{"class":492},[420,4221,2252],{"class":492},[420,4223,4061],{"class":430},[420,4225,2247],{"class":492},[420,4227,750],{"class":492},[420,4229,4230,4232,4234,4236,4238,4240,4242,4244,4246,4248,4250,4252,4254,4256,4258,4260,4262,4264,4266,4268,4270],{"class":422,"line":607},[420,4231,2393],{"class":492},[420,4233,2415],{"class":426},[420,4235,2247],{"class":492},[420,4237,716],{"class":492},[420,4239,493],{"class":492},[420,4241,2252],{"class":492},[420,4243,2426],{"class":2333},[420,4245,2247],{"class":492},[420,4247,716],{"class":492},[420,4249,2252],{"class":492},[420,4251,2137],{"class":430},[420,4253,2247],{"class":492},[420,4255,500],{"class":492},[420,4257,2252],{"class":492},[420,4259,888],{"class":2333},[420,4261,2247],{"class":492},[420,4263,716],{"class":492},[420,4265,2252],{"class":492},[420,4267,4094],{"class":430},[420,4269,2247],{"class":492},[420,4271,768],{"class":492},[420,4273,4274,4276,4278,4280,4282,4284,4286,4288,4290,4292,4294,4296,4298,4300,4302,4304,4306,4308,4310,4312,4314],{"class":422,"line":641},[420,4275,2393],{"class":492},[420,4277,2479],{"class":426},[420,4279,2247],{"class":492},[420,4281,716],{"class":492},[420,4283,493],{"class":492},[420,4285,2252],{"class":492},[420,4287,2426],{"class":2333},[420,4289,2247],{"class":492},[420,4291,716],{"class":492},[420,4293,2252],{"class":492},[420,4295,4115],{"class":430},[420,4297,2247],{"class":492},[420,4299,500],{"class":492},[420,4301,2252],{"class":492},[420,4303,888],{"class":2333},[420,4305,2247],{"class":492},[420,4307,716],{"class":492},[420,4309,2252],{"class":492},[420,4311,4128],{"class":430},[420,4313,2247],{"class":492},[420,4315,768],{"class":492},[420,4317,4318,4320,4322,4324,4326,4328,4330,4332],{"class":422,"line":669},[420,4319,2393],{"class":492},[420,4321,2524],{"class":426},[420,4323,2247],{"class":492},[420,4325,716],{"class":492},[420,4327,2252],{"class":492},[420,4329,1023],{"class":430},[420,4331,2247],{"class":492},[420,4333,750],{"class":492},[420,4335,4336,4338,4340,4342,4344,4346],{"class":422,"line":697},[420,4337,2393],{"class":492},[420,4339,2562],{"class":426},[420,4341,2247],{"class":492},[420,4343,716],{"class":492},[420,4345,2569],{"class":2333},[420,4347,750],{"class":492},[420,4349,4350,4352,4354,4356,4358,4360,4363],{"class":422,"line":753},[420,4351,2393],{"class":492},[420,4353,2578],{"class":426},[420,4355,2247],{"class":492},[420,4357,716],{"class":492},[420,4359,2252],{"class":492},[420,4361,4362],{"class":430},"ak_2b8e1f9d4c6a7b3e",[420,4364,2662],{"class":492},[420,4366,4367],{"class":422,"line":771},[420,4368,2674],{"class":492},[420,4370,4371],{"class":422,"line":777},[420,4372,2680],{"class":492},[4374,4375,4376,4377,4379,4380,4382,4383,4382,4386,4388,4389,4392],"note",{},"Standalone ",[323,4378,4012],{}," events have no ",[323,4381,2363],{},", no ",[323,4384,4385],{},"context.ip",[323,4387,2650],{}," — there is no request to enrich from. Add your own context manually (",[323,4390,4391],{},"context: { jobId, queue, runId }",") when it matters for forensics.",[3248,4394,4396],{"id":4395},"enricher","Enricher",[314,4398,4399,4402,4403,4406],{},[323,4400,4401],{},"auditEnricher()"," populates ",[323,4404,4405],{},"event.audit.context.{requestId, traceId, ip, userAgent, tenantId}",". Skip it and ship a custom enricher if your strategy differs.",[410,4408,4410],{"className":478,"code":4409,"language":481,"meta":416,"style":416},"nitro.hooks.hook('evlog:enrich', auditEnricher({\n  tenantId: ctx => ctx.event.tenant as string | undefined,\n  bridge: { getSession: async ctx => readSessionActor(ctx.headers) },\n}))\n",[323,4411,4412,4440,4475,4508],{"__ignoreMap":416},[420,4413,4414,4416,4418,4420,4422,4424,4426,4428,4430,4432,4434,4436,4438],{"class":422,"line":423},[420,4415,594],{"class":496},[420,4417,330],{"class":492},[420,4419,615],{"class":496},[420,4421,330],{"class":492},[420,4423,620],{"class":584},[420,4425,588],{"class":496},[420,4427,626],{"class":492},[420,4429,629],{"class":430},[420,4431,626],{"class":492},[420,4433,500],{"class":492},[420,4435,497],{"class":584},[420,4437,588],{"class":496},[420,4439,911],{"class":492},[420,4441,4442,4445,4447,4450,4452,4454,4456,4458,4460,4463,4466,4468,4470,4473],{"class":422,"line":526},[420,4443,4444],{"class":584},"  tenantId",[420,4446,716],{"class":492},[420,4448,4449],{"class":593}," ctx",[420,4451,601],{"class":600},[420,4453,4449],{"class":496},[420,4455,330],{"class":492},[420,4457,812],{"class":496},[420,4459,330],{"class":492},[420,4461,4462],{"class":496},"tenant ",[420,4464,4465],{"class":488},"as",[420,4467,2766],{"class":426},[420,4469,2794],{"class":492},[420,4471,4472],{"class":426}," undefined",[420,4474,750],{"class":492},[420,4476,4477,4480,4482,4484,4487,4489,4491,4493,4495,4498,4501,4503,4506],{"class":422,"line":547},[420,4478,4479],{"class":623},"  bridge",[420,4481,716],{"class":492},[420,4483,493],{"class":492},[420,4485,4486],{"class":584}," getSession",[420,4488,716],{"class":492},[420,4490,1488],{"class":600},[420,4492,4449],{"class":593},[420,4494,601],{"class":600},[420,4496,4497],{"class":584}," readSessionActor",[420,4499,4500],{"class":496},"(ctx",[420,4502,330],{"class":492},[420,4504,4505],{"class":496},"headers) ",[420,4507,3326],{"class":492},[420,4509,4510,4512],{"class":422,"line":568},[420,4511,780],{"class":492},[420,4513,893],{"class":496},[3248,4515,4517],{"id":4516},"drain-wrappers","Drain Wrappers",[463,4519,4520,4523,4524,4527,4528,4531,4532,4535],{},[318,4521,4522],{},"Why filter audits to a separate sink?"," Three reasons: ",[318,4525,4526],{},"cost"," (audit volume is tiny next to product telemetry — keep them separate so retention costs don't explode), ",[318,4529,4530],{},"permissions"," (the audit dataset should be read-only for engineers and write-only for the app), and ",[318,4533,4534],{},"retention"," (audits often live 7+ years; product logs rarely live more than 90 days).",[314,4537,4538,4541,4542,4544,4545,4548],{},[323,4539,4540],{},"auditOnly(drain)"," only forwards events with an ",[323,4543,325],{}," field. Compose with ",[318,4546,4547],{},"any"," drain:",[410,4550,4552],{"className":478,"code":4551,"language":481,"meta":416,"style":416},"import { auditOnly } from 'evlog'\nimport { createAxiomDrain } from 'evlog\u002Faxiom'\n\n\u002F\u002F Send audits to a dedicated Axiom dataset:\nnitro.hooks.hook('evlog:drain', auditOnly(\n  createAxiomDrain({ dataset: 'audit', token: process.env.AXIOM_AUDIT_TOKEN }),\n))\n",[323,4553,4554,4572,4590,4594,4599,4625,4671],{"__ignoreMap":416},[420,4555,4556,4558,4560,4562,4564,4566,4568,4570],{"class":422,"line":423},[420,4557,489],{"class":488},[420,4559,493],{"class":492},[420,4561,503],{"class":496},[420,4563,511],{"class":492},[420,4565,514],{"class":488},[420,4567,517],{"class":492},[420,4569,520],{"class":430},[420,4571,523],{"class":492},[420,4573,4574,4576,4578,4580,4582,4584,4586,4588],{"class":422,"line":526},[420,4575,489],{"class":488},[420,4577,493],{"class":492},[420,4579,533],{"class":496},[420,4581,511],{"class":492},[420,4583,514],{"class":488},[420,4585,517],{"class":492},[420,4587,542],{"class":430},[420,4589,523],{"class":492},[420,4591,4592],{"class":422,"line":547},[420,4593,572],{"emptyLinePlaceholder":571},[420,4595,4596],{"class":422,"line":568},[420,4597,4598],{"class":2769},"\u002F\u002F Send audits to a dedicated Axiom dataset:\n",[420,4600,4601,4603,4605,4607,4609,4611,4613,4615,4617,4619,4621,4623],{"class":422,"line":575},[420,4602,594],{"class":496},[420,4604,330],{"class":492},[420,4606,615],{"class":496},[420,4608,330],{"class":492},[420,4610,620],{"class":584},[420,4612,588],{"class":496},[420,4614,626],{"class":492},[420,4616,658],{"class":430},[420,4618,626],{"class":492},[420,4620,500],{"class":492},[420,4622,503],{"class":584},[420,4624,694],{"class":496},[420,4626,4627,4630,4632,4634,4637,4639,4641,4643,4645,4647,4650,4652,4655,4657,4660,4662,4665,4667,4669],{"class":422,"line":607},[420,4628,4629],{"class":584},"  createAxiomDrain",[420,4631,588],{"class":496},[420,4633,710],{"class":492},[420,4635,4636],{"class":623}," dataset",[420,4638,716],{"class":492},[420,4640,517],{"class":492},[420,4642,325],{"class":430},[420,4644,626],{"class":492},[420,4646,500],{"class":492},[420,4648,4649],{"class":623}," token",[420,4651,716],{"class":492},[420,4653,4654],{"class":496}," process",[420,4656,330],{"class":492},[420,4658,4659],{"class":496},"env",[420,4661,330],{"class":492},[420,4663,4664],{"class":496},"AXIOM_AUDIT_TOKEN ",[420,4666,780],{"class":492},[420,4668,597],{"class":496},[420,4670,750],{"class":492},[420,4672,4673],{"class":422,"line":641},[420,4674,893],{"class":496},[314,4676,4677,4678,4681],{},"Set ",[323,4679,4680],{},"await: true"," to make audit writes synchronous (no fire-and-forget for audits — crash-safe by default):",[410,4683,4685],{"className":478,"code":4684,"language":481,"meta":416,"style":416},"auditOnly(createFsDrain({ dir: '.audit' }), { await: true })\n",[323,4686,4687],{"__ignoreMap":416},[420,4688,4689,4691,4693,4695,4697,4699,4701,4703,4705,4707,4709,4711,4713,4715,4717,4719,4721,4723,4725],{"class":422,"line":423},[420,4690,3241],{"class":584},[420,4692,588],{"class":496},[420,4694,705],{"class":584},[420,4696,588],{"class":496},[420,4698,710],{"class":492},[420,4700,713],{"class":623},[420,4702,716],{"class":492},[420,4704,517],{"class":492},[420,4706,721],{"class":430},[420,4708,626],{"class":492},[420,4710,511],{"class":492},[420,4712,597],{"class":496},[420,4714,500],{"class":492},[420,4716,493],{"class":492},[420,4718,759],{"class":623},[420,4720,716],{"class":492},[420,4722,765],{"class":764},[420,4724,511],{"class":492},[420,4726,783],{"class":496},[314,4728,4729,4732],{},[323,4730,4731],{},"signed(drain, opts)"," adds tamper-evident integrity. Strategies:",[340,4734,4735,4745],{},[343,4736,4737,4740,4741,4744],{},[323,4738,4739],{},"'hmac'"," — adds ",[323,4742,4743],{},"event.audit.signature"," (HMAC of the canonical event).",[343,4746,4747,4740,4750,4753,4754,4757,4758,4761],{},[323,4748,4749],{},"'hash-chain'",[323,4751,4752],{},"event.audit.prevHash"," and ",[323,4755,4756],{},"event.audit.hash"," so the sequence forms a verifiable chain. Provide ",[323,4759,4760],{},"state: { load, save }"," for cross-process \u002F durable chains (Redis, file, Postgres).",[463,4763,4764,4771,4772,4775,4776,4778],{},[318,4765,4766,4767,4770],{},"What ",[323,4768,4769],{},"signed()"," actually buys you."," Detection, not prevention. Anyone with write access to the underlying sink can still nuke the file or table — but the chain proves ",[2727,4773,4774],{},"which"," events were dropped or modified after the fact. Skip ",[323,4777,4769],{}," if you already write to an append-only \u002F WORM store (S3 Object Lock, Postgres with row-level immutability, BigQuery append-only tables); doubling integrity layers just adds latency without raising the bar.",[410,4780,4782],{"className":478,"code":4781,"language":481,"meta":416,"style":416},"import { signed } from 'evlog'\n\nsigned(drain, { strategy: 'hmac', secret: process.env.AUDIT_SECRET! })\n\nsigned(drain, {\n  strategy: 'hash-chain',\n  state: {\n    load: () => fs.readFile('.audit\u002Fhead', 'utf8').catch(() => null),\n    save: (h) => fs.writeFile('.audit\u002Fhead', h),\n  },\n})\n",[323,4783,4784,4802,4806,4852,4856,4866,4881,4890,4949,4987,4992],{"__ignoreMap":416},[420,4785,4786,4788,4790,4792,4794,4796,4798,4800],{"class":422,"line":423},[420,4787,489],{"class":488},[420,4789,493],{"class":492},[420,4791,508],{"class":496},[420,4793,511],{"class":492},[420,4795,514],{"class":488},[420,4797,517],{"class":492},[420,4799,520],{"class":430},[420,4801,523],{"class":492},[420,4803,4804],{"class":422,"line":526},[420,4805,572],{"emptyLinePlaceholder":571},[420,4807,4808,4810,4813,4815,4817,4819,4821,4823,4826,4828,4830,4833,4835,4837,4839,4841,4843,4846,4848,4850],{"class":422,"line":547},[420,4809,3245],{"class":584},[420,4811,4812],{"class":496},"(drain",[420,4814,500],{"class":492},[420,4816,493],{"class":492},[420,4818,734],{"class":623},[420,4820,716],{"class":492},[420,4822,517],{"class":492},[420,4824,4825],{"class":430},"hmac",[420,4827,626],{"class":492},[420,4829,500],{"class":492},[420,4831,4832],{"class":623}," secret",[420,4834,716],{"class":492},[420,4836,4654],{"class":496},[420,4838,330],{"class":492},[420,4840,4659],{"class":496},[420,4842,330],{"class":492},[420,4844,4845],{"class":496},"AUDIT_SECRET",[420,4847,3461],{"class":492},[420,4849,511],{"class":492},[420,4851,783],{"class":496},[420,4853,4854],{"class":422,"line":568},[420,4855,572],{"emptyLinePlaceholder":571},[420,4857,4858,4860,4862,4864],{"class":422,"line":575},[420,4859,3245],{"class":584},[420,4861,4812],{"class":496},[420,4863,500],{"class":492},[420,4865,604],{"class":492},[420,4867,4868,4871,4873,4875,4877,4879],{"class":422,"line":607},[420,4869,4870],{"class":623},"  strategy",[420,4872,716],{"class":492},[420,4874,517],{"class":492},[420,4876,741],{"class":430},[420,4878,626],{"class":492},[420,4880,750],{"class":492},[420,4882,4883,4886,4888],{"class":422,"line":641},[420,4884,4885],{"class":623},"  state",[420,4887,716],{"class":492},[420,4889,604],{"class":492},[420,4891,4892,4895,4897,4900,4902,4905,4907,4910,4912,4914,4917,4919,4921,4923,4926,4928,4930,4932,4935,4937,4940,4942,4945,4947],{"class":422,"line":669},[420,4893,4894],{"class":584},"    load",[420,4896,716],{"class":492},[420,4898,4899],{"class":492}," ()",[420,4901,601],{"class":600},[420,4903,4904],{"class":496}," fs",[420,4906,330],{"class":492},[420,4908,4909],{"class":584},"readFile",[420,4911,588],{"class":496},[420,4913,626],{"class":492},[420,4915,4916],{"class":430},".audit\u002Fhead",[420,4918,626],{"class":492},[420,4920,500],{"class":492},[420,4922,517],{"class":492},[420,4924,4925],{"class":430},"utf8",[420,4927,626],{"class":492},[420,4929,597],{"class":496},[420,4931,330],{"class":492},[420,4933,4934],{"class":584},"catch",[420,4936,588],{"class":496},[420,4938,4939],{"class":492},"()",[420,4941,601],{"class":600},[420,4943,4944],{"class":492}," null",[420,4946,597],{"class":496},[420,4948,750],{"class":492},[420,4950,4951,4954,4956,4958,4961,4963,4965,4967,4969,4972,4974,4976,4978,4980,4982,4985],{"class":422,"line":697},[420,4952,4953],{"class":584},"    save",[420,4955,716],{"class":492},[420,4957,809],{"class":492},[420,4959,4960],{"class":593},"h",[420,4962,597],{"class":492},[420,4964,601],{"class":600},[420,4966,4904],{"class":496},[420,4968,330],{"class":492},[420,4970,4971],{"class":584},"writeFile",[420,4973,588],{"class":496},[420,4975,626],{"class":492},[420,4977,4916],{"class":430},[420,4979,626],{"class":492},[420,4981,500],{"class":492},[420,4983,4984],{"class":496}," h)",[420,4986,750],{"class":492},[420,4988,4989],{"class":422,"line":753},[420,4990,4991],{"class":492},"  },\n",[420,4993,4994,4996],{"class":422,"line":771},[420,4995,780],{"class":492},[420,4997,783],{"class":496},[3248,4999,5001],{"id":5000},"schema-discipline","Schema Discipline",[314,5003,5004],{},"Define audit actions in one place to avoid magic strings:",[410,5006,5008],{"className":478,"code":5007,"language":481,"meta":416,"style":416},"import { defineAuditAction } from 'evlog'\n\nconst refund = defineAuditAction('invoice.refund', { target: 'invoice' })\n\nlog.audit(refund({\n  actor: { type: 'user', id: user.id },\n  target: { id: 'inv_889' }, \u002F\u002F type inferred as 'invoice'\n  outcome: 'success',\n}))\n",[323,5009,5010,5029,5033,5071,5075,5092,5124,5148,5162],{"__ignoreMap":416},[420,5011,5012,5014,5016,5019,5021,5023,5025,5027],{"class":422,"line":423},[420,5013,489],{"class":488},[420,5015,493],{"class":492},[420,5017,5018],{"class":496}," defineAuditAction",[420,5020,511],{"class":492},[420,5022,514],{"class":488},[420,5024,517],{"class":492},[420,5026,520],{"class":430},[420,5028,523],{"class":492},[420,5030,5031],{"class":422,"line":526},[420,5032,572],{"emptyLinePlaceholder":571},[420,5034,5035,5037,5040,5042,5044,5046,5048,5050,5052,5054,5056,5059,5061,5063,5065,5067,5069],{"class":422,"line":547},[420,5036,1439],{"class":600},[420,5038,5039],{"class":496}," refund ",[420,5041,1126],{"class":492},[420,5043,5018],{"class":584},[420,5045,588],{"class":496},[420,5047,626],{"class":492},[420,5049,923],{"class":430},[420,5051,626],{"class":492},[420,5053,500],{"class":492},[420,5055,493],{"class":492},[420,5057,5058],{"class":623}," target",[420,5060,716],{"class":492},[420,5062,517],{"class":492},[420,5064,995],{"class":430},[420,5066,626],{"class":492},[420,5068,511],{"class":492},[420,5070,783],{"class":496},[420,5072,5073],{"class":422,"line":568},[420,5074,572],{"emptyLinePlaceholder":571},[420,5076,5077,5079,5081,5083,5085,5088,5090],{"class":422,"line":575},[420,5078,1522],{"class":496},[420,5080,330],{"class":492},[420,5082,325],{"class":584},[420,5084,588],{"class":496},[420,5086,5087],{"class":584},"refund",[420,5089,588],{"class":496},[420,5091,911],{"class":492},[420,5093,5094,5096,5098,5100,5102,5104,5106,5108,5110,5112,5114,5116,5118,5120,5122],{"class":422,"line":607},[420,5095,2124],{"class":623},[420,5097,716],{"class":492},[420,5099,493],{"class":492},[420,5101,939],{"class":623},[420,5103,716],{"class":492},[420,5105,517],{"class":492},[420,5107,946],{"class":430},[420,5109,626],{"class":492},[420,5111,500],{"class":492},[420,5113,953],{"class":623},[420,5115,716],{"class":492},[420,5117,845],{"class":496},[420,5119,330],{"class":492},[420,5121,3323],{"class":496},[420,5123,3326],{"class":492},[420,5125,5126,5128,5130,5132,5134,5136,5138,5140,5142,5145],{"class":422,"line":641},[420,5127,2159],{"class":623},[420,5129,716],{"class":492},[420,5131,493],{"class":492},[420,5133,953],{"class":623},[420,5135,716],{"class":492},[420,5137,517],{"class":492},[420,5139,2184],{"class":430},[420,5141,626],{"class":492},[420,5143,5144],{"class":492}," },",[420,5146,5147],{"class":2769}," \u002F\u002F type inferred as 'invoice'\n",[420,5149,5150,5152,5154,5156,5158,5160],{"class":422,"line":669},[420,5151,2193],{"class":623},[420,5153,716],{"class":492},[420,5155,517],{"class":492},[420,5157,1023],{"class":430},[420,5159,626],{"class":492},[420,5161,750],{"class":492},[420,5163,5164,5166],{"class":422,"line":697},[420,5165,780],{"class":492},[420,5167,893],{"class":496},[3192,5169,5170,5176,5177,5180,5181,5184,5185,5188,5189,5192,5193,5196,5197,5200,5201,5203],{},[318,5171,5172,5173,330],{},"Don't feed entire DB rows into ",[323,5174,5175],{},"auditDiff()"," Strip computed columns, hashed passwords, internal flags, and large JSON blobs before diffing. The point of ",[323,5178,5179],{},"changes"," is ",[2727,5182,5183],{},"what changed semantically"," (status went from ",[323,5186,5187],{},"paid"," → ",[323,5190,5191],{},"refunded","), not ",[2727,5194,5195],{},"what bytes changed"," (a ",[323,5198,5199],{},"lastModified"," timestamp ticked). A noisy ",[323,5202,5179],{}," field is the fastest way to make audit logs unreadable.",[314,5205,5206,5207,5209],{},"For mutating actions, use ",[323,5208,5175],{}," to produce a compact, redact-aware JSON Patch:",[785,5211,5212,5453],{},[410,5213,5215],{"className":478,"code":5214,"filename":3449,"language":481,"meta":416,"style":416},"import { auditDiff } from 'evlog'\n\nconst before = await db.users.byId(id)\nconst after = await db.users.update(id, patch)\n\nlog.audit({\n  action: 'user.update',\n  actor: { type: 'user', id: actorId },\n  target: { type: 'user', id },\n  outcome: 'success',\n  changes: auditDiff(before, after, { redactPaths: ['password', 'token'] }),\n})\n",[323,5216,5217,5236,5240,5267,5297,5301,5313,5328,5357,5382,5396,5447],{"__ignoreMap":416},[420,5218,5219,5221,5223,5226,5228,5230,5232,5234],{"class":422,"line":423},[420,5220,489],{"class":488},[420,5222,493],{"class":492},[420,5224,5225],{"class":496}," auditDiff",[420,5227,511],{"class":492},[420,5229,514],{"class":488},[420,5231,517],{"class":492},[420,5233,520],{"class":430},[420,5235,523],{"class":492},[420,5237,5238],{"class":422,"line":526},[420,5239,572],{"emptyLinePlaceholder":571},[420,5241,5242,5244,5247,5249,5251,5254,5256,5259,5261,5264],{"class":422,"line":547},[420,5243,1439],{"class":600},[420,5245,5246],{"class":496}," before ",[420,5248,1126],{"class":492},[420,5250,759],{"class":488},[420,5252,5253],{"class":496}," db",[420,5255,330],{"class":492},[420,5257,5258],{"class":496},"users",[420,5260,330],{"class":492},[420,5262,5263],{"class":584},"byId",[420,5265,5266],{"class":496},"(id)\n",[420,5268,5269,5271,5274,5276,5278,5280,5282,5284,5286,5289,5292,5294],{"class":422,"line":568},[420,5270,1439],{"class":600},[420,5272,5273],{"class":496}," after ",[420,5275,1126],{"class":492},[420,5277,759],{"class":488},[420,5279,5253],{"class":496},[420,5281,330],{"class":492},[420,5283,5258],{"class":496},[420,5285,330],{"class":492},[420,5287,5288],{"class":584},"update",[420,5290,5291],{"class":496},"(id",[420,5293,500],{"class":492},[420,5295,5296],{"class":496}," patch)\n",[420,5298,5299],{"class":422,"line":575},[420,5300,572],{"emptyLinePlaceholder":571},[420,5302,5303,5305,5307,5309,5311],{"class":422,"line":607},[420,5304,1522],{"class":496},[420,5306,330],{"class":492},[420,5308,325],{"class":584},[420,5310,588],{"class":496},[420,5312,911],{"class":492},[420,5314,5315,5317,5319,5321,5324,5326],{"class":422,"line":641},[420,5316,2109],{"class":623},[420,5318,716],{"class":492},[420,5320,517],{"class":492},[420,5322,5323],{"class":430},"user.update",[420,5325,626],{"class":492},[420,5327,750],{"class":492},[420,5329,5330,5332,5334,5336,5338,5340,5342,5344,5346,5348,5350,5352,5355],{"class":422,"line":669},[420,5331,2124],{"class":623},[420,5333,716],{"class":492},[420,5335,493],{"class":492},[420,5337,939],{"class":623},[420,5339,716],{"class":492},[420,5341,517],{"class":492},[420,5343,946],{"class":430},[420,5345,626],{"class":492},[420,5347,500],{"class":492},[420,5349,953],{"class":623},[420,5351,716],{"class":492},[420,5353,5354],{"class":496}," actorId ",[420,5356,3326],{"class":492},[420,5358,5359,5361,5363,5365,5367,5369,5371,5373,5375,5377,5380],{"class":422,"line":697},[420,5360,2159],{"class":623},[420,5362,716],{"class":492},[420,5364,493],{"class":492},[420,5366,939],{"class":623},[420,5368,716],{"class":492},[420,5370,517],{"class":492},[420,5372,946],{"class":430},[420,5374,626],{"class":492},[420,5376,500],{"class":492},[420,5378,5379],{"class":496}," id ",[420,5381,3326],{"class":492},[420,5383,5384,5386,5388,5390,5392,5394],{"class":422,"line":753},[420,5385,2193],{"class":623},[420,5387,716],{"class":492},[420,5389,517],{"class":492},[420,5391,1023],{"class":430},[420,5393,626],{"class":492},[420,5395,750],{"class":492},[420,5397,5398,5400,5402,5404,5407,5409,5411,5413,5415,5418,5420,5422,5424,5427,5429,5431,5433,5436,5438,5441,5443,5445],{"class":422,"line":771},[420,5399,2981],{"class":623},[420,5401,716],{"class":492},[420,5403,5225],{"class":584},[420,5405,5406],{"class":496},"(before",[420,5408,500],{"class":492},[420,5410,2997],{"class":496},[420,5412,500],{"class":492},[420,5414,493],{"class":492},[420,5416,5417],{"class":623}," redactPaths",[420,5419,716],{"class":492},[420,5421,2921],{"class":496},[420,5423,626],{"class":492},[420,5425,5426],{"class":430},"password",[420,5428,626],{"class":492},[420,5430,500],{"class":492},[420,5432,517],{"class":492},[420,5434,5435],{"class":430},"token",[420,5437,626],{"class":492},[420,5439,5440],{"class":496},"] ",[420,5442,780],{"class":492},[420,5444,597],{"class":496},[420,5446,750],{"class":492},[420,5448,5449,5451],{"class":422,"line":777},[420,5450,780],{"class":492},[420,5452,783],{"class":496},[410,5454,5457],{"className":2228,"code":5455,"filename":5456,"language":1362,"meta":416,"style":416},"{\n  \"audit\": {\n    \"action\": \"user.update\",\n    \"actor\": { \"type\": \"user\", \"id\": \"usr_42\" },\n    \"target\": { \"type\": \"user\", \"id\": \"usr_99\" },\n    \"outcome\": \"success\",\n    \"changes\": [\n      { \"op\": \"replace\", \"path\": \"\u002Femail\", \"from\": \"old@example.com\", \"to\": \"new@example.com\" },\n      { \"op\": \"replace\", \"path\": \"\u002Frole\", \"from\": \"member\", \"to\": \"admin\" },\n      { \"op\": \"replace\", \"path\": \"\u002Fpassword\", \"from\": \"[REDACTED]\", \"to\": \"[REDACTED]\" }\n    ],\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_5e7d8f9a0b1c2d3e\"\n  }\n}\n","Output — changes patch",[323,5458,5459,5463,5475,5493,5537,5582,5600,5613,5689,5760,5830,5835,5849,5866,5870],{"__ignoreMap":416},[420,5460,5461],{"class":422,"line":423},[420,5462,911],{"class":492},[420,5464,5465,5467,5469,5471,5473],{"class":422,"line":526},[420,5466,2241],{"class":492},[420,5468,325],{"class":600},[420,5470,2247],{"class":492},[420,5472,716],{"class":492},[420,5474,604],{"class":492},[420,5476,5477,5479,5481,5483,5485,5487,5489,5491],{"class":422,"line":547},[420,5478,2393],{"class":492},[420,5480,2396],{"class":426},[420,5482,2247],{"class":492},[420,5484,716],{"class":492},[420,5486,2252],{"class":492},[420,5488,5323],{"class":430},[420,5490,2247],{"class":492},[420,5492,750],{"class":492},[420,5494,5495,5497,5499,5501,5503,5505,5507,5509,5511,5513,5515,5517,5519,5521,5523,5525,5527,5529,5531,5533,5535],{"class":422,"line":568},[420,5496,2393],{"class":492},[420,5498,2415],{"class":426},[420,5500,2247],{"class":492},[420,5502,716],{"class":492},[420,5504,493],{"class":492},[420,5506,2252],{"class":492},[420,5508,2426],{"class":2333},[420,5510,2247],{"class":492},[420,5512,716],{"class":492},[420,5514,2252],{"class":492},[420,5516,946],{"class":430},[420,5518,2247],{"class":492},[420,5520,500],{"class":492},[420,5522,2252],{"class":492},[420,5524,888],{"class":2333},[420,5526,2247],{"class":492},[420,5528,716],{"class":492},[420,5530,2252],{"class":492},[420,5532,2451],{"class":430},[420,5534,2247],{"class":492},[420,5536,768],{"class":492},[420,5538,5539,5541,5543,5545,5547,5549,5551,5553,5555,5557,5559,5561,5563,5565,5567,5569,5571,5573,5575,5578,5580],{"class":422,"line":575},[420,5540,2393],{"class":492},[420,5542,2479],{"class":426},[420,5544,2247],{"class":492},[420,5546,716],{"class":492},[420,5548,493],{"class":492},[420,5550,2252],{"class":492},[420,5552,2426],{"class":2333},[420,5554,2247],{"class":492},[420,5556,716],{"class":492},[420,5558,2252],{"class":492},[420,5560,946],{"class":430},[420,5562,2247],{"class":492},[420,5564,500],{"class":492},[420,5566,2252],{"class":492},[420,5568,888],{"class":2333},[420,5570,2247],{"class":492},[420,5572,716],{"class":492},[420,5574,2252],{"class":492},[420,5576,5577],{"class":430},"usr_99",[420,5579,2247],{"class":492},[420,5581,768],{"class":492},[420,5583,5584,5586,5588,5590,5592,5594,5596,5598],{"class":422,"line":607},[420,5585,2393],{"class":492},[420,5587,2524],{"class":426},[420,5589,2247],{"class":492},[420,5591,716],{"class":492},[420,5593,2252],{"class":492},[420,5595,1023],{"class":430},[420,5597,2247],{"class":492},[420,5599,750],{"class":492},[420,5601,5602,5604,5606,5608,5610],{"class":422,"line":641},[420,5603,2393],{"class":492},[420,5605,5179],{"class":426},[420,5607,2247],{"class":492},[420,5609,716],{"class":492},[420,5611,5612],{"class":492}," [\n",[420,5614,5615,5618,5620,5623,5625,5627,5629,5632,5634,5636,5638,5640,5642,5644,5646,5649,5651,5653,5655,5658,5660,5662,5664,5667,5669,5671,5673,5676,5678,5680,5682,5685,5687],{"class":422,"line":669},[420,5616,5617],{"class":492},"      {",[420,5619,2252],{"class":492},[420,5621,5622],{"class":2333},"op",[420,5624,2247],{"class":492},[420,5626,716],{"class":492},[420,5628,2252],{"class":492},[420,5630,5631],{"class":430},"replace",[420,5633,2247],{"class":492},[420,5635,500],{"class":492},[420,5637,2252],{"class":492},[420,5639,2306],{"class":2333},[420,5641,2247],{"class":492},[420,5643,716],{"class":492},[420,5645,2252],{"class":492},[420,5647,5648],{"class":430},"\u002Femail",[420,5650,2247],{"class":492},[420,5652,500],{"class":492},[420,5654,2252],{"class":492},[420,5656,5657],{"class":2333},"from",[420,5659,2247],{"class":492},[420,5661,716],{"class":492},[420,5663,2252],{"class":492},[420,5665,5666],{"class":430},"old@example.com",[420,5668,2247],{"class":492},[420,5670,500],{"class":492},[420,5672,2252],{"class":492},[420,5674,5675],{"class":2333},"to",[420,5677,2247],{"class":492},[420,5679,716],{"class":492},[420,5681,2252],{"class":492},[420,5683,5684],{"class":430},"new@example.com",[420,5686,2247],{"class":492},[420,5688,768],{"class":492},[420,5690,5691,5693,5695,5697,5699,5701,5703,5705,5707,5709,5711,5713,5715,5717,5719,5722,5724,5726,5728,5730,5732,5734,5736,5739,5741,5743,5745,5747,5749,5751,5753,5756,5758],{"class":422,"line":697},[420,5692,5617],{"class":492},[420,5694,2252],{"class":492},[420,5696,5622],{"class":2333},[420,5698,2247],{"class":492},[420,5700,716],{"class":492},[420,5702,2252],{"class":492},[420,5704,5631],{"class":430},[420,5706,2247],{"class":492},[420,5708,500],{"class":492},[420,5710,2252],{"class":492},[420,5712,2306],{"class":2333},[420,5714,2247],{"class":492},[420,5716,716],{"class":492},[420,5718,2252],{"class":492},[420,5720,5721],{"class":430},"\u002Frole",[420,5723,2247],{"class":492},[420,5725,500],{"class":492},[420,5727,2252],{"class":492},[420,5729,5657],{"class":2333},[420,5731,2247],{"class":492},[420,5733,716],{"class":492},[420,5735,2252],{"class":492},[420,5737,5738],{"class":430},"member",[420,5740,2247],{"class":492},[420,5742,500],{"class":492},[420,5744,2252],{"class":492},[420,5746,5675],{"class":2333},[420,5748,2247],{"class":492},[420,5750,716],{"class":492},[420,5752,2252],{"class":492},[420,5754,5755],{"class":430},"admin",[420,5757,2247],{"class":492},[420,5759,768],{"class":492},[420,5761,5762,5764,5766,5768,5770,5772,5774,5776,5778,5780,5782,5784,5786,5788,5790,5793,5795,5797,5799,5801,5803,5805,5807,5810,5812,5814,5816,5818,5820,5822,5824,5826,5828],{"class":422,"line":753},[420,5763,5617],{"class":492},[420,5765,2252],{"class":492},[420,5767,5622],{"class":2333},[420,5769,2247],{"class":492},[420,5771,716],{"class":492},[420,5773,2252],{"class":492},[420,5775,5631],{"class":430},[420,5777,2247],{"class":492},[420,5779,500],{"class":492},[420,5781,2252],{"class":492},[420,5783,2306],{"class":2333},[420,5785,2247],{"class":492},[420,5787,716],{"class":492},[420,5789,2252],{"class":492},[420,5791,5792],{"class":430},"\u002Fpassword",[420,5794,2247],{"class":492},[420,5796,500],{"class":492},[420,5798,2252],{"class":492},[420,5800,5657],{"class":2333},[420,5802,2247],{"class":492},[420,5804,716],{"class":492},[420,5806,2252],{"class":492},[420,5808,5809],{"class":430},"[REDACTED]",[420,5811,2247],{"class":492},[420,5813,500],{"class":492},[420,5815,2252],{"class":492},[420,5817,5675],{"class":2333},[420,5819,2247],{"class":492},[420,5821,716],{"class":492},[420,5823,2252],{"class":492},[420,5825,5809],{"class":430},[420,5827,2247],{"class":492},[420,5829,1073],{"class":492},[420,5831,5832],{"class":422,"line":771},[420,5833,5834],{"class":492},"    ],\n",[420,5836,5837,5839,5841,5843,5845,5847],{"class":422,"line":777},[420,5838,2393],{"class":492},[420,5840,2562],{"class":426},[420,5842,2247],{"class":492},[420,5844,716],{"class":492},[420,5846,2569],{"class":2333},[420,5848,750],{"class":492},[420,5850,5851,5853,5855,5857,5859,5861,5864],{"class":422,"line":1053},[420,5852,2393],{"class":492},[420,5854,2578],{"class":426},[420,5856,2247],{"class":492},[420,5858,716],{"class":492},[420,5860,2252],{"class":492},[420,5862,5863],{"class":430},"ak_5e7d8f9a0b1c2d3e",[420,5865,2662],{"class":492},[420,5867,5868],{"class":422,"line":1058},[420,5869,2674],{"class":492},[420,5871,5872],{"class":422,"line":1076},[420,5873,2680],{"class":492},[3248,5875,5877,5878],{"id":5876},"auto-instrumentation-with-withaudit","Auto-Instrumentation with ",[323,5879,3186],{},[314,5881,5882,5883,5885],{},"Devs forget to call ",[323,5884,3256],{},". Wrap the function and never miss a record:",[463,5887,5888,5891,5892,5895,5896,5898,5899,5902],{},[318,5889,5890],{},"When to wrap vs. call manually."," Wrap functions that are ",[2727,5893,5894],{},"pure audit-worthy actions"," (refund, delete, role change, password reset) — outcome resolution is automatic and you can't accidentally skip the call. Stick to manual ",[323,5897,3256],{}," when the audit is one of several decisions inside a larger handler, or when you need to emit the audit ",[2727,5900,5901],{},"before"," the action completes (e.g. \"user requested deletion\").",[785,5904,5905,6190,6393,6708],{},[410,5906,5908],{"className":478,"code":5907,"filename":3449,"language":481,"meta":416,"style":416},"import { withAudit, AuditDeniedError } from 'evlog'\n\nconst refundInvoice = withAudit(\n  { action: 'invoice.refund', target: input => ({ type: 'invoice', id: input.id }) },\n  async (input: { id: string }, ctx) => {\n    if (!ctx.actor) throw new AuditDeniedError('Anonymous refund denied')\n    return await db.invoices.refund(input.id)\n  },\n)\n\nawait refundInvoice({ id: 'inv_889' }, {\n  actor: { type: 'user', id: user.id },\n  correlationId: requestId,\n})\n",[323,5909,5910,5934,5938,5951,6010,6040,6076,6104,6108,6112,6116,6141,6173,6184],{"__ignoreMap":416},[420,5911,5912,5914,5916,5919,5921,5924,5926,5928,5930,5932],{"class":422,"line":423},[420,5913,489],{"class":488},[420,5915,493],{"class":492},[420,5917,5918],{"class":496}," withAudit",[420,5920,500],{"class":492},[420,5922,5923],{"class":496}," AuditDeniedError",[420,5925,511],{"class":492},[420,5927,514],{"class":488},[420,5929,517],{"class":492},[420,5931,520],{"class":430},[420,5933,523],{"class":492},[420,5935,5936],{"class":422,"line":526},[420,5937,572],{"emptyLinePlaceholder":571},[420,5939,5940,5942,5945,5947,5949],{"class":422,"line":547},[420,5941,1439],{"class":600},[420,5943,5944],{"class":496}," refundInvoice ",[420,5946,1126],{"class":492},[420,5948,5918],{"class":584},[420,5950,694],{"class":496},[420,5952,5953,5956,5958,5960,5962,5964,5966,5968,5970,5972,5975,5977,5979,5981,5983,5985,5987,5989,5991,5993,5995,5997,5999,6001,6003,6005,6008],{"class":422,"line":568},[420,5954,5955],{"class":492},"  {",[420,5957,3409],{"class":623},[420,5959,716],{"class":492},[420,5961,517],{"class":492},[420,5963,923],{"class":430},[420,5965,626],{"class":492},[420,5967,500],{"class":492},[420,5969,5058],{"class":584},[420,5971,716],{"class":492},[420,5973,5974],{"class":593}," input",[420,5976,601],{"class":600},[420,5978,809],{"class":496},[420,5980,710],{"class":492},[420,5982,939],{"class":623},[420,5984,716],{"class":492},[420,5986,517],{"class":492},[420,5988,995],{"class":430},[420,5990,626],{"class":492},[420,5992,500],{"class":492},[420,5994,953],{"class":623},[420,5996,716],{"class":492},[420,5998,5974],{"class":496},[420,6000,330],{"class":492},[420,6002,3323],{"class":496},[420,6004,780],{"class":492},[420,6006,6007],{"class":496},") ",[420,6009,3326],{"class":492},[420,6011,6012,6015,6017,6020,6022,6024,6026,6028,6030,6032,6034,6036,6038],{"class":422,"line":575},[420,6013,6014],{"class":600},"  async",[420,6016,809],{"class":492},[420,6018,6019],{"class":593},"input",[420,6021,716],{"class":492},[420,6023,493],{"class":492},[420,6025,953],{"class":623},[420,6027,716],{"class":492},[420,6029,2766],{"class":426},[420,6031,5144],{"class":492},[420,6033,4449],{"class":593},[420,6035,597],{"class":492},[420,6037,601],{"class":600},[420,6039,604],{"class":492},[420,6041,6042,6045,6047,6049,6052,6054,6056,6058,6061,6063,6065,6067,6069,6072,6074],{"class":422,"line":607},[420,6043,6044],{"class":488},"    if",[420,6046,809],{"class":623},[420,6048,3461],{"class":492},[420,6050,6051],{"class":496},"ctx",[420,6053,330],{"class":492},[420,6055,2415],{"class":496},[420,6057,6007],{"class":623},[420,6059,6060],{"class":488},"throw",[420,6062,1447],{"class":492},[420,6064,5923],{"class":584},[420,6066,588],{"class":623},[420,6068,626],{"class":492},[420,6070,6071],{"class":430},"Anonymous refund denied",[420,6073,626],{"class":492},[420,6075,783],{"class":623},[420,6077,6078,6081,6083,6085,6087,6090,6092,6094,6096,6098,6100,6102],{"class":422,"line":641},[420,6079,6080],{"class":488},"    return",[420,6082,759],{"class":488},[420,6084,5253],{"class":496},[420,6086,330],{"class":492},[420,6088,6089],{"class":496},"invoices",[420,6091,330],{"class":492},[420,6093,5087],{"class":584},[420,6095,588],{"class":623},[420,6097,6019],{"class":496},[420,6099,330],{"class":492},[420,6101,888],{"class":496},[420,6103,783],{"class":623},[420,6105,6106],{"class":422,"line":669},[420,6107,4991],{"class":492},[420,6109,6110],{"class":422,"line":697},[420,6111,783],{"class":496},[420,6113,6114],{"class":422,"line":753},[420,6115,572],{"emptyLinePlaceholder":571},[420,6117,6118,6121,6123,6125,6127,6129,6131,6133,6135,6137,6139],{"class":422,"line":771},[420,6119,6120],{"class":488},"await",[420,6122,872],{"class":584},[420,6124,588],{"class":496},[420,6126,710],{"class":492},[420,6128,953],{"class":623},[420,6130,716],{"class":492},[420,6132,517],{"class":492},[420,6134,2184],{"class":430},[420,6136,626],{"class":492},[420,6138,5144],{"class":492},[420,6140,604],{"class":492},[420,6142,6143,6145,6147,6149,6151,6153,6155,6157,6159,6161,6163,6165,6167,6169,6171],{"class":422,"line":777},[420,6144,2124],{"class":623},[420,6146,716],{"class":492},[420,6148,493],{"class":492},[420,6150,939],{"class":623},[420,6152,716],{"class":492},[420,6154,517],{"class":492},[420,6156,946],{"class":430},[420,6158,626],{"class":492},[420,6160,500],{"class":492},[420,6162,953],{"class":623},[420,6164,716],{"class":492},[420,6166,845],{"class":496},[420,6168,330],{"class":492},[420,6170,3323],{"class":496},[420,6172,3326],{"class":492},[420,6174,6175,6177,6179,6182],{"class":422,"line":1053},[420,6176,3020],{"class":623},[420,6178,716],{"class":492},[420,6180,6181],{"class":496}," requestId",[420,6183,750],{"class":492},[420,6185,6186,6188],{"class":422,"line":1058},[420,6187,780],{"class":492},[420,6189,783],{"class":496},[410,6191,6194],{"className":2228,"code":6192,"filename":6193,"language":1362,"meta":416,"style":416},"{\n  \"audit\": {\n    \"action\": \"invoice.refund\",\n    \"actor\": { \"type\": \"user\", \"id\": \"usr_42\" },\n    \"target\": { \"type\": \"invoice\", \"id\": \"inv_889\" },\n    \"outcome\": \"success\",\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_8f3c4b2a1e5d6f7c\",\n    \"correlationId\": \"a566ef91-7765-4f59-b6f0-b9f40ce71599\"\n  }\n}\n","Output — success",[323,6195,6196,6200,6212,6230,6274,6318,6336,6350,6368,6385,6389],{"__ignoreMap":416},[420,6197,6198],{"class":422,"line":423},[420,6199,911],{"class":492},[420,6201,6202,6204,6206,6208,6210],{"class":422,"line":526},[420,6203,2241],{"class":492},[420,6205,325],{"class":600},[420,6207,2247],{"class":492},[420,6209,716],{"class":492},[420,6211,604],{"class":492},[420,6213,6214,6216,6218,6220,6222,6224,6226,6228],{"class":422,"line":547},[420,6215,2393],{"class":492},[420,6217,2396],{"class":426},[420,6219,2247],{"class":492},[420,6221,716],{"class":492},[420,6223,2252],{"class":492},[420,6225,923],{"class":430},[420,6227,2247],{"class":492},[420,6229,750],{"class":492},[420,6231,6232,6234,6236,6238,6240,6242,6244,6246,6248,6250,6252,6254,6256,6258,6260,6262,6264,6266,6268,6270,6272],{"class":422,"line":568},[420,6233,2393],{"class":492},[420,6235,2415],{"class":426},[420,6237,2247],{"class":492},[420,6239,716],{"class":492},[420,6241,493],{"class":492},[420,6243,2252],{"class":492},[420,6245,2426],{"class":2333},[420,6247,2247],{"class":492},[420,6249,716],{"class":492},[420,6251,2252],{"class":492},[420,6253,946],{"class":430},[420,6255,2247],{"class":492},[420,6257,500],{"class":492},[420,6259,2252],{"class":492},[420,6261,888],{"class":2333},[420,6263,2247],{"class":492},[420,6265,716],{"class":492},[420,6267,2252],{"class":492},[420,6269,2451],{"class":430},[420,6271,2247],{"class":492},[420,6273,768],{"class":492},[420,6275,6276,6278,6280,6282,6284,6286,6288,6290,6292,6294,6296,6298,6300,6302,6304,6306,6308,6310,6312,6314,6316],{"class":422,"line":575},[420,6277,2393],{"class":492},[420,6279,2479],{"class":426},[420,6281,2247],{"class":492},[420,6283,716],{"class":492},[420,6285,493],{"class":492},[420,6287,2252],{"class":492},[420,6289,2426],{"class":2333},[420,6291,2247],{"class":492},[420,6293,716],{"class":492},[420,6295,2252],{"class":492},[420,6297,995],{"class":430},[420,6299,2247],{"class":492},[420,6301,500],{"class":492},[420,6303,2252],{"class":492},[420,6305,888],{"class":2333},[420,6307,2247],{"class":492},[420,6309,716],{"class":492},[420,6311,2252],{"class":492},[420,6313,2184],{"class":430},[420,6315,2247],{"class":492},[420,6317,768],{"class":492},[420,6319,6320,6322,6324,6326,6328,6330,6332,6334],{"class":422,"line":607},[420,6321,2393],{"class":492},[420,6323,2524],{"class":426},[420,6325,2247],{"class":492},[420,6327,716],{"class":492},[420,6329,2252],{"class":492},[420,6331,1023],{"class":430},[420,6333,2247],{"class":492},[420,6335,750],{"class":492},[420,6337,6338,6340,6342,6344,6346,6348],{"class":422,"line":641},[420,6339,2393],{"class":492},[420,6341,2562],{"class":426},[420,6343,2247],{"class":492},[420,6345,716],{"class":492},[420,6347,2569],{"class":2333},[420,6349,750],{"class":492},[420,6351,6352,6354,6356,6358,6360,6362,6364,6366],{"class":422,"line":669},[420,6353,2393],{"class":492},[420,6355,2578],{"class":426},[420,6357,2247],{"class":492},[420,6359,716],{"class":492},[420,6361,2252],{"class":492},[420,6363,2587],{"class":430},[420,6365,2247],{"class":492},[420,6367,750],{"class":492},[420,6369,6370,6372,6375,6377,6379,6381,6383],{"class":422,"line":697},[420,6371,2393],{"class":492},[420,6373,6374],{"class":426},"correlationId",[420,6376,2247],{"class":492},[420,6378,716],{"class":492},[420,6380,2252],{"class":492},[420,6382,2372],{"class":430},[420,6384,2662],{"class":492},[420,6386,6387],{"class":422,"line":753},[420,6388,2674],{"class":492},[420,6390,6391],{"class":422,"line":771},[420,6392,2680],{"class":492},[410,6394,6397],{"className":2228,"code":6395,"filename":6396,"language":1362,"meta":416,"style":416},"{\n  \"level\": \"error\",\n  \"audit\": {\n    \"action\": \"invoice.refund\",\n    \"actor\": { \"type\": \"user\", \"id\": \"usr_42\" },\n    \"target\": { \"type\": \"invoice\", \"id\": \"inv_889\" },\n    \"outcome\": \"failure\",\n    \"reason\": \"Stripe error: charge already refunded\",\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_4c5d6e7f8a9b0c1d\",\n    \"correlationId\": \"a566ef91-7765-4f59-b6f0-b9f40ce71599\"\n  },\n  \"error\": {\n    \"name\": \"StripeError\",\n    \"message\": \"charge already refunded\",\n    \"stack\": \"...\"\n  }\n}\n","Output — failure",[323,6398,6399,6403,6422,6434,6452,6496,6540,6558,6577,6591,6610,6626,6630,6642,6662,6682,6700,6704],{"__ignoreMap":416},[420,6400,6401],{"class":422,"line":423},[420,6402,911],{"class":492},[420,6404,6405,6407,6409,6411,6413,6415,6418,6420],{"class":422,"line":526},[420,6406,2241],{"class":492},[420,6408,2244],{"class":600},[420,6410,2247],{"class":492},[420,6412,716],{"class":492},[420,6414,2252],{"class":492},[420,6416,6417],{"class":430},"error",[420,6419,2247],{"class":492},[420,6421,750],{"class":492},[420,6423,6424,6426,6428,6430,6432],{"class":422,"line":547},[420,6425,2241],{"class":492},[420,6427,325],{"class":600},[420,6429,2247],{"class":492},[420,6431,716],{"class":492},[420,6433,604],{"class":492},[420,6435,6436,6438,6440,6442,6444,6446,6448,6450],{"class":422,"line":568},[420,6437,2393],{"class":492},[420,6439,2396],{"class":426},[420,6441,2247],{"class":492},[420,6443,716],{"class":492},[420,6445,2252],{"class":492},[420,6447,923],{"class":430},[420,6449,2247],{"class":492},[420,6451,750],{"class":492},[420,6453,6454,6456,6458,6460,6462,6464,6466,6468,6470,6472,6474,6476,6478,6480,6482,6484,6486,6488,6490,6492,6494],{"class":422,"line":575},[420,6455,2393],{"class":492},[420,6457,2415],{"class":426},[420,6459,2247],{"class":492},[420,6461,716],{"class":492},[420,6463,493],{"class":492},[420,6465,2252],{"class":492},[420,6467,2426],{"class":2333},[420,6469,2247],{"class":492},[420,6471,716],{"class":492},[420,6473,2252],{"class":492},[420,6475,946],{"class":430},[420,6477,2247],{"class":492},[420,6479,500],{"class":492},[420,6481,2252],{"class":492},[420,6483,888],{"class":2333},[420,6485,2247],{"class":492},[420,6487,716],{"class":492},[420,6489,2252],{"class":492},[420,6491,2451],{"class":430},[420,6493,2247],{"class":492},[420,6495,768],{"class":492},[420,6497,6498,6500,6502,6504,6506,6508,6510,6512,6514,6516,6518,6520,6522,6524,6526,6528,6530,6532,6534,6536,6538],{"class":422,"line":607},[420,6499,2393],{"class":492},[420,6501,2479],{"class":426},[420,6503,2247],{"class":492},[420,6505,716],{"class":492},[420,6507,493],{"class":492},[420,6509,2252],{"class":492},[420,6511,2426],{"class":2333},[420,6513,2247],{"class":492},[420,6515,716],{"class":492},[420,6517,2252],{"class":492},[420,6519,995],{"class":430},[420,6521,2247],{"class":492},[420,6523,500],{"class":492},[420,6525,2252],{"class":492},[420,6527,888],{"class":2333},[420,6529,2247],{"class":492},[420,6531,716],{"class":492},[420,6533,2252],{"class":492},[420,6535,2184],{"class":430},[420,6537,2247],{"class":492},[420,6539,768],{"class":492},[420,6541,6542,6544,6546,6548,6550,6552,6554,6556],{"class":422,"line":641},[420,6543,2393],{"class":492},[420,6545,2524],{"class":426},[420,6547,2247],{"class":492},[420,6549,716],{"class":492},[420,6551,2252],{"class":492},[420,6553,2957],{"class":430},[420,6555,2247],{"class":492},[420,6557,750],{"class":492},[420,6559,6560,6562,6564,6566,6568,6570,6573,6575],{"class":422,"line":669},[420,6561,2393],{"class":492},[420,6563,2543],{"class":426},[420,6565,2247],{"class":492},[420,6567,716],{"class":492},[420,6569,2252],{"class":492},[420,6571,6572],{"class":430},"Stripe error: charge already refunded",[420,6574,2247],{"class":492},[420,6576,750],{"class":492},[420,6578,6579,6581,6583,6585,6587,6589],{"class":422,"line":697},[420,6580,2393],{"class":492},[420,6582,2562],{"class":426},[420,6584,2247],{"class":492},[420,6586,716],{"class":492},[420,6588,2569],{"class":2333},[420,6590,750],{"class":492},[420,6592,6593,6595,6597,6599,6601,6603,6606,6608],{"class":422,"line":753},[420,6594,2393],{"class":492},[420,6596,2578],{"class":426},[420,6598,2247],{"class":492},[420,6600,716],{"class":492},[420,6602,2252],{"class":492},[420,6604,6605],{"class":430},"ak_4c5d6e7f8a9b0c1d",[420,6607,2247],{"class":492},[420,6609,750],{"class":492},[420,6611,6612,6614,6616,6618,6620,6622,6624],{"class":422,"line":771},[420,6613,2393],{"class":492},[420,6615,6374],{"class":426},[420,6617,2247],{"class":492},[420,6619,716],{"class":492},[420,6621,2252],{"class":492},[420,6623,2372],{"class":430},[420,6625,2662],{"class":492},[420,6627,6628],{"class":422,"line":777},[420,6629,4991],{"class":492},[420,6631,6632,6634,6636,6638,6640],{"class":422,"line":1053},[420,6633,2241],{"class":492},[420,6635,6417],{"class":600},[420,6637,2247],{"class":492},[420,6639,716],{"class":492},[420,6641,604],{"class":492},[420,6643,6644,6646,6649,6651,6653,6655,6658,6660],{"class":422,"line":1058},[420,6645,2393],{"class":492},[420,6647,6648],{"class":426},"name",[420,6650,2247],{"class":492},[420,6652,716],{"class":492},[420,6654,2252],{"class":492},[420,6656,6657],{"class":430},"StripeError",[420,6659,2247],{"class":492},[420,6661,750],{"class":492},[420,6663,6664,6666,6669,6671,6673,6675,6678,6680],{"class":422,"line":1076},[420,6665,2393],{"class":492},[420,6667,6668],{"class":426},"message",[420,6670,2247],{"class":492},[420,6672,716],{"class":492},[420,6674,2252],{"class":492},[420,6676,6677],{"class":430},"charge already refunded",[420,6679,2247],{"class":492},[420,6681,750],{"class":492},[420,6683,6684,6686,6689,6691,6693,6695,6698],{"class":422,"line":1352},[420,6685,2393],{"class":492},[420,6687,6688],{"class":426},"stack",[420,6690,2247],{"class":492},[420,6692,716],{"class":492},[420,6694,2252],{"class":492},[420,6696,6697],{"class":430},"...",[420,6699,2662],{"class":492},[420,6701,6702],{"class":422,"line":1379},[420,6703,2674],{"class":492},[420,6705,6706],{"class":422,"line":1722},[420,6707,2680],{"class":492},[410,6709,6711],{"className":2228,"code":6710,"filename":3629,"language":1362,"meta":416,"style":416},"{\n  \"level\": \"warn\",\n  \"audit\": {\n    \"action\": \"invoice.refund\",\n    \"actor\": { \"type\": \"system\", \"id\": \"anonymous\" },\n    \"target\": { \"type\": \"invoice\", \"id\": \"inv_889\" },\n    \"outcome\": \"denied\",\n    \"reason\": \"Anonymous refund denied\",\n    \"version\": 1,\n    \"idempotencyKey\": \"ak_d12c3a4f5b6e7d8c\",\n    \"correlationId\": \"a566ef91-7765-4f59-b6f0-b9f40ce71599\"\n  }\n}\n",[323,6712,6713,6717,6735,6747,6765,6810,6854,6872,6890,6904,6922,6938,6942],{"__ignoreMap":416},[420,6714,6715],{"class":422,"line":423},[420,6716,911],{"class":492},[420,6718,6719,6721,6723,6725,6727,6729,6731,6733],{"class":422,"line":526},[420,6720,2241],{"class":492},[420,6722,2244],{"class":600},[420,6724,2247],{"class":492},[420,6726,716],{"class":492},[420,6728,2252],{"class":492},[420,6730,3650],{"class":430},[420,6732,2247],{"class":492},[420,6734,750],{"class":492},[420,6736,6737,6739,6741,6743,6745],{"class":422,"line":547},[420,6738,2241],{"class":492},[420,6740,325],{"class":600},[420,6742,2247],{"class":492},[420,6744,716],{"class":492},[420,6746,604],{"class":492},[420,6748,6749,6751,6753,6755,6757,6759,6761,6763],{"class":422,"line":568},[420,6750,2393],{"class":492},[420,6752,2396],{"class":426},[420,6754,2247],{"class":492},[420,6756,716],{"class":492},[420,6758,2252],{"class":492},[420,6760,923],{"class":430},[420,6762,2247],{"class":492},[420,6764,750],{"class":492},[420,6766,6767,6769,6771,6773,6775,6777,6779,6781,6783,6785,6787,6789,6791,6793,6795,6797,6799,6801,6803,6806,6808],{"class":422,"line":575},[420,6768,2393],{"class":492},[420,6770,2415],{"class":426},[420,6772,2247],{"class":492},[420,6774,716],{"class":492},[420,6776,493],{"class":492},[420,6778,2252],{"class":492},[420,6780,2426],{"class":2333},[420,6782,2247],{"class":492},[420,6784,716],{"class":492},[420,6786,2252],{"class":492},[420,6788,2137],{"class":430},[420,6790,2247],{"class":492},[420,6792,500],{"class":492},[420,6794,2252],{"class":492},[420,6796,888],{"class":2333},[420,6798,2247],{"class":492},[420,6800,716],{"class":492},[420,6802,2252],{"class":492},[420,6804,6805],{"class":430},"anonymous",[420,6807,2247],{"class":492},[420,6809,768],{"class":492},[420,6811,6812,6814,6816,6818,6820,6822,6824,6826,6828,6830,6832,6834,6836,6838,6840,6842,6844,6846,6848,6850,6852],{"class":422,"line":607},[420,6813,2393],{"class":492},[420,6815,2479],{"class":426},[420,6817,2247],{"class":492},[420,6819,716],{"class":492},[420,6821,493],{"class":492},[420,6823,2252],{"class":492},[420,6825,2426],{"class":2333},[420,6827,2247],{"class":492},[420,6829,716],{"class":492},[420,6831,2252],{"class":492},[420,6833,995],{"class":430},[420,6835,2247],{"class":492},[420,6837,500],{"class":492},[420,6839,2252],{"class":492},[420,6841,888],{"class":2333},[420,6843,2247],{"class":492},[420,6845,716],{"class":492},[420,6847,2252],{"class":492},[420,6849,2184],{"class":430},[420,6851,2247],{"class":492},[420,6853,768],{"class":492},[420,6855,6856,6858,6860,6862,6864,6866,6868,6870],{"class":422,"line":641},[420,6857,2393],{"class":492},[420,6859,2524],{"class":426},[420,6861,2247],{"class":492},[420,6863,716],{"class":492},[420,6865,2252],{"class":492},[420,6867,2966],{"class":430},[420,6869,2247],{"class":492},[420,6871,750],{"class":492},[420,6873,6874,6876,6878,6880,6882,6884,6886,6888],{"class":422,"line":669},[420,6875,2393],{"class":492},[420,6877,2543],{"class":426},[420,6879,2247],{"class":492},[420,6881,716],{"class":492},[420,6883,2252],{"class":492},[420,6885,6071],{"class":430},[420,6887,2247],{"class":492},[420,6889,750],{"class":492},[420,6891,6892,6894,6896,6898,6900,6902],{"class":422,"line":697},[420,6893,2393],{"class":492},[420,6895,2562],{"class":426},[420,6897,2247],{"class":492},[420,6899,716],{"class":492},[420,6901,2569],{"class":2333},[420,6903,750],{"class":492},[420,6905,6906,6908,6910,6912,6914,6916,6918,6920],{"class":422,"line":753},[420,6907,2393],{"class":492},[420,6909,2578],{"class":426},[420,6911,2247],{"class":492},[420,6913,716],{"class":492},[420,6915,2252],{"class":492},[420,6917,3944],{"class":430},[420,6919,2247],{"class":492},[420,6921,750],{"class":492},[420,6923,6924,6926,6928,6930,6932,6934,6936],{"class":422,"line":771},[420,6925,2393],{"class":492},[420,6927,6374],{"class":426},[420,6929,2247],{"class":492},[420,6931,716],{"class":492},[420,6933,2252],{"class":492},[420,6935,2372],{"class":430},[420,6937,2662],{"class":492},[420,6939,6940],{"class":422,"line":777},[420,6941,2674],{"class":492},[420,6943,6944],{"class":422,"line":1053},[420,6945,2680],{"class":492},[314,6947,6948],{},"Outcome resolution:",[340,6950,6951,6960,6979],{},[343,6952,6953,6956,6957,330],{},[323,6954,6955],{},"fn"," resolves → ",[323,6958,6959],{},"outcome: 'success'",[343,6961,6962,6964,6965,6968,6969,6972,6973,6976,6977,330],{},[323,6963,6955],{}," throws an ",[323,6966,6967],{},"AuditDeniedError"," (or any error with ",[323,6970,6971],{},"status === 403",") → ",[323,6974,6975],{},"outcome: 'denied'",", error message becomes ",[323,6978,2543],{},[343,6980,6981,6982,6985],{},"Other thrown errors → ",[323,6983,6984],{},"outcome: 'failure'",", then re-thrown.",[379,6987,6989],{"id":6988},"compliance","Compliance",[3248,6991,6993],{"id":6992},"integrity","Integrity",[314,6995,6996],{},"Hash-chain the audit log so any tampering is detectable. Each event's hash includes the previous hash, so deleting a row breaks the chain forward of that point.",[410,6998,7000],{"className":478,"code":6999,"language":481,"meta":416,"style":416},"auditOnly(\n  signed(createFsDrain({ dir: '.audit' }), { strategy: 'hash-chain' }),\n  { await: true },\n)\n",[323,7001,7002,7008,7055,7067],{"__ignoreMap":416},[420,7003,7004,7006],{"class":422,"line":423},[420,7005,3241],{"class":584},[420,7007,694],{"class":496},[420,7009,7010,7013,7015,7017,7019,7021,7023,7025,7027,7029,7031,7033,7035,7037,7039,7041,7043,7045,7047,7049,7051,7053],{"class":422,"line":526},[420,7011,7012],{"class":584},"  signed",[420,7014,588],{"class":496},[420,7016,705],{"class":584},[420,7018,588],{"class":496},[420,7020,710],{"class":492},[420,7022,713],{"class":623},[420,7024,716],{"class":492},[420,7026,517],{"class":492},[420,7028,721],{"class":430},[420,7030,626],{"class":492},[420,7032,511],{"class":492},[420,7034,597],{"class":496},[420,7036,500],{"class":492},[420,7038,493],{"class":492},[420,7040,734],{"class":623},[420,7042,716],{"class":492},[420,7044,517],{"class":492},[420,7046,741],{"class":430},[420,7048,626],{"class":492},[420,7050,511],{"class":492},[420,7052,597],{"class":496},[420,7054,750],{"class":492},[420,7056,7057,7059,7061,7063,7065],{"class":422,"line":547},[420,7058,5955],{"class":492},[420,7060,759],{"class":623},[420,7062,716],{"class":492},[420,7064,765],{"class":764},[420,7066,768],{"class":492},[420,7068,7069],{"class":422,"line":568},[420,7070,783],{"class":496},[4374,7072,7073,7074,7077,7078,7081,7082,330],{},"A CLI to walk and verify the chain (",[323,7075,7076],{},"evlog audit verify",") is on the roadmap. Until then, validate by recomputing the hashes of stored events and comparing each ",[323,7079,7080],{},"prevHash"," against the previous event's ",[323,7083,7084],{},"hash",[3192,7086,7087,7094,7095,7098,7099,7102,7103,7106],{},[318,7088,7089,7090,7093],{},"Rotate ",[323,7091,7092],{},"secret"," for HMAC-signed audits annually."," When you rotate, embed a key id alongside the signature (e.g. extend ",[323,7096,7097],{},"AuditFields"," with ",[323,7100,7101],{},"keyId"," via ",[323,7104,7105],{},"declare module",") so old events stay verifiable against the previous secret. Verifiers should look up the key by id, not assume a single global secret.",[3248,7108,7110],{"id":7109},"redact","Redact",[314,7112,7113,7114,7117],{},"Audit events run through your existing ",[323,7115,7116],{},"RedactConfig",". Compose with the strict audit preset to harden PII handling:",[410,7119,7121],{"className":478,"code":7120,"language":481,"meta":416,"style":416},"import { auditRedactPreset } from 'evlog'\n\ninitLogger({\n  redact: {\n    paths: [\n      ...(auditRedactPreset.paths ?? []),\n      'user.password',\n    ],\n  },\n})\n",[323,7122,7123,7142,7146,7155,7164,7173,7194,7206,7213,7217],{"__ignoreMap":416},[420,7124,7125,7127,7129,7132,7134,7136,7138,7140],{"class":422,"line":423},[420,7126,489],{"class":488},[420,7128,493],{"class":492},[420,7130,7131],{"class":496}," auditRedactPreset",[420,7133,511],{"class":492},[420,7135,514],{"class":488},[420,7137,517],{"class":492},[420,7139,520],{"class":430},[420,7141,523],{"class":492},[420,7143,7144],{"class":422,"line":526},[420,7145,572],{"emptyLinePlaceholder":571},[420,7147,7148,7151,7153],{"class":422,"line":547},[420,7149,7150],{"class":584},"initLogger",[420,7152,588],{"class":496},[420,7154,911],{"class":492},[420,7156,7157,7160,7162],{"class":422,"line":568},[420,7158,7159],{"class":623},"  redact",[420,7161,716],{"class":492},[420,7163,604],{"class":492},[420,7165,7166,7169,7171],{"class":422,"line":575},[420,7167,7168],{"class":623},"    paths",[420,7170,716],{"class":492},[420,7172,5612],{"class":496},[420,7174,7175,7178,7181,7183,7186,7189,7192],{"class":422,"line":607},[420,7176,7177],{"class":492},"      ...",[420,7179,7180],{"class":496},"(auditRedactPreset",[420,7182,330],{"class":492},[420,7184,7185],{"class":496},"paths ",[420,7187,7188],{"class":492},"??",[420,7190,7191],{"class":496}," [])",[420,7193,750],{"class":492},[420,7195,7196,7199,7202,7204],{"class":422,"line":641},[420,7197,7198],{"class":492},"      '",[420,7200,7201],{"class":430},"user.password",[420,7203,626],{"class":492},[420,7205,750],{"class":492},[420,7207,7208,7211],{"class":422,"line":669},[420,7209,7210],{"class":496},"    ]",[420,7212,750],{"class":492},[420,7214,7215],{"class":422,"line":697},[420,7216,4991],{"class":492},[420,7218,7219,7221],{"class":422,"line":753},[420,7220,780],{"class":492},[420,7222,783],{"class":496},[314,7224,7225,7226,395,7229,7232,7233,447,7235,447,7237,447,7240,447,7243,447,7246,7249,7250,4753,7253,330],{},"The preset drops ",[323,7227,7228],{},"Authorization",[323,7230,7231],{},"Cookie"," headers and common credential field names (",[323,7234,5426],{},[323,7236,5435],{},[323,7238,7239],{},"apiKey",[323,7241,7242],{},"cardNumber",[323,7244,7245],{},"cvv",[323,7247,7248],{},"ssn",") wherever they appear inside ",[323,7251,7252],{},"audit.changes.before",[323,7254,7255],{},"audit.changes.after",[3248,7257,7259],{"id":7258},"gdpr-vs-append-only","GDPR vs Append-Only",[314,7261,7262],{},"Append-only audit logs collide with GDPR's right to be forgotten. Recommended pattern today:",[7264,7265,7266,7269,7272],"ol",{},[343,7267,7268],{},"Keep audit rows immutable.",[343,7270,7271],{},"Encrypt PII fields with a per-actor key (held outside the audit store).",[343,7273,7274],{},"To \"forget\" a user, delete their key — the audit row stays, the chain stays valid, the PII becomes unreadable.",[314,7276,7277,7278,7281,7282,330],{},"A built-in ",[323,7279,7280],{},"cryptoShredding"," helper is on the ",[368,7283,7286],{"href":7284,"rel":7285},"https:\u002F\u002Fgithub.com\u002FHugoRCD\u002Fevlog\u002Fissues",[372],"follow-up roadmap",[3248,7288,7289],{"id":4534},"Retention",[314,7291,7292],{},"Retention is a storage-layer concern by design. evlog's audit layer doesn't enforce retention windows because every supported sink already has a stronger, audited mechanism for it. Pick the one matching your sink:",[340,7294,7295,7305,7314],{},[343,7296,7297,7300,7301,7304],{},[318,7298,7299],{},"FS"," — combine ",[323,7302,7303],{},"createFsDrain({ maxFiles })"," with a daily compactor.",[343,7306,7307,7310,7311,330],{},[318,7308,7309],{},"Postgres"," — schedule ",[323,7312,7313],{},"DELETE FROM audit_events WHERE timestamp \u003C now() - interval '7 years'",[343,7315,7316,7319],{},[318,7317,7318],{},"Axiom \u002F Datadog \u002F Loki"," — set the dataset retention policy in the platform.",[314,7321,7322],{},"Document the chosen window in your security policy. Auditors care about the written rule, not the enforcing component.",[3248,7324,7326],{"id":7325},"common-pitfalls","Common Pitfalls",[340,7328,7329,7341,7362,7368,7387],{},[343,7330,7331,7334,7335,7098,7337,7340],{},[318,7332,7333],{},"Logging only successes."," Auditors care most about denials. Always pair ",[323,7336,3256],{},[323,7338,7339],{},"log.audit.deny()"," on the negative branch of every authorisation check.",[343,7342,7343,7348,7349,7351,7352,7354,7355,447,7357,447,7359,7361],{},[318,7344,7345,7346,330],{},"Leaking PII through ",[323,7347,5179],{}," ",[323,7350,5175],{}," runs through your ",[323,7353,7116],{},", but only if the field paths are listed. Add ",[323,7356,5426],{},[323,7358,5435],{},[323,7360,7239],{},", etc. once globally so you never have to think about it again.",[343,7363,7364,7367],{},[318,7365,7366],{},"Treating audits as observability."," Don't sample, downsample, or summarise audit events. Force-keep is on by default — don't disable it.",[343,7369,7370,7348,7377,7379,7380,395,7383,7386],{},[318,7371,7372,7373,7376],{},"Conflating ",[323,7374,7375],{},"actor.id"," with the session id.",[323,7378,7375],{}," is the stable user id (or system identity). Correlate sessions via ",[323,7381,7382],{},"context.requestId",[323,7384,7385],{},"context.traceId",", never via the actor.",[343,7388,7389,7392,7393,7395,7396,7398],{},[318,7390,7391],{},"Forgetting standalone jobs."," Cron tasks, queue workers, and CLIs trigger audit-worthy actions too. Use ",[323,7394,4012],{}," (no request) or ",[323,7397,3186],{}," to keep coverage parity with your HTTP routes.",[379,7400,7402],{"id":7401},"recipes","Recipes",[3248,7404,7406],{"id":7405},"audit-logs-on-disk","Audit logs on disk",[785,7408,7409,7557],{},[410,7410,7413],{"className":478,"code":7411,"filename":7412,"language":481,"meta":416,"style":416},"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",[323,7414,7415,7437,7455,7459,7485,7541,7553],{"__ignoreMap":416},[420,7416,7417,7419,7421,7423,7425,7427,7429,7431,7433,7435],{"class":422,"line":423},[420,7418,489],{"class":488},[420,7420,493],{"class":492},[420,7422,503],{"class":496},[420,7424,500],{"class":492},[420,7426,508],{"class":496},[420,7428,511],{"class":492},[420,7430,514],{"class":488},[420,7432,517],{"class":492},[420,7434,520],{"class":430},[420,7436,523],{"class":492},[420,7438,7439,7441,7443,7445,7447,7449,7451,7453],{"class":422,"line":526},[420,7440,489],{"class":488},[420,7442,493],{"class":492},[420,7444,554],{"class":496},[420,7446,511],{"class":492},[420,7448,514],{"class":488},[420,7450,517],{"class":492},[420,7452,563],{"class":430},[420,7454,523],{"class":492},[420,7456,7457],{"class":422,"line":547},[420,7458,572],{"emptyLinePlaceholder":571},[420,7460,7461,7463,7465,7467,7469,7471,7473,7475,7477,7479,7481,7483],{"class":422,"line":568},[420,7462,594],{"class":496},[420,7464,330],{"class":492},[420,7466,615],{"class":496},[420,7468,330],{"class":492},[420,7470,620],{"class":584},[420,7472,588],{"class":496},[420,7474,626],{"class":492},[420,7476,658],{"class":430},[420,7478,626],{"class":492},[420,7480,500],{"class":492},[420,7482,503],{"class":584},[420,7484,694],{"class":496},[420,7486,7487,7489,7491,7493,7495,7497,7499,7501,7503,7505,7507,7509,7512,7514,7517,7519,7521,7523,7525,7527,7529,7531,7533,7535,7537,7539],{"class":422,"line":575},[420,7488,7012],{"class":584},[420,7490,588],{"class":496},[420,7492,705],{"class":584},[420,7494,588],{"class":496},[420,7496,710],{"class":492},[420,7498,713],{"class":623},[420,7500,716],{"class":492},[420,7502,517],{"class":492},[420,7504,721],{"class":430},[420,7506,626],{"class":492},[420,7508,500],{"class":492},[420,7510,7511],{"class":623}," maxFiles",[420,7513,716],{"class":492},[420,7515,7516],{"class":2333}," 30",[420,7518,511],{"class":492},[420,7520,597],{"class":496},[420,7522,500],{"class":492},[420,7524,493],{"class":492},[420,7526,734],{"class":623},[420,7528,716],{"class":492},[420,7530,517],{"class":492},[420,7532,741],{"class":430},[420,7534,626],{"class":492},[420,7536,511],{"class":492},[420,7538,597],{"class":496},[420,7540,750],{"class":492},[420,7542,7543,7545,7547,7549,7551],{"class":422,"line":607},[420,7544,5955],{"class":492},[420,7546,759],{"class":623},[420,7548,716],{"class":492},[420,7550,765],{"class":764},[420,7552,768],{"class":492},[420,7554,7555],{"class":422,"line":641},[420,7556,893],{"class":496},[410,7558,7563],{"className":7559,"code":7560,"filename":7561,"language":7562,"meta":416,"style":416},"language-ndjson 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","ndjson",[323,7564,7565,7570],{"__ignoreMap":416},[420,7566,7567],{"class":422,"line":423},[420,7568,7569],{},"{\"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",[420,7571,7572],{"class":422,"line":526},[420,7573,7574],{},"{\"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",[314,7576,7577,7578,7580,7581,7583],{},"Each line's ",[323,7579,7080],{}," matches the previous line's ",[323,7582,7084],{},". Tampering with any row breaks the chain forward of that point — a verifier replays the hashes and reports the first mismatch.",[3248,7585,7587],{"id":7586},"audit-logs-to-a-dedicated-axiom-dataset","Audit logs to a dedicated Axiom dataset",[785,7589,7590,7748,7771],{},[410,7591,7593],{"className":478,"code":7592,"filename":7412,"language":481,"meta":416,"style":416},"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', token: process.env.AXIOM_AUDIT_TOKEN }),\n))\n",[323,7594,7595,7613,7631,7635,7678,7704,7744],{"__ignoreMap":416},[420,7596,7597,7599,7601,7603,7605,7607,7609,7611],{"class":422,"line":423},[420,7598,489],{"class":488},[420,7600,493],{"class":492},[420,7602,503],{"class":496},[420,7604,511],{"class":492},[420,7606,514],{"class":488},[420,7608,517],{"class":492},[420,7610,520],{"class":430},[420,7612,523],{"class":492},[420,7614,7615,7617,7619,7621,7623,7625,7627,7629],{"class":422,"line":526},[420,7616,489],{"class":488},[420,7618,493],{"class":492},[420,7620,533],{"class":496},[420,7622,511],{"class":492},[420,7624,514],{"class":488},[420,7626,517],{"class":492},[420,7628,542],{"class":430},[420,7630,523],{"class":492},[420,7632,7633],{"class":422,"line":547},[420,7634,572],{"emptyLinePlaceholder":571},[420,7636,7637,7639,7641,7643,7645,7647,7649,7651,7653,7655,7657,7659,7661,7663,7665,7667,7669,7672,7674,7676],{"class":422,"line":568},[420,7638,594],{"class":496},[420,7640,330],{"class":492},[420,7642,615],{"class":496},[420,7644,330],{"class":492},[420,7646,620],{"class":584},[420,7648,588],{"class":496},[420,7650,626],{"class":492},[420,7652,658],{"class":430},[420,7654,626],{"class":492},[420,7656,500],{"class":492},[420,7658,533],{"class":584},[420,7660,588],{"class":496},[420,7662,710],{"class":492},[420,7664,4636],{"class":623},[420,7666,716],{"class":492},[420,7668,517],{"class":492},[420,7670,7671],{"class":430},"logs",[420,7673,626],{"class":492},[420,7675,511],{"class":492},[420,7677,893],{"class":496},[420,7679,7680,7682,7684,7686,7688,7690,7692,7694,7696,7698,7700,7702],{"class":422,"line":575},[420,7681,594],{"class":496},[420,7683,330],{"class":492},[420,7685,615],{"class":496},[420,7687,330],{"class":492},[420,7689,620],{"class":584},[420,7691,588],{"class":496},[420,7693,626],{"class":492},[420,7695,658],{"class":430},[420,7697,626],{"class":492},[420,7699,500],{"class":492},[420,7701,503],{"class":584},[420,7703,694],{"class":496},[420,7705,7706,7708,7710,7712,7714,7716,7718,7720,7722,7724,7726,7728,7730,7732,7734,7736,7738,7740,7742],{"class":422,"line":607},[420,7707,4629],{"class":584},[420,7709,588],{"class":496},[420,7711,710],{"class":492},[420,7713,4636],{"class":623},[420,7715,716],{"class":492},[420,7717,517],{"class":492},[420,7719,325],{"class":430},[420,7721,626],{"class":492},[420,7723,500],{"class":492},[420,7725,4649],{"class":623},[420,7727,716],{"class":492},[420,7729,4654],{"class":496},[420,7731,330],{"class":492},[420,7733,4659],{"class":496},[420,7735,330],{"class":492},[420,7737,4664],{"class":496},[420,7739,780],{"class":492},[420,7741,597],{"class":496},[420,7743,750],{"class":492},[420,7745,7746],{"class":422,"line":641},[420,7747,893],{"class":496},[410,7749,7754],{"className":7750,"code":7751,"filename":7752,"language":7753,"meta":416,"style":416},"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",[323,7755,7756,7761,7766],{"__ignoreMap":416},[420,7757,7758],{"class":422,"line":423},[420,7759,7760],{},"['audit']\n",[420,7762,7763],{"class":422,"line":526},[420,7764,7765],{},"| where audit.action == \"invoice.refund\"\n",[420,7767,7768],{"class":422,"line":547},[420,7769,7770],{},"| summarize count() by audit.outcome, bin(_time, 1h)\n",[410,7772,7775],{"className":7750,"code":7773,"filename":7774,"language":7753,"meta":416,"style":416},"['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",[323,7776,7777,7781,7786,7791],{"__ignoreMap":416},[420,7778,7779],{"class":422,"line":423},[420,7780,7760],{},[420,7782,7783],{"class":422,"line":526},[420,7784,7785],{},"| where audit.outcome == \"denied\"\n",[420,7787,7788],{"class":422,"line":547},[420,7789,7790],{},"| summarize count() by audit.actor.id, audit.action\n",[420,7792,7793],{"class":422,"line":568},[420,7794,7795],{},"| order by count_ desc\n",[314,7797,7798],{},"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.",[3248,7800,7802],{"id":7801},"audit-logs-in-postgres","Audit logs in Postgres",[785,7804,7805,8035],{},[410,7806,7808],{"className":478,"code":7807,"filename":7412,"language":481,"meta":416,"style":416},"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",[323,7809,7810,7828,7849,7853,7878,7906,7929,7958,7973,7986,7990,7994],{"__ignoreMap":416},[420,7811,7812,7814,7816,7818,7820,7822,7824,7826],{"class":422,"line":423},[420,7813,489],{"class":488},[420,7815,493],{"class":492},[420,7817,503],{"class":496},[420,7819,511],{"class":492},[420,7821,514],{"class":488},[420,7823,517],{"class":492},[420,7825,520],{"class":430},[420,7827,523],{"class":492},[420,7829,7830,7832,7834,7836,7839,7841,7843,7845,7847],{"class":422,"line":526},[420,7831,489],{"class":488},[420,7833,939],{"class":488},[420,7835,493],{"class":492},[420,7837,7838],{"class":496}," DrainContext",[420,7840,511],{"class":492},[420,7842,514],{"class":488},[420,7844,517],{"class":492},[420,7846,520],{"class":430},[420,7848,523],{"class":492},[420,7850,7851],{"class":422,"line":547},[420,7852,572],{"emptyLinePlaceholder":571},[420,7854,7855,7857,7860,7862,7864,7866,7868,7870,7872,7874,7876],{"class":422,"line":568},[420,7856,1439],{"class":600},[420,7858,7859],{"class":496}," postgresAudit ",[420,7861,1126],{"class":492},[420,7863,1488],{"class":600},[420,7865,809],{"class":492},[420,7867,6051],{"class":593},[420,7869,716],{"class":492},[420,7871,7838],{"class":426},[420,7873,597],{"class":492},[420,7875,601],{"class":600},[420,7877,604],{"class":492},[420,7879,7880,7883,7885,7887,7890,7892,7895,7897,7899,7902,7904],{"class":422,"line":575},[420,7881,7882],{"class":488},"  await",[420,7884,5253],{"class":496},[420,7886,330],{"class":492},[420,7888,7889],{"class":584},"insert",[420,7891,588],{"class":623},[420,7893,7894],{"class":496},"auditEvents",[420,7896,597],{"class":623},[420,7898,330],{"class":492},[420,7900,7901],{"class":584},"values",[420,7903,588],{"class":623},[420,7905,911],{"class":492},[420,7907,7908,7910,7912,7914,7916,7918,7920,7922,7925,7927],{"class":422,"line":607},[420,7909,2823],{"class":623},[420,7911,716],{"class":492},[420,7913,4449],{"class":496},[420,7915,330],{"class":492},[420,7917,812],{"class":496},[420,7919,330],{"class":492},[420,7921,325],{"class":496},[420,7923,7924],{"class":492},"!.",[420,7926,2578],{"class":496},[420,7928,750],{"class":492},[420,7930,7931,7934,7936,7938,7941,7943,7945,7947,7949,7951,7954,7956],{"class":422,"line":641},[420,7932,7933],{"class":623},"    timestamp",[420,7935,716],{"class":492},[420,7937,1447],{"class":492},[420,7939,7940],{"class":584}," Date",[420,7942,588],{"class":623},[420,7944,6051],{"class":496},[420,7946,330],{"class":492},[420,7948,812],{"class":496},[420,7950,330],{"class":492},[420,7952,7953],{"class":496},"timestamp",[420,7955,597],{"class":623},[420,7957,750],{"class":492},[420,7959,7960,7963,7965,7967,7969,7971],{"class":422,"line":669},[420,7961,7962],{"class":623},"    payload",[420,7964,716],{"class":492},[420,7966,4449],{"class":496},[420,7968,330],{"class":492},[420,7970,812],{"class":496},[420,7972,750],{"class":492},[420,7974,7975,7977,7979,7981,7984],{"class":422,"line":697},[420,7976,1048],{"class":492},[420,7978,597],{"class":623},[420,7980,330],{"class":492},[420,7982,7983],{"class":584},"onConflictDoNothing",[420,7985,1164],{"class":623},[420,7987,7988],{"class":422,"line":753},[420,7989,2680],{"class":492},[420,7991,7992],{"class":422,"line":771},[420,7993,572],{"emptyLinePlaceholder":571},[420,7995,7996,7998,8000,8002,8004,8006,8008,8010,8012,8014,8016,8018,8021,8023,8025,8027,8029,8031,8033],{"class":422,"line":777},[420,7997,594],{"class":496},[420,7999,330],{"class":492},[420,8001,615],{"class":496},[420,8003,330],{"class":492},[420,8005,620],{"class":584},[420,8007,588],{"class":496},[420,8009,626],{"class":492},[420,8011,658],{"class":430},[420,8013,626],{"class":492},[420,8015,500],{"class":492},[420,8017,503],{"class":584},[420,8019,8020],{"class":496},"(postgresAudit",[420,8022,500],{"class":492},[420,8024,493],{"class":492},[420,8026,759],{"class":623},[420,8028,716],{"class":492},[420,8030,765],{"class":764},[420,8032,511],{"class":492},[420,8034,893],{"class":496},[410,8036,8041],{"className":8037,"code":8038,"filename":8039,"language":8040,"meta":416,"style":416},"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",[323,8042,8043,8048,8053,8058,8063,8067,8072,8077],{"__ignoreMap":416},[420,8044,8045],{"class":422,"line":423},[420,8046,8047],{},"SELECT id, timestamp, payload->'audit'->>'action' AS action,\n",[420,8049,8050],{"class":422,"line":526},[420,8051,8052],{},"       payload->'audit'->>'outcome' AS outcome\n",[420,8054,8055],{"class":422,"line":547},[420,8056,8057],{},"FROM audit_events\n",[420,8059,8060],{"class":422,"line":568},[420,8061,8062],{},"WHERE id = 'ak_8f3c4b2a1e5d6f7c';\n",[420,8064,8065],{"class":422,"line":575},[420,8066,572],{"emptyLinePlaceholder":571},[420,8068,8069],{"class":422,"line":607},[420,8070,8071],{},"--          id          |       timestamp       |     action      | outcome\n",[420,8073,8074],{"class":422,"line":641},[420,8075,8076],{},"-- ---------------------+-----------------------+-----------------+---------\n",[420,8078,8079],{"class":422,"line":669},[420,8080,8081],{},"--  ak_8f3c4b2a1e5d6f7c | 2026-04-24 10:23:45.6 | invoice.refund  | success\n",[314,8083,8084,8085,8087,8088,8091],{},"The deterministic ",[323,8086,2578],{}," makes retries safe — duplicate inserts collapse via ",[323,8089,8090],{},"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.",[379,8093,8095],{"id":8094},"testing","Testing",[314,8097,8098,8101],{},[323,8099,8100],{},"mockAudit()"," captures every audit event emitted during a test:",[410,8103,8105],{"className":478,"code":8104,"language":481,"meta":416,"style":416},"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  expect(captured.events).toHaveLength(1)\n  expect(captured.toIncludeAuditOf({\n    action: 'invoice.refund',\n    target: { type: 'invoice', id: 'inv_889' },\n    outcome: 'success',\n  })).toBe(true)\n\n  captured.restore()\n})\n",[323,8106,8107,8126,8130,8154,8167,8171,8231,8235,8264,8281,8295,8327,8341,8360,8364,8376],{"__ignoreMap":416},[420,8108,8109,8111,8113,8116,8118,8120,8122,8124],{"class":422,"line":423},[420,8110,489],{"class":488},[420,8112,493],{"class":492},[420,8114,8115],{"class":496}," mockAudit",[420,8117,511],{"class":492},[420,8119,514],{"class":488},[420,8121,517],{"class":492},[420,8123,520],{"class":430},[420,8125,523],{"class":492},[420,8127,8128],{"class":422,"line":526},[420,8129,572],{"emptyLinePlaceholder":571},[420,8131,8132,8135,8137,8139,8142,8144,8146,8148,8150,8152],{"class":422,"line":547},[420,8133,8134],{"class":584},"it",[420,8136,588],{"class":496},[420,8138,626],{"class":492},[420,8140,8141],{"class":430},"refunds the invoice and records an audit",[420,8143,626],{"class":492},[420,8145,500],{"class":492},[420,8147,1488],{"class":600},[420,8149,4899],{"class":492},[420,8151,601],{"class":600},[420,8153,604],{"class":492},[420,8155,8156,8158,8161,8163,8165],{"class":422,"line":568},[420,8157,823],{"class":600},[420,8159,8160],{"class":496}," captured",[420,8162,829],{"class":492},[420,8164,8115],{"class":584},[420,8166,1164],{"class":623},[420,8168,8169],{"class":422,"line":575},[420,8170,572],{"emptyLinePlaceholder":571},[420,8172,8173,8175,8177,8179,8181,8183,8185,8187,8189,8191,8193,8195,8198,8200,8202,8204,8206,8208,8210,8212,8214,8216,8218,8220,8223,8225,8227,8229],{"class":422,"line":607},[420,8174,7882],{"class":488},[420,8176,872],{"class":584},[420,8178,588],{"class":623},[420,8180,710],{"class":492},[420,8182,953],{"class":623},[420,8184,716],{"class":492},[420,8186,517],{"class":492},[420,8188,2184],{"class":430},[420,8190,626],{"class":492},[420,8192,5144],{"class":492},[420,8194,493],{"class":492},[420,8196,8197],{"class":623}," actor",[420,8199,716],{"class":492},[420,8201,493],{"class":492},[420,8203,939],{"class":623},[420,8205,716],{"class":492},[420,8207,517],{"class":492},[420,8209,946],{"class":430},[420,8211,626],{"class":492},[420,8213,500],{"class":492},[420,8215,953],{"class":623},[420,8217,716],{"class":492},[420,8219,517],{"class":492},[420,8221,8222],{"class":430},"u1",[420,8224,626],{"class":492},[420,8226,511],{"class":492},[420,8228,511],{"class":492},[420,8230,783],{"class":623},[420,8232,8233],{"class":422,"line":641},[420,8234,572],{"emptyLinePlaceholder":571},[420,8236,8237,8240,8242,8245,8247,8250,8252,8254,8257,8259,8262],{"class":422,"line":669},[420,8238,8239],{"class":584},"  expect",[420,8241,588],{"class":623},[420,8243,8244],{"class":496},"captured",[420,8246,330],{"class":492},[420,8248,8249],{"class":496},"events",[420,8251,597],{"class":623},[420,8253,330],{"class":492},[420,8255,8256],{"class":584},"toHaveLength",[420,8258,588],{"class":623},[420,8260,8261],{"class":2333},"1",[420,8263,783],{"class":623},[420,8265,8266,8268,8270,8272,8274,8277,8279],{"class":422,"line":697},[420,8267,8239],{"class":584},[420,8269,588],{"class":623},[420,8271,8244],{"class":496},[420,8273,330],{"class":492},[420,8275,8276],{"class":584},"toIncludeAuditOf",[420,8278,588],{"class":623},[420,8280,911],{"class":492},[420,8282,8283,8285,8287,8289,8291,8293],{"class":422,"line":753},[420,8284,916],{"class":623},[420,8286,716],{"class":492},[420,8288,517],{"class":492},[420,8290,923],{"class":430},[420,8292,626],{"class":492},[420,8294,750],{"class":492},[420,8296,8297,8299,8301,8303,8305,8307,8309,8311,8313,8315,8317,8319,8321,8323,8325],{"class":422,"line":771},[420,8298,982],{"class":623},[420,8300,716],{"class":492},[420,8302,493],{"class":492},[420,8304,939],{"class":623},[420,8306,716],{"class":492},[420,8308,517],{"class":492},[420,8310,995],{"class":430},[420,8312,626],{"class":492},[420,8314,500],{"class":492},[420,8316,953],{"class":623},[420,8318,716],{"class":492},[420,8320,517],{"class":492},[420,8322,2184],{"class":430},[420,8324,626],{"class":492},[420,8326,768],{"class":492},[420,8328,8329,8331,8333,8335,8337,8339],{"class":422,"line":777},[420,8330,1016],{"class":623},[420,8332,716],{"class":492},[420,8334,517],{"class":492},[420,8336,1023],{"class":430},[420,8338,626],{"class":492},[420,8340,750],{"class":492},[420,8342,8343,8345,8348,8350,8353,8355,8358],{"class":422,"line":1053},[420,8344,1048],{"class":492},[420,8346,8347],{"class":623},"))",[420,8349,330],{"class":492},[420,8351,8352],{"class":584},"toBe",[420,8354,588],{"class":623},[420,8356,8357],{"class":764},"true",[420,8359,783],{"class":623},[420,8361,8362],{"class":422,"line":1058},[420,8363,572],{"emptyLinePlaceholder":571},[420,8365,8366,8369,8371,8374],{"class":422,"line":1076},[420,8367,8368],{"class":496},"  captured",[420,8370,330],{"class":492},[420,8372,8373],{"class":584},"restore",[420,8375,1164],{"class":623},[420,8377,8378,8380],{"class":422,"line":1352},[420,8379,780],{"class":492},[420,8381,783],{"class":496},[379,8383,8385],{"id":8384},"api-reference","API Reference",[8387,8388,8389,8405],"table",{},[8390,8391,8392],"thead",{},[8393,8394,8395,8399,8402],"tr",{},[8396,8397,8398],"th",{},"Symbol",[8396,8400,8401],{},"Kind",[8396,8403,8404],{},"Notes",[8406,8407,8408,8420,8433,8449,8460,8473,8486,8500,8512,8524,8539,8550],"tbody",{},[8393,8409,8410,8415,8417],{},[8411,8412,8413],"td",{},[323,8414,7097],{},[8411,8416,2426],{},[8411,8418,8419],{},"Reserved field on the wide event",[8393,8421,8422,8427,8430],{},[8411,8423,8424],{},[323,8425,8426],{},"defineAuditAction(name, opts?)",[8411,8428,8429],{},"factory",[8411,8431,8432],{},"Typed action registry, infers target shape",[8393,8434,8435,8440,8442],{},[8411,8436,8437],{},[323,8438,8439],{},"log.audit(fields)",[8411,8441,2286],{},[8411,8443,8444,8445,8448],{},"Sugar over ",[323,8446,8447],{},"log.set({ audit })"," + force-keep",[8393,8450,8451,8455,8457],{},[8411,8452,8453],{},[323,8454,3442],{},[8411,8456,2286],{},[8411,8458,8459],{},"Records a denied action",[8393,8461,8462,8467,8470],{},[8411,8463,8464],{},[323,8465,8466],{},"audit(fields)",[8411,8468,8469],{},"function",[8411,8471,8472],{},"Standalone for scripts \u002F jobs",[8393,8474,8475,8480,8483],{},[8411,8476,8477],{},[323,8478,8479],{},"withAudit({ action, target })(fn)",[8411,8481,8482],{},"wrapper",[8411,8484,8485],{},"Auto-emit success \u002F failure \u002F denied",[8393,8487,8488,8493,8495],{},[8411,8489,8490],{},[323,8491,8492],{},"auditDiff(before, after)",[8411,8494,3250],{},[8411,8496,8497,8498],{},"Redact-aware JSON Patch for ",[323,8499,5179],{},[8393,8501,8502,8506,8509],{},[8411,8503,8504],{},[323,8505,8100],{},[8411,8507,8508],{},"test util",[8411,8510,8511],{},"Capture + assert audits in tests",[8393,8513,8514,8519,8521],{},[8411,8515,8516],{},[323,8517,8518],{},"auditEnricher(opts?)",[8411,8520,4395],{},[8411,8522,8523],{},"Auto-fill request \u002F runtime \u002F tenant context",[8393,8525,8526,8531,8533],{},[8411,8527,8528],{},[323,8529,8530],{},"auditOnly(drain, { await? })",[8411,8532,8482],{},[8411,8534,8535,8536,8538],{},"Routes only events with an ",[323,8537,325],{}," field",[8393,8540,8541,8545,8547],{},[8411,8542,8543],{},[323,8544,4731],{},[8411,8546,8482],{},[8411,8548,8549],{},"Generic integrity wrapper (hmac \u002F hash-chain)",[8393,8551,8552,8557,8560],{},[8411,8553,8554],{},[323,8555,8556],{},"auditRedactPreset",[8411,8558,8559],{},"config",[8411,8561,8562],{},"Strict PII for audit events",[314,8564,8565,8566,8568],{},"Everything ships from the main ",[323,8567,520],{}," entrypoint.",[8570,8571,8572],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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":416,"searchDepth":526,"depth":526,"links":8574},[8575,8576,8577,8578,8579,8587,8594,8599,8600],{"id":381,"depth":526,"text":382},{"id":453,"depth":526,"text":454},{"id":471,"depth":526,"text":472},{"id":2732,"depth":526,"text":2733},{"id":3215,"depth":526,"text":3216,"children":8580},[8581,8582,8583,8584,8585],{"id":3250,"depth":547,"text":3251},{"id":4395,"depth":547,"text":4396},{"id":4516,"depth":547,"text":4517},{"id":5000,"depth":547,"text":5001},{"id":5876,"depth":547,"text":8586},"Auto-Instrumentation with withAudit()",{"id":6988,"depth":526,"text":6989,"children":8588},[8589,8590,8591,8592,8593],{"id":6992,"depth":547,"text":6993},{"id":7109,"depth":547,"text":7110},{"id":7258,"depth":547,"text":7259},{"id":4534,"depth":547,"text":7289},{"id":7325,"depth":547,"text":7326},{"id":7401,"depth":526,"text":7402,"children":8595},[8596,8597,8598],{"id":7405,"depth":547,"text":7406},{"id":7586,"depth":547,"text":7587},{"id":7801,"depth":547,"text":7802},{"id":8094,"depth":526,"text":8095},{"id":8384,"depth":526,"text":8385},"First-class audit logs as a thin layer on top of evlog's wide events. Add tamper-evident audit trails to any app with one enricher, one drain wrapper, and one helper.","md",[8604,8607],{"label":51,"icon":54,"to":52,"color":8605,"variant":8606},"neutral","subtle",{"label":8608,"icon":8609,"to":72,"color":8605,"variant":8606},"Better Auth","i-lucide-key-round",{},{"icon":79},{"title":76,"description":8601},"qNTwiKo59Jv69dbyPH3oickREJt87mChmIETlcXLIgM",[8615,8617],{"title":71,"path":72,"stem":73,"description":8616,"icon":74,"children":-1},"Automatically identify users on every request. Every wide event includes who made the request — userId, user profile, and session metadata — with zero manual work.",{"title":86,"path":87,"stem":88,"description":8618,"icon":89,"children":-1},"Understand the full lifecycle of an evlog event, from creation to drain. Covers all three modes (simple logging, wide events, request logging), sampling, enrichment, and delivery.",1777667163419]