Claude
Skills
Sign in
Back

flow-next-tracker-sync

Included with Lifetime
$97 forever

Project a flow-next spec to a tracker issue (Linear first, GitHub next) and reconcile body/status/comments two-way — projection, not coordination. The spec stays the source of truth; the tracker is a co-editable mirror. Use to configure the bridge (discovery ceremony), link a spec to an issue (flow-first push or tracker-first "grab issue X and spec it"), push/pull/reconcile, or unlink. Triggers on /flow-next:tracker-sync, "sync to linear", "push this spec to the tracker", "grab issue X and spec it", "link this spec to the issue", "reconcile with the tracker". NOT /flow-next:sync (that is plan-sync, a different skill).

General

What this skill does


# flow-next-tracker-sync — project a spec to a tracker, reconcile two-way

The `.flow/specs/<id>.md` spec is the source of truth and the quality layer; the tracker (Linear first, GitHub next) is a **co-editable mirror** for teams that must live in it. This skill is **projection, not coordination** — the tracker mirrors the spec (body, status, comments all sync two-way) but never drives flow state or spawns agents (see the decision record at `.flow/memory/.../tracker-sync-is-projection-not-*`).

This skill is the **spine**: the discovery ceremony, the spec↔issue grain, the identity/naming alias, and a **transport-blind** push/pull/reconcile orchestration skeleton. It does NOT contain transport code or merge logic — those plug in via the interface defined here:

- **Transports** (`fetchIssue` / `writeIssue` / `listComments` / `postComment` / `readStatus` / `setStatus`) are implemented by the Linear adapter (fn-52.3) and GitHub adapter (fn-52.7). This skill calls them through the normalized interface; it never sees a wire shape. The **Linear adapter is a detect-best-available transport ladder** (MCP → GraphQL → no-op, mirroring fn-51's driver ladder) — see [`references/linear-ladder.md`](references/linear-ladder.md); the **GitHub adapter** is the headless-robust `gh` transport (single rung + no-op, reduced-fidelity status) — see [`references/github.md`](references/github.md).
- **Reconcile** operates only on the **normalized payload structs** (`issue` / `comment` / `status`) the adapters exchange. The agentic 3-way **body merge** + format translation + scoped conflict is in [`references/body-merge.md`](references/body-merge.md) (fn-52.4); the per-field **status who-wins** is [`references/status-sync.md`](references/status-sync.md) and **comments/evidence append + dedup** is [`references/comments-sync.md`](references/comments-sync.md) (fn-52.5). The interface is defined in `references/adapter-interface.md`.

**Read [steps.md](steps.md) for the full phase-by-phase execution.** Read [`references/adapter-interface.md`](references/adapter-interface.md) for the transport interface + normalized payload contract, [`references/body-merge.md`](references/body-merge.md) for the agentic 3-way body merge / format translation / scoped conflict, [`references/status-sync.md`](references/status-sync.md) for the per-field status who-wins + deadlock fallback, [`references/comments-sync.md`](references/comments-sync.md) for comments/evidence two-way append + dedup, [`references/identity.md`](references/identity.md) for the hybrid id model (tracker-first canonical vs flow-first alias), [`references/linear-ladder.md`](references/linear-ladder.md) (→ [`linear-mcp.md`](references/linear-mcp.md), [`linear-graphql.md`](references/linear-graphql.md)) for the Linear transport ladder, and [`references/github.md`](references/github.md) for the GitHub adapter (`gh` transport, reduced-fidelity status).

> Sync engine shape (discovery ceremony, per-item `lastSyncedAt`, surface-diffs-never-overwrite) adapted from Ray Fernando's `running-bug-review-board` `issue-trackers.md` (Apache-2.0) — see CHANGELOG.

## Preamble

**CRITICAL: flowctl is BUNDLED — NOT installed globally.** `which flowctl` will fail (expected). Define once; subsequent blocks (here and in `steps.md`) use `$FLOWCTL`:

```bash
FLOWCTL="$HOME/.codex/scripts/flowctl"
[ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl"
```

**Inline skill (no `context: fork`)** — `plain-text numbered prompt` must stay reachable across phases. Subagents can't call plain-text numbered prompts (Claude Code issues #12890, #34592). The discovery ceremony (Phase 1) and genuine-conflict surfacing (handled in fn-52.4/.5) both require user choice in interactive mode.

## flowctl owns plumbing; the skill owns judgment

The canonical flow-next split. flowctl (fn-52.1, fn-52.10) provides atomic, deterministic helpers; this skill, running on the host agent, does the API calls / reconciliation / asking:

| flowctl owns (deterministic) | the skill owns (host-agent judgment) |
|---|---|
| `sync active` — is the bridge active (value-checked)? | discovery ceremony: probe signals, surface, ASK, confirm |
| `sync list-unsynced` / `list-stale` — enumerate | decide which specs to push/pull this run |
| `sync set-tracker-id` / `set-last-synced` / `set-merge-base` — atomic state write | call the transport (`fetchIssue` / `writeIssue` / …) |
| `sync clear` — unlink, wipe state atomically | semantic 3-way body merge (fn-52.4), status who-wins + comment dedup (fn-52.5) |
| `sync receipt` / `sync defer` — proof-of-work + queue | translate flow-structured ↔ tracker free-form |
| `sync check-collisions` — flag shared tracker ids | decide create-vs-link on ambiguity; ASK the user |
| `spec create --tracker-first` / `config set` — id + config write | choose the hybrid id origin (tracker-first vs flow-first) |

Never reimplement a flowctl helper inline; never push a merge/judgment decision into flowctl.

## Discovery ceremony (R2) — detect / surface / ask / never-assume

The bridge is **off until explicitly enabled**. The ceremony probes four signals, surfaces present AND absent, ASKS, and writes config **only on confirmation** — with provenance. No-signal ⇒ nothing written; `enabled` stays `false`. Never assume. But **once the user confirms, enabling is opt-OUT, not opt-in**: the ceremony activates the whole pipeline (every `perEvent` event) by default — hooking up the bridge means you want it to sync. The user excludes events at ceremony time or turns any off later (`flowctl config set tracker.perEvent.<event> off`). The `get_default_config()` schema default stays `off`, so a bare `enabled=true` set WITHOUT the ceremony activates **no lifecycle-event sync** (every `perEvent` event stays dormant) — only the ceremony's explicit writes activate them. (The lone exception: make-pr's PR↔issue link is unconditional whenever the bridge is active — no per-event gate, by design.)

