issue-lifecycle · git:20260831.059fda4 · 2026-08-31 · sha256 9299c8c3d758fdd2

issue-lifecycle git:20260831.059fda4A

Immutable. This exact content is served forever at /api/v1/blob/9299c8c3d758fdd2.

---
name: issue-lifecycle
description: >
  Drive the @swamp/issue-lifecycle model for interactive issue triage and
  plan iteration against swamp-club lab issues. Use when the user wants to
  triage a swamp-club issue, generate an implementation plan, or iterate on
  a plan with feedback. Also handles retroactive lifecycle creation for
  ad-hoc work via "prepare to ship". Triggers on "triage issue", "triage #",
  "issue plan", "review plan", "iterate plan", "approve plan",
  "issue lifecycle", "prepare to ship", "ready to ship".
---

# Issue Lifecycle Skill

Interactive triage and implementation planning for swamp-club lab issues using
the `@swamp/issue-lifecycle` extension model. This skill drives the model
conversationally — the human steers, you execute.

The model operates on swamp-club lab issue numbers. Every step records a
structured lifecycle entry against the issue in swamp-club and transitions its
status as the work progresses. There is no GitHub integration — the issue must
already exist in swamp-club before you start.

## Core Principles

**Always use the installed `swamp` binary.** Every `swamp` command in this skill
must invoke the installed binary from `$PATH` — never `deno run dev` or any
other Deno-based invocation. Before running any swamp command, verify the binary
exists:

```
which swamp
```

If `which swamp` fails (binary not found), **stop immediately** and tell the
human: "The `swamp` binary is not installed or not on your PATH. Install it
before continuing." Do not fall back to `deno run dev`.

**Never auto-approve.** Always stop and show the plan to the human. Always ask
for feedback. Only call `approve` when the human explicitly says to proceed.

## Prepare to Ship (Ad-Hoc Work)

