How GoalT works

Most prioritization tools assume a clean hierarchy: a goal breaks into sub-goals, which break into smaller ones. Real work rarely looks like that. A feature can depend on two things at once; a bug fix can matter to three initiatives for three different reasons. A tree can't show that. A graph can, and GoalT is a small engine built around exactly that.

The rules

  • One root goal. Everything traces back to it, and it always holds a value of 1.0.
  • Multiple parents. Any goal can have several children and several parents. It is a directed acyclic graph (DAG), not a tree.
  • Each parent splits exactly 1.0. The weights a parent gives its children add up to 1.0, so a parent passes all of its value down, divided among its children.
  • Value accumulates. A goal with several parents adds up value from each of them, so work that genuinely matters to more things floats to the top.
  • Local recomputation. Adding a goal only recomputes the part of the graph it affects.
  • No cycles.A goal can't end up depending on itself.

A worked example

Root: “Ship v2 of the product”. Under it, “Improve onboarding” and “Improve performance” get 0.5 each. A third goal, “Fix export bug”, is the only child of both. Each parent passes it its whole 0.5, so it ends up at 1.0, as high as the root.

That is intentional. Value is conserved per parent, not across the whole graph, so the numbers are not shares of a fixed budget. A goal's value is its pull-weight: how much is riding on it. The export bug is load-bearing for both sub-goals, and a 1.0 says exactly that.

Deterministic by default, LLM optional

By default a parent splits its value equally among its children. That rule is deterministic, needs no API key and always converges.

You can plug in a language model to decide the weights from context instead, for example “speed matters more than polish this sprint”. GoalT never trusts the model's numbers directly: whatever comes back is validated and re-normalized, so the graph stays consistent even if the model returns something odd.

How it differs from a task list or a strict hierarchy

  • A task list or issue tracker records what to do. GoalT records why each piece exists and what depends on it, and computes priority from that structure.
  • A strict hierarchy(a classic work breakdown, or OKRs cascading one level at a time) gives every item one parent. GoalT allows several, so shared work isn't hidden under a single branch.
  • A scoring sheetasks people to assign weights by hand. In GoalT, a goal's weight comes from how real dependencies connect to it.

GoalT has not yet been benchmarked against established methods such as AHP or weighted scoring on a real backlog. That comparison is an open question, not a claim.

Open questions

  • Whether repeated LLM-driven re-weighting stays stable on a large, frequently edited graph has only been observed on small examples, not proven.
  • With an LLM plugged in, each add_goalcan trigger one call per affected parent. Caching and batching aren't implemented yet.
  • Value propagation is closely related to PageRank-style algorithms on DAGs. Pointers to prior art that does this better are welcome on GitHub.

Next: install and use GoalT, or read why a project needs a purpose tree.