Probe these four signals (detection lives in the skill, not flowctl — same shape as fn-51's driver-ladder detection):

| Signal | Probe | Means |
|---|---|---|
| Linear MCP registered | the host's MCP/tool list contains a Linear server (e.g. `*Linear*` tools like `save_issue`) | interactive Linear transport available (OAuth handled) |
| `LINEAR_API_KEY` | `[ -n "$LINEAR_API_KEY" ]` | headless Linear GraphQL transport available |
| GitHub auth | `gh auth status` exits 0 | headless GitHub transport available |
| Jira host | a `*.atlassian.net` host configured/visible | Jira present (out of scope here — surface but don't offer) |

Resolution model is **env > config > ASK**, mirroring `cmd_review_backend` (`flowctl.py:4859`): if the transport/tracker is already decided by env or config, don't re-ask. Steps in [steps.md](steps.md) Phase 1.

**On confirmation only**, write via `flowctl config set` (dot-paths are safe — config keys are nested):

```bash
$FLOWCTL config set tracker.enabled true
$FLOWCTL config set tracker.type linear # or github
$FLOWCTL config set tracker.provenance "discovery ceremony 2026-06-03; confirmed by <who>; signals: MCP+API_KEY"
# DEFAULT-ON (opt-out): activate the whole pipeline — skip only what the user excluded.
$FLOWCTL config set tracker.perEvent.capture reconcile
$FLOWCTL config set tracker.perEvent.interview reconcile
$FLOWCTL config set tracker.perEvent.plan reconcile
$FLOWCTL config set tracker.perEvent.work.firstClaim push
$FLOWCTL config set tracker.perEvent.work.done comment
$FLOWCTL config set tracker.perEvent.makePr comment
$FLOWCTL config set tracker.perEvent.resolvePr comment
$FLOWCTL config set tracker.perEvent.completionReview reconcile
```

Confirm the result with `flowctl sync active --json` (must report `active: true` once enabled/type are set). Negative path: user declines ⇒ write nothing; `sync active` stays `active: false`.

## Flexible entry (R2) — no fixed starting point

Two entry flows, both attach sync state **on link** (never impose where the user must sta

Related in General