Activate a groomed design-driven issue — create its worktree + branch (1:1:1:1), run OpenSpec propose to produce proposal/design/specs/tasks, render the spec + recommended design INLINE, then STOP for the owner's approval. This is Seam 1; it never implements. Second stage of the CQLite delivery pipeline. Use when the owner says "activate #N".
Install
npx skillscat add pmcfadin/cqlite/flow-activate Install via the SkillsCat registry.
SKILL.md
flow-activate — spec + design, then stop for approval (Seam 1)
You are the CQLite delivery lead. Take a design-driven issue whose board Status=Ready and produce a
committed, owner-approvable OpenSpec change on an isolated worktree. STOP at approval — do not implement.
Steps
- Load the issue.
gh issue view <N> --json number,title,body,labels. Derive a kebab-caseslug.
If the issue is oracle-driven (per its body), say so and route toflow-implementinstead — no
OpenSpec. - Check eligibility (claim protocol, D2). An item is claimable only if its board
Status=Ready
AND no claim exists on origin. Select by boardStatusONLY — never by thestatus:ready
label (Path A, #1886: labels are decorative; the board is the sole dispatch authority). If the
board is unreachable, STOP and fix auth — do NOT fall back to labels to establish eligibility. Empty
Ready → nothing to activate; stop. The lock is the slugless fixed-name refrefs/claims/issue-<N>
(#2665) — NOT the assignee (@meis identical for the same GitHub user on two machines) and NOT a
slug-named branch (a different slug or an identical-SHA base once double-claimed; #1632):
(For the Project-vs-labels detection snippet shared by all flow-* skills, seegit -C <repo-root> fetch origin -q if bash scripts/flow/claim.sh status <N> | grep -q "CLAIM: STATUS issue=<N>" \ || git -C <repo-root> ls-remote --heads origin "issue-<N>-*" | grep -q .; then echo "Already claimed (claim ref or a legacy issue-<N>-* branch on origin) — take the next item." # exit / pick a different item; another machine may `git fetch` its branch to RESUME instead. fiflow-board.) - Acquire the claim FIRST, then create the worktree + branch (PR plumbing, 1:1:1:1).
claim.shis
the lock — run it before any worktree/spec work. It pushes a UNIQUE root-commit to the fixed-name refrefs/claims/issue-<N>, so git's server-side ref arbitration decides the race regardless of slug or
base (a different-slug or identical-SHA competitor can no longer double-claim):
Ifif ! bash scripts/flow/claim.sh claim <N>; then echo "CLAIM LOST — another session holds refs/claims/issue-<N>. Take the next item." # (Adopting a reaped claim instead? Use: bash scripts/flow/claim.sh adopt <N> --expect <old-sha>) # (Refused with reason=legacy-branch-lock ... claim-ref=free — a FREE claim ref but an # issue-<N>-* branch still on origin? The sanctioned resume is # `claim.sh adopt <N> --expect none --reason resume-legacy-branch-lock:branch-outlived-claim` # (#2945 — a placeholder reason, or one still carrying an unsubstituted <…>, is # rejected with exit 64, so substitute a concrete why). The refusal # deliberately does NOT print it: CONFIRM the lane is abandoned first — # `claim-heartbeat.sh should-reap <machine>` (age > 4h AND no open PR AND pid-dead if # local), board Status, branch/PR author. Never resume blind, never hand-craft a claim # commit) fi # CLAIM HELD → set up the worktree + branch. The branch is naming/PR plumbing, NOT the lock: wt=".claude/worktrees/issue-<N>-<slug>" git -C <repo-root> worktree add "$wt" -b "issue-<N>-<slug>" origin/main git -C "$wt" push -u origin "issue-<N>-<slug>" # PR head — NOT the lock # NO lane-lock acquire HERE, deliberately (#3436 FIX 5): at creation time this session # is acting from the ROOT checkout and is not in the lane yet, so there is no durable # process whose cwd is inside it — the lock would have nothing re-identifiable to # record, and `acquire` now REFUSES with reason=unresolved-identity rather than write a # record that refuses forever. The lane lock is taken by the session that works IN the # lane (flow-implement / flow-address), from inside it. # Board visibility: assignee + Status=In Progress. Run the flow-board detection snippet FIRST — it # does `gh auth switch --user "$project_account"` so the project-capable account is active (the EMU # account flip otherwise makes the board write fail and degrade to a label SILENTLY). gh issue edit <N> --add-assignee @me # have_project=1 → set the board Status. `--field` is NOT a gh flag (verified gh 2.87.3 offers only # --field-id); all four IDs are required or the write fails: gh project item-edit --id <item-id> --project-id <project-id> \ --field-id <status-field-id> --single-select-option-id <In-Progress-option-id> # (have_project=0 cannot occur here — Path A eligibility in step 2 already required a reachable board. # Do NOT write a status:in-progress label — the board→label mirror (#2855) derives it from the # board Status you just set; a hand-written board-derived label is reverted on the next mirror pass.) # scripts/flow/*.sh blobs are mode 100644 (no +x) — ALWAYS invoke them via `bash`: bash scripts/flow/claim-heartbeat.sh beat <N> # FIRST beat — establishes refs/heartbeats/<machine> (#2089)claim.sh claimreportsCLAIM LOST, you did NOT win — do not create the worktree; take the next
eligible item. All spec work happens in that worktree only afterCLAIM HELD. - Propose with OpenSpec (use the
opsx:proposeskill /openspec new change <slug>): authorproposal.md(state milestone + oracle/design + Non-goals + doctrine impact),design.md,specs/<capability>/spec.md(every requirement gets a verifiable#### Scenario:),tasks.md
(each task names the surface it exercises; include gate + C + roborev steps — roborev ALWAYS viabash scripts/flow/roborev-review.sh --agent <agent> --model <model>, the only sanctioned invocation
(#2964), never a bareroborev review --branch). Consult specialists for
facts where useful (e.g. a parity/format question →test-validator/sstable-developer), but
never decide a product/data-model question — surface options to the owner. - Validate:
openspec validate <slug> --strict(must be clean). Commit the artifacts. - Render INLINE and STOP. Show the owner, in the conversation:
- the proposal summary + Non-goals,
- the spec requirements +
#### Scenario:blocks verbatim, - the recommended design (chosen + what it beat),
then set the transient spec-review sub-marker and wait:
# spec-review is a transient skill-managed sub-marker (NOT a board Status option) — the # board→label mirror (#2855) does not touch it. Do NOT write status:ready/in-progress/in-review; # those labels are the mirror's now, derived from the board Status you set. gh issue edit <N> --add-label status:spec-reviewDo not start
flow-implement. Approval is the owner's seam. - Drop the spec render after approval (issue #2085). The inline render exists only to get the owner's
Seam-1 approval — once approved, do not retain the verbatim spec/design body in the session window.
Every downstream agent re-reads it fresh fromopenspec/changes/<slug>/(thespec-auditor/C audit
re-readsspecs/**anyway), so keeping the render is pure inter-issue accretion. Render → approve → drop.