A working prototype of an idea · scroll to try it

ACEthe atomic constraint engine

An idea I want to prove. Planning, scheduling, forecasting, constraints, geometry — construction runs them as five separate systems. I think they are one thing wearing five costumes. This page is my attempt to demonstrate that with a working prototype: one primitive, two link types, one derive step. Every atom is a constraint. Every constraint is an atom. Read the theory, then try the engine — everything below is live and runs on the same fifty lines of math.

Primitive
Atom · id + name + kind + links
Link · vertical
Contains · parent → child
Link · horizontal
Requires · depends on
Engine
Derive · state from the graph
Systems replaced
5 → 1
schedule · work-breakdown · materials · RFI log · risk register
Engine size
~50
lines of core math. The rest is a UI on top.
Dependencies
0
no server, no build, no vendor lock
Built by
one
person, in spare hours, to test the idea
read ↓
§ 1 · Theory · The bet

One thing, not a zoo.

Every project-controls stack today runs on five separate systems: a scheduling tool (usually Primavera P6 or Microsoft Project), a work-package tool, a materials system, an RFI log (request for information — questions to the design team that block work until answered), and a risk register — each with its own database, its own vendor, its own integration bill, and its own version of the truth. Reconciliation is a full-time job, and the reconciliation is usually wrong.

ACE keeps one table. Every row is an atom. Every relationship is one of two links. Every question you can ask about a project — is it ready? what's on the critical path? what will it cost? what happens if we slip? — is a walk on that graph. The engine is fifty lines. The rest is discipline: refusing to add a second primitive when someone waves a whiteboard at you.

Lineage Theory of Constraints, taken off the trailer wall and made the data instead of a poster.
Feature
Primavera P6
MS Project
ACE
Data model
activity table + relationship table + resource table + calendar table + code table + …
task tree + resource pool + calendar
one atom, two links
Constraints
7 relationship types + 5 constraint types
4 dependency types + deadlines
a requires edge, that's it
Monte Carlo
Primavera Risk Analysis · extra module
third-party add-on
native · deterministic seed
Runs in
Windows client · Oracle DB
Windows desktop
a browser tab, offline
Learning curve
2–4 week vendor course
a few afternoons
7 fields, 3 rules
Cost
$2,400/seat/year floor
$300–1,700/user
free · this page is the whole product
§ 2 · Theory · The primitive

The atom.

Every atom is a constraint. Every constraint is an atom. That is the point. A task is a constraint on the schedule. An RFI is a constraint on a work package. A material delivery is a constraint on install. A regulatory hold is a constraint on start. There is no separate constraint table — the primitive is one thing. The type tag tells you which face of that thing you're looking at. Same seven fields for all of them.

Exhibit A · one atomlive
The shape. Every row in every view derives from this. Change the type field and the schema doesn't change — only what the type means to a reader.
§ 3 · Theory · Five kinds

Five ways a thing finishes.

The kind field on an atom answers one question: who declares it done? There are five. Not four. Not seven. Anything you want a "task" or a "constraint" to be is one of these five, wearing a different type tag.

01
Leaf
Somebody flips it.
The atom of manual work. A person clears it — with evidence if the tag says narrative-required.
e.g. · MAT-RBR-014 — rebar delivered to site
02
Gate
Clears when its waits clear.
A pure derived atom. No inherent work. Waits on something else, and flips the moment that thing lands. RFIs and constraints live here.
e.g. · CON-0001 — waiting on Rebar design signoff
03
Rollup
Done when kids are done.
The tree walk. Areas, construction work packages (CWPs), installation work packages (IWPs). If every atom it contains is done, it's done. No separate progress field.
e.g. · CWP-0110 — Civil area 4 complete
04
Verified
Done when proven.
Regulatory or QA atoms. Clearing requires a witness signature and the underlying work. Two locks.
e.g. · REQ-N287 — N286 rebar cage witness inspection
05
Trivial
Born done.
Documentation atoms, historical facts, closed lessons. They exist in the graph so other atoms can reference them, but they need no work.
e.g. · LES-0007 — 2021 stripping lesson learned
Same shape Kind is one field. Every kind uses the same seven-field record. The difference is only who is allowed to flip it and what triggers.
§ 4 · Topology · Vertical

Contains. Parent → children.

