Recipe catalog / postmortem-facets
Label the facets of a postmortem
Which of these does postmortem include: a timeline, a root cause, customer impact, contributing factors, action items?
You need to check an incident postmortem for the sections a review process expects before accepting it, or to tell the author which parts are missing.
Explore this recipe interactively ยท Source and implementation guide
Use postmortem-facets in TypeScript
Install with npm install jev-recipes. Requires Node.js 22.9 or newer and ES modules. Set TYPESAFE_API_KEY in your server environment for live calls, which send input to TypeSafe and use API quota. See the installation guide.
import { postmortemFacets } from 'jev-recipes/postmortem-facets';
const result = await postmortemFacets({
"postmortem": "Incident 2026-09-18: checkout failures. 10:12 UTC: alert on checkout 5xx rate fired. 10:15: on-call acknowledged and confirmed failures in the order-confirmation step. 10:31: deploy of order-service 3.8.0 identified as the trigger and rolled back. 10:36: error rate returned to baseline. Impact: for 24 minutes, roughly 18% of checkout attempts failed at confirmation, affecting all regions. Root cause: 3.8.0 changed the idempotency key format, and the confirmation step rejected keys written by 3.7.x instances still running during the rolling deploy. Action items: (1) add a compatibility test for mixed-version idempotency keys; (2) add a canary stage to the order-service pipeline; (3) document the key format in the service contract.",
"minConfidence": 0.8
});
console.log(result);
Input contract
| Field | Type | Needed |
|---|---|---|
| postmortem | string | Required |
| minConfidence | number | Optional |
Full input and result schemas
{
"input": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"postmortem": {
"type": "string"
},
"minConfidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"postmortem"
]
},
"result": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"model": {
"type": "string"
},
"usage": {
"type": "object",
"properties": {
"input_tokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"output_tokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"input_tokens",
"output_tokens"
],
"additionalProperties": false
},
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"detected": {
"type": "array",
"items": {
"type": "string",
"enum": [
"statesTimeline",
"statesRootCause",
"statesImpact",
"statesContributingFactors",
"statesActionItems"
]
}
},
"labels": {
"type": "object",
"properties": {
"statesTimeline": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"statesRootCause": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"statesImpact": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"statesContributingFactors": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"statesActionItems": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
}
},
"required": [
"statesTimeline",
"statesRootCause",
"statesImpact",
"statesContributingFactors",
"statesActionItems"
],
"additionalProperties": false
}
},
"required": [
"model",
"usage",
"status",
"detected",
"labels"
],
"additionalProperties": false
}
}Saved example result
This hand-authored response demonstrates the contract. It is not a model accuracy measurement. Run it without an API key: npx jev-recipes demo postmortem-facets.
{
"model": "demo-fixture",
"usage": {
"input_tokens": 0,
"output_tokens": 0
},
"status": "ready",
"detected": [
"statesTimeline",
"statesRootCause",
"statesImpact",
"statesActionItems"
],
"labels": {
"statesTimeline": {
"status": "ready",
"verdict": "present",
"probability": 0.95,
"confidence": 0.95
},
"statesRootCause": {
"status": "ready",
"verdict": "present",
"probability": 0.92,
"confidence": 0.92
},
"statesImpact": {
"status": "ready",
"verdict": "present",
"probability": 0.9,
"confidence": 0.9
},
"statesContributingFactors": {
"status": "ready",
"verdict": "absent",
"probability": 0.12,
"confidence": 0.88
},
"statesActionItems": {
"status": "ready",
"verdict": "present",
"probability": 0.94,
"confidence": 0.94
}
}
}
Evaluation evidence
No verified live accuracy measurement is available. Evaluate representative cases before using this decision in your workflow.
Use the evaluation guide to measure this decision on your own labeled cases.
Limitations
- Labels are independent, so a postmortem can carry several or none.
- Detects that a facet is present, not that it is correct. A stated root cause can be wrong, and an action item can be unowned or vague.
- Does not check section headings, templates, or length. Enforce document structure in application code.
Related recipes
- report-facets: Use report-facets for agent progress reports, where the expected parts are an outcome, evidence, blockers, and next steps.
- summary-coverage: Use summary-coverage to check whether a summary covers a source document, rather than whether a document contains expected sections.