Repository navigation
Releases: oernster/Decitect
Release list
Decitect v5.0.0
Release notes
Fulcrum is now Decitect
Same application, new name: Decitect, Decision Architecture Organisational Software. The model, board and guide are unchanged. The website is now https://decitect.com.
Your work comes with you
On first launch Decitect moves your Fulcrum settings and last session (~/.fulcrum) into ~/.decitect. If the move fails it keeps reading the old folder, so nothing is lost. Saved organisations and exported plans open as before.
Upgrading on Windows
Run the Decitect setup as usual. If it finds Fulcrum it offers, ticked by default, to remove it once Decitect is installed, taking only what provably belonged to Fulcrum: its folder, Apps list entry, shortcuts and sign-in entry. Close Fulcrum first if it is running. A Fulcrum icon pinned to the taskbar needs pinning again. Installed Fulcrum releases are offered this setup by their own update check.
Upgrading on macOS and Linux
Decitect installs alongside Fulcrum; your settings still come across. Remove the old copy afterwards: on macOS drag Fulcrum from Applications to the Bin; on Linux run flatpak uninstall uk.codecrafter.Fulcrum.
Smaller changes
The donate button now goes to Decitect's own payment page.
Fulcrum v4.6.0
Release notes
A hardening release: damaged or malformed files are refused cleanly instead of being half loaded, cancelling the guide now frees your processor as well as the progress bar and the promise about network use is now checked automatically.
Saved sessions you can trust
If the saved move record could not be read or no longer replayed, Fulcrum used to restore the organisation without it; the next save then wrote the file without the record, so the moves were lost unseen. Now the file as it was is kept aside first. The organisation still restores and a message on launch says that only the move record was lost and where the original file was kept. Nothing is deleted.
A saved file whose contents are the wrong shape (a list where a value belongs, a word where a number belongs) is now treated like any other unreadable file: kept aside with a message, never a failed launch.
Opening a plan
A plan file that will not read or whose moves will not replay is now refused with one message naming the problem; where a move is the cause, the message names the first move that fails. Your current session stays exactly as it was.
Numbers the model cannot score
An organisation carrying impossible values (a number that is not a number, an infinite or absurdly large count, a yes or no setting written as text) is now refused with a clear error. Before, such a team could pass every check and score a perfect 100. A team and a unit may no longer share an id.
Cancelling the guide
Cancelling a guide build on a large organisation now ends the worker processes it started, so your processor cores are free again straight away rather than finishing work nobody will read.
Network use, now checked
Fulcrum's only connection of its own is the anonymous daily check for a newer release. That was a promise held by review; it is now checked automatically every time the app is tested, so any other connection fails the build until it is argued for.
Fulcrum v4.5.0
Release notes
A small release: a way to support Fulcrum, a sturdier update check and documentation that says only what the app really does.
Supporting Fulcrum
Fulcrum is free and stays free, with no paid tier, no licence key and no feature held back. For anyone who wants to support its development there is now a donate button in the header, just left of the light and dark toggle, reachable from the keyboard like every other control. Pressing it hands the payment page to your browser; Fulcrum itself opens no connection for it. If your desktop declines to open a browser, the app tells you so and shows the address. The same link sits in the README and on the website.
Commercial licences
Fulcrum stays open source under GPL-3.0 with its interface under LGPL-3.0. The README and the website now say that a commercial licence for my own code can also be bought, for anyone whose project those terms do not suit.
A sturdier update check
If the window was closed while an update check was still waiting on GitHub, the answer arriving afterwards could raise an error on the background thread. It is now quietly dropped, since nobody is left to tell. This was found by reading the code rather than reported, so it is hardening rather than the fix for a crash anyone saw.
Documentation that claims only what holds
Generated levels are now described as they behave: each template is resampled in search of a great move up to a limit, so the move is sought rather than guaranteed. The macOS build instructions now describe the keychain route to notarisation as the script actually takes it. The sensitivity sweep on the website now gives its true size of 36 perturbed configurations. A new document in the repository sets out the decisions Fulcrum rests on and what each one costs.
For anyone building from source
The development guide is now DEVELOPMENT.md. The linter is pinned to the release the repository is clean under. The Windows and macOS builds now need Nuitka 4.2.1 or later and stop before compiling, naming the version they found, when an older one is installed.
The website
The tool and model pages are split into a page for each part: the moves and signals, the board and the guide, the weights, the assumptions and the testing. Old links to the long pages still land in the right place. The board screenshot is new and shows the donate button in the header. The installer and the Linux package now name ernster.dev/fulcrum as the app's site.
Fulcrum v4.4.0
Release notes
One new capability: Fulcrum now notices when a newer release has been
published and offers it to you, without nagging and without sending anything
about you or your organisations anywhere.
An update check that respects you
A few seconds after launch and then once a day while it stays open, Fulcrum
asks GitHub's releases API whether a newer version exists. When one does, a
prompt names the version you are on and the version available, with three
choices: Download opens the right file for your platform (the Windows
installer, the macOS disk image or the Linux Flatpak, falling back to the
release page when no matching file is attached), Skip This Version silences
that version permanently and Later closes the prompt until the next check.
Help's Check for updates used to open the releases page in your browser and
leave the comparing to you. It now runs a real check and reports every
outcome: the same prompt when an update exists, a plain "You are running the
latest version." when none does and an honest failure message when GitHub
cannot be reached. The manual check deliberately ignores a skipped version,
so a release you previously declined stays reachable.
The check is built not to intrude. Only a formally published release can
prompt; a failed or malformed check on the automatic path says nothing at all
and tries again another day. The request carries no identifier and nothing
about your organisations or your sessions. Your choice to skip a version
persists beside the theme in the same settings file. The Flatpak now carries
the network permission this needs; the README states plainly that this daily
call is the one thing Fulcrum ever asks the network.
Fulcrum v4.3.0
Release notes
One thing runs through this release. The gentle self-reading behaviour the
help dialogs already had now reaches every explanatory surface that can
overflow, so no part of the family is left half in it.
Experience
-
A signal's definition reads itself. The dialog behind a signal's
magnifier button explains what the reading measures, its unit, when it
reads high and what it maps to. On a short window, or with a longer
definition, the tail of that sat below the fold and had to be found by
hand. It now holds still on open, reads itself down at the same pace as
the glossary and the licence texts, holds at the end and rewinds. Nothing
changes for a definition that already fits: the cycle moves only when the
content actually overflows, so attaching it to a surface that currently
fits costs nothing. -
The guide's move list reads itself. A frame's line can run to more
moves than the pane shows, exactly as the board's own move list can, and
the board's list has read itself down for some time while the guide's did
not. The two now behave identically. Scrolling by hand, dragging the
scrollbar or tabbing onto a move row suspends the cycle, and it picks up
from wherever you left it, so taking over never switches the behaviour off
for the rest of the dialog's life.
Both surfaces run on the shared constants rather than their own, which is
the point of doing it this way: one reading pace for the whole application,
so no dialog can drift into feeling faster or slower than its neighbours.
Fulcrum v4.2.0
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
Two things run through this release. The Windows installer, which until now
sat outside every check the rest of the repository is held to, is now held to
all of them. And several places where the app quietly did the wrong thing
with your work are fixed: it reopens where you left it, it shows you where a
move landed, and it will no longer write over a saved organisation it cannot
read.
Experience
-
Dependency arrows land on the box they point at. An arrow head was
placed by backing off half a box width horizontally and half a box height
vertically at the same time, which is correct only when the approach is
exactly horizontal or exactly vertical. Every diagonal dependency
therefore had its head sitting somewhere off the target rather than on its
edge. Both maps now meet the border properly at any angle, and each run is
drawn from border to border rather than centre to centre, so no line is
painted across the inside of the box it leaves or the box it enters. A
dependency count above one is centred on its run instead of hanging off
the midpoint. -
The presentation's map no longer spills text out of its boxes. Every
node on the exported before-and-after map was drawn at one fixed width,
which was never checked against the text put inside it. A domain with
enough teams for a four-figure count ("1,076 teams, 177 contested teams")
needed half as much width again, so the line simply ran out past the
border. Nodes are now sized to their own longest line, sharing the widest
on the map so the grid stays a grid, and the map states the font it is
measured against rather than inheriting whatever the document supplies.
The one function producing a node's lines is now the one the sizing reads,
so a box cannot be measured from different text than it draws. -
Every button wears the same background. The icon buttons in the header
and the move-preview buttons beside each move declared a transparent
background of their own, so they read as bare glyphs sitting on the window
while every other button in the app sat on the raised grey. Those two
overrides are gone: there is now one rule deciding what a button looks like
at rest, and it governs the main window and every dialog alike. The
distinct darker fill on a disabled button is deliberate and stays, since
that is how unavailable is signalled alongside the red ring. -
The presentation is where you can see it, and it opens itself. Its
button sat out on the right-hand edge among the utilities, which is not
where the board's main output belongs; it now sits at the centre beside
the move record and the provenance mark. Creating a presentation still
writes it into your Downloads folder under a fresh name that never
overwrites an earlier one, but it now opens in your browser instead of
reporting a filename and leaving you to go and find it. The confirmation
box remains only for the case where nothing opens the file.
Fixes
-
The app reopens on the section you were working in. It always came
back at the whole organisation, however deep you had drilled, which on a
large structure meant finding your way back down on every launch. Two
things were wrong: the drilled section was never written to the autosave,
and the board discarded whatever focus a session arrived with before
showing it. Both are fixed, and the restored section is validated against
the organisation that came back, so a file naming a unit that no longer
exists or no longer holds teams opens at the whole organisation rather
than pointing at nothing. A file written by an earlier build simply has no
section recorded and opens as it always did. -
A move you play is now marked on the map. Playing from the move list
redrew the board in the new position and left no visible trace of what had
happened. At whole-org scope that is indistinguishable from nothing
happening at all: a repair inside one section moves the encoding by
hundredths, which no colour can show. The nodes a move acted on are now
ringed on both the complete picture and the drill map, and where the
picture summarises a section, the section holding those teams is ringed
instead. Taking a move back falls back to marking the one before it. The
ring already existed and was used by the move preview and the move record;
the board itself simply never asked for it. -
The uninstaller no longer offers to delete a directory the app has never
written. It looked for user state under LocalAppData while the
application saves its settings and its session to a directory in your home
folder. So "also remove my settings and saved games" removed nothing and
reported success, and a full uninstall left everything behind. The two now
agree, and a test pins them together by comparing the paths both sides
compute, since the installer is compiled separately and cannot import the
app to share a constant. -
A saved organisation that will not load is kept instead of overwritten.
The old behaviour was silent and total: any unreadable or incompatible file
produced a fresh session, and the first thing the fresh session did was
save itself over the file it could not read. One bad file and an
organisation with its whole move record was gone in seconds, with no
message anywhere. Such a file is now moved aside first, under a name that
cannot displace an earlier rescue, and if even that fails the store refuses
to write at all rather than destroy what it found. Either way the app now
says what happened and where the file went.
What's new
- The installer is gated like the application it installs. It was a
1,575-line PySide6 program with no tests, invisible to both the coverage
gate and the module-size gate, wearing a build script's exemption while
carrying real logic: registry writes, path resolution, payload extraction,
shortcut targets and the launcher resolution a onefile build needs. A
defect in any of those lands on a machine before Fulcrum ever starts. It
is now layered the way the app is:installer_logic.pydecides and is held
at 100% coverage by 49 new tests,installer_ops.pyacts on Windows,
installer_lifecycle.pycomposes the two and the Qt surface presents. No
installer behaviour changed. - The 400-line cap now covers the installer too. Every module under
installer/is inside it. The structural suite gained two invariants:
nothing underinstaller/may import from thefulcrumpackage, since
the two binaries are built and released separately; its decision layer may
not reach for the registry, a subprocess, the environment or Qt. - The analysis scripts are inside the suite.
calibrate.py,
sensitivity.pyandgenerate_matrixed_enterprise.pywere covered by
nothing, which mattered most for the calibrator: a silently broken one
reports success. The suite now fails if the sensitivity sweep loses a
qualitative conclusion, if a calibration case drifts outside its expected
band or if the committed matrixed-enterprise case stops matching what its
generator produces. - The matrixed-enterprise generator reads as a hierarchy. Its builder was
one 136-line function nested five deep; it is now an accumulator and four
named builders, at 350 lines rather than 391. The output is byte-identical
to the committed case, which the suite asserts. - The repository states its own outstanding debt.
TECH_DEBT.mdrecords
what is still open, what is deliberately left alone and what only looks
like debt, with the reasoning for each, and the README links to it. It
holds open items only: a resolved one is deleted rather than marked done,
because the history of a debt is not itself a debt. build_docs.pyis retired. It claimed in its own docstring to be the
authoritative source of the site while emitting a single page with no
navigation, so running it would have overwritten the published index and
orphanedwhy.html,model.html,tool.htmlanddownload.html. The
site is hand-maintained and now says so, with nothing left to contradict
it.
Fulcrum v4.1.0
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
What's new
- The presentation judges every move in its own frame too. The
exported report classified each move against the whole organisation
only, so a repair played as good inside a drilled section (worth
points in its frame, hundredths at whole-org scale) read as neutral
and the deliberate balance of a plan vanished from the report. Every
move whose targets sit inside one unit's subtree now carries a second
verdict: the unit is recovered from the move's own targets, scored
before and after exactly as the board scores a drilled section and
badged beside the org-wide verdict ("within Runtime group 2: good,
section health 45.652 to 51.480"), with a summary note explaining the
two scales; org-wide acts keep their single verdict. This is the
book's own move-locality result honoured in the report: a leaf repair
invisible from the summit is priced where it lives. - Rationales never claim a fall the numbers cannot show. The report
named the signal each move most eased even when the easing rounded
away at display precision, producing lines like "Rework rate falls
46% to 46%". A signal now counts as easing only when its displayed
value actually changes; when no visible easing exists the rationale
states the health change alone. - The Flatpak carries the full asset set. The Linux build now ships
the provenance icon (the golden mark beside the app icon that opens
"What grounds the numbers") and the calibration examples, so
Organisation | Open example organisation works in the sandbox exactly
as it does on Windows and macOS. - The macOS icon ships with its glow. The disk-image build derived
its.icnsfrom the raw master artwork (dark ink on a dark fill), so
the Mac icon shipped without the glow treatment the Windows and Linux
builds carry. It now derives from the highest-fidelity glow-treated
PNG the icon generator emits and warns plainly when none is present.
Fulcrum v4.0.0
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
What's new
One idea defines this release, carried through eight adversarial repairs:
the score now prices authority by scale. Machiavelli holds both positions
and the model encodes their union: The Prince (concentrated authority
governs the small state well) and the Discourses (the durable large state
is an institutionalised republic), hinged on the Dunbar horizon and
grounded in the light-cone axiom rather than preference. The claim was
then attacked adversarially, every finding repaired and every repair
pinned by a conformance test, so the scale dependency is structural and
checkable rather than an asserted preference. Alongside the model: two new
signals, glossary entries for the new vocabulary, a calibration harness
for lived-experience organisations and an updated preregistration.
- The prince band. Five new coefficients in
SimulationParameters
(dunbar_headcount150,prince_band_upper200,prince_attenuation0.3,
prince_amplification0.25,prince_survivor_ceiling1.6). Up to 150
people the three authority charges (capacity cut, escalation share,
influence divisor) cost 0.3 of their flat price; the price rises linearly
to parity across 150 to 200, then grows with the log of the population and
caps at 1.6. The cap is survivorship made structural: rare princes persist
at scale, so concentration is graded, never prohibited. - Frames are priced at their own population. Rolled unit nodes and leaf
frames now carry real headcounts, so a Dunbar-sized pocket deep inside a
conglomerate may stay princely in its own frame while the frames above it
demand a republic. - Contest is never forgiven. The attenuation applies only to clean
concentration; a standing claim keeps its full flat price below the
horizon and above the band it deepens in proportion to the scaled
escalation price, so a contested team's capacity sits strictly below a
merely escalating team's at every scale. This closes the adversarial
finding that the first cut let contest and clean escalation converge to
the same capacity price at scale. - A full republic is scale-invariant. A structure with local authority
everywhere and no claims scores identically at every population; the
band leaves the well-designed archetype column untouched (the routed
dependent demand below moves it separately, since even a well-designed
organisation carries supplier hubs). - Resolution neighbourhoods. Two adversarial findings closed in one
mechanism. Each escalating team resolves at the nearest enclosing unit
whose subtree holds a clean authority: its concentration charges are
priced at that unit's population, so a team whose lead sits across the
desk is never priced at conglomerate scale (an org of 100 empowered
50-person pockets now reads the same headline at any unit count), and
escalation_load_share(0.25) of its workload lands on that unit's
authorities' queues, so a founder absorbing thirty teams' escalations
saturates and prices itself as latency. The shed load is deliberately
not attenuated by the band: the band forgives friction, never bandwidth. - Fragmentation is priced (unowned interfaces). The fourth adversarial
finding closed: a dependency between two clean sovereigns that share no
enclosing domain has no institutional roof under which its conflicts can
be arbitrated, so each such edge pushes its endpoints toward the
cannot-decide-cleanly share, weighted byunowned_interface_weight(0.5)
and scaled by the prince factor. Two roofless founders stay near-free;
a roofless network of 200 sovereign teams at 20,000 people falls from
98.8 to 70.4, while the same network under a declared common roof keeps
its score: the roof is a modelling claim that a shared owner exists.
Machiavelli's republic is institutionalised: a senate, not merely
distributed sovereignty. - Dependency concentration prices itself (routed dependent demand).
The escalation machinery priced authority concentration while a fully
empowered dependency hub rode free: a five-person team that thirty-four
teams wait on read as healthy (the matrixed-enterprise sample exposed
the gap once its Developer experience section was delegated: the hub
fan cost about one point against the same teams in disjoint pairs).
dependent_demand_weight(0.15) now routes that fraction of the
frame's workload from each dependent onto its upstream's queue,
authority notwithstanding, grounded in Little's law and LatencyLab's
serial-queue placement result. The imbalance floor keeps a light
fan-out free, so the cost begins where the queue does; the coefficient
is held at or belowescalation_load_share(enforced in code) since
waiting on a supplier may never cost more than resolving through an
authority. The 34-fan hub now prices 5.6 points below its distributed
twin, every calibration case stays in its band and the knife-edge
greedy great on the enterprise archetype (+9.09 against the 9.0
threshold) honestly becomes a strong good. - Frames carry their roof. A focused frame previously dropped its
enclosing domains, so every edge between two sovereign teams inside a
drilled section read as roofless fragmentation (a fully roofed section
showed "Unowned interfaces: 34") while the whole-org score priced the
identical edges as roofed: the same fact, two prices. Every focused
frame (a leaf section, an aggregate unit, a mixed unit's direct-teams
row) now keeps its subtree's domain rows with the root cut loose from
the world outside, so in-frame pricing agrees with the whole
organisation; section scores rise wherever a roof genuinely stands and
the whole-org score is untouched. The top-level frame stays roofless
deliberately: nothing above the top level is modelled. - The matrixed enterprise drills sanely. The calibration sample's
oversized sub-units (a lead plus thirty-four flat teams) now split
into led groups of a handful of teams each, so every leaf has a sane
span and the case reads as the drillable hierarchy it claims to be.
The matrix claims the group leads exactly as it claims the unit and
sub-unit leads (line leadership is dual-reported all the way down),
so the documented-collapse shape survives the restructure and the
case scores 16.3 inside its 0..30 band. - Influence is priced proportionally. The third adversarial finding
closed: the influence divisor reads the per-team mean rather than the
absolute load, so one no-authority advisory hub with ten dependents
costs a 5,000-person organisation 3.4 points instead of half its score.
A knock-on stated honestly: the approval-layer blunder softens on the
large archetypes (enterprise -2.59 vs best repair +3.15 with dependent
demand priced), so the site now says a blunder erases most of the best
repair rather than outweighs it. - Archetypes carry a Company roof. All ten example organisations now
declare the common domain their real counterparts have, which is what
keeps the well-designed column's sovereign interfaces owned. - Claims are priced proportionally. The claim divisor reads the
per-team mean like the influence divisor, so a standing claim costs the
share of the organisation it contests rather than a flat tithe: one
claim on a 5,000-person org costs about a point, not nine. - Shed load follows the wiring. A resolving authority receives the
escalations it actually has dependencies with, so a disconnected puppet
authority absorbs nothing and cannot launder a saturated founder's
queue; wiring the puppet in costs coupling on both ends. Escalators with
no edge to any resolving authority fall back to an equal split. - A roof needs an officer. A shared domain owns its sovereigns'
interfaces only when its subtree holds a clean authority beyond the two
endpoints, so two sovereigns alone under a nominal roof stay unowned. - A claim is strictly additive. Contested no-authority teams still
shed their escalations (a claim disputes who clears the queue, it never
drains it), structural sovereignty keeps an unowned edge unowned when a
claim lands on it and the matrix-overlay actor is now an unmodelled
claimant beside the delivery graph rather than a team, so imposing an
overlay can never dilute the per-team means or relieve a loaded centre. - Two new signals. Centre escalation load (the escalated decisions per
turn landing on the most loaded authority) and unowned interfaces, each
with its own definition and tooltip, so the new pricing is observable in
the app rather than silent. - Glossary grows the new vocabulary. The prince band and the Dunbar
horizon, resolution neighbourhoods with escalation load and unowned
interfaces, in the same plain register as the rest. - Calibration harness.
python calibrate.pyscores the organisations
inexamples/calibration/against expected bands drawn from known
outcomes, with a template for adding lived-experience cases; three
synthetic seed cases mark the healthy, saturated and matrixed shapes.
Each case is a real drillable hierarchy whose leaf teams hold three to
eight people with varied sizes: the startup's eighteen squads group
under three tribes and the enterprise is generated deterministically
(generate_matrixed_enterprise.py, seeded) as eight divisions, 45
domains and about 1,100 small teams with the matrix claiming every
line lead, so drilling into any case shows real structure at every
level. Calibration cases are permanently ineligible for the
preregistered blind validation, stated in ...
Fulcrum v3.0.0
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
What's new
Three changes define this release. Fulcrum can now model the disease the
books call most interesting: matrix and dual-reporting structure,
represented as authority claims and priced by the same deterministic engine
as everything else. The guide became a plan for every level of the
organisation at once, honest about what composes and what merely looks good
from altitude. And the session became a record: move history survives
closing the app, undo reaches across runs and the exported report covers
everything ever played. Alongside them, the site gains a page that
publishes every scoring coefficient with its provenance.
- Authority claims. A claim records another actor asserting the right to
decide for a team: a second reporting line, a functional chapter, a matrix
overlay. The claimant can be a team, a unit at any level or a plain label
for someone not modelled at all (a "Head of QA" need not sit on the
delivery graph to contest a decision class). A team's own authority is
never a self-claim; Ships without asking stays the single source of truth. - Contested ownership is priced, three ways. Every decision class already
has a structural owner (the team itself, or the line it escalates to), so
any standing claim makes its subject contested: who decides must be settled
before anything can be decided. A contested team's capacity takes a
dedicated penalty that is validated never to be gentler than clean
escalation, it counts in the escalation share and the whole score divides
per standing claim. An org without claims scores exactly as before, pinned
by a golden test over the ten example archetypes. - New moves, from great repair to canonical blunder. Resolve authority
collapses a contested class into a single accountable owner, in the team's
favour or a claimant's, either way leaving one resolvable worldline.
Downgrade a claim turns a claimant into a consulted party: an explicit
dependency with a priced delay, an interface rather than shared control.
Impose a matrix overlay is the new standing blunder beside the approval
layer: a second claimant lands on every team at once, so the falsifiable
claim has a twin (model a realistic org where dual reporting improves
structural health and the framework is wrong). A claimed team never gets a
plain delegate move, because granting authority without settling the claims
adds a claimant instead of removing one. - Contest is visible everywhere. A fifth watched signal (Contested
ownership) counts claimed teams; contested nodes border red on the org map,
the complete picture and the exported SVG, with "contested" in their
status line; a unit rolls up how many of its teams are contested; the
glossary explains claims in plain language with the same tooltip source as
the rest of the app. - Claims in the editor and on disk. The organisation editor gains an
authority-claims table beside the dependency table: pick a claimant (any
team or unit) and the team whose decisions it claims, with illegal rows
flagged in red and ignored rather than blocking OK. Claims round-trip
losslessly through Edit my org, the autosave and JSON import and export,
imported free-text claimants included; older files without claims load
unchanged. - The guide now plans every level at once. "Show the guide" opens a
two-pane tree of the whole hierarchy: every leaf row is badged with its
line's worth in whole-org points (the honest currency: the composing
badges sum to the headline), while a frame's own 0 to 100 climb appears only in the
detail pane with its scale stated plainly, so a section's private "50 →
99" never reads as a promise the whole organisation cannot keep. Leaf
lines act on real teams and compose, so the header states an honest
whole-org before and after from playing every leaf line; an aggregate row
is labelled as the view from that altitude and never counted toward the
headline, because its gains overlap the leaf repairs beneath it. Planning
runs on a worker thread, every step states its before and after score on
the frame's scale and any step previews and plays in place. The
grow toggle prices growth where the edges it relieves are visible: a
whole-organisation growth row planned against the real organisation from
the position after every leaf line, appended as the tree's last
composable row with its badge being growth's worth on top of the other
lines, plus split and add moves inside aggregate frames for the real
teams standing in them (a loose team at the top level), since those
frames are where cross-unit edges are priced; when growth improves no
line anywhere the guide states that plainly and a frame whose own line
growth cannot improve says so in its detail pane, so a dependency-free
section never reads as a dead toggle. The planner also never
names the identical move twice in one line: replaying a partial repair
converges with diminishing gains and read as noise. - Every team now counts in the guide. A team held directly by a unit
whose child units also hold teams used to vanish from the plan entirely:
no aggregate view rolled it up and no leaf line contained it, so its
repairs never reached the headline. Such teams now stand as real nodes in
their unit's view and get their own composable "Teams directly in" row
(the top level gains one for its loose teams), restoring the rule that
every team sits in exactly one leaf row. Their claims travel with them,
so a contested direct team is never offered a delegate that would bypass
the contest. - A leaf line composes only when it pays its way. A line that is this
frame's own best play can still cost the whole organisation once composed
(merging healthy teams raises the weight of every problem elsewhere), so
composition now prices each line against the composed position and leaves
a net-harmful line out of the headline, keeping its row and badge but
flagging it as not composing with its cost stated. The header says
plainly when any line was left out. - Stabilise interfaces is now scoped to its frame. The move carries its
frame's nodes and thins only the edges that frame prices: played inside a
unit it steadies that unit's interfaces; played at the top level it
steadies the boundaries between units, unit-level dependencies included.
Previously it thinned every dependency in the organisation from any scope.
Saved plans replay unchanged (an untargeted move keeps the old meaning). - The move column runs the full height of the board. The available-moves
list now starts at the top of the window, headed by the Play this level
button, so more moves and signals are visible without scrolling; the score
block sits with the map on the left and the keyboard ring follows the new
reading order. Every splitter in the app now draws one standard visible
divider colour with clear space either side and both scrollbar
orientations match it, so no native light strip breaks the theme. - Move history survives closing the app. The autosave now records the
starting organisation and every move beside the current org (older saves
load unchanged), and the next launch rebuilds the session by replaying
them, so Take a move back walks through earlier runs' moves too, all the
way to the original organisation. Every play and take-back saves
immediately, so the record survives however the app ends. The presentation
covers the whole record with earlier runs' moves marked apart from the
current run's by colour (a grey rail against an amber one, with a legend
and counts), it is written straight into the Downloads folder under a
fresh name with no save dialog and creating it is available whenever any
move exists in the record, not just after a move this run. Undoing a
historic move rewrites the record: it stops being an earlier run's move.
Replacing the organisation (new random, wizard, import or an edit) starts
a fresh record for the new structure; an imported plan's moves arrive as
its record. Every move is named at the moment it is played (against the
organisation it acted on, since a later collapse can rename its targets)
and the note under the map now reads "Last move played: ..." with that
name, adding "(in an earlier run)" when the move is restored history, so
it always says exactly what it explains. - The complete picture routes its dependency lines cleanly. An edge
whose straight line would cut through unrelated boxes now leaves its
source's right side, runs down its own clear lane beyond the diagram and
enters its target from the side with the arrow, while an unobstructed
edge keeps its straight line; nothing is ever drawn through a box it has
nothing to do with. Where one line crosses another, the horizontal run
hops the vertical with a small semicircle, the circuit-diagram convention
for wires that do not meet, and a box with several connections fans them
out along its edge (ordered by where each counterpart sits) so parallel
runs never overlap. A hub with more connections than its edge can present
merges them into one counted trunk per direction ("× 10" into the box on
a single shared lane), so neither the box edge nor the lane gutter ever
drowns in lines. - The installer hands the app the foreground again. After launch on
finish, the installer now waits for the app's window to appear and fronts
it before closing itself; previously the window could arrive after the
installer had gone and Windows left it flashing on the taskbar. - **A drill...
Fulcrum v2.0.0
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
"Model my organisation" is redesigned around a two-pane
explorer-style editor and every model becomes reopenable, so the single worst
defect of the old editor (a mistake meant starting again) is gone.
- A two-pane editor. The left pane is the org tree itself: units
(Company, Group, Division, Department, Domain or your own label) nest to any
depth with teams as leaves, each row showing a rolled-up badge such as
"3 teams · 24 people". The dialog opens at nearly the full size of the app
window and can be maximised, so a large organisation gets a workspace that
scales with it; the split between the structure and the dependencies table
is draggable. The right pane is an inspector for the selected item.
The footer carries a live whole-org rollup and OK stays disabled (with the
reason shown) until the model has at least one team. A unit with no teams
beneath it shows a warning badge on its own row; hovering the row explains
it, so the signal sits on the content rather than far away in a footer. - Explorer-style building. The New dropdown (or a right-click on empty
space) starts a top-level item as any type, Company down to a single team;- or the context menu adds items inside any
unit and each item's Type dropdown makes it a Division, Department, a
custom label or a Team, converting it in place with its auto name following
("Team Gamma" becomes "Division Gamma"). Placeholder names run the Greek
alphabet (Team Alpha, Team Beta, on to Omega then Alpha 2) in the editor
and the wizard, rather than bare numbers. Rows drag like folders: onto a unit to
move inside, between rows to reorder, Ctrl held to copy. Illegal drops (a
tier above its parent, anything into a team, an item into its own subtree)
show the forbidden cursor, so the nesting rule teaches itself.
- or the context menu adds items inside any
- Edit my org. A new button and File menu entry reopen the current
organisation in the same editor fully populated, whatever its origin
(wizard, JSON import, random generation or a previous edit). Edit, OK,
rescore. "Model my organisation" still starts fresh and now confirms first
when that would discard user work. - The model survives a restart. The current org autosaves to a per-user
file and is restored on the next launch, so Edit my org works across
sessions. Behind the scenes the editor is a pure function of the same
blueprint shape the JSON import uses, which is what makes the round trip
lossless. - Leads and owners are never blank. A built-in pool of over 200 full
names (gender balanced, culturally varied, UK-weighted) fills every lead
and owner across the editor, the wizard and random generation. Focusing a
name field selects the whole value so a real name overtypes it in one
motion and a dice button rolls a different one. - Terms explain themselves. Incentive skew, ships without asking, the
four watched signals and the workload setting now carry plain-language
tooltips with a concrete example each, rendered from the same source as the
decision glossary. - Dependencies at any level. A dependency can now link any two items:
team to team as before, unit to unit or across levels (a division blocked
on a single platform team). The editor's dropdowns list teams and units by
path; an item can never depend on itself or on its own container or
contents, and an illegal row is flagged in red and ignored rather than
blocking OK. A unit-level dependency counts in the frames where both its
endpoints appear as nodes: it merges into the drilled map's arrows and the
aggregate scores, draws between the unit boxes on the complete picture and
is deliberately not converted into synthetic team queues, so the flat
team-level score stays honest. Rank is not policed: a division waiting on
one team is the bottleneck the score exists to expose. - The top level is playable. A "Play this level" toggle beside the map
caption scores the top level as its own frame: each top-level unit rolls
into one actor, loose teams stand as themselves and dependencies between
root units are priced there, completing the rule that an edge counts
wherever both its endpoints are nodes. The headline score stays the flat
team-level truth; "Score the whole org" switches back. The guide follows
the same frame, so a plan opened at the top level recommends unit-scale
moves. - Plain-English polish. Counts pluralise correctly everywhere including
the exported presentation ("over 1 move", never "1 moves"), signal
readings drop their internal unit names in the chips and in plan
rationales ("Escalations per release: 2", "Rework rate: 30%" and
"falls 7 -> 6" rather than "2.0 count", "30.0 percent" and
"falls 7.0 -> 6.0") and the glossary's move-classification
entry now states the exact point ranges behind great, good, neutral, bad
and blunder, taken from the same thresholds the engine uses, and explains
that deltas are scored within the focused section. When an aggregate scope
offers nothing better than neutral, the moves panel says the value lives
deeper and points at the map (and no longer claims a flat org can drill). - Structure operations. Duplicate, Move up, Move down and Move to sit on
the tree's context menu; removal confirms with what would be lost ("Remove
Division 1 and its 2 teams, 16 people?"); dependencies and their delays are
preserved through every edit, and removing a unit prunes any dependency its
subtree carried. - Fit and finish. The tree's + and minus glyphs are optically centred in
their buttons at every UI scale; the Type dropdown opens cleanly on click
instead of bouncing shut; every button that carries a dropdown menu shows
the same arrow as the spinboxes, so there is one disclosure cue across the
app. - A three-state ring model and a calmer palette. Controls show no ring at
rest, a green ring while hovered or keyboard-focused and enabled ("you can
use this") and a permanent red ring while disabled, across the app, its
dialogs and the installer. Amber is never a ring: it keeps carrying meaning
only (the score, authority encoding on the map, checked states). The map's
teal hover and change rings become a muted green, its keyboard cursor ring
matches and the primary button drops its light blue fill for the standard
dark one.
Existing JSON imports load unchanged and scoring is untouched: the same model
produces the same score as 1.4.3.
Licence
Dual-licensed by component: the model under GPL-3.0 and the user interface under
LGPL-3.0. Both texts ship with the app and are shown under Help.