codeburn/packages/core
iamtoruk fb433df656 fix(core): key the diagnostic detail and copilot's JetBrains digest
A diagnostic detail was "any string without a path separator, capped at
200 chars". That let a path with no slashes, a command fragment, a prompt
line, or an API key through verbatim — the rule was structural but it
guarded the wrong structure. A detail is now the 16-hex HMAC-SHA256
fingerprint of the offending input under the host privacy key: identical
failures dedupe, distinct failures differ, and no substring of the input
survives. A caller with no key omits the field entirely rather than
emitting an unkeyed digest, which is what `keyedDetail` is for.

isolateRecords is the only place a detail is derived. Diagnostics a
caller RETURNS are trusted for index and code only; any detail they carry
is stripped, so an unkeyed or caller-invented digest cannot cross the
boundary through a loose cast. The three decoders that reported
malformed-json (opencode-session, vscode-cline, zed) are wired to it.

Copilot's JetBrains dedup key embedded an unkeyed sha256 of the
assistant's REPLY TEXT — dictionary-attackable for short replies ("OK",
"Done.") — and it crosses into the envelope and the CLI ledger. It is now
an HMAC under the host privacy key, with a
`cli-shutdown-cost-v1-skills-dedup-key-hmac-v1` parse version: copilot is
the sole durable provider, so its union-merge would otherwise keep the
old-shape keys and append the new ones for the same records.

Breaking for consumers: DIAGNOSTIC_DETAIL_MAX is gone, sanitizeDetail
takes a key, DiagnosticDetail accepts only the fingerprint, and
RecordOutcome.diagnostics may no longer carry a detail.
2026-08-21 10:18:58 -07:00
..
schemas fix(core): bound the model field at the observation boundary 2026-08-21 10:18:58 -07:00
scripts build(core): stop shipping sourcemaps, expose schemas, tighten the barrel 2026-08-05 03:49:47 +03:00
src fix(core): key the diagnostic detail and copilot's JetBrains digest 2026-08-21 10:18:58 -07:00
tests fix(core): key the diagnostic detail and copilot's JetBrains digest 2026-08-21 10:18:58 -07:00
package.json build(core): stop shipping sourcemaps, expose schemas, tighten the barrel 2026-08-05 03:49:47 +03:00
README.md docs(core): replace Phase 1 skeleton README; bump core to 0.9.20 for republish 2026-07-27 10:52:38 -07:00
tsconfig.build.json chore: stop emitting declaration maps 2026-07-27 15:22:15 -07:00
tsconfig.json feat(core): observation schema, contracts, fingerprints, guardrail harnesses (phase 2) 2026-07-26 10:43:21 -07:00
tsup.config.ts build(core): stop shipping sourcemaps, expose schemas, tighten the barrel 2026-08-05 03:49:47 +03:00
vitest.config.ts feat(core): observation schema, contracts, fingerprints, guardrail harnesses (phase 2) 2026-07-26 10:43:21 -07:00

@codeburn/core

The pure decode/detect engine behind CodeBurn: provider session-log decoding for 36 AI coding tools, content-minimized observation envelopes, and detector contracts.

Status: 0.x. The engine is complete and battle-tested (it is the same code the CodeBurn CLI runs, proven byte-identical to the pre-extraction implementation on a frozen real-world corpus), but the public API may still change between 0.x minor versions. Pin accordingly.

What it does

  • Decode: each provider module (@codeburn/core/providers/<name>) turns that tool's raw session records into structured call data — tokens, models, timing, tool usage — with the provider's exact dedup and skip semantics.
  • Observations: toObservations maps rich decode output into a strict, content-minimized envelope: only fingerprints, enums, numbers, timestamps, dedup keys, and canonical tool names cross the boundary. Enforced by an architecture gate and per-provider content-smuggling tests.
  • Detectors: contracts for waste/optimization findings over fingerprinted data.

What it deliberately does NOT do

No file or network I/O, no environment access, no clock reads, no pricing. Hosts (the CodeBurn CLI, apps, or your own tooling) supply the records and apply their own pricing. The only runtime dependency is zod.

Usage

import { decodeQwen } from '@codeburn/core/providers/qwen'
import { toObservations } from '@codeburn/core/providers/qwen'
import { OBSERVATION_SCHEMA_VERSION } from '@codeburn/core/schema'

const { calls, diagnostics } = decodeQwen({ records, seenKeys })

Each provider is its own subpath export; see package.json#exports for the full list. JSON Schemas for the observation envelope ship under schemas/.

Part of the CodeBurn core extraction (RFC #796, tracking #809). MIT.