Sync A Project Board - alexherrero/crickets GitHub Wiki
Note
Goal: Render the current vault project state for a configured project and push it one-way to its GitHub Project board — idempotently, with a dry-run preview first.
Prereqs: the github-projects plugin installed (requires: development-lifecycle); a project.json (the repo's gitignored .harness/project.json) wiring the vault project to its Project — at minimum vault_project + github.{owner,number}; the gh CLI authenticated.
-
Confirm the
project.jsonresolves. The loader needsvault_project+github.owner+github.number;github.urlis derived from owner+number when omitted, anditems_sourcedefaults to the siblingboard-items.json. A vault-backed project keeps its board mirror in itsdesk/, so pointitems_sourceat<vault>/projects/<slug>/desk/board-items.json. -
Preview the render with the dry-run boundary — no write hits GitHub. Omit
--typefor a full template-driven re-render of one item:python3 "$CLAUDE_PLUGIN_ROOT/scripts/project_sync.py" post \ --config .harness/project.json --id <item-id> --dry-run
-
Push the one-way update via the single live write path — idempotent create-or-update by stable id, so re-running converges. For a progress stage use the
--typeshortcut; for a kickoff or closeout omit it (those re-render in full fromboard-items.json):# full re-render of one item python3 "$CLAUDE_PLUGIN_ROOT/scripts/project_sync.py" post \ --config .harness/project.json --id <item-id> # task progress stage shortcut python3 "$CLAUDE_PLUGIN_ROOT/scripts/project_sync.py" post \ --config .harness/project.json --type task-progress \ --id <task-id> --commit <SHA> --summary "<one human sentence>"
-
Confirm the board matches the vault — run the drift gate (next section). Exit
0= in sync,1= drift,2= operational error.
The inaugural backfill brings both boards (agentm Project #2, crickets Project #5) up to current state in one pass. It is the one bulk write and is operator-gated — it runs only on explicit approval, never automatically.
Author the project's full state into board-items.json, the file items_source names (the project's desk/) — this is the renderer's source of truth; never create items with raw gh project item-create, which the drift gate flags as an orphan. Run the post with --dry-run first and inspect the render. Only on explicit operator approval, drop --dry-run to push. A re-fetch should report every item a noop. Both boards were backfilled this way: crickets #5 (18 open issues) and agentm #2 (16 items).
Warning
The backfill writes to live GitHub Projects. Always run the --dry-run render first and inspect it before approving the bulk push.
The drift gate is the verification surface: it asserts vault == board and is wired into scripts/check-all.sh.
python3 "$CLAUDE_PLUGIN_ROOT/scripts/check_project_sync.py"
# graceful-skip when no project.json or no gh; otherwise asserts vault == boardIt checks four drift kinds: create, missing, update, and orphan. tests-linux.yml also runs it in CI.
Note
With no project.json or no gh the gate graceful-skips — it is never an error to run the check on a repo that has no board wired.
-
The gate reports drift after a sync: the board diverged from the vault. Re-run the
postpath — it is idempotent (create-or-update by stable id), so re-running converges. Anorphanfinding means a board issue is backed by no vault item — add it toboard-items.json(or remove the stray issue). -
A link in the rendered board looks hand-typed / wrong: links are built from
github.url, never hand-typed — a wrong link points at a badgithub.url(or a wrongowner/numberit derives from) inproject.json. -
A phase command didn't emit a board update: emission is gated on the
board-synccapability being available —/plan,/work,/releasecheckagentm_bridge.py capability board-syncand graceful-skip when it returns non-zero. Confirm thegithub-projectsplugin is installed, agentm is present (the capability resolver), andproject.json+ghare present.
- GitHub Projects plugin — the reference for the config schema, Type taxonomy, templates, field schema, and the write path.
- One-way vault-to-board synthesis — why this is one-way and deterministic.
- Development Lifecycle — the base plugin whose phase commands emit board updates.
- CI gates — the gate battery the drift gate joins.