Keep a personal decision journal: write down each decision with its context and a predicted outcome plus a confidence number BEFORE the result is known, then review on a schedule to score predictions against outcomes and calibrate judgment. Use when someone wants to learn from their past decisions, track predictions against what actually happened, or check whether their confidence matches reality.
./install.sh decision-journalsname: "decision_journals" description: "Keep a personal decision journal: write down each decision with its context and a predicted outcome plus a confidence number BEFORE the result is known, then review on a schedule to score predictions against outcomes and calibrate judgment. Use when someone wants to learn from their past decisions, track predictions against what actually happened, or check whether their confidence matches reality." metadata: { "includeInPrompt": true }
Build a personal learning loop around decisions. Before you act, you write down what you expect to happen and how confident you are. Later, after the result is in, you compare the two. Over time this shows where your judgment is sharp and where you are consistently overconfident, so future calls get better.
This is not an architecture decision record. decision_records (ADRs) is an immutable team record of why a technical choice was made, for future contributors to read. A decision journal is personal and predictive: its value is the gap between what you wrote down before and what happened after. It is also not general note-taking. note_taking_systems covers capture methods like Cornell and Zettelkasten. A journal covers one narrow thing: predictions and outcomes, scored.
Save one file per decision, dated, somewhere simple like ~/decisions/2026-09-27-switch-suppliers.md:
markdown
# Decision: <short title>
Date: 2026-09-27
Review by: 2026-11-27
## Context
(What was going on, in a few lines. Only what mattered to the call.)
## Decision
(What you decided, in one or two sentences.)
## Options considered
1. <option> - <why it won or lost>
2. <option> - <why it won or lost>
## Prediction
<I expect to see...> (observable outcome, with a time window)
Confidence: 70%
## What would prove me wrong
(Specific and observable. Write it now, not after you know.)
## Outcome (fill in at review)
Happened / did not happen / partial. Score: 1 / 0 / 0.5
Notes:
Use these to force a prediction without hindsight bias. Stop when the answer is a number plus an observable, not a feeling.
Save this as ~/decisions/calibrate.py. It reads a JSON list of reviewed entries and reports a Brier-style score (mean of (confidence minus outcome) squared, lower is better) against an always-50% baseline, plus confidence bins comparing stated confidence to actual hit rate. Stdlib only. Verified locally against a 10-entry fixture, including the empty and all-unresolved edge cases.
Run it like this:
mkdir -p ~/decisions
python3 ~/decisions/calibrate.py ~/decisions/reviewed.json
reviewed.json is a list of entries with outcomes filled in:
json
[
{
"date": "2026-08-15",
"decision": "Launch feature X early",
"prediction": "No major bugs in week 1",
"confidence": 0.9,
"outcome": 0
}
]
confidence: 0.0 to 1.0, written before the outcome.outcome: 1 (happened), 0 (did not happen), a fraction for partial, or null while still open. Null entries are skipped by the scorer.python
#!/usr/bin/env python3
"""calibrate.py - score decision-journal predictions against outcomes.
Reads a JSON file of reviewed journal entries and reports a Brier-style
calibration score plus a confidence-binned breakdown.
Reviewed-entry JSON format (a list of objects):
[
{
"date": "2026-09-20",
"decision": "Switch suppliers to Acme",
"prediction": "Costs drop 10% by Q4",
"confidence": 0.75,
"outcome": 1
}
]
- confidence: your stated probability, 0.0 to 1.0, written BEFORE the outcome.
- outcome: 1 = it happened, 0 = it did not, a fraction like 0.5 for
a partial, null = still open (skipped by the scorer).
Usage:
python3 calibrate.py reviewed.json
"""
import json
import sys
def main():
if len(sys.argv) != 2:
print("usage: python3 calibrate.py reviewed.json")
sys.exit(1)
with open(sys.argv[1]) as f:
entries = json.load(f)
if not isinstance(entries, list):
print("reviewed.json must hold a JSON list of entries.")
sys.exit(1)
scored = [e for e in entries
if isinstance(e.get("outcome"), (int, float))]
waiting = len(entries) - len(scored) # only null-outcome entries are waiting
if not scored:
print("No resolved entries to score yet.")
sys.exit(0)
# Brier-style score: mean of (confidence - outcome)^2. Lower is better.
brier = sum((e["confidence"] - e["outcome"]) ** 2 for e in scored) / len(scored)
# Baseline: a person who says 50% on everything.
baseline = sum((0.5 - e["outcome"]) ** 2 for e in scored) / len(scored)
print(f"Resolved entries: {len(scored)} ({waiting} still open)")
print(f"Brier score (lower is better): {brier:.3f}")
print(f"Always-50% baseline: {baseline:.3f}")
print(f"Beats baseline: {'yes' if brier < baseline else 'not yet'}")
print("\nCalibration by confidence bin (avg confidence vs actual hit rate):")
for pct in range(0, 100, 10):
lo, hi = pct / 100, (pct + 10) / 100
inbin = [e for e in scored if lo <= e["confidence"] < hi or (hi >= 1.0 and e["confidence"] == 1.0)]
if inbin:
avg_c = sum(e["confidence"] for e in inbin) / len(inbin)
hit = sum(e["outcome"] for e in inbin) / len(inbin)
flag = ""
if avg_c - hit > 0.1:
flag = " <-- overconfident here"
elif hit - avg_c > 0.1:
flag = " <-- underconfident here"
print(f" {pct:2d}-{pct+10:3d}%: n={len(inbin):2d} avg conf {avg_c:.2f} hit rate {hit:.2f}{flag}")
key = lambda e: (e["confidence"] - e["outcome"]) ** 2 # noqa: E731
best = min(scored, key=key)
worst = max(scored, key=key)
print(f"\nBest call: {best['decision'][:60]} (conf {best['confidence']:.0%}, outcome {best['outcome']})")
print(f"Worst miss: {worst['decision'][:60]} (conf {worst['confidence']:.0%}, outcome {worst['outcome']})")
if __name__ == "__main__":
main()
When this skill fires on a decision, it produces:
Done looks like this: every resolved decision has a prediction written before the outcome was known, no prediction was edited after the fact, and the review summary names at least one concrete adjustment for the next round.
decision_records (ADRs) instead. That cousin is built for the team job; this one is built for the personal loop.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.