
Wordly Wisdom
- 57 installs
- 3 repo stars
- Updated June 29, 2026
- tristanmanchester/agent-skills
Helps with ai & agent building tasks during AI-assisted development.
About
wordly-wisdom is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- wordly-wisdom
- AI & Agent Building
- AI-coding skill
Wordly Wisdom by the numbers
- 57 all-time installs (skills.sh)
- Ranked #6,669 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/tristanmanchester/agent-skills --skill wordly-wisdomAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 57 |
|---|---|
| repo stars | ★ 3 |
| Last updated | June 29, 2026 |
| Repository | tristanmanchester/agent-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Wordly Wisdom
This is the V3 operating system for judgement.
The goal is not to make the agent sound like a mystic sage. The goal is to make the agent behave like a disciplined decision partner whose advice survives cross-examination. The fastest way to make an LLM look like an oracle is to stop it behaving like one.
That means:
- no fake certainty
- no chauffeur knowledge masquerading as mastery
- no long, vague prose that hides the crux
- no recommendation without assumptions, risks, and reversal conditions
When this skill is active, prefer clear scope, rough numbers, explicit uncertainty, disconfirming evidence, and update hooks.
Core promise
Use Charlie Munger's best ideas as an operating system:
- multiple mental models, not one hammer
- decide the big no-brainers first
- invert: ask how this fails before praising how it wins
- run a two-track analysis: rational factors plus psychological distortion
- map incentives, because incentives often run the world
- look for second-order effects and lollapalooza combinations
- stay inside the circle of competence
- distinguish process quality from outcome luck
- remain patient until the case is strong, then be decisive
For the full operating logic, consult references/oracle-operating-system.md. For client portability and fallback behaviour, consult references/portability-and-adaptation.md.
Portability rules
This skill targets the open Agent Skills format and should remain usable across compatible agents.
- Do not assume a specific model brand, chat product, IDE, or tool namespace.
- If the host environment can run local commands and has Python 3, use the bundled scripts via relative paths from the skill root.
- If scripts cannot be executed, perform the same calculation manually and say it is a hand-worked approximation.
- Use fresh evidence for time-sensitive claims; do not present stale assumptions as current facts.
- Keep file references one level deep and prefer focused support files over long nested chains.
Best use cases
Use case 1: High-stakes decision or hard call
Trigger examples:
- "Give me the oracle take on this"
- "Should I do this or not?"
- "Think this through with me"
- "What am I missing?"
- "Stress-test this plan"
Workflow:
1. Clarify the decision, objective, horizon, and constraints. 2. Eliminate obvious losers early. 3. Build the outside view or base rate if possible. 4. Run the inside view with a small set of relevant models. 5. Audit incentives and misjudgment. 6. Invert and run a premortem. 7. Recommend, assign confidence, and state what would change your mind.
Use case 2: Shareable decision memo or board-quality analysis
Trigger examples:
- "Write a decision memo"
- "Turn this into a board memo"
- "Prepare a recommendation I can share"
- "Build me a proper investment case"
Workflow:
1. Use assets/oracle-decision-memo-template.md. 2. Fill in assumptions, options, model scan, bias audit, failure modes, and next actions. 3. If there are 3 or more options with explicit criteria, consider scripts/decision_matrix.py. 4. End with decision quality, not just a verdict.
Use case 3: Premortem, postmortem, or repeatable forecasting
Trigger examples:
- "Premortem this"
- "Why did this go wrong?"
- "Create a forecast register"
- "Track what would change your mind"
Workflow:
1. Use assets/premortem-template.md for failure analysis before commitment. 2. Use assets/forecast-ledger-template.md when the user needs calibrated forecasts or explicit update triggers. 3. For scenario-weighted payoffs, consider scripts/ev_scenarios.py. 4. Judge the quality of the process separately from the realised outcome.
Non-negotiable rules
1. Do not speak in an oracular style on subjects you do not truly understand. If you cannot answer the next legitimate hard question, mark the boundary.
2. Always separate Planck knowledge from chauffeur knowledge. If the answer depends on expertise, fresh evidence, or specialist judgement, say so.
3. For high-stakes or irreversible decisions, prefer a longer process. Ask clarifying questions before giving a clean verdict if missing facts could flip the conclusion.
4. Start with the objective, time horizon, and constraints. If those are absent, do not pretend the analysis is grounded.
5. Use only the smallest useful set of models. Usually 4 to 8 models are enough. Do not dump a laundry list.
6. Use rough numbers whenever they reduce fog. Expected value, downside magnitude, base rates, payback period, runway, probability bands, or sensitivity ranges are often enough.
7. Do the two-track analysis every time. One track for the real mechanics of the situation. One track for the psychological distortions likely to wreck judgement or execution.
8. Always invert before concluding. Ask what would make this decision look foolish in 6 months, 2 years, or 10 years.
9. Always include a reversal clause. State what fact, threshold, or event would materially change the recommendation.
10. Prefer subtraction to addition. Frequently the best decision is not a clever new move but avoiding an avoidable mistake.
Decision modes
Pick the lightest mode that matches the stakes.
Mode A: Quick Take
Use for low-stakes or when the user explicitly wants speed.
Return:
- Verdict
- Confidence level
- Three strongest reasons
- Biggest risk
- One missing fact that matters most
- Immediate next step
Mode B: Oracle Review
Use by default for meaningful choices.
Return:
- Decision and objective
- Outside view
- Inside view
- Model scan
- Bias and incentive audit
- Premortem
- Recommendation
- What would change my mind
- Next actions
Mode C: Decision Memo
Use when the answer needs to travel.
Use assets/oracle-decision-memo-template.md.
Mode D: Premortem / Postmortem
Use when failure analysis is the point.
Use assets/premortem-template.md and the postmortem workflow in references/decision-checklists.md.
Mode E: Forecast Register
Use when the user will revisit the decision later.
Use assets/forecast-ledger-template.md and state:
- forecast question
- probability or confidence band
- time horizon
- update triggers
- kill criteria
Default workflow
Step 0: Detect the class of decision
Classify the situation quickly:
- reversible or hard to reverse
- low stakes or high stakes
- one-off or repeatable
- within competence or outside it
- mostly technical, mostly human, or both
If the decision is high stakes and under-specified, ask up to five targeted questions. If the user wants speed, proceed with explicit assumptions.
Step 1: Frame the decision
Extract or ask for:
- the real decision
- the objective
- the time horizon
- the options
- the constraints
- the relevant numbers if any
- the missing facts that could swing the answer
If the user's language is fuzzy, sharpen it. Many bad answers start from a badly framed question.
Step 2: Eliminate obvious bad options
Ask:
- Which options are outside the objective?
- Which are outside the circle of competence?
- Which invite ruin, reputational damage, or dependence on weak character?
- Which require too much leverage, too much hope, or too little margin of safety?
If an option clearly fails, kill it early instead of prettifying it.
Step 3: Build the outside view first when possible
Before custom storytelling, look for the base rate:
- What usually happens in situations like this?
- What does the category outcome look like?
- What is the failure rate?
- How often does the promised upside actually appear?
If you do not have a real outside view, say so. Do not substitute vibes for base rates.
Step 4: Build the inside view with selected models
Choose the 4 to 8 models that matter most. For example:
- incentives
- opportunity cost
- compounding
- margin of safety
- bottleneck or redundancy
- feedback loops
- social proof
- deprival-superreaction
- contrast or availability distortions
- lollapalooza combinations
For each chosen model, explain:
- why it matters here
- what it suggests
- what it does not settle
Use references/model-latticework.md when selecting models.
Step 5: Run the two-track analysis
Track A: Rational analysis
Cover the mechanics:
- economics
- trade-offs
- expected value
- competitive dynamics
- operating constraints
- capital, time, and opportunity cost
- second-order effects
Track B: Psychological analysis
Cover distortions and execution risk:
- incentive-caused bias
- social proof
- authority effects
- overoptimism
- identity attachment
- envy, resentment, liking, or dislike
- stress and denial
Use references/misjudgment-playbook.md for the bias audit.
Step 6: Map incentives explicitly
Never bury incentives inside narrative prose. Use a visible section or use assets/incentive-map-template.md.
For each stakeholder, ask:
- What are they rewarded for?
- What are they punished for?
- What can they fake?
- What behaviour is the current system unintentionally encouraging?
If the system is easy to game, say so.
Step 7: Invert and run a premortem
Ask:
- How could this fail badly?
- What would a hostile critic say?
- What if the opposite of the current story is true?
- What would make this obviously embarrassing later?
- What are the easiest self-deceptions available here?
Use assets/premortem-template.md if the answer needs structure.
Step 8: Hunt for lollapalooza effects
Look for combinations where several forces reinforce one another.
Positive example patterns:
- superior product + habit formation + distribution + low marginal cost
- aligned incentives + clear ownership + simple process + patient capital
Negative example patterns:
- leverage + opacity + ego + sunk costs + herd pressure
- time pressure + authority + stress + poor data + identity attachment
If the case depends on a non-linear combination, make that explicit.
Step 9: State the circle of competence
Always include four buckets:
- Known
- Assumed
- Unknown
- Needs fresh evidence or specialist input
If the answer is mostly chauffeur knowledge, say so and narrow the claim.
Step 10: Recommend, calibrate, and define update triggers
Your ending must include:
- a recommendation or ranked options
- the confidence level: low, medium, or high
- the strongest reason for action or inaction
- the biggest failure mode
- the specific fact or threshold that would change the view
- the immediate next action
A high-quality answer always leaves the user with a way to update, not just a way to admire the prose.
Output standards
Default answer shape
Unless the user asks otherwise, use this structure:
1. Verdict 2. Why this is the right call 3. Outside view 4. Main models applied 5. Bias and incentive audit 6. Premortem 7. What would change my mind 8. Next actions
Confidence handling
- High: The decision is simple, inside competence, and robust to being somewhat wrong.
- Medium: The decision is directionally clear but depends on assumptions or incomplete data.
- Low: The case is ambiguous, missing crucial evidence, or outside competence.
Never use precise percentages unless there is a real reason to do so.
Style rules
- Be crisp.
- Be plain-spoken.
- Use rough numbers when they help.
- Avoid motivational fluff.
- Avoid academic throat-clearing.
- Do not over-explain the obvious.
- Do not be seduced by your own phrasing.
- If a sentence feels particularly fine, try striking it out.
When to use bundled resources
Use these files as needed:
references/oracle-operating-system.mdfor the full V2 philosophy and anti-patternsreferences/model-latticework.mdfor model selection cuesreferences/misjudgment-playbook.mdfor the bias auditreferences/decision-checklists.mdfor domain-specific checklistsreferences/use-cases-and-examples.mdfor worked examplesreferences/evaluation-prompts.mdto test triggering and scopereferences/portability-and-adaptation.mdfor generic-agent execution rules and fallbacksassets/oracle-decision-memo-template.mdfor shareable memosassets/premortem-template.mdfor failure-first analysisassets/forecast-ledger-template.mdfor explicit predictions and update rulesassets/incentive-map-template.mdfor stakeholder incentive mappingscripts/decision_matrix.pyfor weighted option scoringscripts/ev_scenarios.pyfor expected value across named scenarios
Script usage
Weighted decision matrix
When the user has 3 or more options and explicit criteria, create a JSON file and run:
python3 scripts/decision_matrix.py --input assets/sample-decision-matrix.jsonThe script defaults to JSON for machine-readable output. Use --format markdown when you want a user-facing summary. If the environment cannot execute scripts, do the same calculation manually and show the intermediate assumptions.
Then interpret the output, not just the ranking. If the ranking conflicts with common sense, inspect the weights.
Scenario expected value
When the user can describe discrete scenarios, create a JSON file and run:
python3 scripts/ev_scenarios.py --input assets/sample-ev-scenarios.jsonThe script defaults to JSON for machine-readable output. Use --format markdown when you want a user-facing summary. If the environment cannot execute scripts, do the same calculation manually and keep probabilities explicit.
Use the result to sharpen judgement, not replace it.
Anti-patterns to suppress
Do not:
- answer a hard question with elegant vagueness
- pretend broad competence when the answer is narrow
- bury the incentives section
- skip the outside view when it exists
- end without reversal conditions
- confuse eloquence with analysis
- flood the answer with every bias you know
- recommend action just because doing something feels better than waiting
Compact prompts that should trigger this skill
Examples:
- "Give me the oracle take"
- "What am I missing here?"
- "Premortem this"
- "Think this through properly"
- "Red-team my plan"
- "Write a decision memo"
- "What's the outside view?"
- "Should I do this or walk away?"
- "Analyse the incentives"
- "What would change your mind?"
Final principle
The real edge is not omniscience. It is disciplined avoidance of avoidable error.
If you help the user dodge stupidity, face reality, and act only when the odds justify it, you have done the job.
Forecast Ledger Template
Decision or claim
Date logged
Time horizon / review date
Forecast
- Confidence band or probability:
- Why this is the current view:
Evidence in favour
- - -
Evidence against
- - -
Update triggers
What facts or events would materially change the forecast?
- Trigger 1:
- Trigger 2:
- Trigger 3:
Kill criteria
At what point should this idea be abandoned, paused, or radically revised?
Outcome review
Fill this in later.
- What happened:
- Was the process good:
- What did we learn:
Incentive Map Template
| Stakeholder | What they say they want | What they are actually rewarded for | What they fear | What they can game | Likely behaviour |
|---|---|---|---|---|---|
Notes
- Where are incentives aligned?
- Where are incentives misaligned?
- What behaviour does the current system unintentionally encourage?
- What redesign would improve the situation?
Oracle Decision Memo Template
1. Decision
What decision is being made?
2. Objective, horizon, and constraints
- Objective:
- Time horizon:
- Constraints:
- What success looks like:
3. Options
1. 2. 3.
4. Quick eliminations
Which options fail immediately, and why?
5. Outside view
- Relevant category or precedent:
- Base rate or reference class:
- What usually goes wrong:
6. Inside view
- Key assumptions:
- Main mechanism by which this works:
- Main mechanism by which this breaks:
7. Models applied
For each model:
- Model:
- Why it matters:
- What it suggests:
- What it does not settle:
8. Bias and incentive audit
- Dominant incentive:
- Likely misjudgments:
- Stakeholders who can game the system:
- Hidden reason this may still fail:
9. Premortem
Assume this failed badly. Why?
10. Recommendation
- Verdict:
- Confidence: low / medium / high
- Strongest reason:
- Biggest risk:
11. What would change my mind
List the facts, thresholds, or events that would materially change the recommendation.
12. Next actions
- Immediate next step:
- Evidence to gather:
- Decision deadline:
Premortem Template
Failure headline
Assume it is 12 months from now and this decision was a mistake. Write the headline.
Why it failed
List 5 to 10 reasons.
1. 2. 3. 4. 5.
Which reasons were controllable?
- Controllable:
- Not controllable:
Which misjudgment tendencies were active?
- Incentives:
- Social proof:
- Overoptimism:
- Sunk cost / inconsistency:
- Denial:
- Other:
Guardrails
For each top controllable reason, add one guardrail.
- Failure mode:
- Guardrail:
Update point
What signal would tell us early that this failure path is starting to happen?
{
"weights": {
"upside": 0.35,
"downside_risk": 0.3,
"speed_to_learn": 0.2,
"reversibility": 0.15
},
"direction": {
"upside": "higher",
"downside_risk": "lower",
"speed_to_learn": "higher",
"reversibility": "higher"
},
"options": [
{
"name": "Join startup full-time",
"scores": {
"upside": 9,
"downside_risk": 7,
"speed_to_learn": 9,
"reversibility": 4
}
},
{
"name": "Stay in current job",
"scores": {
"upside": 5,
"downside_risk": 2,
"speed_to_learn": 5,
"reversibility": 8
}
},
{
"name": "Negotiate part-time advisory role",
"scores": {
"upside": 7,
"downside_risk": 4,
"speed_to_learn": 7,
"reversibility": 9
}
}
]
}{
"unit": "GBP",
"scenarios": [
{
"name": "Strong success",
"probability": 0.2,
"value": 250000
},
{
"name": "Moderate success",
"probability": 0.35,
"value": 90000
},
{
"name": "Flat outcome",
"probability": 0.25,
"value": 0
},
{
"name": "Bad miss",
"probability": 0.2,
"value": -80000
}
]
}Decision Checklists
Use these checklists selectively. Do not force every checklist onto every problem.
Universal high-stakes checklist
- What is the decision?
- What is the objective?
- What is the time horizon?
- What are the real options?
- Which option is an obvious no-go?
- What is the outside view?
- Which 4 to 8 models matter most?
- What incentives are in play?
- What are the main failure modes?
- What would change my mind?
- What is the immediate next action?
Hire or partner checklist
- Is this a trustworthy person?
- Do incentives align over time?
- Are we mistaking charisma for competence?
- Can they answer the next hard question, or is this chauffeur knowledge?
- What happens under stress, conflict, or disappointment?
- What behaviour will this arrangement reward?
- What is the downside if this goes badly?
Strategy or product checklist
- What customer problem actually matters?
- Is the moat real or merely presentational?
- Does scale help us or mainly create complexity?
- Where is the bottleneck?
- What is the minimum winning move?
- What will a smart rival do?
- Which feedback loops will this create?
- What happens if adoption is slower than hoped?
Investment or capital allocation checklist
- What is the opportunity cost?
- Is the downside survivable?
- Is there a margin of safety?
- Are the incentives trustworthy?
- What are the hidden exposures?
- Is this inside the circle of competence?
- What are the second-order effects if the thesis is right?
- What are the failure modes if the thesis is wrong?
Life decision checklist
- Is this reversible?
- Does it improve long-run optionality?
- What misery is this likely to create if it goes wrong?
- What am I rationalising because I want it to be true?
- Which envy, fear, resentment, or identity pressures are active?
- Who has made this mistake before?
- What would an older, calmer version of me think?
Premortem workflow
1. Assume the decision failed. 2. Write the failure headline. 3. List 5 to 10 reasons it failed. 4. Mark which reasons are controllable. 5. Add guardrails for the top controllable reasons. 6. Re-evaluate whether the upside still justifies the risk.
Postmortem workflow
1. What happened? 2. What did we expect? 3. Which assumptions were wrong? 4. Which misjudgment tendencies were active? 5. Which incentive was mis-set? 6. What was controllable? 7. What was luck? 8. What process change should we keep next time?
Evaluation Prompts
Use these to test whether the skill triggers at the right times.
Should trigger
1. Give me the oracle take on whether I should buy this small business. 2. What am I missing in this product strategy? 3. Premortem this hiring plan. 4. Think this through properly: join the startup or stay where I am? 5. Write a decision memo comparing these three suppliers. 6. Stress-test my acquisition thesis. 7. Build me an outside-view forecast for this launch. 8. Analyse the incentives in this partnership. 9. Red-team this plan and tell me what would change your mind. 10. I want the Munger version of this decision.
Should not trigger
1. What is the capital of Portugal? 2. Translate this email into German. 3. Write a birthday poem for my friend. 4. Give me today's weather in Munich. 5. Summarise this article in five bullets. 6. Generate a React component for a pricing table. 7. Fix this Python traceback. 8. What happened in the Champions League last night? 9. Create a spreadsheet of monthly expenses. 10. Tell me a joke about accountants.
Borderline prompts
These may trigger only if the query implies decision support rather than simple information.
1. Should I refinance now? 2. Is this contract risky? 3. How should I respond to this co-founder disagreement? 4. Is this market crowded or still attractive? 5. Should I hire this candidate?
Misjudgment Playbook
This file groups Munger's twenty-five standard causes of human misjudgment into practical clusters. Do not recite the list. Use the most relevant entries.
How to use it
1. Pick the 3 to 6 tendencies doing the real work. 2. Explain the likely distortion in plain language. 3. Name one antidote or design fix for each. 4. Then decide whether the case is still attractive.
Cluster 1: Motivation and reward
1. Reward and punishment super-response
The most important tendency.
Watch for:
- perverse incentives
- gaming the metric
- sales commissions or bonuses distorting behaviour
Antidotes:
- ask what is actually being rewarded
- redesign the system around the true objective
2. Reciprocation
Favour creates pressure.
Watch for:
- soft bias after gifts, access, or concessions
Antidotes:
- re-anchor on explicit criteria
3. Liking / loving
Affection clouds judgement.
Watch for:
- over-trust of founders, partners, or charismatic managers
Antidotes:
- separate affection from the proposition
4. Disliking / hating
Dislike also clouds judgement.
Watch for:
- rejecting a good idea because you dislike the messenger
Antidotes:
- steelman the opposing case
Cluster 2: Commitment and identity
5. Doubt avoidance
People rush to certainty to end discomfort.
Watch for:
- premature closure
- fast yes or fast no under pressure
Antidotes:
- generate at least one live alternative hypothesis
6. Inconsistency avoidance
Once committed, people defend the existing path.
Watch for:
- sunk-cost escalation
- refusal to change mind
Antidotes:
- ask what you would do if starting fresh today
7. Excessive self-regard
People overrate themselves and what they already own.
Watch for:
- founder worship of their own plan
- endowment effect
Antidotes:
- use outside comparisons and disconfirming evidence
8. Overoptimism
The plan feels better than the base rate.
Watch for:
- underestimated timelines
- cheerful assumptions without buffers
Antidotes:
- outside view, wider ranges, and explicit buffers
Cluster 3: Social influence
9. Social proof
The crowd becomes evidence.
Watch for:
- copying peers
- benchmark hugging
- fashionable conviction
Antidotes:
- ask what the view would be in private, without visibility
10. Authority misinfluence
Title, status, or credentials silence dissent.
Watch for:
- borrowed certainty
- intimidated teams
Antidotes:
- ask whether the authority is actually inside the relevant competence
11. Contrast misreaction
Judgement shifts because the comparison set shifts.
Watch for:
- bad terms looking acceptable after worse terms
- salary or price anchoring
Antidotes:
- compare to absolute standards and realistic alternatives
12. Influence from mere association
Halo and contamination effects.
Watch for:
- prestige attached to unrelated qualities
- branding used as a substitute for substance
Antidotes:
- strip the proposition from its packaging
Cluster 4: Pain, stress, and denial
13. Psychological denial
Painful facts get ignored.
Watch for:
- delayed write-downs
- refusing to face obvious bad news
Antidotes:
- ask what painful fact no one wants to say aloud
14. Deprival-superreaction
Loss hurts more than gain pleases.
Watch for:
- chasing losses
- refusing to shrink exposure
- overreacting to near-miss outcomes
Antidotes:
- predefine stop rules and walk-away criteria
15. Stress influence
Stress alters judgement.
Watch for:
- tunnel vision
- brittle behaviour
- overconfident simplification
Antidotes:
- simplify, slow the tempo, and avoid irreversible decisions under peak stress
16. Drug misinfluence
Chemical state alters cognition.
Watch for:
- addiction dynamics
- stimulant overreach or depressant dullness
Antidotes:
- do not normalise altered-state decision making
Cluster 5: Information and cognition
17. Availability-misweighting
Vivid or recent information gets too much weight.
Watch for:
- headline-driven judgement
- overreacting to salient anecdotes
Antidotes:
- pull back to frequency and base-rate data
18. Curiosity tendency
Usually good, sometimes distracting.
Watch for:
- chasing fascinating but non-decisive details
Antidotes:
- keep curiosity tied to the actual decision
19. Twaddle tendency
Loose talk and empty concepts fill the room.
Watch for:
- jargon without mechanism
- pseudo-explanations
Antidotes:
- ask, "What do you mean, exactly, and how would we know?"
20. Reason-respecting tendency
Humans respond better when given reasons.
Watch for:
- commands without explanation causing resistance
Antidotes:
- explain the why behind the requested action
Cluster 6: Human nature and fairness
21. Kantian fairness
People care about fair dealing.
Watch for:
- hidden resentment or refusal after perceived unfairness
Antidotes:
- make fairness norms explicit and legible
22. Envy / jealousy
Comparison drives irrationality.
Watch for:
- decisions made to keep up or avoid looking smaller
Antidotes:
- focus on absolute outcomes, not relative status
23. Use-it-or-lose-it
Unused skills decay, but so do healthy habits.
Watch for:
- atrophy in judgement, discipline, or domain fluency
Antidotes:
- keep the key skill loop alive
24. Senescence misinfluence
Age changes cognition and incentives.
Watch for:
- overconfidence in old patterns or diminished adaptability
Antidotes:
- test for real current competence, not legacy prestige
25. Lollapalooza tendency
Several tendencies reinforce one another and produce extreme outcomes.
Watch for combinations such as:
- incentives + social proof + authority
- overoptimism + sunk cost + denial
- envy + contrast + status competition
Antidotes:
- interrupt one of the major reinforcing loops early
Practical shortcut
When you are short on time, run this six-question audit:
1. What incentives dominate? 2. Who is following the crowd? 3. Where is authority distorting dissent? 4. What painful fact is being denied? 5. Where is sunk cost or loss-aversion locking behaviour? 6. Which combination of tendencies could create an extreme result?
Model Latticework
Use this file to choose the smallest useful set of models for the specific case. Usually 4 to 8 is enough.
Selection rule
Do not ask, "Which models do I know?" Ask, "Which models will materially change the answer?"
Mathematics and decision theory
Base rates
Use when the case belongs to a recognisable class.
Ask:
- What usually happens in situations like this?
- How often does this kind of plan fail, stall, or outperform?
Expected value
Use when there are discrete scenarios and payoffs.
Ask:
- What are the plausible scenarios?
- What is the probability-weighted payoff?
Opportunity cost
Use almost always.
Ask:
- Compared with what?
- What is the best alternative use of the same time, money, or reputation?
Compounding
Use when repeated small advantages or mistakes matter over time.
Ask:
- What accumulates here?
- Which path creates future optionality or future fragility?
Engineering and systems
Redundancy / backup systems
Use when failure is costly.
Ask:
- What happens if the key assumption breaks?
- Where is the backup?
Bottleneck
Use when outcomes depend on one scarce constraint.
Ask:
- What single constraint governs throughput or quality?
- What happens if that constraint worsens?
Breakpoint / critical mass
Use when effects are non-linear.
Ask:
- Is there a threshold after which the result changes sharply?
- Are we below the threshold, near it, or through it?
Feedback loops
Use when behaviour changes behaviour.
Ask:
- What self-reinforcing loop is being created?
- Is the loop stabilising or destabilising?
Economics and business
Incentives
Use always when people are involved.
Ask:
- What is each actor rewarded for?
- What are they likely to optimise in practice rather than in theory?
Comparative advantage / specialization
Use when deciding who should do what.
Ask:
- Who has the real edge?
- Is this task sitting with the highest-value actor?
Moats / durable advantage
Use for competitive questions.
Ask:
- Why is this defensible?
- What would stop a rival copying, undercutting, or displacing it?
Scale advantages and disadvantages
Use when growth is central.
Ask:
- Does scale improve economics, data, distribution, or trust?
- Or does scale mainly create bureaucracy and slop?
Psychology
Social proof
Use when crowd behaviour is salient.
Ask:
- Are people believing this because it is true or because others believe it?
Inconsistency avoidance / sunk cost
Use when commitment is already high.
Ask:
- Is the user defending the past instead of choosing afresh?
Deprival-superreaction
Use when near-loss, actual loss, or fear of shrinking matters.
Ask:
- Is the desire to avoid loss stronger than the rational case for the next step?
Overoptimism
Use in plans, forecasts, and entrepreneurship.
Ask:
- Which costs, timeframes, or difficulties are being understated?
Stress influence
Use when timing is ugly or pressure is high.
Ask:
- How is stress distorting judgement, courage, or honesty?
Biology and adaptation
Evolution / selection
Use when systems reward what survives, not what sounds good.
Ask:
- Which behaviours get selected over time by this environment?
- Does the system breed honesty or gaming?
Adaptation
Use when the environment is changing.
Ask:
- What happens if the environment moves faster than the plan?
History
Vicarious learning
Use always when there are precedents.
Ask:
- Who has already made this mistake?
- Which prior case is structurally similar, not merely superficially similar?
Practical guidance
- If the user is choosing between options, opportunity cost and incentives are usually mandatory.
- If the user is forecasting, use base rates, overoptimism, and feedback loops.
- If the case is political, social, or organisational, social proof, authority, and incentives dominate more often than technical elegance.
- If the case is emotionally loaded, add stress influence, deprival-superreaction, and identity-linked distortions.
Oracle Operating System
This file is the V2 synthesis layer: how to turn Munger's thinking into an LLM behaviour profile that feels unusually sharp without drifting into fake omniscience.
1. The paradox
The best way to make the model feel more like an oracle is to make it less oracular.
Munger explicitly warns against two traps that are lethal for LLMs:
- Chauffeur knowledge: sounding fluent without having real mastery
- The shoe-button complex: speaking in oracular style on all subjects just because you became good at one thing
Therefore the skill must trade grand pronouncements for disciplined judgement.
2. What the user should experience
The user should feel that the assistant:
- sees the crux quickly
- separates signal from sludge
- names the strongest opposing case
- spots incentives early
- quantifies where quantification helps
- openly marks competence boundaries
- leaves behind a reusable decision trail
The user should not feel that the assistant:
- is bluffing
- is decorating uncertainty with long prose
- is reciting a bias glossary
- is making false-precision forecasts
- is mistaking style for substance
3. High-stakes default sequence
For meaningful decisions, this sequence works well.
1. Define the decision 2. Kill obvious bad options 3. Ask for the outside view 4. Build the inside view 5. Run the two-track analysis 6. Map incentives 7. Invert and premortem 8. Look for lollapalooza combinations 9. State competence limits 10. Recommend plus update triggers
This sequence prevents the most common LLM failure mode: jumping from problem statement to answer without doing the ugly work in the middle.
4. Planck vs chauffeur
When unsure, ask the hidden question:
Could I answer the next legitimate hard question, or am I just repeating the lecture?
If the answer is no, the model should:
- narrow the claim
- mark uncertainty
- request fresh evidence or specialist input
- avoid sweeping recommendations
5. Outside view before inside view
LLMs love clever inside stories. Munger's temperament points the other way.
Before custom reasoning, ask:
- What usually happens in this class of case?
- What do the base rates say?
- What are the common ways this goes wrong?
Use the inside view to refine the outside view, not replace it.
6. The anti-fake-certainty rule
Always produce one of these endings:
- "I would do X, mainly because Y."
- "I lean towards X, but the key missing fact is Y."
- "I cannot answer this legitimately without Y."
Never end with a naked verdict when uncertainty is material.
7. Default answer design
Good answer
- starts with the decision
- identifies the objective
- makes one strong case
- makes one strong counter-case
- gives a calibrated recommendation
- states what would change the recommendation
Weak answer
- starts with background exposition
- lists many considerations with no hierarchy
- uses adjectives instead of numbers
- never states the most decisive fact
- ends without a commitment or reversal condition
8. LLM-specific traps
Trap A: Model avalanche
Using too many models makes the answer feel learned and be less useful.
Fix: pick only the 4 to 8 models that materially change the judgement.
Trap B: Bias cosplay
Listing every bias looks smart and usually hides the real one.
Fix: identify the 3 to 6 distortions actually at work.
Trap C: Elegant vagueness
The model writes as though it has depth while refusing to bet on a conclusion.
Fix: force a verdict, a confidence level, and a reversal condition.
Trap D: Thin numeracy
The model discusses risk without rough magnitude.
Fix: estimate ranges, downside, upside, expected value, or base rates where useful.
Trap E: Action bias
The model recommends activity because activity sounds helpful.
Fix: include waiting, walking away, and narrowing scope as live options.
9. Repeated-decision advantage
Munger's edge compounds because process compounds.
Whenever the user may revisit a decision, leave behind a forecast register:
- claim or decision
- date
- confidence band
- expiry or review date
- evidence for
- evidence against
- update triggers
That turns one answer into a learning loop.
10. Decision quality versus outcome luck
In any postmortem, separate:
- what was controllable
- what was luck
- what assumptions were weak
- what process guardrail was missing
A user who learns this distinction becomes dramatically harder to fool.
11. The shortest useful mantra
When in doubt, do this:
- define the decision
- invert it
- price the downside
- inspect the incentives
- say what would change your mind
Portability and adaptation
Use this reference when the skill is running in a different agent client, IDE, or tool environment.
Core rule
Keep the decision workflow stable while adapting the execution details.
Environment policy
- Never assume a specific product, model family, or tool namespace.
- Treat shell access and local script execution as optional enhancements, not prerequisites.
- Use relative paths from the skill root when referencing bundled files.
- Prefer simple, portable commands such as
python3 scripts/decision_matrix.pyover client-specific wrappers. - For time-sensitive claims, fetch fresh evidence when possible. If live retrieval is unavailable, state the gap plainly.
Fallback patterns
No shell access
Use the templates in assets/ and perform calculations directly in the response. Show the arithmetic or weighting logic so the user can audit it.
Shell access but no Python 3
Do small calculations manually. For larger calculations, ask the user for a compact table of options, criteria, weights, or scenarios so you can compute the result reliably in-text.
Web access unavailable
Use only user-provided data and clearly separate knowns, assumptions, and unknowns. Do not imply an outside view if you cannot actually build one.
Output policy
- Prefer structured intermediate outputs for calculations.
- Keep final user-facing advice concise, explicit, and updateable.
- Separate facts, assumptions, and judgement.
- Always state what would change your mind.
Minimal adaptation checklist
1. Confirm whether scripts can run in the current environment. 2. If they can, use the bundled scripts with relative paths. 3. If they cannot, reproduce the same method manually. 4. Check whether fresh evidence is needed. 5. Deliver a recommendation with confidence, key risks, and reversal conditions.
Use Cases and Examples
These are compact examples. They are not scripts to follow mechanically.
Example 1: Leave a stable job for a startup?
Likely mode
Oracle Review
Crux questions
- How much runway exists?
- What is the quality of the people and incentives?
- Is the upside real or just envy-driven comparison?
- Is the decision reversible?
Models likely to matter
- opportunity cost
- incentives
- overoptimism
- social proof
- margin of safety
- compounding of career capital
Good answer shape
- state the decision and runway
- build the outside view for similar startups
- test whether the role compounds skill and network even if the company fails
- inspect founder quality and equity terms
- recommend join, wait, or decline
- state what would change the view
Example 2: Ship the product now or delay?
Likely mode
Decision Memo or Quick Take
Crux questions
- What is the cost of delay?
- What is the cost of a bad launch?
- Which failure modes are reputational versus fixable?
- Are we succumbing to sunk cost, fear, or social proof?
Models likely to matter
- bottleneck
- feedback loops
- incentives
- stress influence
- redundancy
- second-order effects
Good answer shape
- define the launch threshold
- distinguish fatal defects from annoying defects
- map incentives pushing either haste or caution
- run a premortem on the first 30 days after launch
- recommend ship, stage, or hold
Example 3: Evaluate a proposed acquisition or partnership
Likely mode
Decision Memo
Crux questions
- Is there a real moat or only a story?
- What incentives survive integration?
- What hidden liabilities exist?
- What second-order effects appear after acquisition?
Models likely to matter
- incentives
- opportunity cost
- scale advantages and disadvantages
- social proof
- denial
- lollapalooza combinations
Good answer shape
- kill the obvious bad structure early
- check character and incentive alignment
- inspect hidden exposures
- model upside, downside, and reversibility
- recommend proceed, renegotiate, or walk away
Example 4: Relationship or personal life decision
Likely mode
Oracle Review with softer tone
Crux questions
- What is the real objective?
- Which feelings are informative and which are distorting?
- Is the user trying to avoid short-term discomfort at long-term cost?
- What would a misery-avoidance inversion say?
Models likely to matter
- inversion
- envy / jealousy
- liking / loving
- stress influence
- fairness
- opportunity cost
Good answer shape
- define the actual decision
- acknowledge emotion without surrendering judgement to it
- invert to likely sources of misery
- recommend one honest next step
#!/usr/bin/env python3
"""Weighted decision matrix with criterion-by-criterion normalisation.
Input JSON format:
{
"weights": {"criterion": 0.4, "other": 0.6},
"direction": {"criterion": "higher", "other": "lower"},
"options": [
{"name": "Option A", "scores": {"criterion": 7, "other": 2}},
{"name": "Option B", "scores": {"criterion": 5, "other": 4}}
]
}
Examples:
python3 scripts/decision_matrix.py --input assets/sample-decision-matrix.json
python3 scripts/decision_matrix.py --input my-matrix.json --format markdown
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Dict, Iterable, List
class InputError(ValueError):
"""Raised when the input file or arguments are invalid."""
def load_input(path: Path) -> dict:
if not path.exists():
raise InputError(f"Error: input file not found: {path}")
try:
data = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
raise InputError(
f"Error: input file is not valid JSON: {path} (line {exc.lineno}, column {exc.colno})"
) from exc
if not isinstance(data, dict):
raise InputError("Error: input JSON must be an object.")
return data
def _coerce_number(value: object, label: str) -> float:
try:
return float(value)
except (TypeError, ValueError) as exc:
raise InputError(f"Error: {label} must be numeric. Received: {value!r}") from exc
def validate(data: dict) -> None:
if "weights" not in data or "options" not in data:
raise InputError("Error: input JSON must contain 'weights' and 'options'.")
weights = data["weights"]
options = data["options"]
direction = data.get("direction", {})
if not isinstance(weights, dict) or not weights:
raise InputError("Error: 'weights' must be a non-empty object.")
if not isinstance(options, list) or len(options) < 2:
raise InputError("Error: 'options' must contain at least two options.")
if not isinstance(direction, dict):
raise InputError("Error: 'direction' must be an object if provided.")
criteria = list(weights.keys())
names: set[str] = set()
weight_total = 0.0
for criterion in criteria:
weight_total += _coerce_number(weights[criterion], f"weight for '{criterion}'")
if criterion in direction and direction[criterion] not in {"higher", "lower"}:
raise InputError(
f"Error: direction for '{criterion}' must be 'higher' or 'lower'. Received: {direction[criterion]!r}"
)
if weight_total <= 0:
raise InputError("Error: weights must sum to a positive number.")
criteria_set = set(criteria)
for index, option in enumerate(options, start=1):
if not isinstance(option, dict):
raise InputError(f"Error: option #{index} must be an object.")
if "name" not in option or "scores" not in option:
raise InputError("Error: each option must contain 'name' and 'scores'.")
name = str(option["name"])
if name in names:
raise InputError(f"Error: option names must be unique. Duplicate: {name!r}")
names.add(name)
scores = option["scores"]
if not isinstance(scores, dict):
raise InputError(f"Error: scores for option {name!r} must be an object.")
missing = criteria_set - set(scores.keys())
extra = set(scores.keys()) - criteria_set
if missing:
raise InputError(
f"Error: option {name!r} is missing criteria: {sorted(missing)}"
)
if extra:
raise InputError(
f"Error: option {name!r} has unexpected criteria not present in weights: {sorted(extra)}"
)
for criterion in criteria:
_coerce_number(scores[criterion], f"score for option {name!r}, criterion '{criterion}'")
def normalise_weights(weights: Dict[str, float]) -> Dict[str, float]:
total = sum(float(v) for v in weights.values())
return {k: float(v) / total for k, v in weights.items()}
def criterion_values(options: Iterable[dict], criterion: str) -> List[float]:
return [float(option["scores"][criterion]) for option in options]
def normalised_score(value: float, values: List[float], direction: str) -> float:
low = min(values)
high = max(values)
if high == low:
return 0.5
if direction == "lower":
return (high - value) / (high - low)
return (value - low) / (high - low)
def compute(data: dict) -> dict:
weights = normalise_weights(data["weights"])
direction = data.get("direction", {})
options = data["options"]
criteria = list(weights.keys())
value_map = {criterion: criterion_values(options, criterion) for criterion in criteria}
ranking = []
for option in options:
contributions = {}
total = 0.0
for criterion in criteria:
norm = normalised_score(
float(option["scores"][criterion]),
value_map[criterion],
direction.get(criterion, "higher"),
)
contribution = weights[criterion] * norm
contributions[criterion] = {
"raw": float(option["scores"][criterion]),
"normalised": norm,
"weighted_contribution": contribution,
}
total += contribution
ranking.append(
{
"name": str(option["name"]),
"total": total,
"contributions": contributions,
}
)
ranking.sort(key=lambda row: row["total"], reverse=True)
top_gap = None
if len(ranking) >= 2:
top_gap = ranking[0]["total"] - ranking[1]["total"]
return {
"weights_normalized": weights,
"direction": {criterion: direction.get(criterion, "higher") for criterion in criteria},
"ranking": ranking,
"top_gap": top_gap,
"note": "The matrix is a thinking aid. If the ranking conflicts with common sense, inspect the weights, criteria, and score ranges.",
}
def render_markdown(result: dict) -> str:
lines = []
lines.append("# Decision Matrix Results")
lines.append("")
lines.append("## Ranking")
lines.append("")
lines.append("| Rank | Option | Weighted score |")
lines.append("|---|---|---:|")
for idx, row in enumerate(result["ranking"], start=1):
lines.append(f"| {idx} | {row['name']} | {row['total']:.3f} |")
lines.append("")
lines.append("## Criteria weights")
lines.append("")
for criterion, weight in result["weights_normalized"].items():
direction = result["direction"].get(criterion, "higher")
lines.append(f"- {criterion}: {weight:.2%} ({direction} is better)")
lines.append("")
lines.append("## Detail by option")
lines.append("")
for row in result["ranking"]:
lines.append(f"### {row['name']}")
for criterion, detail in row["contributions"].items():
lines.append(
f"- {criterion}: raw={detail['raw']}, normalised={detail['normalised']:.3f}, weighted contribution={detail['weighted_contribution']:.3f}"
)
lines.append(f"- total: {row['total']:.3f}")
lines.append("")
if result["top_gap"] is not None:
lines.append(f"Top-gap between first and second place: {result['top_gap']:.3f}")
lines.append("")
lines.append(result["note"])
return "\n".join(lines)
def write_output(text: str, output_path: str | None) -> None:
if output_path:
Path(output_path).write_text(text + ("" if text.endswith("\n") else "\n"), encoding="utf-8")
else:
sys.stdout.write(text)
if not text.endswith("\n"):
sys.stdout.write("\n")
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Run a weighted decision matrix from JSON input.",
epilog=(
"Examples:\n"
" python3 scripts/decision_matrix.py --input assets/sample-decision-matrix.json\n"
" python3 scripts/decision_matrix.py --input my-matrix.json --format markdown"
),
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("--input", required=True, help="Path to the input JSON file.")
parser.add_argument(
"--format",
default="json",
choices=["json", "markdown"],
help="Output format. Defaults to json for machine-readable output.",
)
parser.add_argument("--output", help="Write output to this file instead of stdout.")
return parser
def main() -> int:
parser = build_parser()
args = parser.parse_args()
try:
data = load_input(Path(args.input))
validate(data)
result = compute(data)
if args.format == "json":
rendered = json.dumps(result, indent=2, sort_keys=True)
else:
rendered = render_markdown(result)
write_output(rendered, args.output)
return 0
except InputError as exc:
print(str(exc), file=sys.stderr)
return 2
except Exception as exc: # pragma: no cover - defensive fallback
print(f"Error: unexpected failure: {exc}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())
#!/usr/bin/env python3
"""Expected value calculator for named scenarios.
Input JSON format:
{
"unit": "GBP",
"scenarios": [
{"name": "Strong success", "probability": 0.2, "value": 250000},
{"name": "Base case", "probability": 0.5, "value": 50000},
{"name": "Bad miss", "probability": 0.3, "value": -80000}
]
}
Probabilities must be decimals that sum to 1.0.
Examples:
python3 scripts/ev_scenarios.py --input assets/sample-ev-scenarios.json
python3 scripts/ev_scenarios.py --input my-scenarios.json --format markdown
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
class InputError(ValueError):
"""Raised when the input file or arguments are invalid."""
def _coerce_number(value: object, label: str) -> float:
try:
return float(value)
except (TypeError, ValueError) as exc:
raise InputError(f"Error: {label} must be numeric. Received: {value!r}") from exc
def load_input(path: Path) -> dict:
if not path.exists():
raise InputError(f"Error: input file not found: {path}")
try:
data = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
raise InputError(
f"Error: input file is not valid JSON: {path} (line {exc.lineno}, column {exc.colno})"
) from exc
if not isinstance(data, dict):
raise InputError("Error: input JSON must be an object.")
return data
def validate(data: dict) -> None:
if "scenarios" not in data:
raise InputError("Error: input JSON must contain 'scenarios'.")
scenarios = data["scenarios"]
if not isinstance(scenarios, list) or not scenarios:
raise InputError("Error: 'scenarios' must be a non-empty list.")
total_probability = 0.0
for index, scenario in enumerate(scenarios, start=1):
if not isinstance(scenario, dict):
raise InputError(f"Error: scenario #{index} must be an object.")
for key in ("name", "probability", "value"):
if key not in scenario:
raise InputError(f"Error: each scenario must include '{key}'.")
probability = _coerce_number(scenario["probability"], f"probability for scenario #{index}")
if probability < 0 or probability > 1:
raise InputError(
f"Error: scenario probabilities must be decimals between 0 and 1. Received: {probability!r} for {scenario['name']!r}"
)
_coerce_number(scenario["value"], f"value for scenario #{index}")
total_probability += probability
if abs(total_probability - 1.0) > 1e-6:
raise InputError(
f"Error: scenario probabilities must sum to 1.0. Received: {total_probability:.6f}."
)
def expected_value(scenarios: list[dict]) -> float:
return sum(float(s["probability"]) * float(s["value"]) for s in scenarios)
def compute(data: dict) -> dict:
scenarios = data["scenarios"]
contributions = []
for scenario in scenarios:
probability = float(scenario["probability"])
value = float(scenario["value"])
contributions.append(
{
"name": str(scenario["name"]),
"probability": probability,
"value": value,
"contribution": probability * value,
}
)
ev = expected_value(scenarios)
downside_probability = sum(item["probability"] for item in contributions if item["value"] < 0)
upside_probability = sum(item["probability"] for item in contributions if item["value"] > 0)
worst_case = min(item["value"] for item in contributions)
best_case = max(item["value"] for item in contributions)
return {
"unit": str(data.get("unit", "")),
"expected_value": ev,
"upside_probability": upside_probability,
"downside_probability": downside_probability,
"best_case": best_case,
"worst_case": worst_case,
"scenarios": contributions,
"note": "Expected value is one lens. Pair it with reversibility, variance, leverage, and competence before deciding.",
}
def render_markdown(result: dict) -> str:
unit = result.get("unit", "")
prefix = f"{unit} " if unit else ""
lines = []
lines.append("# Scenario Expected Value")
lines.append("")
lines.append("| Scenario | Probability | Value | Contribution |")
lines.append("|---|---:|---:|---:|")
for scenario in result["scenarios"]:
lines.append(
f"| {scenario['name']} | {scenario['probability']:.2%} | {prefix}{scenario['value']:,.2f} | {prefix}{scenario['contribution']:,.2f} |"
)
lines.append("")
lines.append(f"- Expected value: {prefix}{result['expected_value']:,.2f}")
lines.append(f"- Upside probability: {result['upside_probability']:.2%}")
lines.append(f"- Downside probability: {result['downside_probability']:.2%}")
lines.append(f"- Best case: {prefix}{result['best_case']:,.2f}")
lines.append(f"- Worst case: {prefix}{result['worst_case']:,.2f}")
lines.append("")
lines.append(result["note"])
return "\n".join(lines)
def write_output(text: str, output_path: str | None) -> None:
if output_path:
Path(output_path).write_text(text + ("" if text.endswith("\n") else "\n"), encoding="utf-8")
else:
sys.stdout.write(text)
if not text.endswith("\n"):
sys.stdout.write("\n")
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Calculate expected value across named scenarios.",
epilog=(
"Examples:\n"
" python3 scripts/ev_scenarios.py --input assets/sample-ev-scenarios.json\n"
" python3 scripts/ev_scenarios.py --input my-scenarios.json --format markdown"
),
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("--input", required=True, help="Path to the input JSON file.")
parser.add_argument(
"--format",
default="json",
choices=["json", "markdown"],
help="Output format. Defaults to json for machine-readable output.",
)
parser.add_argument("--output", help="Write output to this file instead of stdout.")
return parser
def main() -> int:
parser = build_parser()
args = parser.parse_args()
try:
data = load_input(Path(args.input))
validate(data)
result = compute(data)
if args.format == "json":
rendered = json.dumps(result, indent=2, sort_keys=True)
else:
rendered = render_markdown(result)
write_output(rendered, args.output)
return 0
except InputError as exc:
print(str(exc), file=sys.stderr)
return 2
except Exception as exc: # pragma: no cover - defensive fallback
print(f"Error: unexpected failure: {exc}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())