The first link is a tree — a work-breakdown structure (WBS). A project contains areas. Areas contain work packages. Work packages contain tasks. Every atom has exactly one parent. Rollups climb the tree from leaves to root. No many-to-many. No secondary breakdown. If you want a matrix view, that's a tag, not a link.

Exhibit B · the WBSlive
Unit-4 refurb. 1 project · 3 areas · 10 work packages. Every leaf inherits its parent's context. Rollup math walks bottom-up.
§ 5 · Topology · Horizontal

Requires. The depends-on chain.

The second link goes sideways. Formwork requires rebar. Pour requires formwork. Cure requires pour. This is where "ready" lives. An atom is workable when everything it requires is done — no separate constraint system, no "5 categories of readiness". Just walks the graph.

No cycles allowed. Ever. The engine refuses to save a graph that would deadlock.

Exhibit C · the DAGlive
Cross-area edges are fine. Pipe install requires the cure to finish first. Same graph. Same math.
§ 6 · Engine · Fixed point

Derive. Completion is computed, never stored.

Mark a leaf done and watch the graph. Its parent's done state is never written anywhere. It's a function: done when everything I contain is done, and everything I require is done. Walk the graph, resolve each atom, loop until nothing changes. Because the graph is acyclic — a DAG (directed acyclic graph, no loops allowed) — one pass suffices.

Some atoms are tagged narrative-required (marked with a ): a regulator or a QA signature demands a written record of how it went. Click one of those below and a canned-response modal opens — pick a match or type your own. Without a narrative entry, the graph won't close that atom. This is where the model refuses to lie for you.

Exhibit D · watch the cascadelive
0 / 14 resolved0%
Narrative journal · 0 entries
Complete a witness-required atom (marked ★) to record a narrative. Click one below.
Try it. Click a leaf tagged with ★ (marked as narrative-required) and a canned-response modal opens. Pick a match or type your own. The journal below fills in as the audit trail — you cannot close a required atom without one.
§ 7 · Schedule · Longest chain

Critical path. Slip one, slip everything.

The critical path method (CPM) is standard planning math: the longest chain of dependent work from start to end. Every task on that chain has zero float — slip any one of them by a day, the whole project slips by a day.

Here's the interesting part: the links that answer "is this work ready?" already answer "what has to come first?" Put a duration on each atom, walk the requires graph, and the dates and the longest chain fall right out. Same graph. No separate P6 file, no reconciliation, no midnight import-error emails.

Exhibit E · the chainlive
Total path
— d
On-path atoms
Zero float
Red pulses. Every atom on the longest chain has zero float. Protect these first.
§ 8 · Schedule · Uncertainty

Forecast. Bet on the numbers.

Every work atom has three durations: [min, likely, max]. Sample a triangular distribution, walk the graph, record a finish date. One thousand runs. Read the histogram — P50, P80, P90 (the 50th, 80th, and 90th percentiles: half your simulated runs finish by P50, 80% by P80, 90% by P90). The plan isn't a date; it's a distribution.

Exhibit F · 1000 runslive
0 runs
Seeded, deterministic. Same seed → same distribution. Change durations and re-run to see the impact.
§ 9 · Views · Morning stand-up

Triage. Six a.m., what matters.

Triage is a query, not a table. It walks the graph every morning and answers four questions in order:

Red — atoms on the critical path that aren't ready. Amber — atoms one hop off the critical path with a floating constraint. Blue — new atoms with no parent yet (the whiteboard's contribution to the graph). Green — quietly workable, no attention needed.

Nothing gets its color stored anywhere. Colors are derived.

Exhibit I · triage boardlive
Try it. Complete atoms in Exhibit D above and the triage column counts here re-derive on your next scroll. Same graph, different view.
§ 10 · Practice · Absorbing variance

Flex. Same primitive, different constraints.

Earlier I wrote that flex atoms have no requires. That was wrong. Every atom is a constraint. Flex is no exception. A flex package still needs a crew with the right competency (requires: a rotating "any-idle-crew" atom). It still needs the physical zone unlocked (requires: zone access). It still needs materials on hand (requires: on-shelf inventory). What makes flex flex isn't the absence of constraints. It's the shape of the constraints: they're capacity constraints, not sequence constraints.

The distinction is real and mathematical. A sequence constraint (requires: REBAR) points at a specific atom by id. A capacity constraint (requires: any(crew where competency=civil, status=idle)) points at a predicate — a set. Same requires link; the target is a query instead of a name.

