Skip to content

ticket doc sync

Ian Smith edited this page May 24, 2026 · 5 revisions

ticket-doc-sync — Design Document

Status: Draft, 2026-05-24.

Summary

A skill that mirrors the design/ directory's markdown files to the project's ticket-system documentation store, on demand. One-way push: the committed design/ files remain the source of truth; the doc-store copy is a convenience view, refreshed wholesale on each sync. Supersedes the spec in iansmith/ticket-plugin#1.

Goals

  • Single-command sync: /ticket-plugin:doc-sync reads design/ and pushes to whatever doc store the project's .project-conf.toml system maps to.
  • Idempotent: re-running with no design/ changes is a no-op.
  • Orphan-pruning: pages in the doc store without a corresponding design/ file are deleted on each sync.
  • Backend-agnostic at the user level: same command across backends; behavior varies by system.

Non-goals

  • Two-way sync. Editing the wiki page never propagates back to design/.
  • Asset / binary uploads. Embedded images stay as external-URL references in the markdown.
  • Confluence / JIRA support in the first cut.
  • Auto-invocation on design/ change. User-triggered only.

Per-system targets

System Doc store Status
GitHub Repo wiki (<owner>/<repo>.wiki.git) In scope
Linear Linear Docs (mcp__linear-server__save_document) In scope (second)
JIRA Confluence Deferred — explicit error

Resolved decisions

Question Resolution
Orphans in the doc store Prune. Pages without a design/ counterpart are deleted on each sync.
Frontmatter title override Optional title: (and slug:) in YAML frontmatter. Default is filename-derived.
Images / assets External URLs only. Binaries are never uploaded; embedded ![alt](url) references pass through unchanged.
Per-file vs. consolidated on Linear Per-file across all backends. One source file → one upstream page or document.

Frontmatter (optional)

A design/*.md file may begin with YAML frontmatter:

---
title: My preferred page title
slug:  my-preferred-slug
---
  • title overrides the auto-derived title (filename minus .md).
  • slug overrides the auto-derived slug (lowercased filename, only meaningful on backends that distinguish title from URL — GH wiki being the main one).

Both fields are optional. Frontmatter is stripped before push — the doc-store copy contains body only.

Per-system mechanics

GitHub wiki

A GH wiki is itself a git repo at <owner>/<repo>.wiki.git. Flow:

  1. Clone the wiki repo to a temp directory. If the wiki doesn't exist yet (Repository not found), initialize a fresh local repo with the wiki remote and let the first push create it on GitHub.
  2. For each design/*.md: parse frontmatter, compute the page filename (<slug>.md), strip frontmatter, write the body to $TMP/<slug>.md.
  3. For each *.md in $TMP/ that doesn't correspond to a current design/ source: delete it. (Orphan prune.)
  4. git add -A && git commit -m "doc-sync from <source-sha>" && git push origin master. Skip the commit if there are no staged changes.
  5. Remove the temp directory.

The commit message captures the source repo's HEAD SHA so the wiki history is traceable to a specific source commit.

Linear Docs

Linear Docs are accessible via mcp__linear-server__save_document (create/update), mcp__linear-server__list_documents (enumerate), and the corresponding delete tool. Flow:

  1. List existing docs in the project / team identified by $KEY.
  2. For each design/*.md: parse frontmatter, compute the document title, strip frontmatter, then:
    • If an upstream doc with the matching title exists: update its body via save_document.
    • Otherwise: create via save_document.
  3. For each upstream doc whose title doesn't match any current design/ source: delete it. (Orphan prune.)

Title matching is exact. Project / team scoping defaults to whatever $KEY resolves to; refinement via a [doc_sync] namespace in .project-conf.toml is reserved but not required for first cut.

JIRA / Confluence

Out of scope. The skill stops with "Confluence sync not yet supported." for system = "jira".

Errors

Condition Behavior
.project-conf.toml missing Stop with standard missing-config message.
design/ directory missing Stop with "No design/ directory found in cwd."
gh auth status fails (GH) Stop with auth instructions.
Wiki repo doesn't exist yet (GH) Initialize locally; first push creates the wiki upstream.
Linear MCP unavailable Stop with "Linear MCP not available."
system = "jira" Stop with "Confluence sync not yet supported."
Network / API error mid-sync Stop and report which file failed. Partial state may exist; re-running is safe (idempotent).

Acceptance

  1. On a GH-backed project, /ticket-plugin:doc-sync mirrors design/*.md to the repo wiki. Re-running with no design/ changes produces no commit.
  2. Adding a new design/foo.md and re-running creates the wiki page.
  3. Deleting design/bar.md and re-running deletes the corresponding wiki page (orphan prune).
  4. A frontmatter title: correctly overrides the default page title.
  5. Embedded image references (![alt](https://...)) render correctly in the wiki.
  6. On a Linear-backed project, the same flow works against Linear Docs.

Out-of-scope refinements (future work)

  • Subdirectories inside design/ (e.g. design/notes/foo.md). First cut handles only flat *.md files at the top of design/.
  • README.mdHome.md special-casing on GH wiki. Frontmatter slug: Home handles this if needed; no built-in remap.
  • Two-way edit propagation. Explicitly not supported.

Prerequisites

No dependency on the multi-ticket or RAG designs.

Clone this wiki locally