altimate-receipts 0.22.0 → 0.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/dist/{chunk-OW3O53BD.js → chunk-BC2NBB4X.js} +34 -22
- package/dist/chunk-BC2NBB4X.js.map +1 -0
- package/dist/cli.js +19 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-OW3O53BD.js.map +0 -1
package/README.md
CHANGED
|
@@ -137,9 +137,21 @@ _Real output — [the PR that built this very feature](https://github.com/Altima
|
|
|
137
137
|
- **Destructive ops.** `rm -rf`, force-pushes, history rewrites.
|
|
138
138
|
- **Gamed checks.** A weakened linter or `tsconfig`, an edited grader or test assertion.
|
|
139
139
|
- **Quiet churn.** Files edited then reverted; loops that burned spend with nothing to show.
|
|
140
|
+
- **Half-finished work.** Agent TODOs left open, deferred-for-later markers, and net-new stubs
|
|
141
|
+
introduced in this change (`agent-todo-incomplete`, `deferred-marker-introduced`, `net-new-stub`).
|
|
142
|
+
- **Unverified completion.** Acceptance criteria with no covering evidence, and "green" runs with a
|
|
143
|
+
weak or self-authored oracle (`weak-oracle`, `self-tested` — behind `RECEIPTS_EXPERIMENTAL_DETECTORS`).
|
|
144
|
+
- **Claims vs. the world.** External-state claims ("opened the PR", "cut the release") reconciled
|
|
145
|
+
against the GitHub API (`receipts reconcile`, opt-in).
|
|
140
146
|
|
|
141
147
|
Every finding is cited to a line in the transcript, or it doesn't ship.
|
|
142
148
|
|
|
149
|
+
Beyond the record, receipts can also produce a **work-verdict** (`receipts verdict` —
|
|
150
|
+
VERIFIED / INCOMPLETE / WRONG / ESCALATE, from the facts + your `.receipts/asserts.json` policy),
|
|
151
|
+
fold external **scanner** results (SARIF/semgrep) into the receipt, and — when the session ran
|
|
152
|
+
through [`altimate-router`](https://github.com/AltimateAI/altimate-router) — carry an independent
|
|
153
|
+
**witnessed** attestation of the model's decisions (`receipts verify --witness`).
|
|
154
|
+
|
|
143
155
|
## Why you can trust it
|
|
144
156
|
|
|
145
157
|
- **Deterministic — no LLM in the path.** Findings come from rules over the transcript.
|
|
@@ -200,13 +212,16 @@ three tiers:
|
|
|
200
212
|
Blocked calls never reach the transcript, so the guard **records each deny/ask/warn into the
|
|
201
213
|
Receipt** — the highest-signal line a record can carry: *what the agent was stopped from doing.*
|
|
202
214
|
|
|
203
|
-
**
|
|
215
|
+
**Active gating is your call — one env var, three modes:**
|
|
204
216
|
|
|
205
217
|
```sh
|
|
206
|
-
RECEIPTS_GUARD=
|
|
218
|
+
RECEIPTS_GUARD=watch # shadow: narrate what it WOULD block ("👁️ WOULD BLOCK …"), never block
|
|
219
|
+
RECEIPTS_GUARD=on # enforce (the default once installed) — deny/ask as above
|
|
220
|
+
RECEIPTS_GUARD=0 # off without un-installing (fail-open, records nothing)
|
|
207
221
|
```
|
|
208
222
|
|
|
209
|
-
|
|
223
|
+
`watch` is the on-ramp: see the policy fire on your real traffic, build trust, then flip to `on`.
|
|
224
|
+
Either way the guard is **fail-open by contract** — any error, or the opt-out, allows the call. The
|
|
210
225
|
post-hoc Record is the backstop, so live enforcement favors letting work through.
|
|
211
226
|
|
|
212
227
|
## Going deeper (optional)
|
|
@@ -400,6 +400,9 @@ var VERB = {
|
|
|
400
400
|
function norm(s) {
|
|
401
401
|
return s.replace(/[`'"]/g, "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
402
402
|
}
|
|
403
|
+
function oneLine(s) {
|
|
404
|
+
return s.replace(/`/g, "").replace(/\s+/g, " ").trim();
|
|
405
|
+
}
|
|
403
406
|
function deriveGuardEvents(events, existing = []) {
|
|
404
407
|
const existingSubjects = existing.map((f) => norm(`${f.title} ${f.filePath ?? ""} ${f.detail ?? ""}`)).filter(Boolean);
|
|
405
408
|
const out = [];
|
|
@@ -424,8 +427,8 @@ function deriveGuardEvents(events, existing = []) {
|
|
|
424
427
|
out.push({
|
|
425
428
|
id: `${ID[e.action]}-${i}`,
|
|
426
429
|
severity: SEV[e.action],
|
|
427
|
-
title: `Live guard ${VERB[e.action]}: ${e.subject.slice(0, 80)}`,
|
|
428
|
-
detail: `The receipts-guard hook ${VERB[e.action]} \`${e.subject.slice(0, 200)}\` before it ran (guardrail: ${e.ruleId}). ${e.guardrail}${fix} This is a live-guard record \u2014 it is attested, not re-derived from the transcript (the blocked call never reached it).`,
|
|
430
|
+
title: `Live guard ${VERB[e.action]}: ${oneLine(e.subject).slice(0, 80)}`,
|
|
431
|
+
detail: `The receipts-guard hook ${VERB[e.action]} \`${oneLine(e.subject).slice(0, 200)}\` before it ran (guardrail: ${e.ruleId}). ${e.guardrail}${fix} This is a live-guard record \u2014 it is attested, not re-derived from the transcript (the blocked call never reached it).`,
|
|
429
432
|
impactLabel: `guard ${e.action}`,
|
|
430
433
|
confidence: 1,
|
|
431
434
|
score: e.action === "deny" ? 1e3 : e.action === "ask" ? 100 : 10,
|
|
@@ -670,13 +673,19 @@ function masthead(p, ev, files) {
|
|
|
670
673
|
parts.push(`${files.length} file${files.length === 1 ? "" : "s"}`);
|
|
671
674
|
}
|
|
672
675
|
const band = costConfidence(ev.diffTurns ?? 0, ev.diffTokens ?? 0, files.length, ev.diffCostUsd);
|
|
676
|
+
let clarifier = "";
|
|
673
677
|
if (p.prEffort && p.prEffort.sessions > 1) {
|
|
674
678
|
parts.push(`${p.prEffort.sessions} sessions`);
|
|
675
679
|
parts.push(`${costVerb(band)} ${formatCostAlways(p.prEffort.totalUsd)} on this PR`);
|
|
676
680
|
} else if (ev.diffCostUsd != null && band !== "none") {
|
|
677
|
-
parts.push(`${costVerb(band)} ${formatCostAlways(ev.diffCostUsd)} on this
|
|
681
|
+
parts.push(`${costVerb(band)} ${formatCostAlways(ev.diffCostUsd)} on this change`);
|
|
682
|
+
const peak = Math.max(0, ...(p.prHistory ?? []).map((h) => h.costUsd ?? 0));
|
|
683
|
+
if (peak > ev.diffCostUsd + 5e-3) {
|
|
684
|
+
clarifier = `
|
|
685
|
+
<sub>final diff \u2014 an earlier push attributed ${formatCostAlways(peak)} on a broader diff; see the ledger below.</sub>`;
|
|
686
|
+
}
|
|
678
687
|
}
|
|
679
|
-
return `### ${parts.join(" \xB7 ")}`;
|
|
688
|
+
return `### ${parts.join(" \xB7 ")}${clarifier}`;
|
|
680
689
|
}
|
|
681
690
|
function coverageCell(ev, files) {
|
|
682
691
|
if (ev.coveredFiles == null || !files.length) {
|
|
@@ -798,7 +807,7 @@ function testsCell(ev) {
|
|
|
798
807
|
}
|
|
799
808
|
function recordDetails(p, ev, cats, operatorCount, opts, feedback) {
|
|
800
809
|
const inner = [];
|
|
801
|
-
if (p.prHistory
|
|
810
|
+
if (p.prHistory && p.prHistory.length > 1) {
|
|
802
811
|
inner.push("| push | events | change cost |", "| :-- | :-- | :-- |");
|
|
803
812
|
for (const h of p.prHistory) {
|
|
804
813
|
const id = h.sha ? ` \xB7 \`${h.sha}\`` : "";
|
|
@@ -808,7 +817,7 @@ function recordDetails(p, ev, cats, operatorCount, opts, feedback) {
|
|
|
808
817
|
);
|
|
809
818
|
}
|
|
810
819
|
inner.push(
|
|
811
|
-
"<sub>change cost per row = the attributed cost at that push (
|
|
820
|
+
"<sub>change cost per row = the diff-attributed cost at that push \u2014 re-derived against that push's diff, so rows are independent (not additive) and shrink when the diff narrows.</sub>",
|
|
812
821
|
""
|
|
813
822
|
);
|
|
814
823
|
}
|
|
@@ -820,12 +829,7 @@ function recordDetails(p, ev, cats, operatorCount, opts, feedback) {
|
|
|
820
829
|
if (ledger) {
|
|
821
830
|
inner.push(ledger, "");
|
|
822
831
|
}
|
|
823
|
-
inner.push(
|
|
824
|
-
`**Checks** _("not detected" means this check found nothing \u2014 not that nothing exists)_`,
|
|
825
|
-
"",
|
|
826
|
-
checksTable(cats),
|
|
827
|
-
""
|
|
828
|
-
);
|
|
832
|
+
inner.push(checksSection(cats), "");
|
|
829
833
|
const cl = diffCostLine(ev, files, p.prEffort);
|
|
830
834
|
if (cl) {
|
|
831
835
|
inner.push(cl);
|
|
@@ -959,15 +963,23 @@ function feedbackLine(agent, flagged) {
|
|
|
959
963
|
const url = `${FEEDBACK_ISSUE_BASE}?${qs}`;
|
|
960
964
|
return `<sub>Wrong or noisy event? [Report it \u2014 prefilled \u203A](${url}) \xB7 or react \u{1F44D}/\u{1F44E} on this comment. It tunes the checks.</sub>`;
|
|
961
965
|
}
|
|
962
|
-
function
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
return
|
|
968
|
-
}
|
|
969
|
-
rows.
|
|
970
|
-
return [
|
|
966
|
+
function checksSection(cats) {
|
|
967
|
+
const ran = cats.flagged.length + cats.cleared.length;
|
|
968
|
+
if (ran === 0) return "";
|
|
969
|
+
const clearedNote = cats.cleared.length ? `<sub>Also ran \u2014 nothing detected: ${cats.cleared.map((c) => c.label).join(" \xB7 ")}. "not detected" means a check found nothing, not that nothing exists.</sub>` : "";
|
|
970
|
+
if (!cats.flagged.length) {
|
|
971
|
+
return [`**Checks** \u2014 all ${ran} clear`, "", clearedNote].filter(Boolean).join("\n");
|
|
972
|
+
}
|
|
973
|
+
const rows = cats.flagged.map((fl) => `| ${fl.check.label} | ${fl.count} detected |`);
|
|
974
|
+
return [
|
|
975
|
+
`**Checks** \u2014 ${cats.flagged.length} flagged \xB7 ${cats.cleared.length} found nothing`,
|
|
976
|
+
"",
|
|
977
|
+
"| check | reading |",
|
|
978
|
+
"| :-- | :-- |",
|
|
979
|
+
...rows,
|
|
980
|
+
"",
|
|
981
|
+
clearedNote
|
|
982
|
+
].filter(Boolean).join("\n");
|
|
971
983
|
}
|
|
972
984
|
function diffCostInline(ev, files) {
|
|
973
985
|
if (ev.diffCostUsd == null) return "";
|
|
@@ -1391,4 +1403,4 @@ export {
|
|
|
1391
1403
|
rederiveFromTranscript,
|
|
1392
1404
|
compareToTranscript
|
|
1393
1405
|
};
|
|
1394
|
-
//# sourceMappingURL=chunk-
|
|
1406
|
+
//# sourceMappingURL=chunk-BC2NBB4X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/report/sarif.ts","../src/export/otel.ts","../src/export/registry.ts","../src/receipt/canonical.ts","../src/report/prComment.ts","../src/findings/externalState.ts","../src/findings/guardEvents.ts","../src/report/costBand.ts","../src/share/clipboard.ts","../src/share/markdown.ts","../src/sign/envelope.ts","../src/trace/commitMatch.ts","../src/trace/gitCommand.ts","../src/trace/slice.ts","../src/sign/rederive.ts"],"sourcesContent":["import type { Receipt, ReceiptFinding } from \"../receipt/build.js\";\nimport { type CheckSeverity, checkForId } from \"./checks.js\";\n\n/**\n * `receipts sarif` (M63) — render a receipt's findings as a SARIF 2.1.0 log so GitHub\n * code-scanning can post them **inline on the diff** and in the **Security tab** (the native\n * machine-findings surface). Unlocked by M62: file-anchored findings now carry `line`, so each\n * maps to a SARIF result with `region.startLine`. Pure transform of a verified receipt;\n * deterministic; zero model calls. It re-presents the same facts (R2) — no new judgement.\n *\n * Uploading is the user's CI step (`github/codeql-action/upload-sarif`, needs\n * `security-events: write` + GHAS on private repos) — see docs/sarif.md.\n */\n\nconst INFO_URI = \"https://github.com/AltimateAI/altimate-receipts\";\n\nexport interface SarifLog {\n $schema: string;\n version: \"2.1.0\";\n runs: SarifRun[];\n}\ninterface SarifRun {\n tool: { driver: { name: string; informationUri: string; version?: string; rules: SarifRule[] } };\n results: SarifResult[];\n}\ninterface SarifRule {\n id: string;\n name: string;\n shortDescription: { text: string };\n defaultConfiguration: { level: SarifLevel };\n helpUri: string;\n}\ninterface SarifResult {\n ruleId: string;\n ruleIndex: number;\n level: SarifLevel;\n message: { text: string };\n locations?: {\n physicalLocation: {\n artifactLocation: { uri: string };\n region?: { startLine: number };\n };\n }[];\n partialFingerprints: { receiptsId: string };\n}\ntype SarifLevel = \"error\" | \"warning\" | \"note\";\n\n/** SARIF severity level for a finding's severity (the catalog/PR-comment mapping). */\nfunction levelOf(severity: CheckSeverity | undefined): SarifLevel {\n if (severity === \"critical\" || severity === \"high\") return \"error\";\n if (severity === \"medium\") return \"warning\";\n return \"note\";\n}\n\n/** Stable rule id for a finding: the merge-surface category key when it's in the catalog\n * (groups like the PR comment), else the finding-id prefix with the volatile span suffix\n * stripped (e.g. `claimed-commit-none-gen-3` → `claimed-commit-none`). */\nfunction ruleIdOf(id: string): string {\n const check = checkForId(id);\n if (check) return check.key;\n return id.replace(/-(?:tool|gen|span|s)-?\\d.*$/i, \"\") || id;\n}\n\n/** Map a finding's `filePath` to a repo-relative path: prefer the matching scope-file entry\n * (so code-scanning anchors correctly), else fall back to the basename. */\nfunction repoRelative(filePath: string, scopeFiles: readonly string[]): string {\n const base = filePath.split(\"/\").pop() ?? filePath;\n for (const sf of scopeFiles) {\n if (sf === filePath || sf.endsWith(`/${filePath}`) || filePath.endsWith(`/${sf}`)) return sf;\n if ((sf.split(\"/\").pop() ?? sf) === base) return sf;\n }\n return base;\n}\n\n/** Build a SARIF 2.1.0 log from a verified receipt. */\nexport function toSarif(receipt: Receipt): SarifLog {\n const p = receipt.predicate;\n const scopeFiles = p.scope?.files ?? [];\n const findings: ReceiptFinding[] = p.findings ?? [];\n\n // Collect rules (deduped by ruleId), tracking the worst level seen per rule.\n const ruleOrder: string[] = [];\n const rules = new Map<string, SarifRule>();\n const sevRank: Record<SarifLevel, number> = { error: 0, warning: 1, note: 2 };\n\n const results: SarifResult[] = findings.map((f) => {\n const ruleId = ruleIdOf(f.id);\n const level = levelOf(f.severity);\n const existing = rules.get(ruleId);\n if (!existing) {\n ruleOrder.push(ruleId);\n rules.set(ruleId, {\n id: ruleId,\n name: checkForId(f.id)?.label ?? ruleId,\n shortDescription: { text: checkForId(f.id)?.label ?? ruleId },\n defaultConfiguration: { level },\n helpUri: INFO_URI,\n });\n } else if (sevRank[level] < sevRank[existing.defaultConfiguration.level]) {\n existing.defaultConfiguration.level = level;\n }\n const uri = f.filePath ? repoRelative(f.filePath, scopeFiles) : undefined;\n const result: SarifResult = {\n ruleId,\n ruleIndex: ruleOrder.indexOf(ruleId),\n level,\n message: { text: f.detail ? `${f.title} — ${f.detail}` : f.title },\n // Stable across commits: rule + path, never the volatile span id.\n partialFingerprints: { receiptsId: `${ruleId}::${uri ?? \"session\"}` },\n };\n if (uri) {\n result.locations = [\n {\n physicalLocation: {\n artifactLocation: { uri },\n ...(f.line ? { region: { startLine: f.line } } : {}),\n },\n },\n ];\n }\n return result;\n });\n\n // SPEC-0124 R7 — also map L2 scanner results onto the diff, so a reviewer sees scanner hits\n // inline. Facts-only: a scanner result already IS a {ruleId,file,line,level} SARIF fact, so\n // ingest → re-export is identity on those keys (no synthesized scanner verdict).\n for (const scanner of p.scanners ?? []) {\n for (const sr of scanner.results ?? []) {\n const ruleId = sr.ruleId || scanner.tool;\n const level: SarifLevel = sr.level;\n const existingRule = rules.get(ruleId);\n if (!existingRule) {\n ruleOrder.push(ruleId);\n rules.set(ruleId, {\n id: ruleId,\n name: `${scanner.tool}:${ruleId}`,\n shortDescription: { text: `${scanner.category} (${scanner.tool})` },\n defaultConfiguration: { level },\n helpUri: INFO_URI,\n });\n } else if (sevRank[level] < sevRank[existingRule.defaultConfiguration.level]) {\n existingRule.defaultConfiguration.level = level; // track the worst level seen (codex review)\n }\n // The result is already diff-scoped + repo-relative by sarifIngest — use it verbatim, never\n // re-anchor via a basename fallback to a different changed file (codex review).\n const uri = sr.file;\n const result: SarifResult = {\n ruleId,\n ruleIndex: ruleOrder.indexOf(ruleId),\n level,\n message: { text: sr.message ?? `${scanner.tool} ${ruleId}` },\n partialFingerprints: { receiptsId: `${ruleId}::${uri ?? \"scanner\"}` },\n };\n if (uri) {\n result.locations = [\n {\n physicalLocation: {\n artifactLocation: { uri },\n ...(sr.line ? { region: { startLine: sr.line } } : {}),\n },\n },\n ];\n }\n results.push(result);\n }\n }\n\n // ruleIndex was assigned by first-seen order; finalize the rules array in that order.\n const ruleList = ruleOrder.map((id) => rules.get(id) as SarifRule);\n\n return {\n $schema: \"https://json.schemastore.org/sarif-2.1.0.json\",\n version: \"2.1.0\",\n runs: [\n {\n tool: {\n driver: {\n name: \"Receipts\",\n informationUri: INFO_URI,\n version: p.generator?.version,\n rules: ruleList,\n },\n },\n results,\n },\n ],\n };\n}\n","import { createHash } from \"node:crypto\";\nimport type { DerivedSpan, DerivedSummary } from \"../findings/spans.js\";\nimport type { Receipt, ReceiptFinding } from \"../receipt/build.js\";\nimport { getVersion } from \"../version.js\";\nimport type { Exporter } from \"./registry.js\";\n\n/**\n * OTLP/JSON trace exporter (SPEC-0116 / M114). Maps a session's derived spans + the receipt's\n * findings onto an OpenTelemetry trace so teams can join Receipts evidence to an existing\n * observability backend (Honeycomb / Datadog / Phoenix / Langfuse) — a new INTEGRATION surface,\n * not a detector. Attributes follow OpenTelemetry GenAI semantic conventions (`gen_ai.*`) +\n * OpenInference (`openinference.span.kind`); Receipts-specific facts live under `receipts.*`.\n *\n * R2 — FACTS ONLY: this emits what ran / cost / took how long / which finding fired. It NEVER\n * emits the receipt's grade, a finding's score, or any synthesized verdict. The attribute key set\n * is a fixed allowlist, pinned by `test/export/otel.test.ts`.\n */\n\ntype AnyValue = { stringValue: string } | { intValue: string } | { doubleValue: number };\ninterface Attr {\n key: string;\n value: AnyValue;\n}\n\nconst sAttr = (key: string, v: string | undefined): Attr | null =>\n v == null || v === \"\" ? null : { key, value: { stringValue: v } };\nconst iAttr = (key: string, v: number | undefined): Attr | null =>\n v == null ? null : { key, value: { intValue: String(Math.round(v)) } };\nconst dAttr = (key: string, v: number | undefined): Attr | null =>\n v == null ? null : { key, value: { doubleValue: v } };\nconst attrs = (...a: (Attr | null)[]): Attr[] => a.filter((x): x is Attr => x !== null);\n\n/** Deterministic hex id of `bytes` length from `input` (traceId=16 bytes, spanId=8 bytes). */\nconst hexId = (input: string, bytes: number): string =>\n createHash(\"sha256\")\n .update(input)\n .digest(\"hex\")\n .slice(0, bytes * 2);\n\n/** epoch-ms → unix-nano string (BigInt — ms*1e6 overflows Number.MAX_SAFE_INTEGER). */\nconst toNano = (ms: number): string =>\n (BigInt(Math.max(0, Math.round(ms || 0))) * 1_000_000n).toString();\n\n// OTLP SpanKind ints: 1=INTERNAL, 3=CLIENT. A model call → CLIENT; tool/session → INTERNAL.\nconst OTLP_KIND: Record<DerivedSpan[\"kind\"], number> = { generation: 3, tool: 1, session: 1 };\n// OpenInference span-kind taxonomy.\nconst OI_KIND: Record<DerivedSpan[\"kind\"], string> = {\n generation: \"LLM\",\n tool: \"TOOL\",\n session: \"CHAIN\",\n};\n// OTLP StatusCode ints: 0=UNSET, 1=OK, 2=ERROR.\nconst OTLP_STATUS: Record<DerivedSpan[\"status\"], number> = { ok: 1, error: 2, running: 0 };\n\ninterface OtelEvent {\n name: string;\n timeUnixNano: string;\n attributes: Attr[];\n}\ninterface OtelSpan {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes: Attr[];\n status: { code: number; message?: string };\n events?: OtelEvent[];\n}\n\nfunction buildSpan(sp: DerivedSpan, traceId: string, spanIdOf: (id: string) => string): OtelSpan {\n const isGen = sp.kind === \"generation\";\n const span: OtelSpan = {\n traceId,\n spanId: spanIdOf(sp.spanId),\n name: sp.name,\n kind: OTLP_KIND[sp.kind],\n startTimeUnixNano: toNano(sp.startTime),\n endTimeUnixNano: toNano(sp.endTime),\n attributes: attrs(\n sAttr(\"openinference.span.kind\", OI_KIND[sp.kind]),\n sp.kind === \"tool\" ? sAttr(\"gen_ai.tool.name\", sp.name) : null,\n isGen ? sAttr(\"gen_ai.request.model\", sp.model) : null,\n isGen ? iAttr(\"gen_ai.usage.input_tokens\", sp.tokens?.input) : null,\n isGen ? iAttr(\"gen_ai.usage.output_tokens\", sp.tokens?.output) : null,\n isGen ? iAttr(\"gen_ai.usage.total_tokens\", sp.tokens?.total) : null,\n isGen ? sAttr(\"gen_ai.response.finish_reasons\", sp.finishReason) : null,\n dAttr(\"receipts.cost_usd\", sp.estCost),\n ),\n status: {\n code: OTLP_STATUS[sp.status] ?? 0,\n ...(sp.statusMessage ? { message: sp.statusMessage } : {}),\n },\n };\n if (sp.parentSpanId) {\n span.parentSpanId = spanIdOf(sp.parentSpanId);\n }\n return span;\n}\n\n/** A finding rendered as a span event — its evidence facts, never its score. */\nfunction findingEvent(f: ReceiptFinding, tsNano: string): OtelEvent {\n return {\n name: \"receipts.finding\",\n timeUnixNano: tsNano,\n attributes: attrs(\n sAttr(\"receipts.finding.id\", f.id),\n sAttr(\"receipts.finding.severity\", f.severity),\n sAttr(\"receipts.finding.title\", f.title),\n sAttr(\"receipts.finding.file\", f.filePath),\n iAttr(\"receipts.finding.line\", f.line),\n ),\n };\n}\n\nexport const otelExporter: Exporter = {\n id: \"otel\",\n label: \"OpenTelemetry OTLP/JSON trace\",\n export(receipt: Receipt, summary: DerivedSummary | undefined): string {\n // Stable trace identity from the receipt subject (`<agent>/<sessionId>`).\n const sid = receipt.subject?.[0]?.name ?? \"altimate-receipts/session\";\n const traceId = hexId(sid, 16);\n const spanIdOf = (id: string): string => hexId(`${sid}|${id}`, 8);\n const sourceSpans = summary?.spans ?? [];\n const spans = sourceSpans.map((sp) => buildSpan(sp, traceId, spanIdOf));\n\n // Attach findings as events on the root span (the session-level facts).\n const findings = receipt.predicate.findings ?? [];\n if (findings.length > 0) {\n const root = sourceSpans.find((s) => s.parentSpanId === null) ?? sourceSpans[0];\n const tsNano = toNano(root?.startTime ?? 0);\n const events = findings.map((f) => findingEvent(f, tsNano));\n const rootOut = root ? spans.find((s) => s.spanId === spanIdOf(root.spanId)) : undefined;\n if (rootOut) {\n rootOut.events = events;\n } else {\n // Receipt-only export (no live span tree): emit a single carrier span for the findings.\n spans.push({\n traceId,\n spanId: spanIdOf(\"__receipt__\"),\n name: \"agent-work-record\",\n kind: 1,\n startTimeUnixNano: tsNano,\n endTimeUnixNano: tsNano,\n attributes: attrs(sAttr(\"openinference.span.kind\", \"CHAIN\")),\n status: { code: 0 },\n events,\n });\n }\n }\n\n const agent = receipt.predicate.session?.agent ?? \"unknown\";\n const version = getVersion();\n const doc = {\n resourceSpans: [\n {\n resource: {\n attributes: attrs(\n sAttr(\"service.name\", \"altimate-receipts\"),\n sAttr(\"gen_ai.provider.name\", agent),\n sAttr(\"receipts.agent\", agent),\n sAttr(\"receipts.session.id\", sid),\n sAttr(\"receipts.version\", version),\n ),\n },\n scopeSpans: [{ scope: { name: \"altimate-receipts\", version }, spans }],\n },\n ],\n };\n return `${JSON.stringify(doc, null, 2)}\\n`;\n },\n};\n","import type { DerivedSummary } from \"../findings/spans.js\";\nimport type { Receipt } from \"../receipt/build.js\";\nimport { toSarif } from \"../report/sarif.js\";\nimport { otelExporter } from \"./otel.js\";\n\n/**\n * The EXPORTERS registry — the extension point for emitting a Receipt to an external format.\n *\n * Each exporter is **pure**: a receipt (+ the derived span summary, when a live session is\n * available) in → serialized bytes out. The hard rule (R2): an exporter emits mechanically-true\n * FACTS ONLY (what ran/changed/cost/took how long/which finding fired) — it MUST NEVER emit a\n * synthesized grade, score, or verdict. The receipt's `predicate.grade` is off-limits.\n *\n * To ADD an exporter: write `src/export/<id>.ts` exporting an `Exporter`, append ONE entry to\n * `EXPORTERS`, and add its `id` as a `--format` value to the `export` CLI verb. See the\n * `/add-exporter` skill.\n */\nexport interface Exporter {\n /** the `--format` value, e.g. \"otel\" */\n id: string;\n label: string;\n /** Receipt (+ derived spans when present) → serialized output. FACTS ONLY — never a verdict/score. */\n export(receipt: Receipt, summary: DerivedSummary | undefined): string;\n}\n\n/** SARIF, registered as an exporter to prove the seam generalizes. Reuses the shipped `toSarif`\n * (the standalone `receipts sarif` command is unchanged). */\nconst sarifExporter: Exporter = {\n id: \"sarif\",\n label: \"SARIF 2.1.0 (GitHub code-scanning)\",\n export: (receipt) => `${JSON.stringify(toSarif(receipt), null, 2)}\\n`,\n};\n\nexport const EXPORTERS: readonly Exporter[] = [otelExporter, sarifExporter];\n\nexport function exporterFor(id: string): Exporter | undefined {\n return EXPORTERS.find((e) => e.id === id);\n}\n\nexport const exporterIds = (): string[] => EXPORTERS.map((e) => e.id);\n","/**\n * Canonical JSON (RFC 8785-style): object keys sorted lexicographically, minimal\n * whitespace, arrays in order. Used now for deterministic hashing/equality and\n * reused verbatim as M4's DSSE signing payload, so a Receipt and its signature\n * always agree on the exact bytes.\n *\n * Scope note: this is a pragmatic subset — all numbers in a Receipt are integers\n * or values we round before emitting, so JSON.stringify's number formatting is\n * already stable. We do not implement RFC 8785's full number canonicalization.\n */\nexport function canonicalize(value: unknown): string {\n return serialize(value);\n}\n\nfunction serialize(value: unknown): string {\n if (value === null || typeof value === \"number\" || typeof value === \"boolean\") {\n return JSON.stringify(value);\n }\n if (typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return `[${value.map(serialize).join(\",\")}]`;\n }\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj)\n .filter((k) => obj[k] !== undefined)\n .sort();\n const body = keys.map((k) => `${JSON.stringify(k)}:${serialize(obj[k])}`).join(\",\");\n return `{${body}}`;\n }\n // undefined / function / symbol — not valid Receipt content\n return \"null\";\n}\n","import { createHash } from \"node:crypto\";\nimport { deriveExternalStateRows } from \"../findings/externalState.js\";\nimport type { Finding } from \"../findings/findings.js\";\nimport { formatCostAlways, formatTokens } from \"../findings/format.js\";\nimport { deriveGuardEvents } from \"../findings/guardEvents.js\";\nimport {\n destructiveOutsideRepo,\n findingSurface,\n privileged,\n regenerableBuildArtifact,\n} from \"../findings/surface.js\";\nimport type { Receipt, ReceiptFinding } from \"../receipt/build.js\";\nimport { type CategorizedChecks, categorize } from \"./checks.js\";\nimport { type CostBand, costConfidence, costVerb } from \"./costBand.js\";\nimport { FIX_FOR } from \"./fixForMap.js\";\nimport { renderLedger } from \"./ledger.js\";\n\n/**\n * The **Agent Work Record** PR comment (SPEC-0073/M74) — the de-verdicted renderer.\n * A factual masthead, per-push delta line, transcript-coverage stat, privileged events first,\n * one-line event rows, cleared events struck through with their evidence, an\n * append-only push ledger, and an embedded JSON state block. No grades, no verdicts,\n * no traffic lights anywhere a human reads (R2: evidence, not judgement —\n * `gradeLetter()` survives machine-side only, for opt-in gating).\n *\n * MIRRORED in action/verified-by.mjs — keep the two renderers byte-identical for the\n * same receipt.\n */\n\n// command classes ordered most-notable first, for the session-totals line.\nconst CLASS_ORDER = [\n \"mutating\",\n \"vcs-history\",\n \"transport\",\n \"test\",\n \"build\",\n \"read-only\",\n \"opaque\",\n];\n\n/** Stable marker so the Action can find and update its own comment. */\nexport const PR_COMMENT_MARKER = \"<!-- verified-by-receipts -->\";\n\nconst TRUST_DOC_URL = \"https://github.com/AltimateAI/altimate-receipts/blob/main/docs/trust.md\";\nconst ABOUT_DOC_URL = \"https://github.com/AltimateAI/altimate-receipts/blob/main/docs/problems.md\";\nconst FEEDBACK_ISSUE_BASE = \"https://github.com/AltimateAI/altimate-receipts/issues/new\";\n\n/** Max Sanity-check rows rendered before the overflow note (SPEC-0073 R5). */\nconst VISIBLE_ROWS = 7;\n\n/** M91 — \"process\" findings describe the agent's working STYLE (oscillation, duplication),\n * not an OUTCOME risk to the merged artifact. The paper (arxiv 2606.02060) shows process\n * errors ≠ outcome failure (36.9% of successful runs have them); they dominate codex's\n * signature and are the least-actionable findings. In actionable mode they demote off the\n * loud surface into the operator count (still in the Record), so the headline carries only\n * outcome-risk events. */\nconst PROCESS_KINDS = [\"edit-reversion\", \"duplicated-code\", \"dup-file\"];\nconst isProcessFinding = (id: string): boolean =>\n PROCESS_KINDS.some((p) => id === p || id.startsWith(`${p}-`));\n\n/** Normalize a finding id to its catalog-key prefix by stripping the `-tool-…` and numeric\n * instance suffixes (`secret-tool-3-0` → `secret`). Used by the event id, next-action, and\n * machine-state mirror so they key off the same prefix. */\nconst idToCatalogKey = (id: string): string =>\n id.replace(/-tool-.*$/, \"\").replace(/-\\d+(-\\d+)?$/, \"\");\n\n/** fixFor lookup keys, longest-first (precomputed once) so the most specific prefix wins without\n * re-sorting on every finding. */\nconst FIX_FOR_KEYS_BY_LENGTH = Object.keys(FIX_FOR).sort((a, b) => b.length - a.length);\n\nexport interface PrCommentOptions {\n /** link to the signed attestation / Rekor entry, when available */\n attestationUrl?: string;\n /** whether the Receipt was Sigstore-signed in this run */\n signed?: boolean;\n /** M68 — the verifier's version; when the receipt's generator is older, a muted\n * upgrade line is appended. The local CLI passes nothing. */\n compareVersion?: string;\n /** Base URL of the PR's files tab (\\`<pr>/files\\`) — when present, file chips and\n * evidence refs link to the file's diff anchor (\\`#diff-sha256(path)R<line>\\`).\n * The Action passes a token action.yml substitutes post-render. */\n diffLinkBase?: string;\n /** \"Actionable mode\" (M87 ↳ next-action lines, M90 triage line, M91 process demotion).\n * M92 — the Action + CLI default this ON (opt-out via RECEIPTS_NEXT_ACTION=0); the research\n * + dogfood proved the actionable form is the value. `renderPrComment` itself still defaults\n * OFF when the opt is absent — the callers pass the env. De-verdicted (R2). */\n nextAction?: boolean;\n}\n\n/** The merge-surface findings a reviewer sees: merge-gate, non-low severity, and not a\n * destructive op on a scratch path. One predicate shared by renderer + accumulation\n * (cli.ts prCleared) so cleared rows only ever reference events that were shown. */\nexport function visibleMergeFindings(findings: readonly ReceiptFinding[]): ReceiptFinding[] {\n return findings.filter(\n (f) =>\n findingSurface(f.id) === \"merge\" &&\n f.severity !== \"low\" &&\n !(\n f.id.startsWith(\"destructive-\") &&\n (destructiveOutsideRepo(f.title) || regenerableBuildArtifact(f.title))\n ),\n );\n}\n\n/** Stable event identity across runs/pushes (report/diff.ts discipline). */\nexport function eventKey(f: Pick<ReceiptFinding, \"title\" | \"filePath\">): string {\n return `${f.title} ${f.filePath ?? \"\"}`;\n}\n\n/** Short stable event id for the state block: fnv1a-32 hex over kind-prefix + path. */\nexport function eventId(f: Pick<ReceiptFinding, \"id\" | \"title\" | \"filePath\">): string {\n const prefix = idToCatalogKey(f.id);\n let h = 0x811c9dc5;\n for (const ch of `${prefix}:${f.filePath ?? f.title}`) {\n h ^= ch.charCodeAt(0);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h.toString(16).padStart(8, \"0\");\n}\n\n/**\n * Render the Agent Work Record. The Receipt is assumed already redacted.\n */\n/** M103 — render-time guard rows from the recorded `guardEvents` input (NOT stored in\n * `findings`, so the transcript-derived findings stay byte-stable). Deduped against the\n * transcript findings so an ask/warn that ran + was caught shows once. */\nfunction guardRows(p: Receipt[\"predicate\"]): ReceiptFinding[] {\n if (!p.guardEvents?.length) {\n return [];\n }\n return deriveGuardEvents(p.guardEvents, p.findings as Finding[]).map((f) => ({\n id: f.id,\n severity: f.severity,\n title: f.title,\n detail: f.detail,\n confidence: f.confidence,\n score: f.score,\n impactLabel: f.impactLabel,\n }));\n}\n\n/** M104 — render-time rows for merge-relevant subagent findings (from the recorded `subagents`\n * input, NOT stored in `findings` so the parent's transcript-derived findings stay byte-stable).\n * Each keeps its original id prefix (so categorize/privileged still classify it) + an agentId\n * suffix for uniqueness, and is attributed to the subagent's brief. */\nfunction subagentRows(p: Receipt[\"predicate\"]): ReceiptFinding[] {\n const surfaced = p.subagents?.surfaced ?? [];\n return surfaced.map((s) => ({\n id: `${s.id}-sa-${s.agentId.slice(0, 8)}`,\n severity: s.severity,\n // Keep the finding title CLEAN (the subagent attribution lives in the detail, not the headline)\n // — a verbatim brief in the title both leaks the prompt and breaks downstream title parsing.\n title: s.title,\n detail: `Run by a subagent (briefed: «${s.brief}», agentId ${s.agentId}), whose work the parent transcript doesn't record. ${s.detail}`,\n confidence: 1,\n score: 0,\n ...(s.filePath ? { filePath: s.filePath } : {}),\n }));\n}\n\n/** M116 — render-time rows for external-state DIVERGENCES (from the recorded `externalState`\n * input, NOT stored in `findings` so the transcript-derived findings stay byte-stable). A\n * corroboration (`match:true`) is not a finding — it renders as the quiet line below. */\nfunction externalStateRows(p: Receipt[\"predicate\"]): ReceiptFinding[] {\n if (!p.externalState?.length) {\n return [];\n }\n return deriveExternalStateRows(p.externalState).map((f) => ({\n id: f.id,\n severity: f.severity,\n title: f.title,\n detail: f.detail,\n confidence: f.confidence,\n score: f.score,\n impactLabel: f.impactLabel,\n }));\n}\n\n/** M116 — one muted line per corroborated external-state claim (the API confirmed it). Positive\n * evidence; never inflates a grade. */\nfunction externalStateCorroborations(p: Receipt[\"predicate\"]): string | undefined {\n const ok = (p.externalState ?? []).filter((r) => r.match);\n if (ok.length === 0) {\n return undefined;\n }\n const chips = ok\n .map((r) => {\n const who = r.actor ? ` by \\`${r.actor}\\`` : \"\";\n const when = r.ts ? ` · ${r.ts}` : \"\";\n return `✔ ${r.target} ${r.kind === \"merged\" ? \"merged\" : \"CI green\"}${who}${when}`;\n })\n .join(\" · \");\n return `<sub>🌐 external state reconciled: ${chips} (authoritative API, attested).</sub>`;\n}\n\n/** M104 — one muted line summarizing subagent fan-out, shown when the session spawned any. */\nfunction subagentCountLine(p: Receipt[\"predicate\"]): string | undefined {\n const sa = p.subagents;\n if (!sa || sa.total === 0) {\n return undefined;\n }\n const shown = sa.surfaced.length;\n const tail = shown > 0 ? `, ${shown} surfaced above` : \", none merge-relevant\";\n return `<sub>🧷 ${sa.total} subagent${sa.total === 1 ? \"\" : \"s\"} ran (${sa.considered} did file/command work${tail}) — separate transcripts, attributed.</sub>`;\n}\n\n/** M106b — one muted line stating the witness provenance when `altimate-router` independently\n * witnessed this session's model decisions. Evidence, not judgement: states the fact, no verdict.\n * Absent ⇒ self-reported (the silent default — no row). */\nfunction witnessLine(p: Receipt[\"predicate\"]): string | undefined {\n const w = p.witness;\n if (!w) {\n return undefined;\n }\n if (w.tier === \"witness-divergence\") {\n return `<sub>🛰️ model-side: <b>diverges from altimate-router</b> — ${w.present}/${w.witnessed} model decisions match the independent record; the rest are missing from this transcript.</sub>`;\n }\n const sig =\n w.signed === \"verified\"\n ? \", signature verified\"\n : w.signed === \"unverified\"\n ? \", signature unverified\"\n : \"\";\n return `<sub>🛰️ model-side: witnessed by altimate-router — ${w.present}/${w.witnessed} model decisions independently recorded${sig}.</sub>`;\n}\n\nexport function renderPrComment(receipt: Receipt, opts: PrCommentOptions = {}): string {\n const p = receipt.predicate;\n const ev = p.evidence;\n const operatorCount = p.findings.filter((f) => findingSurface(f.id) === \"operator\").length;\n // M103/M104 — guard rows + subagent rows (recorded inputs) join the merge findings for render.\n const main = visibleMergeFindings([\n ...guardRows(p),\n ...subagentRows(p),\n ...externalStateRows(p),\n ...p.findings,\n ]);\n const cats = categorize(main);\n const files = p.scope?.kind === \"diff\" ? (p.scope.files ?? []) : [];\n\n const priv = main.filter((f) => privileged(f.id, f.filePath));\n const restAll = main.filter((f) => !privileged(f.id, f.filePath));\n // M91 — in actionable mode, demote process/thrash findings off the loud tier into the\n // operator count (still in the Record). None of PROCESS_KINDS are privileged.\n const rest = opts.nextAction ? restAll.filter((f) => !isProcessFinding(f.id)) : restAll;\n const demotedProcess = restAll.length - rest.length;\n const operatorTotal = operatorCount + demotedProcess;\n const cleared = p.prCleared ?? [];\n const lastPush = p.prHistory?.[p.prHistory.length - 1];\n\n const out: string[] = [];\n out.push(PR_COMMENT_MARKER);\n\n // Clean PR (R10): one muted line — never \"Safe\", never silence.\n if (main.length === 0 && cleared.length === 0 && coverageFull(ev, files)) {\n out.push(masthead(p, ev, files));\n out.push(\"\");\n out.push(\n `receipts — nothing detected${coverageCell(ev, files) ? ` · ${coverageCell(ev, files)}` : \"\"}${diffCostInline(ev, files)} · ${testsCell(ev)}`,\n );\n out.push(\"\");\n out.push(recordDetails(p, ev, cats, operatorTotal, opts, feedbackLine(p.session.agent, main)));\n out.push(footer());\n out.push(stateBlock(p, ev, files, main, cleared));\n return `${out.join(\"\\n\")}\\n`;\n }\n\n // Masthead (R2) + delta/coverage line (R3/R4).\n out.push(masthead(p, ev, files));\n out.push(\"\");\n const status = [\n lastPush && p.prHistory && p.prHistory.length > 1\n ? `push ${lastPush.push}${lastPush.sha ? ` · \\`${lastPush.sha}\\`` : \"\"} — +${lastPush.new} new · ${lastPush.cleared} cleared · ${lastPush.open} open`\n : null,\n coverageCell(ev, files),\n ].filter(Boolean);\n if (status.length) {\n out.push(status.join(\" · \"));\n out.push(\"\");\n }\n\n // M90 — fewer-louder triage line: when there's a list to triage, lead with the count +\n // the one place to start (the first rendered row), so a reviewer who reads one line is\n // still steered. A pointer, never a verdict (R2). Gated with M87 (one \"actionable mode\").\n const tline = triageLine(priv, rest, files, opts.nextAction);\n if (tline) {\n out.push(tline, \"\");\n }\n\n // Tier 1 — privileged surface (R5). Never rendered when empty (NG5).\n if (priv.length) {\n out.push(\"**Review as access control**\");\n for (const f of priv) {\n out.push(eventRow(f, true, files, opts.diffLinkBase, opts.nextAction));\n }\n out.push(\"\");\n }\n\n // Tier 2 — everything else, capped.\n if (rest.length) {\n out.push(\"**Sanity-check**\");\n for (const f of rest.slice(0, VISIBLE_ROWS)) {\n out.push(eventRow(f, false, files, opts.diffLinkBase, opts.nextAction));\n }\n if (rest.length > VISIBLE_ROWS) {\n out.push(`- _+${rest.length - VISIBLE_ROWS} more in the record below_`);\n }\n out.push(\"\");\n }\n\n // M91 — transparency: note the demoted process findings (oscillation/duplication) so the\n // reviewer knows they were found and where, without crowding the outcome surface.\n if (demotedProcess > 0) {\n out.push(\n `<sub>${demotedProcess} process note${demotedProcess === 1 ? \"\" : \"s\"} (oscillation / duplication — working style, not a merge risk) in the record below.</sub>`,\n \"\",\n );\n }\n\n // Cleared events — struck through in place for one push cycle (R6).\n if (cleared.length) {\n for (const c of cleared) {\n // M84 — normalize the path like active findings do (`displayPath`); rendering\n // `c.filePath` raw leaked an absolute worktree path (`…/.claude/worktrees/agent-…/`).\n const loc = c.filePath ? ` (\\`${displayPath(c.filePath, files)}\\`)` : \"\";\n out.push(\n `- ~~${c.title}~~${loc} · no longer detected${lastPush ? ` push ${lastPush.push}` : \"\"}`,\n );\n }\n out.push(\"\");\n }\n\n // Negative space — facts about what was NOT detected, with provenance.\n const flaggedSet = new Set(\n main.map((f) => (f.filePath ? displayPath(f.filePath, files) : null)).filter(Boolean),\n );\n if (files.length) {\n // M85 — when nothing was file-flagged (e.g. only file-less destructive ops), \"Other N\"\n // wrongly equals the total (\"other\" than what?). Say \"No file-level findings across N\".\n const others = Math.max(0, files.length - flaggedSet.size);\n out.push(\n flaggedSet.size === 0\n ? `No file-level findings across ${files.length} changed file${files.length === 1 ? \"\" : \"s\"}.`\n : `Other ${others} file${others === 1 ? \"\" : \"s\"}: nothing detected.`,\n );\n out.push(\"\");\n }\n out.push(`<sub>tests: ${testsCell(ev)}</sub>`);\n out.push(\"\");\n\n // M94 — \"hand back to the agent\": a copy-paste correction prompt (agent-steering is the\n // dominant agent-PR reviewer action). Outcome findings only; collapsed; gated.\n const handback = handbackBlock([...priv, ...rest], files, opts.nextAction);\n if (handback) {\n out.push(handback, \"\");\n }\n\n out.push(recordDetails(p, ev, cats, operatorCount, opts, feedbackLine(p.session.agent, main)));\n out.push(footer());\n out.push(stateBlock(p, ev, files, main, cleared, opts.compareVersion));\n return `${out.join(\"\\n\")}\\n`;\n}\n\n/** `### Agent work record — <agent> · N files[ · k sessions] · spent ≈ $X on this change` */\nfunction masthead(\n p: Receipt[\"predicate\"],\n ev: Receipt[\"predicate\"][\"evidence\"],\n files: readonly string[],\n): string {\n const parts = [`Agent work record — ${p.session.agent}`];\n if (files.length) {\n parts.push(`${files.length} file${files.length === 1 ? \"\" : \"s\"}`);\n }\n // The masthead figure is the PR's total: branch-narrowed cost for a single session,\n // accumulated prEffort across sessions. M82 — the diff-cost band labels the upper\n // bound's credibility: hedge a loose bound (`up to ≈`), and drop a no-attribution\n // single-session figure rather than headline a misleading `$0.000`.\n const band = costConfidence(ev.diffTurns ?? 0, ev.diffTokens ?? 0, files.length, ev.diffCostUsd);\n // The headline figure is the cost of the CURRENT diff (`on this change`). It is NOT a PR total:\n // the per-push diff-cost is re-derived each push and shrinks when the diff narrows, so summing or\n // headlining the latest as \"the PR cost\" would mislead. Cross-session work IS accumulated via\n // prEffort (a recorded input) — that genuinely spans the PR, so it keeps \"on this PR\".\n let clarifier = \"\";\n if (p.prEffort && p.prEffort.sessions > 1) {\n parts.push(`${p.prEffort.sessions} sessions`);\n parts.push(`${costVerb(band)} ${formatCostAlways(p.prEffort.totalUsd)} on this PR`);\n } else if (ev.diffCostUsd != null && band !== \"none\") {\n parts.push(`${costVerb(band)} ${formatCostAlways(ev.diffCostUsd)} on this change`);\n // Honesty (B1): never headline a figure SMALLER than a push row in the ledger below without\n // saying why — when the diff narrowed, an earlier push attributed more.\n const peak = Math.max(0, ...(p.prHistory ?? []).map((h) => h.costUsd ?? 0));\n if (peak > ev.diffCostUsd + 0.005) {\n clarifier = `\\n<sub>final diff — an earlier push attributed ${formatCostAlways(peak)} on a broader diff; see the ledger below.</sub>`;\n }\n }\n return `### ${parts.join(\" · \")}${clarifier}`;\n}\n\n/** `transcript covers N/M changed files` — or the M83 split gap form (R3/R4). */\nfunction coverageCell(\n ev: Receipt[\"predicate\"][\"evidence\"],\n files: readonly string[],\n): string | null {\n if (ev.coveredFiles == null || !files.length) {\n return null;\n }\n const gap = files.length - ev.coveredFiles;\n if (gap <= 0) {\n return `transcript covers ${ev.coveredFiles}/${files.length} changed files`;\n }\n // M83 — split the gap: `unwitnessed` (the real blind spot) vs `generated` (benign\n // build artifacts). Generated files no longer inflate the alarm. Old receipts without\n // `coverageGaps` keep the count-only form (back-compat).\n const gaps = ev.coverageGaps;\n if (!gaps) {\n return `⚠ ${gap} changed file${gap === 1 ? \"\" : \"s\"} ha${gap === 1 ? \"s\" : \"ve\"} no transcript activity (${ev.coveredFiles}/${files.length} covered)`;\n }\n const generated = gaps.filter((g) => g.kind === \"generated\").length;\n const overflow = Math.max(0, gap - gaps.length); // beyond the 30-cap → treat as loud\n const unwitnessed = gaps.length - generated + overflow;\n const genNote = generated\n ? ` (+ ${generated} generated file${generated === 1 ? \"\" : \"s\"} not expected in the transcript)`\n : \"\";\n if (unwitnessed === 0) {\n return `transcript covers ${ev.coveredFiles}/${files.length} changed files${genNote}`;\n }\n return `⚠ ${unwitnessed} of ${files.length} changed file${files.length === 1 ? \"\" : \"s\"} unwitnessed by the transcript${genNote}`;\n}\n\nfunction coverageFull(ev: Receipt[\"predicate\"][\"evidence\"], files: readonly string[]): boolean {\n return ev.coveredFiles == null || !files.length || ev.coveredFiles >= files.length;\n}\n\n/** Render a finding's path repo-relative: match it into the diff's file set when\n * possible (transcript paths are absolute), else keep the last two segments. The\n * absolute worktree path leaked into the first live render — pure noise. */\nexport function displayPath(filePath: string, scopeFiles: readonly string[]): string {\n for (const sf of scopeFiles) {\n if (filePath === sf || filePath.endsWith(`/${sf}`)) {\n return sf;\n }\n }\n if (!filePath.startsWith(\"/\") && !filePath.startsWith(\"~\")) {\n return filePath; // already repo-relative — keep it whole\n }\n const segs = filePath.split(\"/\").filter(Boolean);\n return segs.length > 2 ? segs.slice(-2).join(\"/\") : filePath;\n}\n\n/** GitHub anchors each file in a PR diff as `#diff-<sha256(path)>`; `R<line>` jumps\n * to the right-side line. Pure function of the displayed (repo-relative) path. */\nfunction diffAnchor(base: string, path: string, line?: number): string {\n const h = createHash(\"sha256\").update(path).digest(\"hex\");\n return `${base}#diff-${h}${line ? `R${line}` : \"\"}`;\n}\n\n/** The finding's headline fact, with the detector convention's trailing \": <basename>\"\n * stripped (ONLY that exact shape, so a mid-sentence filename survives). Shared by the\n * event row and the M90 triage line so they word the fact identically. */\nfunction factOf(f: Pick<ReceiptFinding, \"title\" | \"filePath\">): string {\n const base = f.filePath?.split(\"/\").pop();\n if (!base) {\n return f.title;\n }\n return f.title.replace(new RegExp(`:\\\\s*\\`?${escapeRe(base)}\\`?\\\\s*$`), \"\").trim();\n}\n\n/** M90 — the fewer-louder triage line. Null unless `nextAction` and ≥2 shown findings.\n * Leads with the count + the one place to start (the first rendered row: privileged tier\n * first). A pointer, never a verdict (R2). Pure function of the shown findings. */\nfunction triageLine(\n priv: readonly ReceiptFinding[],\n rest: readonly ReceiptFinding[],\n files: readonly string[],\n nextAction?: boolean,\n): string | null {\n const shown = priv.length + rest.length;\n if (!nextAction || shown < 2) {\n return null;\n }\n const top = priv[0] ?? rest[0];\n // M95 — name the file when there is one; for a file-less finding (e.g. a destructive\n // command) lead straight with the fact, not a vague \"the first event\".\n const where = top.filePath ? `\\`${displayPath(top.filePath, files)}\\`: ` : \"\";\n return `**${shown} events flagged — start with ${where}${factOf(top)}.**`;\n}\n\n/** M94 — agent-facing corrective instruction per outcome-finding kind, for the \"hand back\n * to the agent\" prompt. Keyed by id prefix. Returns null for kinds with no clean agent fix\n * (those are omitted). A process instruction (\"re-read\", \"log or rethrow\"), never a verdict\n * (R2). `f` is a path placeholder (the displayed file, or \"the changed file\"). */\nfunction fixFor(id: string, f: string): string | null {\n const k = idToCatalogKey(id);\n // Single-sourced in src/report/fixForMap.ts (mirrored into the Action via the generated catalog).\n // `${f}` is a literal placeholder in each template; substitute the displayed file here.\n // Exact match, else the most specific prefix (so `secret-in-file` → `secret`, `destructive-git`\n // → `destructive`). Keys are pre-sorted longest-first, so the first match is the most specific.\n const key = FIX_FOR_KEYS_BY_LENGTH.find((m) => k === m || k.startsWith(`${m}-`));\n return key ? FIX_FOR[key].replaceAll(\"${f}\", f) : null;\n}\n\n/** M94 — the collapsed \"hand back to the agent\" copy-paste block. Null unless `nextAction`\n * and ≥1 outcome finding maps to a fix. Outcome (priv+rest) only — process/thrash excluded\n * by the caller. A single paste-ready prompt; deterministic; no verdict (R2). */\nfunction handbackBlock(\n outcome: readonly ReceiptFinding[],\n files: readonly string[],\n nextAction?: boolean,\n): string | null {\n if (!nextAction) {\n return null;\n }\n const fixes: string[] = [];\n const seen = new Set<string>();\n for (const x of outcome) {\n const where = x.filePath ? `\\`${displayPath(x.filePath, files)}\\`` : \"the changed file\";\n const fix = fixFor(x.id, where);\n if (fix && !seen.has(fix)) {\n seen.add(fix);\n fixes.push(fix);\n }\n }\n if (!fixes.length) {\n return null;\n }\n const body = fixes.map((fx, i) => `${i + 1}. ${fx}`).join(\"\\n\");\n return [\n `<details><summary>🔧 Hand back to the agent — ${fixes.length} fix${fixes.length === 1 ? \"\" : \"es\"}</summary>`,\n \"\",\n \"Copy this to the agent:\",\n \"\",\n \"```\",\n \"Please address the following from the work record:\",\n body,\n \"```\",\n \"</details>\",\n ].join(\"\\n\");\n}\n\n/** One event row: `file` — **fact** · why it surfaced · evidence link (R5). */\nfunction eventRow(\n f: ReceiptFinding,\n priv: boolean,\n scopeFiles: readonly string[],\n linkBase?: string,\n nextAction?: boolean,\n): string {\n const mark = priv ? \"▲ \" : \"\";\n const shown = f.filePath ? displayPath(f.filePath, scopeFiles) : undefined;\n const chip = shown ? `\\`${shown}${f.line ? `:${f.line}` : \"\"}\\`` : \"\";\n const file = chip\n ? `${linkBase && shown ? `[${chip}](${diffAnchor(linkBase, shown, f.line)})` : chip} — `\n : \"\";\n const fact = factOf(f);\n const why = f.impactLabel ? ` · ${f.impactLabel}` : \"\";\n // The evidence ref links to the same diff spot (the transcript itself is local —\n // the runnable \\`receipts log --ref\\` command lives in the Record below).\n const ref = f.evidenceRef\n ? linkBase && shown\n ? ` · [evidence \\`${f.evidenceRef}\\`](${diffAnchor(linkBase, shown, f.line)})`\n : ` · evidence \\`${f.evidenceRef}\\``\n : \"\";\n const row = `- ${mark}${file}**${fact}**${why}${ref}`;\n // M87 — the next-action line: the detector's `detail` (mechanism + what to check),\n // already in the receipt, rendered as a nested continuation so the row is actionable.\n return nextAction && f.detail ? `${row}\\n ↳ ${f.detail}` : row;\n}\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** Tests cell — parsed counts with provenance, or honest ignorance. Never \"✅ ran\". */\nfunction testsCell(ev: Receipt[\"predicate\"][\"evidence\"]): string {\n const tm = ev.testMetrics;\n if (tm) {\n const seg = [\n tm.passed != null ? `${tm.passed} passed` : null,\n tm.failed ? `**${tm.failed} failed**` : null,\n tm.skipped ? `${tm.skipped} skipped` : null,\n ]\n .filter(Boolean)\n .join(\", \");\n return `${seg || tm.exitStatus} _(parsed from runner output in transcript)_`;\n }\n return ev.testsRan\n ? \"test command observed — outcome not parsed\"\n : \"no test run detected in transcript\";\n}\n\n/** The collapsed Record — ledger, checks (\"not detected\"), files, sessions, custody. */\nfunction recordDetails(\n p: Receipt[\"predicate\"],\n ev: Receipt[\"predicate\"][\"evidence\"],\n cats: CategorizedChecks,\n operatorCount: number,\n opts: PrCommentOptions,\n feedback: string,\n): string {\n const inner: string[] = [];\n\n // Append-only push ledger (R7). Shown only for a MULTI-push PR — the first push now seeds a\n // 1-row prHistory (so push 1 carries its commit sha, B2), but a single push needs no ledger.\n if (p.prHistory && p.prHistory.length > 1) {\n inner.push(\"| push | events | change cost |\", \"| :-- | :-- | :-- |\");\n for (const h of p.prHistory) {\n const id = h.sha ? ` · \\`${h.sha}\\`` : \"\";\n const cost = h.costUsd != null ? formatCostAlways(h.costUsd) : \"—\";\n inner.push(\n `| ${h.push}${id}${dateCell(h.endedAt)} | +${h.new} new · ${h.cleared} cleared · ${h.open} open | ${cost} |`,\n );\n }\n inner.push(\n \"<sub>change cost per row = the diff-attributed cost at that push — re-derived against that push's diff, so rows are independent (not additive) and shrink when the diff narrows.</sub>\",\n \"\",\n );\n }\n\n const files = p.scope?.kind === \"diff\" ? (p.scope.files ?? []) : [];\n if (files.length) {\n inner.push(changedFilesBlock(files), \"\");\n }\n const ledger = renderLedger(ev.claims ?? []);\n if (ledger) {\n inner.push(ledger, \"\");\n }\n\n // Check readings — lab register, COMPACT (fewer-louder): only FLAGGED checks get a table row;\n // the (usually ~25) cleared checks collapse into one muted line so they can't bury the finding.\n inner.push(checksSection(cats), \"\");\n\n const cl = diffCostLine(ev, files, p.prEffort);\n if (cl) {\n inner.push(cl);\n }\n inner.push(`<sub>${effortLine(ev, operatorCount)}</sub>`);\n const saLine = subagentCountLine(p);\n if (saLine) {\n inner.push(saLine);\n }\n const wLine = witnessLine(p);\n if (wLine) {\n inner.push(wLine);\n }\n const xLine = externalStateCorroborations(p);\n if (xLine) {\n inner.push(xLine);\n }\n\n const signed = opts.signed\n ? `Signed (Sigstore → Rekor)${opts.attestationUrl ? ` · [attestation](${opts.attestationUrl})` : \"\"} · `\n : \"\";\n inner.push(\n `<sub>${signed}Re-derivable (L1: \\`receipts verify <receipt> --transcript <t>\\`) · pull any event's tape: \\`npx altimate-receipts log --ref <evidence-id>\\` · deterministic · 0 model calls · evidence, not judgement · [trust model](${TRUST_DOC_URL}).</sub>`,\n );\n const hint = upgradeHint(p.generator?.version, opts.compareVersion);\n if (hint) {\n inner.push(hint);\n }\n inner.push(feedback);\n return [\n \"<details><summary>Record — pushes, files, checks, custody (append-only)</summary>\",\n \"\",\n ...inner,\n \"\",\n \"</details>\",\n ].join(\"\\n\");\n}\n\nfunction dateCell(endedAt?: number): string {\n if (!endedAt || !Number.isFinite(endedAt)) {\n return \"\";\n }\n return ` · ${new Date(endedAt).toISOString().slice(0, 10)}`;\n}\n\nfunction footer(): string {\n return `\\n<sub>[what is this? ›](${ABOUT_DOC_URL}) — a record of the agent's process, not a code review · entries are never edited or removed</sub>`;\n}\n\n/** Embedded versioned state block (R8) — machine mirror for fleets/rollups. Key-sorted\n * for cross-renderer byte parity. */\nfunction stateBlock(\n p: Receipt[\"predicate\"],\n ev: Receipt[\"predicate\"][\"evidence\"],\n files: readonly string[],\n main: readonly ReceiptFinding[],\n cleared: readonly { title: string; filePath?: string }[],\n renderVer?: string,\n): string {\n const lastPush = p.prHistory?.[p.prHistory.length - 1]?.push ?? 1;\n const events = [\n ...main.map((f) => ({\n file: f.filePath ? displayPath(f.filePath, files) : \"\",\n id: eventId({ ...f, filePath: f.filePath ? displayPath(f.filePath, files) : undefined }),\n privileged: privileged(f.id, f.filePath),\n state: \"open\",\n type: idToCatalogKey(f.id),\n })),\n ...cleared.map((c) => ({\n file: c.filePath ? displayPath(c.filePath, files) : \"\",\n id: eventId({\n id: \"cleared\",\n title: c.title,\n filePath: c.filePath ? displayPath(c.filePath, files) : undefined,\n }),\n privileged: false,\n state: \"cleared\",\n type: \"cleared\",\n })),\n ];\n const state = {\n cost_cents:\n ev.diffCostUsd != null ? Math.round((p.prEffort?.totalUsd ?? ev.diffCostUsd) * 100) : null,\n coverage: ev.coveredFiles != null ? { covered: ev.coveredFiles, total: files.length } : null,\n events,\n push: lastPush,\n // M81 — the RENDERER self-declares its version + format contract, so a stale\n // renderer (one emitting the pre-M74 grade layout) is detectable from the comment.\n renderer: { format: \"work-record\", version: renderVer ?? null },\n schema_version: 1,\n };\n return `<!-- receipts-state v1 ${JSON.stringify(state)} -->`;\n}\n\n/** Changed-file block — grouped by dir for big PRs (unchanged from the old renderer). */\nfunction changedFilesBlock(files: readonly string[]): string {\n if (files.length <= 12) {\n return `**Changed** ${files.map((f) => `\\`${f}\\``).join(\", \")}`;\n }\n const byDir = new Map<string, number>();\n for (const f of files) {\n const top = f.includes(\"/\") ? `${f.split(\"/\")[0]}/` : \"(root)\";\n byDir.set(top, (byDir.get(top) ?? 0) + 1);\n }\n const dirs = [...byDir.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 8)\n .map(([d, n]) => `\\`${d}\\` ${n}`)\n .join(\" · \");\n const moreDirs = byDir.size > 8 ? ` · _+${byDir.size - 8} more dirs_` : \"\";\n const sample = files\n .slice(0, 60)\n .map((f) => `\\`${f}\\``)\n .join(\", \");\n const moreFiles =\n files.length > 60 ? ` _…+${files.length - 60} more (full set in the receipt JSON)_` : \"\";\n return [\n `**Changed ${files.length} files** by area: ${dirs}${moreDirs}`,\n \"\",\n \"<details><summary>file list</summary>\",\n \"\",\n `${sample}${moreFiles}`,\n \"\",\n \"</details>\",\n ].join(\"\\n\");\n}\n\n// M68 — upgrade-skew notice (MIRRORS action/verified-by.mjs).\nfunction parseSemver(v?: string): [number, number, number] | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)/.exec(String(v ?? \"\").trim());\n return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;\n}\nfunction semverLt(a?: string, b?: string): boolean {\n const pa = parseSemver(a);\n const pb = parseSemver(b);\n if (!pa || !pb) return false;\n for (let i = 0; i < 3; i++) if (pa[i] !== pb[i]) return pa[i] < pb[i];\n return false;\n}\n/** One muted footer line when the receipt was made by an older CLI than the verifier. */\nexport function upgradeHint(receiptVer?: string, compareVer?: string): string | null {\n if (!compareVer || !semverLt(receiptVer, compareVer)) return null;\n return `<sub>Receipt generated by \\`receipts@${receiptVer}\\` · this check runs \\`@${compareVer}\\` — \\`npm i -g altimate-receipts@latest\\` (or \\`npx altimate-receipts@latest\\`) for the newer checks.</sub>`;\n}\n\n/** Feedback footer — prefilled false-positive issue (no grade — events only). */\nfunction feedbackLine(agent: string, flagged: readonly ReceiptFinding[]): string {\n const findingLines = flagged.length\n ? flagged.slice(0, 8).map((f) => `- ${f.title} (\\`${f.id}\\`)`)\n : [\"- (nothing was flagged — describe what you expected)\"];\n const body = [\n \"**Repo / PR:** __PR_URL__\",\n `**Agent:** ${agent}`,\n \"\",\n \"**Flagged event(s) being disputed:**\",\n ...findingLines,\n \"\",\n \"**Why this is a false positive / noise:**\",\n \"_(your notes — what should it have done instead?)_\",\n ].join(\"\\n\");\n const title = flagged.length ? `False positive: ${flagged[0].title}` : \"Receipts feedback\";\n const qs = `labels=${encodeURIComponent(\"false-positive,dogfooding\")}&title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`;\n const url = `${FEEDBACK_ISSUE_BASE}?${qs}`;\n return `<sub>Wrong or noisy event? [Report it — prefilled ›](${url}) · or react 👍/👎 on this comment. It tunes the checks.</sub>`;\n}\n\n/** Check readings — lab register, COMPACT. Flagged checks get a table row (the actionable part);\n * the cleared checks collapse into one muted line that still names every check that ran (the\n * transparency the register exists for) without a wall of \"not detected\" rows. */\nfunction checksSection(cats: CategorizedChecks): string {\n const ran = cats.flagged.length + cats.cleared.length;\n if (ran === 0) return \"\"; // empty catalog ⇒ omit the section (no \"all 0 clear\" nonsense)\n const clearedNote = cats.cleared.length\n ? `<sub>Also ran — nothing detected: ${cats.cleared.map((c) => c.label).join(\" · \")}. \"not detected\" means a check found nothing, not that nothing exists.</sub>`\n : \"\";\n if (!cats.flagged.length) {\n return [`**Checks** — all ${ran} clear`, \"\", clearedNote].filter(Boolean).join(\"\\n\");\n }\n const rows = cats.flagged.map((fl) => `| ${fl.check.label} | ${fl.count} detected |`);\n return [\n `**Checks** — ${cats.flagged.length} flagged · ${cats.cleared.length} found nothing`,\n \"\",\n \"| check | reading |\",\n \"| :-- | :-- |\",\n ...rows,\n \"\",\n clearedNote,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\n/** The clean-PR one-liner's cost chip — band-aware; \"\" when nothing is attributable. */\nfunction diffCostInline(ev: Receipt[\"predicate\"][\"evidence\"], files: readonly string[]): string {\n if (ev.diffCostUsd == null) return \"\";\n const band = costConfidence(ev.diffTurns ?? 0, ev.diffTokens ?? 0, files.length, ev.diffCostUsd);\n if (band === \"none\") return \"\";\n return ` · ${band === \"loose\" ? \"up to ≈\" : \"≈\"} ${formatCostAlways(ev.diffCostUsd)}`;\n}\n\n/** The diff-cost line — this change's cost, an upper bound; never the session total.\n * M82 — bands the bound: a `none` case states \"not separable\" rather than \"$0.000\"; a\n * `loose` case names the turns/files ratio that makes it loose. */\nfunction diffCostLine(\n ev: Receipt[\"predicate\"][\"evidence\"],\n files: readonly string[],\n pr?: Receipt[\"predicate\"][\"prEffort\"],\n): string | null {\n if (ev.diffCostUsd == null) return null;\n const band: CostBand = costConfidence(\n ev.diffTurns ?? 0,\n ev.diffTokens ?? 0,\n files.length,\n ev.diffCostUsd,\n );\n const turns = ev.diffTurns ?? 0;\n const t = `${turns} turn${turns === 1 ? \"\" : \"s\"}`;\n if (band === \"none\") {\n if (pr && pr.sessions > 1) {\n return `**Cost** ≈ ${formatCostAlways(pr.totalUsd)} _(this PR, ${pr.sessions} sessions)_ · this push not separable from these files`;\n }\n return \"**Cost** not separable from this change _(no turns attributed to these files; session total below)_\";\n }\n const note =\n band === \"loose\"\n ? `loose upper bound — ${t} across ${files.length} file${files.length === 1 ? \"\" : \"s\"}`\n : \"this change — upper bound; the turns that edited these files\";\n const push = `≈ ${formatCostAlways(ev.diffCostUsd)} · ${formatTokens(ev.diffTokens ?? 0)} tokens · ${t}`;\n if (pr && pr.sessions > 1) {\n return `**Cost** ≈ ${formatCostAlways(pr.totalUsd)} _(this PR, ${pr.sessions} sessions)_ · this push ${push} _(${note})_`;\n }\n return `**Cost** ${push} _(${note})_`;\n}\n\n/** Session-level effort, explicitly demoted — these totals are the run, not this diff. */\nfunction effortLine(ev: Receipt[\"predicate\"][\"evidence\"], operatorCount: number): string {\n const cbc = ev.commandsByClass;\n const brk = cbc\n ? ` _(${CLASS_ORDER.filter((c) => cbc[c])\n .map((c) => `${cbc[c]} ${c}`)\n .join(\", \")})_`\n : \"\";\n const op =\n operatorCount > 0\n ? ` · ${operatorCount} efficiency/behaviour finding${operatorCount === 1 ? \"\" : \"s\"}`\n : \"\";\n return `Session totals (may span other work): ${ev.edits} edits · ${ev.commands} commands${brk} · ${formatCostAlways(ev.costUsd)} · ${formatTokens(ev.tokens.total)} tokens${op}.`;\n}\n","import type { Finding } from \"./findings\";\n\n/**\n * External-state reconciliation (SPEC-0120 / external-state-reconciler — THE WEDGE,\n * registry #33). The strongest oracle an agent can lie about is state the reviewer\n * CANNOT see in the diff: a merged PR, a green pipeline, a deploy, a closed ticket. The\n * in-transcript claim detectors (`claimed-commit-none`, `fake-green`) structurally cannot\n * reach a system of record outside the session. This module:\n *\n * - parses the EXTERNAL-STATE claims from the final assistant text (frozen grammar,\n * resolvable target required — the FP wall, mirroring `CLAIMS_COMMITTED`), and\n * - renders the reconciliation RESULT (an authoritative API answer compared to a claim)\n * as evidence: a divergence is a finding, a corroboration is a quiet positive.\n *\n * The network call + creds live ENTIRELY in the opt-in CI reconciler (src/reconcile/*);\n * the deterministic CLI core never makes the call. The result enters the receipt as a\n * RECORDED INPUT (`predicate.externalState[]`), exempt from the L1 byte-compare like\n * `guardEvents`/`subagents`. Evidence, not judgement (R2): it attests the API's answer\n * (\"PR #123 reports state OPEN\"), never \"the agent lied.\"\n */\n\n/** A parseable external-state claim found in the agent's final text. */\nexport interface ExternalClaim {\n kind: \"merged\" | \"ci-green\";\n /** the resolvable target: a bare `#N` or a fully-qualified `owner/repo#N` */\n target: string;\n /** the matched claim sentence (for evidence) */\n raw: string;\n}\n\n/** One reconciliation row — the API's authoritative answer compared to the claim. A\n * recorded input; the producer of these (the reconciler) is opt-in and runs in CI. */\nexport interface ExternalStateRow {\n kind: \"merged\" | \"ci-green\";\n /** the resolvable target the claim named (`#123`, `owner/repo#7`) */\n target: string;\n /** the state the agent claimed (e.g. \"merged\", \"green\") */\n claimed: string;\n /** the authoritative state the API returned (e.g. \"OPEN\", \"MERGED\", \"fail\") */\n actual: string;\n /** did the claim match the API? false ⇒ a divergence (the finding) */\n match: boolean;\n /** the API's authoritative actor, when present (e.g. `mergedBy.login`) */\n actor?: string;\n /** the API's own event timestamp, when present (e.g. `mergedAt`) */\n ts?: string;\n /** the reconciler's UTC clock at fetch time */\n fetchedAt?: string;\n /** the API URL the answer came from */\n url?: string;\n}\n\n// A resolvable PR/issue target: `owner/repo#123` (fully-qualified) or a bare `#123`.\n// Without a concrete number there is no claim (R3 — the FP wall: prose like \"PRs should\n// be merged\" has no target → no reconciliation).\nconst TARGET = /\\b([A-Za-z0-9][\\w.-]*\\/[\\w.-]+)#(\\d+)\\b|(?:^|[\\s(])#(\\d+)\\b/;\n\n// A \"merged\" claim must BIND the target to the verb — as its OBJECT (\"merged #123\", \"merged PR\n// #123\", \"landed altimate/x#7\") or its SUBJECT (\"#123 was merged\", \"#123 has been merged\",\n// \"owner/repo#7 landed\"). A target floating elsewhere in the sentence (\"merged the fixes for\n// #123\", \"merged main, closes #123\") is NOT a merge claim ABOUT that PR (codex review: require\n// grammatical subject/object adjacency, not \"merge-verb anywhere + #N anywhere\"). The connector\n// in the subject form is a whitelist (`is now merged`, `has been merged`), never arbitrary prose.\nconst PR_REF = /(?:[A-Za-z0-9][\\w.-]*\\/[\\w.-]+)?#\\d+/;\nconst MERGED_OBJECT = new RegExp(\n `\\\\b(?:merged|landed)\\\\s+(?:(?:the\\\\s+)?(?:pr|pull\\\\s*request)\\\\s+)?${PR_REF.source}`,\n \"i\",\n);\nconst MERGED_SUBJECT = new RegExp(\n `${PR_REF.source}\\\\s+(?:(?:has|have|is|was|been|got|now|successfully|finally)\\\\s+){0,4}(?:merged|landed)\\\\b`,\n \"i\",\n);\nconst isMergedClaim = (s: string): boolean =>\n (MERGED_OBJECT.test(s) || MERGED_SUBJECT.test(s)) && !LOCAL_MERGE.test(s);\n// CI/checks green on a resolvable PR/commit — NOT \"tests pass\" (that is fake-green's\n// in-transcript job, NG4).\nconst CI_GREEN =\n /\\b(?:ci|checks?|pipeline|the build|all checks?)\\b[^.!?\\n]*\\b(?:is|are|all)?\\s*(?:green|passing|passed|pass)\\b/i;\n// Hedges that disqualify a sentence (uncertainty ⇒ no claim).\nconst HEDGE =\n /\\b(should|will|going to|once|after|when|if|need to|needs to|ready to|about to|pending|waiting)\\b/i;\n// Negations that disqualify a sentence — \"#123 is NOT merged\", \"CI is not green\" assert the\n// OPPOSITE of the claim, so treating them as a positive claim would false-fire. Under-claim:\n// a \"not\"-containing sentence is dropped (e.g. \"merged #1, not #2\" abstains — safe).\nconst NEGATION =\n /\\b(not|isn'?t|aren'?t|wasn'?t|weren'?t|never|no longer|failed to|couldn'?t|can'?t|cannot|won'?t|without)\\b/i;\n// A LOCAL git merge (\"merged main into …\", \"merged origin/…\") is NOT a PR merge — the `#N`\n// nearby is usually the working PR, so binding \"merged\" to it false-fires (codex/FP review).\nconst LOCAL_MERGE =\n /\\bmerged\\s+\\S+\\s+into\\b|\\bmerged\\s+(?:main|master|develop|trunk|origin|upstream|HEAD)\\b/i;\n// The `#N` is cited as BACKDROP — another PR/issue, or the base branch — not the agent's own claim\n// (\"the approach from #88\", \"the config in #50\", \"green on the base branch #3\"). Under-claim: drop\n// the sentence (a missed real claim is far cheaper than a false external-state-mismatch).\nconst OTHER_PR_BACKDROP =\n /\\b(?:from|in|like|see|per|via)\\s+(?:pr\\s+)?#\\s*\\d|\\bapproach\\s+(?:from|in)\\b|\\bbase\\s+branch\\b|\\bduplicat\\w*/i;\n\n/** Extract the resolvable target from a sentence, preferring `owner/repo#N`. */\nfunction targetOf(sentence: string): string | undefined {\n const m = TARGET.exec(sentence);\n if (!m) {\n return undefined;\n }\n if (m[1] && m[2]) {\n return `${m[1]}#${m[2]}`;\n }\n return m[3] ? `#${m[3]}` : undefined;\n}\n\n/**\n * Parse external-state claims from the agent's final text. Per-sentence: a claim fires\n * only when the sentence asserts the state (no hedge) AND names a resolvable target\n * (R3). De-duplicated by (kind, target). This is the only claim-side input the reconciler\n * acts on; everything ambiguous is dropped (under-claim).\n */\nexport function parseExternalClaims(finalText: string): ExternalClaim[] {\n const out: ExternalClaim[] = [];\n const seen = new Set<string>();\n for (const sentence of finalText.split(/[.!?\\n]+/)) {\n if (HEDGE.test(sentence) || NEGATION.test(sentence) || OTHER_PR_BACKDROP.test(sentence)) {\n continue;\n }\n const target = targetOf(sentence);\n if (!target) {\n continue;\n }\n const kind: ExternalClaim[\"kind\"] | undefined = isMergedClaim(sentence)\n ? \"merged\"\n : CI_GREEN.test(sentence)\n ? \"ci-green\"\n : undefined;\n if (!kind) {\n continue;\n }\n const key = `${kind}|${target}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n out.push({ kind, target, raw: sentence.trim().slice(0, 200) });\n }\n return out;\n}\n\nfunction label(kind: ExternalStateRow[\"kind\"]): string {\n return kind === \"merged\" ? \"merged\" : \"CI green\";\n}\n\n/**\n * Render the reconciliation rows. A DIVERGENCE (`match:false`) becomes a high\n * `external-state-mismatch` finding citing the API's actor + fetchedAt + url — the\n * actionable row. A corroboration (`match:true`) is NOT a finding (it renders elsewhere\n * as a quiet evidence chip), so it never inflates a grade (R2). Recorded-input tier: the\n * detail says it is attested, not transcript-re-derived.\n */\nexport function deriveExternalStateRows(rows: readonly ExternalStateRow[]): Finding[] {\n const out: Finding[] = [];\n let i = 0;\n for (const r of rows) {\n if (r.match) {\n continue; // corroboration is positive evidence, not a finding\n }\n const who = r.actor ? ` by \\`${r.actor}\\`` : \"\";\n const when = r.ts ? ` (${r.ts})` : \"\";\n const at = r.fetchedAt ? ` fetched ${r.fetchedAt}` : \"\";\n out.push({\n id: `external-state-mismatch-${i}`,\n severity: \"high\",\n title: `Claimed ${r.target} ${label(r.kind)}, API reports ${r.actual}`,\n detail:\n `The session claimed ${r.target} was ${r.claimed}, but the authoritative API reports \\`${r.actual}\\`${who}${when}${at}. This is a recorded input — the reconciler fetched it in CI; the deterministic core never makes the call. Confirm the claim, or correct the summary. ${r.url ?? \"\"}`.trim(),\n impactLabel: \"external state\",\n confidence: 1.0,\n score: 100,\n guardrailRule:\n \"Don't claim a PR is merged / CI is green until the authoritative API confirms it; reconcile claims about external state before reporting done.\",\n });\n i++;\n }\n return out;\n}\n","import type { Finding } from \"./findings\";\n\n/**\n * Live-guard events (SPEC-0095 / M103) — the decisions the `receipts-guard` PreToolUse hook made\n * BEFORE a tool ran: `deny` (hard-blocked a catastrophe), `ask` (routed to user confirm), `warn`\n * (surfaced but allowed). These are the one class of evidence the transcript structurally CANNOT\n * carry — a blocked call never runs, so it never appears in the session log (empirically confirmed:\n * 1858 real transcripts, zero hook records). They are an **attested recorded input** (like\n * `prEffort`): envelope-covered + tamper-evident, but NOT re-derivable from the transcript, and so\n * labelled \"live-guard attested\" wherever they render. Evidence, not judgement (R2): \"the guard\n * blocked `rm -rf /`\" is a fact; we never say the agent was malicious.\n */\nexport interface GuardEvent {\n /** the guard's decision class */\n action: \"deny\" | \"ask\" | \"warn\";\n /** the shared-policy rule id (policy/guardrails.policy.json) */\n ruleId: string;\n /** the tool the decision was about (Bash, Edit, Write, …) */\n tool: string;\n /** the command or file path the decision concerned (truncated at record time) */\n subject: string;\n /** the human guardrail line from the policy */\n guardrail: string;\n /** the paste-ready fix from the policy, when present */\n fix?: string;\n /** epoch ms the decision was recorded (informational; not load-bearing) */\n ts?: number;\n}\n\nconst SEV: Record<GuardEvent[\"action\"], Finding[\"severity\"]> = {\n deny: \"critical\",\n ask: \"high\",\n warn: \"medium\",\n};\nconst ID: Record<GuardEvent[\"action\"], string> = {\n deny: \"guard-blocked\",\n ask: \"guard-asked\",\n warn: \"guard-warned\",\n};\nconst VERB: Record<GuardEvent[\"action\"], string> = {\n deny: \"blocked\",\n ask: \"asked to confirm\",\n warn: \"flagged\",\n};\n\n/** Normalize a subject for dedupe — strip backticks/quotes/whitespace, lowercase. */\nfunction norm(s: string): string {\n return s.replace(/[`'\"]/g, \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n}\n\n/** Flatten a recorded subject (often a multi-line shell command) to ONE clean line for the title/\n * detail (B4): collapse newlines/whitespace runs to single spaces and drop backticks (which would\n * otherwise break the inline-code span in the detail). Preserves case, unlike `norm`. */\nfunction oneLine(s: string): string {\n return s.replace(/`/g, \"\").replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Turn recorded guard events into findings. `deny` is always surfaced (critical, ▲ — a\n * catastrophe with no transcript twin by construction). `ask`/`warn` events whose subject is\n * ALSO already covered by a transcript finding (the op ran and the post-hoc detector caught it)\n * are dropped to avoid a double row (R4) — the reviewer sees one. Conservative: a `deny` is never\n * deduped (it didn't run, so any transcript finding is a different event).\n */\nexport function deriveGuardEvents(\n events: readonly GuardEvent[],\n existing: readonly Finding[] = [],\n): Finding[] {\n const existingSubjects = existing\n .map((f) => norm(`${f.title} ${f.filePath ?? \"\"} ${f.detail ?? \"\"}`))\n .filter(Boolean);\n const out: Finding[] = [];\n const seen = new Set<string>();\n let i = 0;\n for (const e of events) {\n if (e.action !== \"deny\" && e.action !== \"ask\" && e.action !== \"warn\") {\n continue;\n }\n const key = `${e.action}|${e.ruleId}|${norm(e.subject)}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n // dedupe ask/warn against a transcript finding for the same subject (it ran + was caught).\n if (e.action !== \"deny\") {\n const sub = norm(e.subject);\n if (sub && existingSubjects.some((t) => t.includes(sub) || sub.includes(t))) {\n continue;\n }\n }\n const fix = e.fix ? ` ${e.fix}` : \"\";\n out.push({\n id: `${ID[e.action]}-${i}`,\n severity: SEV[e.action],\n title: `Live guard ${VERB[e.action]}: ${oneLine(e.subject).slice(0, 80)}`,\n detail: `The receipts-guard hook ${VERB[e.action]} \\`${oneLine(e.subject).slice(0, 200)}\\` before it ran (guardrail: ${e.ruleId}). ${e.guardrail}${fix} This is a live-guard record — it is attested, not re-derived from the transcript (the blocked call never reached it).`,\n impactLabel: `guard ${e.action}`,\n confidence: 1.0,\n score: e.action === \"deny\" ? 1000 : e.action === \"ask\" ? 100 : 10,\n guardrailRule: e.guardrail,\n });\n i++;\n }\n return out;\n}\n","/**\n * Cost-attribution confidence band (SPEC-0080/M82).\n *\n * The per-change cost is an honest UPPER BOUND — it sums every turn that touched a\n * changed file (`diffEffort`, `diffScope.ts`). For a large interleaved session that\n * bound is absurd: a real 5-file `codex` PR summed 3801 turns into $228.59. This labels\n * the bound's credibility at render time WITHOUT changing the recorded number, so a\n * re-derived receipt is byte-identical (L1 holds). A loose bound is hedged (\"up to ≈\n * $X\"); a no-attribution case becomes a qualitative fallback instead of \"$0.000\".\n *\n * Thresholds from the 2026-06-14 corpus: normal PRs ran < 10 turns/file (7f/14t,\n * 43f/138t, 19f/6t); the anomaly was 760 (5f/3801t). 25 separates them with headroom.\n * Pure · deterministic · MIRRORED in action/verified-by.mjs.\n */\nexport const TURNS_PER_FILE = 25;\nexport const TOKENS_CAP = 50_000_000;\n\nexport type CostBand = \"none\" | \"loose\" | \"tight\";\n\n/** Confidence of the diff-cost upper bound. `none` = nothing attributable (don't headline\n * a $-figure); `loose` = implausibly large bound (hedge it); `tight` = today's normal PR. */\nexport function costConfidence(\n turns: number,\n tokens: number,\n files: number,\n costUsd: number | null | undefined,\n): CostBand {\n // `none` only when the cost itself is absent/zero — NOT merely because `diffTurns`\n // wasn't recorded (older receipts carry a real cost with no turn count; dropping it\n // would lose a legitimate figure). A zero cost is the `$0.000` case to suppress.\n if (costUsd == null || costUsd === 0) {\n return \"none\";\n }\n // A loose bound needs turns to detect the thrash ratio; with no turns recorded the\n // ratio is 0 ⇒ tight (show it normally), which is the right default.\n if (turns / Math.max(files, 1) > TURNS_PER_FILE || tokens > TOKENS_CAP) {\n return \"loose\";\n }\n return \"tight\";\n}\n\n/** Masthead verb for a band: `spent ≈` (tight) vs `up to ≈` (loose). */\nexport function costVerb(band: CostBand): string {\n return band === \"loose\" ? \"up to ≈\" : \"spent ≈\";\n}\n","import { spawnSync } from \"node:child_process\";\n\ninterface ClipboardTool {\n cmd: string;\n args: string[];\n}\n\n/** OS clipboard tools, by platform, in preference order. */\nfunction candidates(): ClipboardTool[] {\n if (process.platform === \"darwin\") {\n return [{ cmd: \"pbcopy\", args: [] }];\n }\n if (process.platform === \"win32\") {\n return [{ cmd: \"clip\", args: [] }];\n }\n // linux / other: Wayland first, then X11\n return [\n { cmd: \"wl-copy\", args: [] },\n { cmd: \"xclip\", args: [\"-selection\", \"clipboard\"] },\n { cmd: \"xsel\", args: [\"--clipboard\", \"--input\"] },\n ];\n}\n\n/**\n * Best-effort copy to the OS clipboard. Returns true on success, false if no tool\n * is available or the copy failed — the caller prints a note and still exits 0.\n * No npm dependency; shells out to the platform tool.\n */\nexport function copyToClipboard(text: string): boolean {\n for (const { cmd, args } of candidates()) {\n try {\n const res = spawnSync(cmd, args, { input: text, stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n if (!res.error && res.status === 0) {\n return true;\n }\n } catch {\n // try the next tool\n }\n }\n return false;\n}\n","import type { FindingSet, Severity } from \"../findings/findings.js\";\nimport { type GradeLetter, gradeLetter } from \"../findings/grade.js\";\nimport type { DerivedSummary } from \"../findings/spans.js\";\nimport { deriveEvidence } from \"../receipt/build.js\";\nimport type { Session, SessionSummary } from \"../trace/types.js\";\nimport { redact } from \"./redact.js\";\n\nconst ICON: Record<Severity, string> = {\n critical: \"⛔\",\n high: \"⚠️\",\n medium: \"🔍\",\n low: \"·\",\n};\n\nconst base = (p: string): string => p.split(\"/\").pop() ?? p;\n\n/**\n * A redacted, paste-ready Markdown summary of a session — the `--share` artifact.\n * Pure function of the derived data; all user-text is passed through `redact()`.\n */\nexport function renderShareMarkdown(args: {\n summary: SessionSummary;\n session: Session;\n derived: DerivedSummary;\n findings: FindingSet;\n}): string {\n const { summary, session, derived, findings } = args;\n const { main, minor } = findings;\n const g = gradeLetter(main);\n const ev = deriveEvidence(session, derived);\n\n const counts =\n ([\"critical\", \"high\", \"medium\"] as const)\n .map((s) => {\n const n = main.filter((f) => f.severity === s).length;\n return n ? `${n} ${s}` : null;\n })\n .filter(Boolean)\n .join(\" · \") || \"no findings\";\n\n const title = redact(summary.title || \"untitled session\");\n const out: string[] = [];\n out.push(`## 🧾 Receipt — ${title} · Grade ${g}`);\n out.push(\"\");\n out.push(\n `**${main.length ? `${main.length} EVENT${main.length === 1 ? \"\" : \"S\"} ON RECORD` : \"NOTHING DETECTED\"}** · ${counts} · _${summary.source}_`,\n );\n out.push(\"\");\n\n if (main.length) {\n out.push(\"### Findings\");\n const order: Record<Severity, number> = { critical: 0, high: 1, medium: 2, low: 3 };\n const sorted = [...main].sort(\n (a, b) => order[a.severity] - order[b.severity] || b.score - a.score,\n );\n for (const f of sorted.slice(0, 12)) {\n const tag = f.impactLabel ? ` — ${redact(f.impactLabel)}` : \"\";\n const loc = f.filePath ? ` (\\`${redact(base(f.filePath))}\\`)` : \"\";\n out.push(`- ${ICON[f.severity]} **${redact(f.title)}**${tag}${loc}`);\n }\n if (minor.length) {\n out.push(`- _+${minor.length} minor (collapsed)_`);\n }\n out.push(\"\");\n }\n\n out.push(\"### Evidence\");\n out.push(\n `${ev.filesChanged} files · ${ev.edits} edits · ${ev.commands} commands · ` +\n `${ev.testsRan ? \"tests ran ✓\" : \"no test run detected\"} · ` +\n `${ev.destructiveOps} destructive ops`,\n );\n out.push(\"\");\n out.push(\"_Verified by Receipts · deterministic · 0 model calls · evidence, not judgement_\");\n return `${out.join(\"\\n\")}\\n`;\n}\n","import type { Receipt } from \"../receipt/build.js\";\nimport { canonicalize } from \"../receipt/canonical.js\";\n\n/** in-toto payloads ride in DSSE with this type. */\nexport const DSSE_PAYLOAD_TYPE = \"application/vnd.in-toto+json\";\n\nexport interface DsseSignature {\n sig: string;\n keyid?: string;\n}\n\nexport interface DsseEnvelope {\n payloadType: string;\n /** base64 of the canonical Receipt JSON */\n payload: string;\n signatures: DsseSignature[];\n}\n\n/**\n * DSSE Pre-Authentication Encoding (PAE) — the exact bytes a signer signs:\n * \"DSSEv1\" SP len(payloadType) SP payloadType SP len(payload) SP payload\n * Lengths count UTF-8 bytes; `payload` here is the raw (un-base64) payload.\n */\nexport function pae(payloadType: string, payload: string): Buffer {\n const typeBytes = Buffer.from(payloadType, \"utf8\");\n const bodyBytes = Buffer.from(payload, \"utf8\");\n const header = `DSSEv1 ${typeBytes.length} ${payloadType} ${bodyBytes.length} `;\n return Buffer.concat([Buffer.from(header, \"utf8\"), bodyBytes]);\n}\n\n/**\n * Wrap a Receipt as an UNSIGNED DSSE envelope. The payload is the canonical\n * Receipt JSON (so signature and content always agree on the exact bytes). The\n * signature array is filled by the signer (the GitHub Action), not here.\n */\nexport function toDsseEnvelope(receipt: Receipt): DsseEnvelope {\n const canonical = canonicalize(receipt);\n return {\n payloadType: DSSE_PAYLOAD_TYPE,\n payload: Buffer.from(canonical, \"utf8\").toString(\"base64\"),\n signatures: [],\n };\n}\n\n/** The PAE bytes for an envelope (what a verifier checks the signature against). */\nexport function envelopePae(env: DsseEnvelope): Buffer {\n const raw = Buffer.from(env.payload, \"base64\").toString(\"utf8\");\n return pae(env.payloadType, raw);\n}\n","import { spawnSync } from \"node:child_process\";\nimport type { DerivedSpan } from \"../findings/spans.js\";\nimport { gitInvocations } from \"./gitCommand.js\";\n\n/**\n * Commit-SHA attribution (SPEC-0069 / M70). When any agent runs `git commit` or\n * `git push`, the captured output carries the commit SHA (\"[feat-x 5f8a31d] msg\",\n * \"abc1234..def5678 feat-x -> feat-x\"). Matching those SHAs against the branch's\n * `git log` gives an exact, agent-agnostic session↔branch binding — no branch\n * tags, no edit spans, nothing new recorded. Prior art: aider stamps commits,\n * git-ai/Entire attach notes; we read the binding the transcript already holds.\n */\n\n/** Max branch commits to match against — far beyond any sane PR; newest first. */\nconst SHA_CAP = 200;\n\n/** Full SHAs of the commits unique to this branch (newest first), or [] when\n * unknowable (no base / no commits / no git). */\nexport function branchShas(base?: string, cwd?: string): string[] {\n if (!base) {\n return [];\n }\n const r = spawnSync(\"git\", [\"log\", `--max-count=${SHA_CAP}`, \"--format=%H\", `${base}..HEAD`], {\n encoding: \"utf8\",\n cwd,\n });\n if (r.status !== 0) {\n return [];\n }\n return r.stdout.split(\"\\n\").filter((s) => /^[0-9a-f]{40}$/.test(s));\n}\n\nconst HEX_RUN = /\\b[0-9a-f]{7,40}\\b/g;\n\n/** The command string of a tool span, across agent input shapes: Claude's\n * `{command}` object, Codex's raw arguments JSON string (`'{\"cmd\":\"…\"}'`, string\n * or argv array inside). Raw inputs per R5. */\nfunction commandOf(input: unknown): string {\n if (typeof input === \"string\") {\n const t = input.trim();\n if (t.startsWith(\"{\")) {\n try {\n return commandOf(JSON.parse(t));\n } catch {\n return input;\n }\n }\n return input;\n }\n if (input && typeof input === \"object\") {\n const o = input as Record<string, unknown>;\n for (const key of [\"command\", \"cmd\"]) {\n const v = o[key];\n if (typeof v === \"string\") {\n return v;\n }\n if (Array.isArray(v)) {\n return v.filter((t) => typeof t === \"string\").join(\" \");\n }\n }\n }\n return \"\";\n}\n\n/**\n * Is this command a real `git commit`/`git push` invocation? Tokenized via the\n * shared M67-discipline matcher — an orchestrating session running\n * `codex exec \"...then git push...\"` (the SHA-bearing instruction-in-a-string\n * case, observed live) never counts as the author of its child agent's commits.\n */\nexport function isGitWrite(command: string): boolean {\n return gitInvocations(command).some((g) => g.sub === \"commit\" || g.sub === \"push\");\n}\n\n/**\n * Did this session author any of the branch's commits? True iff a hex run (≥7\n * chars) in the OUTPUT of a `git commit`/`git push` command span prefixes one of\n * the branch's full SHAs. Output-only: a SHA pasted into a command's input isn't\n * authorship. Deterministic string scan; zero git calls.\n */\nexport function authoredBranch(spans: readonly DerivedSpan[], shas: readonly string[]): boolean {\n if (shas.length === 0) {\n return false;\n }\n for (const s of spans) {\n if (s.kind !== \"tool\" || typeof s.output !== \"string\") {\n continue;\n }\n if (!isGitWrite(commandOf(s.input))) {\n continue;\n }\n for (const token of s.output.match(HEX_RUN) ?? []) {\n if (shas.some((full) => full.startsWith(token))) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * The branch's commit WINDOW inside a session (SPEC-0072 R1): span indices from\n * just after the last FOREIGN commit anchor preceding the branch's first own\n * anchor, through the last own anchor. Own anchor = a `git commit`/`git push`\n * span whose OUTPUT contains one of the branch's SHAs (same output-only\n * discipline as `authoredBranch`); foreign anchor = such a span whose output\n * carries hex runs but none of ours — the previous sibling branch's commit in a\n * multi-PR session. Null when the session authored none of the branch's commits.\n * Pure span scan ⇒ re-derivable at verify from the transcript + recorded SHAs.\n */\nexport function shaWindow(\n spans: readonly DerivedSpan[],\n shas: readonly string[],\n): { start: number; end: number } | null {\n if (shas.length === 0) {\n return null;\n }\n let firstOwn = -1;\n let lastOwn = -1;\n let lastForeignBeforeOwn = -1;\n spans.forEach((s, i) => {\n if (s.kind !== \"tool\" || typeof s.output !== \"string\") {\n return;\n }\n if (!isGitWrite(commandOf(s.input))) {\n return;\n }\n const tokens = s.output.match(HEX_RUN) ?? [];\n if (tokens.length === 0) {\n return;\n }\n const own = tokens.some((t) => shas.some((full) => full.startsWith(t)));\n if (own) {\n if (firstOwn === -1) {\n firstOwn = i;\n }\n lastOwn = i;\n } else if (firstOwn === -1) {\n lastForeignBeforeOwn = i;\n }\n });\n if (lastOwn === -1) {\n return null;\n }\n return { start: lastForeignBeforeOwn + 1, end: lastOwn };\n}\n","/**\n * Shared git-invocation tokenizer (extracted in SPEC-0069 — the M67 push matcher\n * and the M70 authorship matcher need identical discipline). Quoted text is\n * blanked first, so `git push` inside a prompt string (`codex exec \"...git\n * push...\"`, `echo \"git push\"`, commit-message text) never reads as a git call;\n * then each `&&`/`||`/`;`/`|`-separated simple command must START with `git`\n * (after env assignments / benign wrappers and git's global flags).\n */\n\n/** Shell wrappers that may legitimately precede `git` in a simple command. */\nconst WRAPPERS = new Set([\"command\", \"exec\", \"nohup\", \"time\", \"env\"]);\n/** Global git flags between `git` and the subcommand that consume a value. */\nconst GIT_VALUE_FLAGS = new Set([\"-C\", \"-c\", \"--git-dir\", \"--work-tree\", \"--exec-path\"]);\n\nexport interface GitInvocation {\n /** the git subcommand: \"push\", \"commit\", \"log\", … */\n sub: string;\n /** tokens after the subcommand (flags + positionals) */\n rest: string[];\n}\n\n/** Every real `git <sub> …` invocation in a (possibly compound) shell command. */\nexport function gitInvocations(command: string): GitInvocation[] {\n const blanked = command\n .replace(/\\\\[\"']/g, \" \")\n .replace(/'[^']*'/g, \" \")\n .replace(/\"[^\"]*\"/g, \" \");\n const out: GitInvocation[] = [];\n for (const simple of blanked.split(/(?:&&|\\|\\||[;|\\n])/)) {\n const tokens = simple.trim().split(/\\s+/).filter(Boolean);\n let i = 0;\n while (\n i < tokens.length &&\n (/^[A-Za-z_][A-Za-z0-9_]*=/.test(tokens[i]) || WRAPPERS.has(tokens[i]))\n ) {\n i++;\n }\n if (tokens[i] !== \"git\") {\n continue;\n }\n i++;\n while (i < tokens.length && tokens[i].startsWith(\"-\")) {\n const flag = tokens[i];\n i++;\n if (GIT_VALUE_FLAGS.has(flag)) {\n i++;\n }\n }\n const sub = tokens[i];\n if (sub) {\n out.push({ sub, rest: tokens.slice(i + 1) });\n }\n }\n return out;\n}\n","import type { Session, SessionMessage } from \"./types.js\";\n\n/** The distinct branches that appear across a session's messages, in first-seen order. */\nexport function branchesIn(session: Session): string[] {\n const seen: string[] = [];\n for (const m of session.messages) {\n if (m.gitBranch && !seen.includes(m.gitBranch)) {\n seen.push(m.gitBranch);\n }\n }\n return seen;\n}\n\n/**\n * Assign every message an effective branch: its own `gitBranch`, else the nearest\n * preceding tagged branch (carry-forward); leading untagged messages take the\n * first branch that appears. Deterministic.\n */\nfunction effectiveBranches(messages: SessionMessage[]): (string | undefined)[] {\n const firstTagged = messages.find((m) => m.gitBranch)?.gitBranch;\n let current = firstTagged;\n return messages.map((m) => {\n if (m.gitBranch) {\n current = m.gitBranch;\n }\n return current;\n });\n}\n\n/**\n * Slice a session down to the messages belonging to `branch` (non-contiguous\n * visits included), recomputing the per-session `digestSource` over the slice so\n * the Receipt's subject digest is scoped to this branch's work. Deterministic.\n *\n * Returns null when the branch isn't present in the session at all.\n */\nexport function sliceByBranch(session: Session, branch: string): Session | null {\n if (!branchesIn(session).includes(branch)) {\n return null;\n }\n const eff = effectiveBranches(session.messages);\n const messages = session.messages.filter((_, i) => eff[i] === branch);\n if (messages.length === 0) {\n return null;\n }\n const timestamps = messages\n .map((m) => m.timestamp)\n .filter((t): t is number => typeof t === \"number\");\n const startedAt = timestamps.length ? Math.min(...timestamps) : session.startedAt;\n const endedAt = timestamps.length ? Math.max(...timestamps) : session.endedAt;\n\n return {\n ...session,\n id: `${session.id}#${branch}`,\n gitBranch: branch,\n startedAt,\n endedAt,\n messages,\n // Scope the subject digest to this branch's slice (reproducible by re-slicing).\n digestSource: JSON.stringify({ id: session.id, branch, messages }),\n };\n}\n","import { computeCompletion } from \"../findings/completionFindings.js\";\nimport { deriveFindings } from \"../findings/findings.js\";\nimport { deriveSpans } from \"../findings/spans.js\";\nimport { type Receipt, type ReceiptScope, buildReceipt } from \"../receipt/build.js\";\nimport { canonicalize } from \"../receipt/canonical.js\";\nimport { redactReceipt } from \"../share/redact.js\";\nimport { shaWindow } from \"../trace/commitMatch.js\";\nimport { applyDiffScope, narrowEffort, windowedEffort } from \"../trace/diffScope.js\";\nimport { loadById } from \"../trace/load.js\";\nimport { agentIds } from \"../trace/registry.js\";\nimport { sliceByBranch } from \"../trace/slice.js\";\nimport type { AgentSource } from \"../trace/types.js\";\n\n/**\n * The agent that produced a receipt, read from its subject prefix (`<source>/<id>`,\n * set in buildReceipt). Re-derivation must load the transcript through the SAME\n * adapter the receipt was built with, or the bytes can't match (e.g. a `codex/…`\n * receipt re-derived through the Claude adapter yields empty evidence). Returns\n * undefined for an unknown prefix so the caller keeps its default.\n */\nexport function sourceFromReceipt(receipt: Receipt): AgentSource | undefined {\n const prefix = receipt.subject?.[0]?.name?.split(\"/\")[0];\n return agentIds().find((id) => id === prefix);\n}\n\nexport interface RederiveOptions {\n /** agent that produced the transcript (default: claude-code) */\n source?: AgentSource;\n /** scope to one branch's turns before deriving */\n branch?: string;\n /** the committed receipt's recorded scope — re-applied so the re-derivation\n * matches a scoped receipt byte-for-byte (SPEC-0013 L1). Its `files`/`branch`\n * come from the receipt, so no git is needed at verify time. */\n scope?: ReceiptScope;\n /** SPEC-0118 completion-oracle — the receipt's recorded definition-of-done\n * (`evidence.completion.criteria`), re-applied before deriving so the `completion-uncovered`\n * finding re-derives byte-identically. The criteria come from the receipt (committed\n * basis), not from disk, so verify needs no `.receipts/asserts.json` — like `scope`. */\n criteria?: string[];\n /** apply secret redaction (to compare against a redacted committed Receipt) */\n redact?: boolean;\n}\n\n/**\n * Re-run the deterministic engine on a transcript file to reproduce its Receipt.\n * Because the pipeline is deterministic, a verifier with the transcript gets the\n * exact same Receipt — that's what proves a committed Receipt is faithful and not\n * fabricated (SPEC-0009 Part B, L1). When the committed receipt was scoped\n * (SPEC-0013), the same recorded scope is re-applied so the bytes still match.\n */\nexport async function rederiveFromTranscript(\n path: string,\n opts: RederiveOptions = {},\n): Promise<Receipt | null> {\n const loaded = await loadById(opts.source ?? \"claude-code\", path);\n if (!loaded) {\n return null;\n }\n // Resolve scope: the recorded `predicate.scope` takes precedence; fall back to a\n // bare `--branch` for pre-SPEC-0013 (branch-only) receipts.\n const scope = opts.scope;\n const branch = scope?.kind === \"branch\" ? scope.branch : opts.branch;\n const session = branch ? (sliceByBranch(loaded, branch) ?? loaded) : loaded;\n\n let derived = deriveSpans(session);\n // SPEC-0118 — re-apply the recorded criteria basis before deriving, so the\n // completion-oracle finding reproduces byte-identically (the verifier has no\n // `.receipts/asserts.json`; the basis travels in the receipt, like `scope`).\n if (opts.criteria?.length) {\n derived.criteria = opts.criteria;\n }\n let findings = deriveFindings(derived);\n // SPEC-0118 — capture completion on the PRE-scope summary (same inputs as the finding) so\n // the recorded count matches the surviving finding after diff-scoping, and produce ≡ rederive.\n const completion = opts.criteria?.length\n ? computeCompletion(derived, [...findings.main, ...findings.minor])\n : undefined;\n if (scope?.kind === \"diff\" && scope.files) {\n const scoped = applyDiffScope(derived, findings, scope.files, session.projectPath);\n derived = scoped.derived;\n findings = scoped.findings;\n if (scope.branch) {\n // SPEC-0068 R4: the receipt declares branch-narrowed effort — recompute it the\n // same way (branch turns ∩ diff-file edits) so the byte-compare holds.\n const slice = sliceByBranch(loaded, scope.branch);\n let eff = narrowEffort(slice ? deriveSpans(slice) : null, scope.files);\n if (!eff && scope.shas?.length) {\n // SPEC-0072 R2: a tagless session declared a SHA-anchored commit window —\n // reproduce it from the transcript + the recorded anchors.\n const win = shaWindow(derived.spans, scope.shas);\n if (win) {\n eff = windowedEffort(derived, scope.files, win);\n }\n }\n if (eff) {\n derived = {\n ...derived,\n diffCostUsd: eff.cost,\n diffTokens: eff.tokens,\n diffTurns: eff.turns,\n };\n }\n }\n }\n\n const receipt = await buildReceipt(session, derived, findings, { scope, completion });\n return opts.redact ? redactReceipt(receipt) : receipt;\n}\n\nexport interface RederiveCompare {\n /** the re-derivation produced a Receipt at all */\n rederived: boolean;\n /** the committed Receipt byte-equals the re-derivation (faithful, not fabricated) */\n matches: boolean;\n}\n\n/**\n * Compare a committed Receipt against a fresh re-derivation from its transcript.\n * `matches` true ⇒ the Receipt is the deterministic function of that transcript.\n */\nexport async function compareToTranscript(\n committed: Receipt,\n transcriptPath: string,\n opts: RederiveOptions = {},\n): Promise<RederiveCompare> {\n // Re-apply the committed receipt's own recorded scope so a scoped receipt\n // re-derives byte-for-byte (the basis is in the receipt, so no git is needed).\n const fresh = await rederiveFromTranscript(transcriptPath, {\n redact: true,\n ...opts,\n // Re-derive through the adapter the receipt names (its subject prefix), so a\n // codex/cursor receipt isn't re-run through the Claude adapter. An explicit\n // opts.source still wins.\n source: opts.source ?? sourceFromReceipt(committed),\n scope: committed.predicate.scope,\n // SPEC-0118 — re-apply the recorded criteria basis (like scope) so a receipt\n // carrying completion findings re-derives byte-identically with no asserts.json.\n criteria: committed.predicate.evidence.completion?.criteria,\n });\n if (!fresh) {\n return { rederived: false, matches: false };\n }\n // SPEC-0072 R4: `prEffort` accumulates PRIOR receipts — by construction not a\n // function of this transcript, so it is exempt from the byte-compare. It stays\n // tamper-evident through the envelope/attestation digest.\n const strip = (r: Receipt): Receipt => {\n if (\n !r.predicate.prEffort &&\n !r.predicate.prHistory &&\n !r.predicate.prCleared &&\n !r.predicate.guardEvents &&\n !r.predicate.subagents &&\n !r.predicate.scanners &&\n !r.predicate.externalState &&\n !r.predicate.witness\n ) {\n return r;\n }\n // M103/M104/M106b — `guardEvents` + `subagents` + `witness` are recorded inputs (the live guard's\n // decisions, the subagent transcripts the CI verifier can't load, and the router's independent\n // witness log), exempt from the byte-compare like prEffort.\n const {\n prEffort: _x,\n prHistory: _y,\n prCleared: _z,\n guardEvents: _g,\n subagents: _s,\n scanners: _sc,\n externalState: _e,\n witness: _w,\n ...rest\n } = r.predicate;\n return { ...r, predicate: rest as Receipt[\"predicate\"] };\n };\n return {\n rederived: true,\n matches: canonicalize(strip(committed)) === canonicalize(strip(fresh)),\n };\n}\n"],"mappings":"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","names":["base","createHash","base","createHash","spawnSync","base","spawnSync"]}
|
package/dist/cli.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
toDsseEnvelope,
|
|
19
19
|
toSarif,
|
|
20
20
|
visibleMergeFindings
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-BC2NBB4X.js";
|
|
22
22
|
import {
|
|
23
23
|
computeTrends,
|
|
24
24
|
deriveTargets,
|
|
@@ -2302,6 +2302,10 @@ Usage
|
|
|
2302
2302
|
in repos that have adopted the Receipts workflow)
|
|
2303
2303
|
receipts rederive <file> Reproduce the canonical Receipt from a transcript
|
|
2304
2304
|
receipts assert [selector] Check the receipt against committed .receipts/asserts.json (CI gate)
|
|
2305
|
+
receipts verdict [selector] Work-verdict from the facts + .receipts/asserts.json policy \u2014
|
|
2306
|
+
VERIFIED / INCOMPLETE / WRONG / ESCALATE (no policy \u21D2 UNJUDGED; CI gate)
|
|
2307
|
+
receipts reconcile Reconcile the agent's external-state claims (PRs/issues/releases)
|
|
2308
|
+
against the GitHub API \u2014 opt-in (RECEIPTS_RECONCILE=1), local side-log
|
|
2305
2309
|
receipts mcp Start the MCP server (stdio) for IDEs/agents
|
|
2306
2310
|
|
|
2307
2311
|
selector: a list number (e.g. 3), a session id, or part of the title.
|
|
@@ -2933,6 +2937,20 @@ Build the branch with a coding agent first, or run \`receipts --list\`.
|
|
|
2933
2937
|
}
|
|
2934
2938
|
} catch {
|
|
2935
2939
|
}
|
|
2940
|
+
} else {
|
|
2941
|
+
const sha = git5(["rev-parse", "--short=7", "HEAD"]) || void 0;
|
|
2942
|
+
const currVisible = visibleMergeFindings(p.findings);
|
|
2943
|
+
p.prHistory = [
|
|
2944
|
+
{
|
|
2945
|
+
push: 1,
|
|
2946
|
+
...sha ? { sha } : {},
|
|
2947
|
+
...p.session.endedAt ? { endedAt: p.session.endedAt } : {},
|
|
2948
|
+
new: currVisible.length,
|
|
2949
|
+
cleared: 0,
|
|
2950
|
+
open: currVisible.length,
|
|
2951
|
+
...p.evidence.diffCostUsd != null ? { costUsd: p.evidence.diffCostUsd } : {}
|
|
2952
|
+
}
|
|
2953
|
+
];
|
|
2936
2954
|
}
|
|
2937
2955
|
}
|
|
2938
2956
|
if (opts.preview) {
|