That's why flex packages absorb schedule variance: their gates fire on availability, not on completion. The engine treats them identically to every other atom during derive.

Exhibit J · flex poollive
Assign then complete. Assigning writes a narrative entry against the atom. Completing rolls into earned value.
§ 11 · Practice · Executable prose

Literate procedures. The document is the graph.

Construction runs on procedures — Word documents, PDFs, laminated cards taped to walls. They read as prose. They never talk to the schedule, the RFI list, or the material log. When something is late, nobody reads the procedure. When the procedure is wrong, nobody updates the atoms.

ACE fixes this by making the procedure be the atom graph. Every noun in the prose — every step, every tool, every material, every check, every witness — is a live atom pill. Hover it and the right rail shows its state. Click and it opens in the workbench. When a material atom flips to done, the pill in the procedure turns green. When an RFI comes back and clears a gate, the pill turns blue. The procedure reads exactly the same. But now it runs.

Exhibit L · rebar pour procedurelive
Prose = graph. No dual maintenance. The document you write for the crew is the same one the engine schedules. Change a step, it's a graph mutation. Complete an atom, the prose lights up.
§ 12 · Space · Constraints as geometry

Parametric. Positions solve themselves.

The same primitive that carries schedule and rollup carries space. Every building on a site is an atom. Its position isn't a stored coordinate — it's an expression, evaluated from a handful of dimensions. The reactor building has a diameter. The turbine building sits 15 m east of the reactor edge. The cooling towers sit 20 m south of the turbine, spaced by ct-sp.

Drag the sliders. Every atom's coordinates re-solve. The 3D view is generated the same way — same expressions, isometric projection.

Exhibit K · parametric sitelive
Zero raw coordinates. Every position is an expression, not a number. Change one dimension, watch six atoms move. The same primitive that carries schedule carries space.
§ 13 · Theory · The taxonomy

Everything is an atom. Here is what "everything" means.

The whitepaper claims one primitive. That's a strong claim. The obvious pushback is: surely some things aren't atoms. I built this taxonomy by asking, for every noun a construction organization uses, "would treating it as an atom break anything?" The answer, so far, is no.

Nine families. Seventy-two atom types. Each one gets seven fields, two link types, one derive. The engine doesn't know the difference between them.

1 / 9 Work & structure

project
Project
contains: areas · requires: authorization
area
Construction work area (CWA)
contains: CWPs · requires: site turnover
cwp
Construction work package
contains: IWPs · requires: design release
iwp
Installation work package
contains: tasks · requires: five gates cleared
task
Task
leaf · requires: predecessors done
step
Procedure step
leaf inside a procedure · sequenced
milestone
Milestone
zero-duration verified · requires: rollup
flex
Flex package
requires: capacity match, not sequence

2 / 9 Gates & controls

constraint
Constraint
gate · one atom's readiness in wait
rfi
Request for information
gate · waits on design answer
risk
Risk
probability × impact · fires in MC
hazard
Hazard
safety atom · requires: mitigations
control
Control
mitigates hazards · verified
permit
Permit
gate · waits on authority sign-off
exception
Approved deviation
override · time-boxed
ncr
Non-conformance
gate · requires: corrective action
stop-work
Stop-work order
blocks by tag · authority-issued

3 / 9 Verify & audit

verify
Witness inspection
verified kind · requires signature
test
Test
requires: procedure + witness
audit
Audit
contains: findings
finding
Audit finding
requires: corrective action
corrective
Corrective action
closes findings by id
narrative
Narrative
forces human input on close

4 / 9 Resources

material
Material
requires: PO delivered · consumable
consumable
Consumable
material with depletion tracking
tool
Tool
shared asset · requires: calibration
equipment
Heavy equipment
requires: operator + PM cycle
vehicle
Vehicle
equipment with license atom
ppe
Personal protective equipment
requires: valid inspection
inventory
Inventory line
on-hand quantity of a material
lift-plan
Rigging / lift plan
verified · requires: engineer review

5 / 9 Humans

person
Individual
contains: certifications · role atoms
crew
Crew
contains: persons · has competency tag
role
Role / function
what a person does on a given atom
shift
Shift
calendar window · assigns crew
competency
Competency
tag with expiry · gates work
certification
Certification
verified · has expiry atom
stakeholder
Stakeholder
relationship + interest weight
commitment
Verbal commitment
promise made in the hallway · trackable

