One Way Vault To Board Synthesis - alexherrero/crickets GitHub Wiki

One-way vault-to-board synthesis

Note

Implemented β€” catalog bundle #8 (roadmap #41). The github-projects plugin is built under src/github-projects/; the design calls below are locked and recorded in the GitHub Projects design. This page is the why; GitHub Projects plugin is the reference surface and Sync a project board the operator recipe.

The github-projects plugin answers a specific question: how does a project's state become legible to a human without making the human's view a second place that has to be kept in sync? The answer crickets settles on is one-way deterministic synthesis β€” the vault is the single source of truth, and the GitHub Project board is a generated mirror of it, never an editable peer. That shape pays off in a specific way, and one structural property makes it both safe and a little uncanny: the plugin that maintains the boards is itself tracked on a board.

Two sources of truth, one direction

There are two audiences for project state. The agent needs a working substrate it can read and write freely β€” that's the vault (roadmap, plans, progress). The human needs a glanceable, familiar surface β€” that's a GitHub Project board. The temptation is to let both be authoritative and reconcile them. Crickets refuses that: reconciliation between two writable stores is where drift, conflicts, and "which one is right?" live.

Instead the relationship is strictly directional:

  vault (agent's source of truth)
      β”‚  project_model.py  β†’  item graph (stable ids, parent-chain)
      β”‚  project_sync.py   β†’  deterministic render
      β–Ό
  GitHub Project board (generated human mirror β€” never hand-maintained)

The board is downstream. Nothing flows back. A human reading the board is reading a faithful projection of the vault; a human editing the board is editing something that the next sync will overwrite — which is exactly the signal that the board is not where state lives (DC-4: one write path; deterministic, one-way, idempotent vault→board synthesis).

Why deterministic, idempotent, single-path

Three properties make the projection trustworthy rather than merely automatic:

  • Deterministic render β€” the same vault state always renders the same board: stable field order, YYYY-MM-DD dates, and links built from the configured remote URL rather than hand-typed. Determinism is what lets a vault == board drift gate (check_project_sync.py) exist at all β€” you can only assert equality against a render that's reproducible.
  • Idempotent writes β€” project_sync.py post is a create-or-update keyed by a stable id. Re-running it converges; it never duplicates. This is what makes the board recoverable: if it drifts, you re-sync and it's correct again, with no manual cleanup.
  • A single write path β€” exactly one path (project_sync.py post, backed by gh) ever writes to GitHub. There is no second writer to race, no back-channel to audit. The --dry-run boundary lets you see the render before any of it lands.

Together, these properties turn "sync the board" from a risky bulk mutation into a safe, repeatable projection.

What the board mirrors β€” and what stays vault-only

The board does not mirror the whole vault. The materialization rule (DC-1) draws a deliberate line:

  • Feature-level-and-up is always on the board β€” Versions, Features, Sub-features, Backlog items, and Ideas appear whether or not work has started. This is the part a human plans against, so it should be visible early.
  • Plans and Tasks are materialized only for the active plan β€” task breakdowns are never pre-persisted to the board. A planned-but-not-started feature shows up; its eventual task decomposition does not, until that plan is the active one.

The reasoning is that a task breakdown is working detail, not planning surface. Pre-persisting every future task would flood the human view with speculative structure that churns as plans are re-cut. Keeping Plan/Task vault-only until activation keeps the board a map of intent and active work, not a dump of every possible decomposition.

Silent-source attribution: present in private, stripped in public

The vault's roadmap can name a silent source β€” attribution that is meaningful in the private working record. The public Project mirror is a different audience with a different contract: the renderer strips silent-source attribution so it never reaches the public board. This is renderer-enforced, not a convention someone has to remember β€” the same determinism that makes the render reproducible makes the stripping reliable. The private vault keeps the attribution; the public projection does not carry it.

The meta-loop

The property that makes this plugin distinctive: the plugin that maintains the boards is itself tracked on a board. The crickets project's own roadmap (#41 is this very plugin) is synthesized onto crickets' GitHub Project #5; agentm's roadmap onto Project #2. So the work of building the board-synthesizer appears, as Features and an active Plan, on a board the board-synthesizer renders.

The meta-loop is the strongest dogfood available: if the projection is wrong, it's wrong about its own development, visibly. It means the plugin's correctness is continuously under test against the one project whose state its authors know best.

Locked design calls

Call Resolution
Dependency requires: development-lifecycle; the vault path comes from project.json config, not a hard agentm dependency (supersedes a pre-V5-split requires: agentm note)
Taxonomy flat Type taxonomy (Version Β· Feature Β· Sub-feature Β· Plan Β· Task Β· Backlog-item Β· Idea)
Materialization (DC-1) board persists feature-and-up + Sub-feature; Plan + Task stay vault-only until the plan is active
Synthesis (DC-4) one write path; deterministic, one-way, idempotent vault β†’ board
Silent-source attribution named in the private vault roadmap, stripped from the public Project mirror (renderer-enforced)
Surfaces this cycle github-board only β€” local-index / none deferred to a follow-up

Note

These calls are recorded formally in the GitHub Projects design, with the "why not the alternative" reasoning per call and the re-audit triggers. This section is the narrative; the design is the decision of record.

Related

⚠️ **GitHub.com Fallback** ⚠️