Skip to main content

Good Planning

@magistr/good-planningv2026.05.01.1· 1mo agoMODELS·SKILLS
01README

Good-planning model that operationalizes Felipe Bovolon's "Good Planning Bad Planning" four-layer architecture as queryable swamp state. Strategy chooses; planning commits — this model holds the commitment.

Article: https://bovolon.substack.com/p/good-planning-bad-planning

A plan is not a slide deck. The article's thesis: the real plan is the pattern of commitments the organization has actually funded, sequenced, protected, and agreed to review. This model makes those commitments first- class state with explicit assumptions, signposts, tripwires, ceiling trigger points, and a pullback ladder — so the plan can be evaluated and revised on a cadence rather than executed-as-written until reality breaks it.

Four Layers (from the article)

  • Layer 1 — Assumption: what the plan believes about the world. Each assumption has impact, vulnerability, and a signpost.
  • Layer 2 — Allocative: what is actually funded and protected. Targets, forecasts, and allocations are tracked separately (Beyond Budgeting).
  • Layer 3 — Coordinative: how commitments interlock. Captured via dependsOn on each commitment.
  • Layer 4 — Adaptive: how the plan revises. Ceiling discipline (first-binding crux + trigger formula) and floor discipline (signposts → tripwires → pre-authorized actions
    • pullback ladder + max tolerable loss).

State Machine

drafted ──[commit]──> committed     (gated: all four layers populated)
committed ──[monitor]──> monitoring
monitoring ──[evaluate]──> monitoring  (read signposts, update layer state)
monitoring ──[trigger]──> adapting     (tripwire fired or ceiling crossed)
adapting ──[adapt]──> committed        (pullback or option exercised)
adapting ──[revise]──> drafted         (assumption broken — re-plan)
committed ──[archive]──> archived
monitoring ──[archive]──> archived

commit is the gate the article calls for: it refuses to leave drafted unless every layer is materially populated, including the six properties on every commitment (owner, resource, time, dependencies, review rule, consequence-if-changed) and at least one tripwire on the floor side.

Methods

  • start — create a draft plan with strategicChoice + horizon
  • add_assumption — record an assumption with impact / vulnerability / signpost
  • add_commitment — record a commitment or hypothesis (six-property gate)
  • add_allocation — record protected budget per priority (Layer 2)
  • add_ceiling — record a first-binding crux + lead time + signpost
  • add_tripwire — record a signpost threshold + pre-authorized action
  • set_pullback_ladder — ordered list of cuts (what to cut first)
  • set_loss_budget — sunk + shutdown + liabilities + working-capital + tail
  • commit — gate; transitions drafted → committed
  • monitor — committed → monitoring
  • evaluate — read a signpost; updates assumption/tripwire/ceiling state
  • trigger — explicit transition into adapting (action required)
  • adapt — record adaptation taken; back to committed
  • revise — assumption broken; back to drafted
  • archive — terminal
  • hydrate — write a compact governability scorecard summary
  • audit — answer the four diagnostic questions (one per layer)
02Release Notes

2026.05.01.1 — Add article link to extension description

Surface the source article URL directly in the manifest description so the swamp.club extension page links to it without forcing readers into the README:

Article: https://bovolon.substack.com/p/good-planning-bad-planning

The link was already present in README.md, SKILL.md, and the model source file as a citation, but missing from the manifest description that drives the registry summary card. No code or schema changes — this is a metadata-only release.

