Files
initiative/.claude/commands/sync-issue.md
Lukas 613bb70065 Consolidate 36 per-change specs into 4 feature-level specs and align workflow
Replace granular change-level specs (001–036) with living feature specs:
- 001-combatant-management (CRUD, persistence, clear, confirm buttons)
- 002-turn-tracking (rounds, turn order, advance/retreat, top bar)
- 003-combatant-state (HP, AC, conditions, concentration, initiative)
- 004-bestiary (search, stat blocks, source management, panel UX)

Workflow changes:
- Add /integrate-issue command (replaces /issue-to-spec) for routing
  issues to existing specs or handing off to /speckit.specify
- Update /sync-issue to list specs instead of requiring feature branch
- Update /write-issue to reference /integrate-issue
- Add RPI skills (research, plan, implement) to .claude/skills/
- Create docs/agents/ for RPI artifacts (research reports, plans)
- Remove update-agent-context.sh call from /speckit.plan
- Update CLAUDE.md with proportional scope-based workflow table
- Bump constitution to 3.0.0 (specs describe features, not changes)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:33:27 +01:00

5.2 KiB

description
description
Update a Gitea issue with business-level acceptance criteria extracted from the feature spec's user stories.

User Input

$ARGUMENTS

You MUST provide an issue number as the argument (e.g. /sync-issue 42). If $ARGUMENTS is empty or not a valid number, ask the user for the issue number.

Prerequisites

  1. Verify the GITEA_TOKEN_ISSUES environment variable is set:
test -n "$GITEA_TOKEN_ISSUES" && echo "TOKEN_OK" || echo "TOKEN_MISSING"

If missing, tell the user to set it:

export GITEA_TOKEN_ISSUES="your-gitea-personal-access-token"

Then abort.

  1. Parse the git remote to extract the Gitea API base URL, owner, and repo:
git config --get remote.origin.url

Expected format: ssh://git@<host>:<port>/<owner>/<repo>.git or https://<host>/<owner>/<repo>.git

Extract:

  • GITEA_HOST — the hostname
  • OWNER — the repo owner/org
  • REPO — the repo name (strip .git suffix)
  • API_BASEhttps://<GITEA_HOST>/api/v1
  1. Locate the spec file. List the available feature specs:
ls specs/*/spec.md

Present the specs to the user and ask which one contains the acceptance criteria for this issue. If only one spec exists, use it automatically.

Execution

Step 1 — Read the spec

Load the spec file at FEATURE_SPEC. Extract user stories and acceptance scenarios using these patterns:

Flat specs (001-combatant-management, 002-turn-tracking):

  • Look for the ## User Scenarios & Testing section
  • Each ### ... Story ... or **Story ...** block
  • The Acceptance Scenarios numbered list within each story (Given/When/Then format)
  • The Edge Cases section(s)

Per-topic specs (003-combatant-state, 004-bestiary):

  • Stories are nested inside topic sections (e.g., ## Hit Points > ### User Stories > **Story HP-1 — ...**)
  • Scan ALL ## sections for **Story ... or **US-... patterns
  • Extract acceptance scenarios from each story regardless of nesting depth
  • Collect edge cases from each topic section's ### Edge Cases subsection

Step 2 — Condense into business-level acceptance criteria

For each user story, extract the acceptance scenarios and rewrite them as concise, business-level checkbox items. Group by user story title.

Transformation rules:

  • Strip Given/When/Then syntax — write as plain outcomes
  • Remove implementation details (API names, database references, component names, file paths, config values, tool names)
  • Focus on what the user can do or can see
  • Keep each item to one line
  • Preserve the grouping by user story for readability

Example transformation:

Input (from spec):

**Given** no sources are cached, **When** the user clicks the import button in the top bar,
**Then** the stat block side panel opens showing a descriptive explanation, an editable
pre-filled base URL, and a "Load All" button.

Output (for issue):

- [ ] Clicking the import button opens a panel with a description, editable URL, and "Load All" button

Also include edge cases as a separate group if they describe user-facing behavior.

Step 3 — Fetch the existing issue

curl -sf -H "Authorization: token $GITEA_TOKEN_ISSUES" "$API_BASE/repos/$OWNER/$REPO/issues/<NUMBER>"

Extract the current body from the response.

Step 4 — Update the issue body

Merge the acceptance criteria into the existing issue body:

  • If the body already has an ## Acceptance Criteria section, replace its contents (everything between ## Acceptance Criteria and the next ## heading or end of body).
  • If the body does not have an ## Acceptance Criteria section, insert it after the ## Summary section (or at the end if no Summary exists).

Preserve all other sections of the issue body unchanged.

The acceptance criteria section should look like:

## Acceptance Criteria

### <User Story 1 Title>
- [ ] <criterion from acceptance scenario>
- [ ] <criterion from acceptance scenario>

### <User Story 2 Title>
- [ ] <criterion from acceptance scenario>

### Edge Cases
- [ ] <edge case behavior>

Step 5 — Preview and confirm

Show the user:

  • The full updated issue body
  • A diff summary of what changed (sections added/replaced)

Ask for confirmation before updating.

Step 6 — Push the update

On confirmation:

curl -sf -X PATCH \
  -H "Authorization: token $GITEA_TOKEN_ISSUES" \
  -H "Content-Type: application/json" \
  "$API_BASE/repos/$OWNER/$REPO/issues/<NUMBER>" \
  -d @- <<'PAYLOAD'
{
  "body": "<updated body>"
}
PAYLOAD

Report success with the issue URL.

Behavior Rules

  • Never modify the issue title, labels, milestone, or assignees — only the body.
  • Always preview before updating — never push without user confirmation.
  • If the spec has no user stories or acceptance scenarios, abort with a clear message suggesting the user run /speckit.specify first.
  • Acceptance criteria must be business-level. If you find yourself writing implementation details, rewrite at a higher level of abstraction.
  • Use curl for all API calls — do not rely on gh CLI.
  • Always use HEREDOC for the JSON payload to handle special characters in the body.
  • Escape double quotes and newlines properly in the JSON body.