6 / 9 Space & time

site
Site
root physical container
zone
Zone
bounded region · has access atoms
footprint
Footprint
parametric geometry expression
clearance
Clearance envelope
geometric constraint
clash
Interference
negative geometry · two atoms can't share
window
Time window
interval · gates work by calendar
deadline
Deadline
verified atom with target date
holiday
Blackout day
excludes shifts by date
weather
Weather window
external state · gates outdoor work

7 / 9 Money & agreements

budget
Budget line
contains: estimates · has variance
estimate
Estimate
bottom-up cost expression
purchase-order
Purchase order
requires: vendor + budget line
invoice
Invoice
gate · requires: PO + delivery
payment
Payment
verified · closes invoice
change-order
Change order
modifies contract + budget atoms
contract
Contract
contains: clauses · requires: signatures
clause
Clause
obligation atom · references binding law
claim
Claim
contested change · requires: evidence chain

8 / 9 Documents & decisions

design
Design drawing
contains: revisions · requires: stamp
spec
Specification
rule-set atom · generates constraints
procedure
Procedure (SOP)
literate · contains: steps
runbook
Runbook
procedure for incident response
report
Report
snapshot atom · derived at time-t
decision
Decision
closes an open-question atom
action-item
Action item
leaf · owner + due
meeting
Meeting
contains: decisions + action items
lesson
Lesson learned
trivial kind · referenced by others
assumption
Assumption
belief atom · can be invalidated
hypothesis
Hypothesis
tested by an experiment atom

9 / 9 Meta

tag
Tag
free label · no math
view
Saved query
a view is itself an atom
template
Template
produces family of atoms on instantiation
ruleset
Rule-set / policy
generates constraint atoms
event
Transition
an atom's state change is itself an atom
override
Override
time-boxed suspension of a constraint
alias
Alias
two atoms refer to the same real thing
Novel links, novel primitives? No. Every one of these atoms uses the same seven fields, same contains and requires. The variation is in what the fields mean. A weather atom's duration is a forecast window. A hazard atom's duration is exposure time. A commitment atom's duration is time-to-fulfillment. The engine doesn't care.
§ 14 · Theory · Limits

What can't be an atom?

The taxonomy above is 72 types. Every one fits. That should make anyone suspicious — the model is too accommodating. So let me try to break it. Pick the hardest cases. Prove there's a thing that can't be an atom. Then read the disproof. Then pick a harder case.

I stopped at round eight. I don't think there's a round nine, but I'd love to be wrong.

Round 1
Claim: Relationships aren't atoms.
Disproof. A relationship is already an atom — the two link types (contains, requires) are relationships and they're first-class in the schema. If you want a labeled relationship ("blocks", "duplicates", "co-signed-by"), give it its own atom type, put the two endpoints in its requires list, and now the relationship carries its own state, its own narrative, its own audit trail. Every relationship is an atom looking sideways.
so try harder
Round 2
Claim: A number isn't an atom.
Disproof. A raw number isn't. A measurement is: it has a source, a time, a unit, an instrument, a tolerance. Those are all fields. The number is a leaf inside a measurement atom. Same for a cost figure (bound to a budget line), a duration (bound to a work atom), a coordinate (bound to a footprint expression). Loose numbers are homeless. Bind them to context and they become atoms.
still too easy
Round 3
Claim: A moment in time isn't an atom.
Disproof. A moment is a zero-duration verified atom — it's a milestone. A moment with a name is a milestone with a name. A moment nobody noticed passing is still an atom, just one with an empty narrative. The claim conflates "a moment" with "the number denoting the moment". The number is a field. The moment is the atom.
try something soft
Round 4
Claim: Trust between two people isn't an atom.
Disproof. It is a relationship atom, and a fragile one. Its kind is manual and its tags include narrative-required. It gets updated when the two people work together on other atoms — you write about the work, and the trust atom's narrative accrues history. Its "duration" is the time to rebuild after a breach. Its "requires" is a series of small commitments kept. This is why work relationships are engineerable.
go abstract
Round 5
Claim: An assumption isn't an atom because it isn't real.
Disproof. An assumption is an atom of kind: manual and type: assumption. It has a manualDone: true until someone challenges it — at which point it flips to manualDone: false and every atom that requires it becomes not-ready. Assumptions are real: they are load-bearing in the graph. The whole schedule is built on them. The engine's job is to know which ones are being trusted and by what.
try the void
Round 6
Claim: The absence of something isn't an atom.
Disproof. Two ways to model absence. First: a missing atom in a required list — the schedule tells you exactly what's absent by what fails to derive. Second: a first-class void atom explicitly noting a decision not to do something (a de-scoped work package, a rejected change order). Both are atoms. What isn't in the graph is still describable by the graph — the shape of the hole is data.
try the engine itself
Round 7
Claim: The ACE engine itself can't be an atom.
Disproof. The engine is a ruleset atom in the meta-graph. Its derive function is a procedure atom. Its contains field points at the type registry, its requires field points at the axioms it depends on ("no cycles", "finite atoms", "acyclic requires"). The settings that configure ACE are atoms. The schema is an atom. The engine describes itself in its own language. That's how you know the language is complete.
the last one
Round 8
Claim: "Not an atom" isn't an atom.
Disproof. The category "not-an-atom" is a view — a saved query with the predicate false. Every view is an atom. So the concept of a thing that isn't an atom is itself an atom pointing at an empty set. The claim eats itself.
fixed point reached
The recursion terminates. Every candidate for "not an atom" turns out to be an atom describing an atom-shaped thing. This is not a coincidence — it's what it means for a modeling primitive to be complete. The graph is closed under its own description. That's the property that lets one engine run the whole show.
§ 15 · Engine · Try it