03Models1
@magistr/good-planningv2026.04.30.1good_planning.ts
fn start(strategicChoice: string, horizon: string, notes?: string)
Create a draft plan with strategicChoice + horizon. Strategy
ArgumentTypeDescription
strategicChoicestringThe where-to-play / how-to-win sentence in one line
horizonstringe.g. '3y', '12m'
notes?string
fn add_assumption(statement: string, signpostName: string, signpostExpr?: string, lastReading?: string)
Record a Layer 1 assumption with impact, vulnerability,
ArgumentTypeDescription
statementstring
signpostNamestring
signpostExpr?string
lastReading?string
fn add_commitment(description: string, owner: string, budgetUsd: number, byDate: string, dependsOn: array, reviewCadence: string, consequenceIfChanged: string)
Record a commitment OR hypothesis with all six properties.
ArgumentTypeDescription
descriptionstring
ownerstring
budgetUsdnumber
byDatestring
dependsOnarray
reviewCadencestring
consequenceIfChangedstring
fn add_allocation(priority: string, protectedBudgetUsd: number, target?: string, forecast?: string, raidLog: array)
Record a Layer 2 protected allocation. Target / forecast /
ArgumentTypeDescription
prioritystring
protectedBudgetUsdnumber
target?string
forecast?string
raidLogarray
fn add_ceiling(crux: string, leadTimeWeeks: number, safetyMarginWeeks: number, signpostName: string, optionPremiums: array, lastTimeToCruxWeeks?: number, lastTriggerPointWeeks?: number)
Record a Layer 4a ceiling: first-binding crux + lead
ArgumentTypeDescription
cruxstring
leadTimeWeeksnumber
safetyMarginWeeksnumber
signpostNamestring
optionPremiumsarray
lastTimeToCruxWeeks?number
lastTriggerPointWeeks?number
fn add_tripwire(signpostName: string, thresholdExpr: string, preAuthorizedAction: string, pullbackRung?: number, lastReading?: string)
Record a Layer 4b tripwire: signpost + threshold + pre-authorized
ArgumentTypeDescription
signpostNamestring
thresholdExprstring
preAuthorizedActionstring
pullbackRung?number
lastReading?string
fn set_pullback_ladder(rungs: array)
Record the ordered list of cuts. Index 0 is what gets
ArgumentTypeDescription
rungsarray
fn set_loss_budget(sunkCostUsd: number, shutdownCostUsd: number, committedLiabilitiesUsd: number, workingCapitalUnwindUsd: number, tailProvisionsUsd: number)
Record the maximum tolerable loss components. Total = sunk +
ArgumentTypeDescription
sunkCostUsdnumber
shutdownCostUsdnumber
committedLiabilitiesUsdnumber
workingCapitalUnwindUsdnumber
tailProvisionsUsdnumber
fn commit()
drafted → committed. Refuses unless every layer is materially
fn monitor()
committed → monitoring. Begin signpost evaluation.
fn evaluate(signpostName: string, reading: string, timeToCruxWeeks?: number)
Read a signpost's current value and update every assumption,
ArgumentTypeDescription
signpostNamestring
readingstringObserved value, free-form string
timeToCruxWeeks?numberIf reading impacts a ceiling: observed weeks until crux.
fn trigger(signpostName: string, reason: string)
monitoring → adapting. Call when a tripwire has fired or a
ArgumentTypeDescription
signpostNamestring
reasonstring
fn adapt(triggeredBy: string, actionTaken: string, reason: string, reading?: string, exercisedCeilingCrux?: string)
adapting → committed. Record the action taken (pullback rung
ArgumentTypeDescription
triggeredBystringSignpost name or ceiling crux that caused the adapt
actionTakenstring
reasonstring
reading?string
exercisedCeilingCrux?stringIf the action exercised a ceiling option, name the crux to mark it
fn revise(reason: string, brokenAssumptions: array)
adapting → drafted. An assumption has broken; the strategic
ArgumentTypeDescription
reasonstring
brokenAssumptionsarray
fn archive(reason: string)
Terminal. committed or monitoring → archived. Plan is no longer
ArgumentTypeDescription
reasonstring
fn audit()
Answer the four diagnostic questions from the article (Layer 4
fn hydrate()
Write a compact governability scorecard summary. Does

Resources

state(infinite)— Plan state — strategic choice, four-layer collections, history
summary(infinite)— Compact governability scorecard written by `hydrate`.
04Skills1
good-planning1 file
05Previous Versions1
2026.04.30.1Apr 30, 2026
06Stats
A
100 / 100
Downloads
10
Archive size
25.7 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types1/1earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
07Platforms
08Labels