Open tooling, agent-run engineering, and the products built on both.

The standard as a state machine: making PMBOK assessable

  • #project-management
  • #pmbok
  • #mechanical-enforcement
  • #state-machine
  • #assessment
  • #driftless

A body of knowledge usually arrives as a document. Someone buys the guide, a consultant maps it onto the organisation, and the mapping lives in a spreadsheet that is wrong within a quarter. The processes are real; the representation is inert. Nothing in a PDF can tell you which of those processes a project is actually running today.

driftless models them as data instead. The PMBOK predictive process set — 49 processes across five process groups and ten knowledge areas — is a versioned in-code catalog, and each project’s position on each process is computed, never stored. What comes out is a completeness figure a machine derived from the project’s own records, rather than a number a consultant negotiated.

The catalog is code, not prose

Each process is a frozen record: an id (its clause number), a name, exactly one (group, area) cell, and its inputs, tools and techniques, and outputs. The ITTOs are named by reference — inputs and outputs point into an artifact-kind catalog, tools and techniques into a technique catalog. Property tests pin that referential integrity, so a process cannot name an artifact kind or a technique the rest of the system does not otherwise understand.

That is the cheapest tier of quality control. Not a linter that catches a bad reference after the fact, but a structure in which writing one fails the build. The catalog does no I/O and reads no clock, so a query over it answers identically run to run.

State is computed, so there is nothing to type

A project’s state on a process is one of five values: not started, in progress, produced, signed off, or waived. There is deliberately no process-instance table. Nobody sets a process to “in progress”. The state is derived on every read from two sources — which artifacts actually exist in the store, and the sign-off ledger:

  • Waived, when the latest sign-off tailors the process out.
  • Signed off, when the latest sign-off accepts or resolves it.
  • Otherwise judged on outputs: produced when every required tracked output exists, in progress when some but not all do (or when an optional output has appeared), not started when none do.

An optional output is evidence of activity but never enough to reach produced. And tailoring a process out is a ledger entry rather than a deletion — the standard still lists it; the project simply recorded a decision against it.

This is the same move the service makes with percent complete, and the same one this journal keeps arguing for a layer down: behavioural rules are suggestions, structure is a constraint. Find the field where someone can type a comfortable answer, and delete the field.

The honest part is what gets excluded

Completeness is the share of processes that reached produced or signed off. The interesting design is not the numerator — it is the two things that leave the denominator, because both are refusals to guess.

A waived process drops out. Tailoring is legitimate. A small project that skips formal procurement planning should not be marked down for a decision it made deliberately.

A process the store cannot observe drops out too. One predicate asks whether any required output of a process is a kind the store actually tracks. If none are, the process is not assessable and never enters a completeness figure at all, because counting it either way would be a guess. Optional outputs deliberately do not confer assessability: a process whose only tracked output is optional could never honestly reach produced, so admitting it to the denominator would manufacture a permanent, meaningless deficit.

Both exclusions live in one function that every consumer calls — the per-project figure, the per-area share, and the roll-up pooled across every project in the business. They cannot drift apart from one another, because there is only one of them.

A sign-off cannot bury a regression

Alongside the process view runs a second engine that grades knowledge areas and raises findings. Integration is not a separate signal there; it is the worst of the other nine, so a red anywhere surfaces at the top rather than averaging away.

Findings can be suppressed by signing off on them, and this is where most systems quietly lose their honesty — a sign-off is normally permanent, so the first acceptable moment silences a finding forever. Here suppression is conditional: a signed-off finding stays hidden only while its live score is no worse than the score recorded at sign-off. Let the underlying signal degrade past that threshold and the finding returns on its own, with no watchdog job and nobody remembering to re-review it. A sign-off carrying no recorded score suppresses nothing at all, so the number always has to be captured in order to be waived.

Same input, same bytes

Every function in both engines takes an explicit as-of date and reads no wall clock. Rankings break ties on a stable id. Sign-offs are filtered by the date they were recorded against, so a decision made this week cannot rewrite what last month’s page said.

The property that falls out is that any view regenerates byte-identically from the same store and the same date. That makes generated documents disposable — they were never the artifact, the store is — and it turns a disagreement between two numbers into a bug with a short list of causes, instead of a reconciliation meeting.

What travels

There is no repository to link here, and there will not be one. That is not a launch being held back: the assessment engine is wired directly into this product’s data models — the evaluators read its baselines, its milestones, its ledger — so extracting it would hand you the shape and none of the substance. driftless stays private.

The pattern is portable regardless, and it is three decisions:

  • Put the standard in the type system. A catalog of frozen records whose cross-references are checked beats a document whose mapping is maintained by hand.
  • Compute the state instead of storing it. A status that can be typed will eventually be typed optimistically, and usually in the week it matters most. Derive it from artifacts that either exist or do not.
  • Make the exclusions explicit and conservative. Refuse to score what you cannot observe, and say so in the output. A completeness figure that quietly counts unobservable work as done is worse than no figure at all.

None of that requires this product, or even this standard. It requires a catalog, a ledger, and the willingness to delete every field that invites a comfortable answer.

Configuration details reflect a production environment at time of writing. Implementation specifics vary based on tooling versions, platform updates, and organizational requirements. Validate approaches against current documentation before deployment.

← Back to Journal