The workbench. Same engine. Real commands.

The demos above and the workbench below share the same ACE instance in memory. Every command you type here is the actual application programming interface (API). Every mutation re-derives the graph.

Exhibit G · terminallive
ace · shell
Type help for the full command list, or click a chip.
§ 16 · Presentation · The reel

The whole thing, rendered.

Same math. Same atoms. Same derive. A two-and-a-half minute rendered composition where every frame is pure(frame) → pixels. Watch it below, or scrub through the scenes with the transport.

Exhibit H · ACE-Xlive
0:00 / 2:30
Deterministic. Seed 42, triangular distribution, same histogram every time. That's the guarantee.
The close

Same graph. All the way through.

You read the theory. You watched the graph resolve itself. You ran a thousand Monte Carlo scenarios. You dragged the parametric sliders. You clicked through the literate procedure. You typed real commands into a real shell. Every one of those interactions was the same seven-field record and the same fifty-line derive step. That is the entire pitch.

What this delivers

  • Plan, forecast, and constraints in one graph
  • Monte Carlo with a seed and a reproducible histogram
  • Parametric site geometry from the same primitive
  • Literate procedures — the SOP is the graph
  • A working REPL (read-eval-print loop) over the actual API

What you avoid

  • Reconciling five systems that see different truth
  • Per-seat licensing that scales with the org chart
  • Multi-week vendor onboarding for every new PM
  • An Oracle DBA in the loop for a project schedule
  • Anything that isn't in this HTML file

Prove it right now

Reference · grammar

The API, in one page.

Everything the engine exposes. Everything you can put in your project file. Copy-paste from here.

The atom

id · string, unique
name · human-readable
type · string, free
kind · manual | derived
tags · string[]
requires · id[]
contains · id[]

Optional

duration · [min, ml, max] days
cost · number (dollars)
evidence · any (proof)
narrative · string

API

add(spec) · create atom
link(a, rel, b) · contains|requires
derive() · fixed-point resolve
cpm(end) · critical path
mc(end, N, seed) · forecast
query(pred) · filter

Five kinds

leaf · manual, person flips
gate · pure derived, waits
rollup · done when kids done
verified · manual + proof
trivial · born done

Link types

contains · vertical, tree
requires · horizontal, DAG
tag · free label, no math

Common types

project · root
area · CWA
iwp · work package
constraint · gate atom
flex · variance absorber
rfi · question atom
risk · MC-triggered
milestone · zero-duration

Triage colors

red · critical path + blocked
amber · off-path + blocked
blue · ready · workable now
green · resolved · done

Also derived

float · end - late-start
ready · all requires done
earned · ∑ complete × value
Rule If you find yourself wanting a third link type, you're building a new tag. If you find yourself wanting a second store, you're duplicating a view.