Postil

Envelope schema

The envelope is the contract between the CLI and everything else: the hosted worker, the Action, your own tooling. It is versioned and frozen; the control plane stores it verbatim.

Schema (version 1)

{
  "version": 1,
  "summary": "1-3 sentence merge-relevant summary, empty string when silent",
  "silent": true,
  "findings": [
    { "path": "src/x.ts", "line": 42, "endLine": 45,
      "severity": "info|warn|error",
      "kind": "risk|humanEscalation|guardrail|uncertainty",
      "confidence": 0.85, "title": "short", "body": "markdown" }
  ],
  "resolved": [ /* same shape as findings; from the baseline, now fixed */ ],
  "counts": { "info": 0, "warn": 0, "error": 0, "suppressed": 0, "ungrounded": 0 },
  "confidenceBuckets": [0, 0, 0, 0, 0],
  "gate": { "failOn": "error", "failing": false },
  "modelUsed": "deepseek/deepseek-v4-pro",
  "usage": { "promptTokens": 0, "completionTokens": 0 },
  "durationMs": 0,
  "baseSha": "...", "headSha": "...", "sinceSha": null
}

Field notes

FieldMeaning
silentTrue when the review produced no shippable finding. The summary is the empty string and no comment is posted anywhere.
findings[].kindrisk (a concrete defect or hazard), humanEscalation (a consequential decision that needs an accountable human), guardrail (the change violates a rule stated in .postil/guardrails.md; the finding quotes the rule it breaks), uncertainty (the model flags its own doubt).
findings[].confidence0 to 1. Findings below minConfidence are suppressed and counted in counts.suppressed.
resolvedFindings from the previous review's envelope (the baseline) that the new diff fixes. Powers "N resolved, M open" on incremental re-review.
confidenceBucketsFive counts over [0-0.2, 0.2-0.4, 0.4-0.6, 0.6-0.8, 0.8-1.0]. Aggregated across reviews, this is the dashboard's confidence distribution.
gateThe configured fail-on severity and whether this review fails the gate. Mirrors the exit code: failing: true means exit 1.
counts.ungroundedFindings the model reported that did not cite a changed line and were dropped. A nonzero value is a model-quality signal; a run where every finding was ungrounded fails closed. Optional within v1 (absent means 0).
durationMsWall-clock duration of the review engine run in milliseconds. Optional within v1 (absent means 0 from older CLIs).
sinceShaThe previously reviewed head when this was an incremental review; null on a full review.

Grounding guarantee

Every finding must cite a (path, line) present in the reviewed diff. Ungrounded model output is dropped; an entirely invalid response becomes a synthetic error finding at .postil/model-output:1 after one JSON-repair retry, and the gate fails. There is no code path in which malformed model output produces a passing review.

Stability

Consumers should accept unknown additional fields and reject unknown version values. Any breaking change ships as version: 2 alongside, never in place.