Productizer is an open-source Claude Code plugin that makes the agreement the artifact. It runs locally in your own repo — no account, no server, no telemetry, free — and keeps one living spec per product at .claude/productizer/spec.md: EARS requirements with permanent ids that are never reused and never renumbered, a constitution of P-numbered principles above them, superseded text retained verbatim, and a classification of every new intent against the whole spec — extend, refine, duplicate or contradict. A contradiction halts the work pending a human ruling recorded as a D id. Around that sit nine linear stages, declared checks in a committed checks.yaml where a check that exits clean having examined less than it declared is “hollow” and blocks, human gates on deploy and publish as PreToolUse hooks, and a generated read-only dashboard where views are output only.
Gas City is a serious, well-engineered stack, and this page is an honest architecture-level comparison rather than a hit piece. It is really three products, two of them open source and genuinely so. Beads (github.com/gastownhall/beads, MIT, 26,704 stars, 1,802 forks, created 12 October 2025, 10,731 commits) is authored by Steve Yegge — verified rather than inferred: steveyegge/beads redirects to gastownhall/beads, and he has 4,795 commits to the next contributor’s 772. It is a Dolt-backed — version-controlled SQL — issue tracker, knowledge graph and agent-state store: one very wide issues table of roughly 60 columns plus a dependencies edge table, synced between machines over Dolt remotes. Gas City (github.com/gastownhall/gascity, MIT, 1,196 stars, created 22 February 2026, about 1.64 million lines of Go) has different authors — Julian Knutsen and Chris Sells — and merely depends on Beads. It is an orchestration SDK that starts coding-agent CLIs, typically tmux new-session -d ... "claude --print <prompt>", and reconciles them against declarative TOML in two nested loops: a 10-second supervisor tick and a 30-second controller tick. Work routing is one primitive — stamp gc.routed_to=<agent> on a bead and agents poll for it. Beads Team Server and Gasworks are withheld as design-partner or coming-soon, and it is only fair to add that there is no licence-key or entitlement check in either repository: this is genuine MIT, not crippled open core, and multi-machine team sync is not withheld either, because Dolt push and pull are inherently open.
The fair framing, stated once and held to for the rest of the page: they orchestrate many agents and remember what happened; Productizer decides what should be true before the work and stops when a change contradicts it. Those are different layers, and on distribution, cross-session memory, multi-agent coordination, output contracts and a lifecycle that actually fires, Gas City leads outright — those rows are marked in its favour below rather than buried.
Read the table as two answers to two different questions. Gas City answers how do many agents get work done, in parallel, without losing what they learned — and answers it with real machinery: content-addressed ids so parallel branches never collide, leases and heartbeats so a dead agent’s claim can be reclaimed, merge slots that serialise conflict-prone work, and a SessionStart hook that restores context so an agent resumes instead of reconstructing. Productizer answers what are we agreed this product does, and what happens when a new request contradicts it. Neither mechanism substitutes for the other, and the honest reading of the two repositories is that Gas City has built far more of its answer than Productizer has of its.
| Productizer | Gas City & Beads | |
|---|---|---|
| Primary artifact | A declared living spec — one per product, at .claude/productizer/spec.md | A Dolt-backed work graph — one wide issues table of ~60 columns plus a dependencies edge table — and a TOML-declared fleet of agent processes |
| One living document of agreed behaviour | ✓ EARS requirements, permanent ids, never reused, never renumbered | ✗ The primitives exist — 13 issue types including TypeDecision and TypeGate, 20 dependency types including supersedes and duplicates — but there is no single document of agreed behaviour |
| New intent classified against every prior agreement | ✓ Extend / refine / duplicate / contradict, against the whole spec | ✗ No standing artifact to classify a new intent against |
| Contradiction handling | ✓ Halts pending a human ruling, recorded as a D id | ✗ bd rules audit detects contradictions between rule files by keyword overlap plus a 12-entry hardcoded antonym list, and reports without blocking — no non-zero exit. Nothing in either repository halts on a semantic contradiction |
| Principles layer above requirements | ✓ A constitution of P-numbered principles above the requirements | ✗ |
| Supersession preserves the original text | ✓ A superseded requirement keeps its original sentence verbatim; violating that is an ERROR | bd supersede keeps the original text — but the compaction their own help labels “# Agent-driven workflow (recommended)”, bd admin compact --apply, blanks fields and overwrites the description with an LLM summary with no snapshot; their agent-facing doc says “original content is discarded” |
| Cross-session memory | ✗ None at all — nothing restores an agent’s context between sessions | ✓✓ Ships. A SessionStart hook plus one reload command restores context, so agents resume instead of reconstructing |
| Coding agents supported | ✗ Claude Code only | ✓✓ Hook installers for 14 agent tools — Claude, Gemini, Codex, Cursor, Copilot, Aider, Windsurf and more. Fair caveat: only four get automatic context injection; the rest are static instruction files |
| Multi-agent coordination | ✗ Nothing of the kind; a single agent in a single repo | ✓✓ Solved plumbing — content-addressed ids (sha256 hashed, base36 encoded) so parallel branches never collide, leases and heartbeats so a dead agent’s claim is reclaimable, merge slots for serialising conflict-prone work |
| Starts and supervises agent processes | ✗ Productizer does not run agents; it governs the one you are already in | ✓✓ An orchestration SDK: tmux new-session -d ... "claude --print <prompt>", reconciled against declarative TOML in a 10s supervisor tick and a 30s controller tick |
| Work routing between agents | ✗ | ✓ One primitive — stamp gc.routed_to=<agent> on a bead, and agents poll for it |
| Machine-readable output contract | ✗ Not something Productizer ships | ✓✓ 127 result.schema.json files, one per command, embedded and enforced by a meta-test that fails on any schema lacking a top-level success discriminator — with every exemption named in source |
| Does the project’s own lifecycle actually run? | ✗ The lifecycle has never run end to end through CI — the CI exists and has never fired | ✓✓ Theirs fires |
| Lifecycle stages | ✓ Nine linear stages | ✗ Not a lifecycle model — a reconciliation loop over a work graph |
| Declared checks with a hollow-check rule | ✓ A committed checks.yaml; a check that exits clean having examined less than it declared is hollow and blocks | ✗ Nothing of this kind was found in what was read of the two repositories |
| Human gate before the change lands | ✓ PreToolUse hooks on deploy and publish | A TypeGate issue type exists as a primitive; what it enforces beyond marking an item was not established from the repositories |
| Views are output, never an input | ✓ A generated read-only dashboard; views never feed back into the files | ✓ The same rule, reached independently — their docs state that .beads/issues.jsonl “is an export … not the canonical cross-machine sync channel” |
| What you install and what it needs | A Claude Code plugin. Files in your repo — no daemon, no database, no account | Beads requires Dolt 2.1.0 or newer and flock, and carries 66 migrations, several of them documented workarounds for upstream Dolt defects |
| Account / server / telemetry | ✓ None — local only, no account, no server, no telemetry | Local tools syncing over Dolt remotes; two further products, Beads Team Server and Gasworks, are withheld as design-partner or coming-soon |
| Licence | ✓ Open source — github.com/gitayg/productizer, free, no tier to buy | ✓ MIT on both repositories, and genuinely so — no licence-key or entitlement check in either, and team sync is not withheld because Dolt push and pull are inherently open |
| Distribution and scale | One person’s free open-source project | ✓✓ Beads: 26,704 stars, 1,802 forks, 10,731 commits since October 2025. Gas City: 1,196 stars, about 1.64M lines of Go |
| Accuracy evaluation | Measured, on a small corpus we wrote ourselves: end-to-end 16/16 recall and 0.94 precision on 26 cases, against 13/16 for the same model with no plugin. The symbolic cross-check alone scores 0.70 on our first 21 cases and 0.12 on the harder 26 | ✗ Neither repository contains any accuracy evaluation |
| Performance benchmarks | ✗ None published | A BENCHMARKS.md that reports -benchtime=1x -count=1 — n=1, one iteration — to one decimal place, with no variance |
| Author and provenance | One person, working in the open | ✓ Beads by Steve Yegge — 4,795 commits to the next contributor’s 772, and steveyegge/beads redirects to gastownhall/beads. Gas City by Julian Knutsen and Chris Sells, depending on Beads |
Distribution first, because it is the least arguable. Beads has 26,704 stars, 1,802 forks and 10,731 commits in the time since October 2025, and it installs hooks for 14 agent tools — Claude, Gemini, Codex, Cursor, Copilot, Aider, Windsurf and more — against Productizer’s one. The fair caveat, which they would probably state themselves, is that only four of those fourteen get automatic context injection; the rest are static instruction files. It is still fourteen to one.
Cross-session memory ships, and Productizer has none at all. This is Gas City’s clearest win over Productizer and there is no softening it. A SessionStart hook plus one reload command restores an agent’s context, so it resumes rather than reconstructing what it already knew. Productizer’s answer to “what did we agree” is a file the agent re-reads; its answer to “what was I doing an hour ago” is nothing.
Multi-agent coordination is solved plumbing there, and absent here. Ids are content-addressed — hashed with sha256, encoded base36 — so two agents on parallel branches cannot collide on an identifier. Claims are held under leases with heartbeats, so a dead agent’s work becomes reclaimable rather than stuck. Merge slots serialise the work that would otherwise conflict. Productizer has none of this because it never contemplated a second agent.
Their output contract is stronger than Productizer’s, and their lifecycle actually fires. There are 127 result.schema.json files, one per command, embedded in the binary and enforced by a meta-test that fails on any schema lacking a top-level success discriminator — with every exemption named in source rather than silently tolerated. That is a discipline Productizer talks about and does not yet have. And on the plainest measure of all: their CI runs; Productizer’s exists and has never run end to end.
Nothing in either Gas City repository halts on a semantic contradiction. The nearest thing is bd rules audit, which detects contradictions between rule files by keyword overlap plus a 12-entry hardcoded antonym list, and reports without blocking — there is no non-zero exit. Productizer classifies every intent against the whole spec and stops, pending a human ruling that is itself recorded as a D id. That is the single mechanical difference the rest of this page hangs on.
They have no spec, and the interesting part is that the primitives are already there. Beads carries 13 issue types including TypeDecision and TypeGate, and 20 dependency types including supersedes and duplicates. Everything needed to express “this decision replaced that one” exists in the schema. What does not exist is one living document of agreed behaviour that a new intent is classified against — a graph of work items is not the same object as a standing statement of what the product does.
Superseding preserves; the recommended compaction does not. bd supersede keeps the original text, which is the right call. But bd admin compact --apply — labelled “# Agent-driven workflow (recommended)” in its own help — blanks fields and overwrites the description with an LLM summary with no snapshot, and their agent-facing documentation says plainly that “original content is discarded”. Productizer’s rule is the opposite and is enforced as such: a superseded requirement keeps its original sentence verbatim, and violating that is an ERROR. Two defensible positions — theirs optimises the working set an agent must read, ours optimises what a human can still audit in a year — but only one of them survives the recommended path.
Storage is the quiet difference. Beads needs Dolt 2.1.0 or newer and flock, and carries 66 migrations, several of them documented workarounds for upstream Dolt defects. That is the price of a version-controlled SQL knowledge graph, and it buys real capability. Productizer is files in your repo: no daemon, no database, no account. Less capability, less to keep alive.
And one convergence worth crediting rather than claiming. Their documentation states that .beads/issues.jsonl “is an export … not the canonical cross-machine sync channel” (beads docs). That is exactly Productizer’s views-are-output rule, arrived at independently by people solving a different problem. When two projects reach the same constraint from opposite directions it is usually because the constraint is real.
It is Claude Code only, against fourteen agent tools. It has no cross-session memory at all — not a thin version, none — and that is the gap a Gas City user would notice within an hour. Its lifecycle has never run end to end through CI. Its accuracy is measured but the sample is small and self-authored, so the honest phrasing is the whole phrasing: 16/16 recall and 0.94 precision end to end on a 26-case corpus we wrote ourselves, against 13/16 for the same model with no plugin, while the symbolic cross-check alone scores 0.70 on our first 21 cases and 0.12 on the harder 26. Those are two different numbers about two different things and neither is a benchmark. And it is one person’s free open-source project against a stack with 26,704 stars behind it. If what you need is many agents running in parallel without losing their memory or colliding on ids, Productizer is the wrong tool and Beads plus Gas City is the right one.
The verdict — different layers, and they compose. They orchestrate many agents and remember what happened; Productizer decides what should be true before the work and stops when a change contradicts it. Run Beads and Gas City when the problem is throughput and continuity: a fleet of agent processes reconciled against declarative TOML, a shared work graph that survives the session, ids that never collide and claims that can be reclaimed. Run Productizer when the thing you are missing is a standing agreement — permanent requirement ids, principles above them, superseded text kept verbatim, and a classifier that halts the work when today’s request contradicts a decision taken four months ago. Nothing about running one rules out the other, and pretending they are rivals on every row would be less credible than saying that plainly.
Gas City and Beads capabilities here were read from the cloned gastownhall/beads and gastownhall/gascity repositories and the GitHub API as of 2026; star, fork and commit counts are point-in-time and will have moved. Quoted phrases are theirs, verbatim. Where a row says a thing was not found or not established, that means exactly that — the limit of what was read, not a proof of absence. Productizer marks reflect shipped capability in github.com/gitayg/productizer; the accuracy figures are our own, on a corpus we wrote ourselves, and are stated with their sample sizes rather than as bare numbers. Gas City, Gasworks and Beads are the property of their owners; this is an independent capability comparison, and this page is not affiliated with, endorsed by, or partnered with Gas City, Beads, or their authors. Both projects evolve — verify specifics against current documentation.