Summary
An optional, GitHub-specific skill, board-sync, that derives a live GitHub
Project (v2) board from production/epics/*/story-*.md and keeps it in sync
incrementally — without ever editing a document. I have a battle-tested version
running in production on my own game project and would adapt a clean, generic,
English-only one for upstream. Opening this first to check the direction is wanted
before sending the PR.
Type
Problem / Motivation
CCGS has several skills that read story status off disk — /sprint-status,
/content-audit, /story-readiness — but none that projects that status into
a board view. The usual stand-in is a hand-maintained summary table in an
index.md, which drifts the moment a story's Status: changes and nobody
re-counts (you end up with a wall of ~~strikethrough~~ ✅). board-sync fills that
gap: one command derives a board that always matches the stories on disk.
Proposed Solution
A sonnet-tier, user-invocable skill at .claude/skills/board-sync/ plus two
zero-dependency Node scripts. Data flow:
production/epics/*/story-*.md ← SSoT (the **Status** field in each story header)
│ parse_stories.mjs (scan every story header, normalize Status → enum)
▼
state.json ← derived snapshot (an intermediate layer, NOT a data source)
│ export_github.mjs --incremental
▼
GitHub Project (the board)
- Reads CCGS-standard story headers (
> **Status**:, > **Type**:,
> **Estimate**:) — no project-specific files. Any CCGS project works as-is.
- Derives four single-select Project fields: Stage (Backlog / Ready /
In Progress / Blocked / Done / Deferred), Type (Logic / Integration /
Visual / UI / Config — the existing story types), Size (S/M/L), Epic
(one option per epic, added automatically).
- A
setup subcommand creates the Project + fields and writes the project number
into a small board.config.json.
- The iron rule: it only reads story
.md, writes its own
state.json / mapping.json, and pushes to an external board. It never
edits any existing document (index.md / story md / EPIC.md / PLAN / TODO) —
maintaining markdown stays other skills' job. So it doesn't conflict with the
Collaborative Principle: it makes no design decisions and writes no project
documents. Output is previewable (--dry) and can be tried one epic at a time
(--epic <slug>) before a full run.
Alternatives Considered
- Use GitHub Milestones for epics. Rejected: a Milestone is a time-boxed,
due-date container (a release/sprint window), while a CCGS epic is an
architectural module — a grouping, not a deadline. Modeling it as a board
dimension (group/filter by Epic) fits better, and a single-select value is one
idempotent field-edit vs. a second object lifecycle to reconcile. (A story →
Milestone mapping could be a clean follow-up if anyone wants it.)
- Drive the Project's built-in Status field. Rejected: it only has three
options (no Backlog/Ready/Blocked/Deferred) and auto-links to issue open/close,
which fights the exporter. The skill uses its own Stage field instead.
- Keep maintaining a markdown summary table. That's the status quo that
drifts — the problem this solves.
Additional Context
- Optional & opt-in by design. Depends on the
gh CLI with the project
scope. Projects on GitLab / Gitea / plain local git just don't install it;
nothing else in CCGS depends on it.
- Zero npm dependencies (Node built-ins only). Cross-platform.
- Production-grade robustness: incremental + idempotent + reconcile-by-title +
retry + stable-snapshot reads. Safe to re-run after a crash (adopts orphaned
issues instead of double-creating).
Questions before I open the PR:
- Are you open to an optional, GitHub-specific skill in the set, given non-GitHub
projects can't use it?
- Any preference on how optional/forge-specific skills should be flagged (naming,
a note in skills-reference, a separate section)?
- Anything in the iron-rule / no-milestone framing you'd want changed first?
Happy to send the full PR (skill + scripts + README + skills-reference entry, with
a note on the clean-project verification run) once I know it's wanted. Thanks for
CCGS — great foundation to build on.
Summary
An optional, GitHub-specific skill,
board-sync, that derives a live GitHubProject (v2) board from
production/epics/*/story-*.mdand keeps it in syncincrementally — without ever editing a document. I have a battle-tested version
running in production on my own game project and would adapt a clean, generic,
English-only one for upstream. Opening this first to check the direction is wanted
before sending the PR.
Type
Problem / Motivation
CCGS has several skills that read story status off disk —
/sprint-status,/content-audit,/story-readiness— but none that projects that status intoa board view. The usual stand-in is a hand-maintained summary table in an
index.md, which drifts the moment a story'sStatus:changes and nobodyre-counts (you end up with a wall of
~~strikethrough~~ ✅). board-sync fills thatgap: one command derives a board that always matches the stories on disk.
Proposed Solution
A
sonnet-tier, user-invocable skill at.claude/skills/board-sync/plus twozero-dependency Node scripts. Data flow:
> **Status**:,> **Type**:,> **Estimate**:) — no project-specific files. Any CCGS project works as-is.In Progress / Blocked / Done / Deferred), Type (Logic / Integration /
Visual / UI / Config — the existing story types), Size (S/M/L), Epic
(one option per epic, added automatically).
setupsubcommand creates the Project + fields and writes the project numberinto a small
board.config.json..md, writes its ownstate.json/mapping.json, and pushes to an external board. It neveredits any existing document (
index.md/ story md / EPIC.md / PLAN / TODO) —maintaining markdown stays other skills' job. So it doesn't conflict with the
Collaborative Principle: it makes no design decisions and writes no project
documents. Output is previewable (
--dry) and can be tried one epic at a time(
--epic <slug>) before a full run.Alternatives Considered
due-date container (a release/sprint window), while a CCGS epic is an
architectural module — a grouping, not a deadline. Modeling it as a board
dimension (group/filter by Epic) fits better, and a single-select value is one
idempotent field-edit vs. a second object lifecycle to reconcile. (A story →
Milestone mapping could be a clean follow-up if anyone wants it.)
options (no Backlog/Ready/Blocked/Deferred) and auto-links to issue open/close,
which fights the exporter. The skill uses its own Stage field instead.
drifts — the problem this solves.
Additional Context
ghCLI with theprojectscope. Projects on GitLab / Gitea / plain local git just don't install it;
nothing else in CCGS depends on it.
retry + stable-snapshot reads. Safe to re-run after a crash (adopts orphaned
issues instead of double-creating).
Questions before I open the PR:
projects can't use it?
a note in skills-reference, a separate section)?
Happy to send the full PR (skill + scripts + README + skills-reference entry, with
a note on the clean-project verification run) once I know it's wanted. Thanks for
CCGS — great foundation to build on.