Skip to content

critpath

A dependency-graph + critical-path tool for a package of markdown artifacts.

When a canonical decision changes (e.g. OPEN PANEL’s pivot from a 501(c)(3) Foundation to a PBC), the change must propagate through a web of docs. critpath models the docs as a slime-mold network — artifacts are nodes, conforms_to/depends_on lineage edges are tubes — and treats a change as a nutrient pulse from the source. It finds the trunk (highest-flux source nodes), the critical path (longest conformance chain), and for any changed term the sweep set plus the starved/stale nodes the pulse hasn’t reached.

Stdlib-only Python (no installs). Annotation standard: see LINEAGE.md.

Terminal window
cd /path/to/package # the artifact root (e.g. the openpanel repo)
# trunk + critical path + untracked/dangling
python3 -m critpath --root . graph
# what must change when the meaning of a term changes
python3 -m critpath --root . sweep Foundation
python3 -m critpath --root . sweep PBC
# which artifacts still lack a lineage block
python3 -m critpath --root . lint

(From inside tools/critpath, point --root at the repo: --root ../...)

VerdictMeaningAction
SOURCEowns the term (defines)change it here first
REVIEWon the path, contains the termconfirm it reads in the new sense
HIDDEN-DEPcontains the term but lineage omits itadd the term to consumes
UNTRACKEDcontains the term, no lineage at alladd a lineage block, then re-sweep
  • The graph is a DAG of derived → source edges; flux(node) = size of its transitive dependent set (downstream blast radius). The trunk is flux-sorted.
  • The critical path is the longest source→leaf chain (cycle-safe DP).
  • Sweeps combine the lineage graph (precise, declared dependencies) with a literal token scan (catches reality the annotations missed) — the gap between them is the actionable finding.
  • Extensible: add fields to the lineage spec and read them in parse.py.