When the user says **"prepare to ship"** (or "ready to ship", "prepare to ship
this work"), they have completed ad-hoc work that is not linked to an existing
issue. The lifecycle still needs a tracking issue for verification and
attestation to flow through.

**This flow is fully automatic — do not ask for confirmation at each step.**

### Steps

1. **Summarize the work.** Inspect the current branch: `git log main..HEAD`,
   `git diff --stat main..HEAD`. Build a title and summary from the commits and
   changed files.

2. **Create a tracking issue in swamp-club:**

   ```
   swamp issue create --title "<title>" --body "<summary of work done>" --type platform
   ```

   Capture the issue number from the output.

3. **Start the lifecycle:**

   ```
   swamp model @swamp/issue-lifecycle method run start issue-<N> --input issueNumber=<N>
   ```

4. **Fast-forward to implementing:**

   ```
   swamp model @swamp/issue-lifecycle method run fast_forward issue-<N> \
     --input summary="<summary>" \
     --input steps='<JSON array of plan steps>' \
     --input testingStrategy="<testing approach>"
   ```

   Build the plan steps retroactively from the actual work — each step should
   describe a logical unit of change with its files. The testing strategy should
   reflect how the changes were validated.

5. **Proceed with normal verification.** Read
   [references/verification.md](references/verification.md) and continue the
   standard verify → post_attestation → link_pr flow.

### Example

```
User: prepare to ship this work

Agent:
1. git log main..HEAD → "Add retry logic to HTTP client"
2. swamp issue create --title "Add retry logic to HTTP client" --body "..." --type platform
   → issue #247
3. swamp model @swamp/issue-lifecycle method run start issue-247 --input issueNumber=247
4. swamp model @swamp/issue-lifecycle method run fast_forward issue-247 \
     --input summary="Add exponential backoff retry to HTTP client" \
     --input steps='[{"order":1,"description":"Add retry wrapper","files":["src/http/client.ts"]}]' \
     --input testingStrategy="Unit tests for retry logic added in client_test.ts"
5. Proceed to verification...
```

## Repository Configuration

This skill reads repo-specific conventions from `agent-constraints/` at the
repository root. If these files exist, they customize how each phase works:

- `agent-constraints/adversarial-dimensions.md` — review criteria and dimensions
- `agent-constraints/planning-conventions.md` — analysis and documentation
  requirements
- `agent-constraints/triage-conventions.md` — codebase exploration and bug
  reproduction
- `agent-constraints/code-conformance-dimensions.md` — code vs plan review
  criteria
- `agent-constraints/implementation-conventions.md` — build, verify, and PR
  conventions
- `agent-constraints/verification-conventions.md` — container sandbox and
  verification workflow configuration

If these files do not exist, the skill uses generic defaults documented in each
reference file.

## Lifecycle Phases

Each phase has detailed instructions in a reference file. Read only the
reference you need for the current phase.

### Phase 1: Triage (steps 1–4)

Read [references/triage.md](references/triage.md) when starting a new triage or
resuming an issue in the `triaging` phase. Covers: starting the lifecycle (using
direct type execution to auto-create the model and fetch issue context in one
command), reading the codebase, classifying the issue, and reproducing bugs.

The first command to run is always the existence check:

```
swamp data get issue-<N> state-main --json
```

- If this **returns data**, the model already exists — check the `phase` field
  and go to the "Resuming a Session" table below. **Do NOT call `start`.**
- If this **fails** (model not found), the issue is new — run:

```
swamp model @swamp/issue-lifecycle method run start issue-<N> --input issueNumber=<N>
```

This fetches the issue from swamp-club and writes context automatically — do NOT
use `gh issue view` or any other mechanism to fetch issue data.

### Phase 2: Planning (steps 5–7)

Read [references/planning.md](references/planning.md) after triage is complete.
Covers: generating the implementation plan, applying repo-specific planning
conventions, and presenting to the human.

### Phase 3: Adversarial Review & Iteration

Read [references/adversarial-review.md](references/adversarial-review.md)
**immediately after every `plan` or `iterate` call — no exceptions.** Planning
and adversarial review are always paired: you never present a plan without
running the review first. Covers: challenging the plan across repo-specific
dimensions, verifying against the codebase, recording findings, presenting to
the human, and the iteration loop until approval.

### Phase 4: Implementation & Code Conformance Review

Read [references/implementation.md](references/implementation.md) after plan
approval. Covers: signalling implementation start and doing the work.

After the code is written, read
[references/code-conformance-review.md](references/code-conformance-review.md)
**before verification.** This adversarially compares the implemented code
against the approved plan. Deviations are expected — they just need a documented
justification.

### Phase 4a: Verification Loop

Read [references/verification.md](references/verification.md) **after code
conformance review is complete.** This runs the same checks as CI (lint, test,
compile, agent reviews) inside a container sandbox before the PR opens. The
agent iterates — fixing failures and re-verifying — until all steps pass. Only
then can a PR be created.

### Phase 5: Contributor Notification

After `ship` or `complete`, the lifecycle enters the `notify` phase. This is
where you decide whether to thank the issue author:

- If the issue author is an **external contributor** (not a repo collaborator),
  call `notify` to post a thank-you ripple mentioning them by handle.
- If the issue author is a **collaborator**, call `skip_notify` to proceed.

Check collaborator status with:

```
gh api /repos/swamp-club/swamp/collaborators --jq '.[].login' | grep -qx '<author>'
```

If the author is NOT in the collaborator list, they are external — call
`notify`. Otherwise call `skip_notify`.

### Phase 6: Session Summary

After `notify` or `skip_notify`, the lifecycle enters the `summarizing` phase.
Read [references/implementation.md](references/implementation.md) — section 7
covers the summary step.

Restate the original problem and the delivered outcome in plain language, then
call `summarize` to close out the lifecycle. This final check ensures the work
actually addressed the issue.

## Classification Types

The `triage` method classifies issues into one of four types (matching
swamp-club):

- `bug` — something is broken or behaving incorrectly
- `feature` — a request for new functionality or enhancement
- `platform` — admin-only platform infrastructure work
- `security` — security vulnerability or hardening work

Two additional classification details are captured in the classification record
but do NOT map to separate swamp-club types:

- `isRegression` — set to `true` when the bug previously worked. Implies
  `type: bug`. Look for signals like "this used to work", "stopped working
  after", or git history showing recent changes to the affected code.
- Low-confidence classifications — if you cannot classify the issue confidently,
  use `confidence: low` and populate `clarifyingQuestions`. Do not guess the
  type — ask the human before calling `triage`.

## Reviewing Plan History

To review a specific plan version:

```
swamp model @swamp/issue-lifecycle method run review issue-<N> --input version=<V>
```

To see all model data:

```
swamp model output search issue-<N> --json
```

## Resuming a Session

If the human comes back to an in-progress issue, check the current phase:

```
swamp data get issue-<N> state-main --json
```

Read the `phase` field from the response. **Do NOT call `start` to resume** —
`start` unconditionally resets the phase to `triaging`, destroying progress.

Use this table to determine what to do next:

| Phase            | Action                                                                     |
| ---------------- | -------------------------------------------------------------------------- |
| `triaging`       | Read [references/triage.md](references/triage.md)                          |
| `classified`     | Read [references/planning.md](references/planning.md)                      |
| `plan_generated` | Read [references/adversarial-review.md](references/adversarial-review.md)  |
| `approved`       | Read [references/implementation.md](references/implementation.md)          |
| `implementing`   | Run code conformance review, then verify                                   |
| `verifying`      | Read [references/verification.md](references/verification.md)              |
| `pr_open`        | Wait 3 min, then check PR: `pr_merged` if merged, `pr_failed` if failed    |
| `pr_failed`      | Fix the issue, then `link_pr` (new PR) or `implement` (major rework)       |
| `releasing`      | Check release build: `ship` when done, or `complete` as fallback           |
| `notify`         | Check if author is external: `notify` to thank them, `skip_notify` to skip |
| `summarizing`    | Call `summarize` with the problem restatement and delivered outcome        |
| `done`           | Nothing to do — lifecycle is complete                                      |

The canonical phase list lives in the `TRANSITIONS` constant in
`extensions/models/_lib/schemas.ts`.

## Closing Out a Shipped Issue

When a PR has already merged and the lifecycle just needs to be marked done:

1. Check the current phase:
   ```
   swamp data get issue-<N> state-main --json
   ```
2. If the phase is `implementing`, link the PR first:
   ```
   swamp model @swamp/issue-lifecycle method run link_pr issue-<N> --input url=<PR URL>
   ```
3. If the phase is `pr_open`, record the merge:
   ```
   swamp model @swamp/issue-lifecycle method run pr_merged issue-<N>
   ```
4. If the phase is `releasing`, ship it:
   ```
   swamp model @swamp/issue-lifecycle method run ship issue-<N>
   ```
5. If the phase is `notify`, check if the author is external and either thank
   them or skip:
   ```
   swamp model @swamp/issue-lifecycle method run notify issue-<N>
   swamp model @swamp/issue-lifecycle method run skip_notify issue-<N>
   ```
6. If the phase is `summarizing`, record the summary:
   ```
   swamp model @swamp/issue-lifecycle method run summarize issue-<N> \
     --input originalProblem="<problem>" --input deliveredOutcome="<outcome>" --input outcomeMet=true
   ```
7. For quick close-out, `complete` still works from `implementing`, `pr_open`,
   or `releasing` (transitions to `notify`, then `notify`/`skip_notify`, then
   `summarize`).

## Key Rules

1. **Never use `gh` to fetch issue data.** All issue context comes from
   swamp-club via the `start` method — not from GitHub. The only place `gh` is
   used in this skill is checking collaborator status during contributor
   notification.
2. **Never skip the feedback loop.** Always show the plan. Always ask.
3. **Never call approve without explicit human approval.**
4. **Persist everything through the model.** Don't just have a conversation —
   call the model methods so state survives context compression and sessions.
5. **swamp-club is the source of truth.** Every state transition posts a
   lifecycle entry and transitions the issue status in swamp-club automatically.
   You don't need to manually update the issue.
6. **Read the codebase thoroughly** before generating the plan. The plan should
   reference specific files, functions, and test paths.
7. **Follow the planning conventions for this repository.** Read
   `agent-constraints/planning-conventions.md` if it exists.
8. **Never open a PR without asking first.** Present the changes summary and
   wait for the human to confirm before creating the pull request.
9. **File unrelated issues immediately.** If you discover a bug, code smell, or
   problem during investigation that is NOT related to the current issue, file
   it as a new swamp-club issue. Do not try to fix it in the current work span —
   keep the scope focused.
10. **Never use `deno run dev` for swamp commands.** All `swamp` invocations
    must use the installed binary. Run `which swamp` first — if it's missing,
    stop and tell the human.