-
Notifications
You must be signed in to change notification settings - Fork 0
ticket doc sync
Status: Draft, 2026-05-24.
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/slopstop#1.
- Single-command sync:
/slopstop:doc-syncreadsdesign/and pushes to whatever doc store the project's.project-conf.tomlsystem 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.
- 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.
| 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 |
| 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  references pass through unchanged. |
| Per-file vs. consolidated on Linear | Per-file across all backends. One source file → one upstream page or document. |
A design/*.md file may begin with YAML frontmatter:
---
title: My preferred page title
slug: my-preferred-slug
----
titleoverrides the auto-derived title (filename minus.md). -
slugoverrides 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.
Before any system-specific logic:
-
.project-conf.tomlpresent in cwd. Stop if missing. -
design/directory present in cwd. Stop if missing. -
Dirty-design check (informational). Run
git status --porcelain -- design/. If non-empty, print:"design/ has uncommitted changes. The sync will push your current working-tree state, not the last committed state. If you intended to push the committed version, stash or commit first."
Do not block — continue with the sync. The check exists to surface the "I just edited a doc, did I mean to push this version?" case.
System-specific pre-flight (auth, wiki initialization) lives in the per-system sections below.
Do not invoke this skill in the same tool-use turn as Edit or Write operations targeting files under design/. The sync reads each source file at one moment while concurrent edits modify them; the pushed content becomes a mid-edit snapshot rather than the intended final state. This was observed in development: a parallel sync + edit batch pushed a wiki page in a half-stale form. Complete all design/ edits in one turn, then invoke sync in a subsequent turn.
The dirty-design pre-flight catches the committed-state version of this concern (uncommitted edits exist on disk); the in-turn race is invisible to the pre-flight because edits and the sync both read/write within the same instant of process state.
A GH wiki is itself a git repo at <owner>/<repo>.wiki.git. Flow:
- Clone the wiki repo to a temp directory. If clone fails with "Repository not found", stop with instructions for the user to initialize the wiki via the web UI. GitHub requires the first wiki page to be created through the UI before
git pushto.wiki.gitwill work; an empty wiki (feature enabled but no pages) cannot be populated by push alone. The skill does not attempt to work around this — it surfaces the limitation cleanly and waits for the user to do the one-time UI step. - For each
design/*.md: parse frontmatter, compute the page filename (<slug>.md), strip frontmatter, write the body to$TMP/<slug>.md. - For each
*.mdin$TMP/that doesn't correspond to a currentdesign/source: delete it. (Orphan prune.) -
git add -A && git commit -m "doc-sync from <source-sha>" && git push origin master. Skip the commit if there are no staged changes. - 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 are accessible via mcp__linear-server__save_document (create/update), mcp__linear-server__list_documents (enumerate), and the corresponding delete tool. Flow:
- List existing docs in the project / team identified by
$KEY. - 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.
- If an upstream doc with the matching title exists: update its body via
- 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.
Out of scope. The skill stops with "Confluence sync not yet supported." for system = "jira".
| Condition | Behavior |
|---|---|
.project-conf.toml missing |
Stop with standard missing-config message. |
design/ directory missing |
Stop with "No design/ directory found in cwd."
|
design/ has uncommitted changes |
Informational warning only; sync continues. The user's working-tree state is what gets pushed. |
gh auth status fails (GH) |
Stop with auth instructions. |
| Wiki not initialized upstream (GH) | Stop with instructions to visit https://github.com/<owner>/<repo>/wiki and create the first page via the web UI. GitHub does not support git-push-only initialization. One-time user action. |
| 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). |
- On a GH-backed project,
/slopstop:doc-syncmirrorsdesign/*.mdto the repo wiki. Re-running with nodesign/changes produces no commit. - Adding a new
design/foo.mdand re-running creates the wiki page. - Deleting
design/bar.mdand re-running deletes the corresponding wiki page (orphan prune). - A frontmatter
title:correctly overrides the default page title. - Embedded image references (
) render correctly in the wiki. - On a Linear-backed project, the same flow works against Linear Docs.
- Subdirectories inside
design/(e.g.design/notes/foo.md). First cut handles only flat*.mdfiles at the top ofdesign/. -
README.md→Home.mdspecial-casing on GH wiki. Frontmatterslug: Homehandles this if needed; no built-in remap. - Two-way edit propagation. Explicitly not supported.
-
.project-conf.toml— the skill readssystemandkeyfrom this file.
No dependency on the multi-ticket or RAG designs.