Port the PM board tool to Go as allod pm (first bash-to-Go carve-off) #103
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
User story: So that I can refresh and reorganize my project board with one first-class command instead of a pile of coupled bash scripts, I want the PM board tooling reimplemented in Go as
allod pm— the pilot for moving the workspace CLI off bash.Part of allod/tools#98.
Context
There is a working PM board toolkit: a JSON overlay that references issues by
owner/repo#num, a deterministic renderer that joins it with live forge state into a self-contained HTML board, an integrity checker (schema + ref resolution + overlay purity), and a wrapper that refreshes and grooms it. It works, but it is a set of coupled bash/POSIX scripts. This issue carves it off as the first concrete step of the bash→Go migration — reimplement it as a first-classallod pmsubcommand, establishing the Go patterns the rest of the migration reuses.Scope
Reimplement the toolkit as
allod pm:allod pm— usage.allod pm refresh— validate the overlay, re-render the HTML board from live forge state, commit. Deterministic; no agent.allod pm groom [--dry-run]— run the grooming agent to rebuild the overlay from current forge state (add new issues, drop closed, re-prioritize), then refresh.--dry-runpreviews without committing.Boundaries
refreshandgroomare read-only on the forge;groomwrites only the operator's overlay file.Validation
allod pm refreshreproduces the existing renderer's output byte-for-byte on a fixture overlay + issue snapshot.<script>, no external URLs, forge-sourced text escaped.Part of allod/tools#98.
Design note for the Go port — keep
groom --dry-runas a review-without-re-running mode.The groom agent writes the rebuilt overlay to the working tree;
--dry-runonly withholds thegit commit. So after reviewing the diff you finalize the already-produced overlay without re-invoking the agent — a second LLM run is never needed to approve. The bash version pairs this withcommit(re-render + commit the pending overlay) anddiscard(revert it).Preserve in Go: the agent's output persists to the working tree,
--dry-runwithholds only the commit, andcommit/discardfinalize it — so review is free.Status (2026-07-17): the bash version has landed as
allod pm(thepm/tree in this repo) and is packaged into the store, so the "land after the bash ergonomics stabilize" boundary is essentially met — the Go port can start against a stable reference.Two points for the dev-plan / review pass that the body doesn't yet cover:
1. Build structure — the main open decision. This repo is pure shell today with no build step (the tools are read into
writeShellApplicationby the consuming home config). A Go binary addsgo.mod+buildGoModule(vendorHash, a real compile). Decide up front: either this repo grows its own flake exposing apmpackage (the build lives with the code andnix runworks), or the consuming config carries thebuildGoModule. The own-flake option is the cleaner default, and since this is the pilot carve-off of the bash→Go migration (#98), whatever we pick sets the pattern for the rest.2. Oracle first. No tests or golden output exist for the tool yet. Step 0 of the port: freeze a golden HTML from the bash renderer on the committed fixtures (deterministic via
--issue-snapshot), then hold the Go renderer byte-identical to it — that operationalizes the "reproduces byte-for-byte" criterion already in the body.Dispatcher note:
allodcurrently hardcodesexec bash "$pm_script"; for a compiled binary that becomesexec "$pm_script"— the only dispatcher coupling, and a one-line change.Decision (2026-07-17): the tools flake owns the build.
allod/toolsgrows its own flake exposingpackages.<system>.pmviabuildGoModule, sogo.mod+ vendorHash, the compile, andnix run .#pmall live with the code. The consuming home config stopsreadFile-ing thepmscripts intowriteShellApplicationand instead pulls the builtpmpackage from theallod-toolsflake input it already has.This is the pattern for the rest of #98: program-shaped tools become Go packages exposed by this flake, while the shell workspace helpers keep the current readFile path until they migrate too. The flake can also host the render golden + integrity-check fixtures as flake checks, so the "reproduces byte-for-byte" criterion runs in CI rather than by hand.