Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 70 additions & 8 deletions .claude/skills/swamp-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,80 @@ routing matrix, examples, and refusal semantics.
PVR is off. See [references/security_routing.md](references/security_routing.md)
for the full PVR-state matrix and rationale.

## Workflow
## Bug Report Workflow

1. Gather details from the user (bug reproduction steps, feature context, or
vulnerability description).
2. For extension-scoped reports, confirm the extension is pulled locally with
`swamp extension list` — if missing, run `swamp extension pull <name>` first.
A state machine. Each state gates the next — do not advance until the current
state's **Verify** passes. If Verify fails, run **On Failure** and re-verify.

```
gather_details → version_check → submit → verify
```

### State 1: gather_details

**Gate:** None (first state).

**Action:** Gather bug details from the user — reproduction steps, affected
component, environment. For extension-scoped reports, confirm the extension is
pulled locally with `swamp extension list` — if missing, run
`swamp extension pull <name>` first. Note which source files you investigated
during diagnosis — you will need these paths in the next state.

**Verify:** Title and body are ready. Ideally you also know which source files
are relevant to the bug (for the version check in the next state).

**On Failure:** Ask the user for more details.

### State 2: version_check

**Gate:** State 1 passed (title, body, and diagnosed file paths are known).

**Action:** Check if the bug was already fixed in a newer version. Read
[references/version_check.md](references/version_check.md) for the full
procedure.

**Verify:** One of three outcomes determined:

- **bug_fixed** — the code changed and the bug appears resolved. Tell the user
to run `swamp update` instead of filing. Do not advance to submit.
- **bug_present** — the code is unchanged or the bug still exists. Advance to
submit.
- **inconclusive** — could not determine (source fetch failed, comparison
unclear). Advance to submit.

**On Failure:** If `swamp update --check` or `swamp source fetch` fails, treat
as inconclusive and advance.

### State 3: submit

**Gate:** State 2 passed with `bug_present` or `inconclusive`.

**Action:** Verify syntax with `swamp help issue bug`. Run the command.

**Verify:** The command succeeded and returned an issue number or URL.

**On Failure:** See Error Recovery table below.

### State 4: verify

**Gate:** State 3 passed.

**Action:** Confirm the returned issue number / URL with the user (or relay
refusal guidance).

**Verify:** User acknowledged.

## Feature / Security Workflow

Feature requests and security reports use a linear flow (no version check):

1. Gather details from the user.
2. For extension-scoped reports, confirm the extension is pulled locally.
3. Verify syntax with `swamp help issue`.
4. Run the appropriate command.
5. Verify with the returned issue number / URL (or relay the refusal guidance to
the user).
5. Verify with the returned issue number / URL.

### Error Recovery
## Error Recovery

Map the failure to the right fix rather than retrying blindly:

Expand Down
76 changes: 76 additions & 0 deletions .claude/skills/swamp-issue/references/version_check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Version Check

Detailed procedure for the `version_check` state in the bug report workflow. The
goal is to determine whether the bug you diagnosed has already been fixed in a
newer release before filing it.

## Step 1: Check for Updates

```bash
swamp update --check --json
```

Parse the JSON output:

- `{"status": "up_to_date", ...}` → the user is on the latest version. Result:
**inconclusive** (no newer version to compare against). Advance to submit.
- `{"status": "update_available", "currentVersion": "...", "latestVersion": "..."}`
→ a newer version exists. Proceed to step 2 with the `latestVersion` value.

If the command fails, result: **inconclusive**. Advance to submit.

## Step 2: Fetch Latest Source

```bash
swamp source fetch --version <latestVersion>
```

Pass the `latestVersion` string from step 1 directly — the CLI adds the `v`
prefix automatically.

Then get the source path:

```bash
swamp source path --json
```

The `path` field in the JSON output is the root directory of the fetched source.

If either command fails, result: **inconclusive**. Advance to submit.

## Step 3: Re-read Diagnosed Files

If you did not investigate any source files during `gather_details` (e.g. the
user described the bug without code investigation), result: **inconclusive**.
Advance to submit.

Otherwise, read the files you investigated from the fetched source tree.

For each file you investigated (e.g.
`src/domain/workflows/execution_service.ts`), read it from the fetched source
path:

```
<source_path>/src/domain/workflows/execution_service.ts
```

If a file does not exist in the latest source (deleted or renamed), note that as
a signal that the code changed.

## Step 4: Compare and Decide

Compare what you see in the latest source against your diagnosis:

- **bug_fixed**: The code you identified as broken has been modified. The fix
addresses the root cause you diagnosed. Tell the user:
> "The code related to your bug has been updated in version `<latestVersion>`.
> The issue appears to be fixed. Run `swamp update` to get the fix instead of
> filing."
- **bug_present**: The relevant code is identical to what you diagnosed — the
bug still exists in the latest version. Proceed to submit.
- **inconclusive**: The code changed but you cannot determine whether the change
fixes this specific bug, or the diagnosed files were restructured and you
cannot trace the issue. Proceed to submit.

When in doubt, prefer **inconclusive** over **bug_fixed** — it is better to file
a duplicate than to tell the user a bug is fixed when it is not.
88 changes: 20 additions & 68 deletions .claude/skills/swamp-repo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,9 @@ etc.) — remove them by hand if desired. Adding a tool that didn't share a skil
directory with the previous primary surfaces an `extensionsToReinstall` warning
naming pulled extensions that need to be re-installed for the new tool.

If the upgrade detects extensions tracked at a legacy on-disk layout
(`extensions/<type>/…` or `.swamp/pulled-extensions/<type>/…`), it re-pulls each
one into the current per-extension subtree
(`.swamp/pulled-extensions/<ext-name>/<type>/…`) and sweeps the old files
automatically — no follow-up `swamp extension install` command is required. This
step requires registry access; on failure, the legacy files are preserved and
the error names the affected extensions.
Legacy extension layouts are automatically migrated during upgrade. See
[references/troubleshooting.md](references/troubleshooting.md) for details on
legacy layout migration behavior.

## Start Web Interface

Expand Down Expand Up @@ -247,17 +243,10 @@ swamp datastore setup extension @swamp/s3-datastore \
--config '{"bucket":"my-bucket","prefix":"my-project","region":"us-east-1"}' --json
```

Verifies the backend is accessible, pushes existing local `.swamp/` data to the
remote, hydrates the local cache from any data already present in the remote (so
a contributor joining a populated shared bucket starts with their cache primed),
and updates `.swamp.yaml`. Subsequent commands automatically pull before
execution and push after.

`--skip-migration` skips only the local→remote push; the remote→local hydration
step still runs, so a fresh contributor can opt out of pushing their `.swamp/`
(or skip the migration entirely if they have no local data) without ending up
with an empty cache. Legacy type name `s3` is auto-remapped to
`@swamp/s3-datastore`.
Verifies the backend, migrates local data to the remote, hydrates the local
cache, and updates `.swamp.yaml`. Subsequent commands automatically sync. See
[references/troubleshooting.md](references/troubleshooting.md) for
`--skip-migration` behavior and edge cases.

### Migrating Between Datastores

Expand All @@ -280,65 +269,22 @@ sync from other commands, and they are not a no-op summary.

### Lock Management

Both filesystem and S3 datastores use a distributed lock to prevent concurrent
write access. Write commands (create, edit, delete, run, gc) acquire the lock
via `requireInitializedRepo()`. Read-only commands (search, get, list, validate,
history) use `requireInitializedRepoReadOnly()` which skips the lock, allowing
them to run concurrently with write operations. Locks auto-expire after 30
seconds if a process crashes.
Datastores use a distributed lock to prevent concurrent write access. Locks
auto-expire after 30 seconds if a process crashes.

```bash
swamp datastore lock status --json # Show lock holder
swamp datastore lock release --force --json # Force-release stuck lock
```

**Lock status output shape:**

```json
{
"holder": "user@hostname",
"hostname": "hostname",
"pid": 12345,
"acquiredAt": "2026-03-10T12:00:00.000Z",
"ttlMs": 30000
}
```

Returns `null` if no lock is held.

### Custom Datastores

Install a community datastore or create your own in `extensions/datastores/`:

```bash
swamp extension search datastore --json # Find community datastores
```

Configure in `.swamp.yaml` with `type:` and `config:` fields:

```yaml
datastore:
type: "@myorg/my-store"
config:
endpoint: "https://storage.example.com"
bucket: "my-data"
```

Or via environment variable (JSON config after the type):
After releasing a stuck lock, verify it cleared:

```bash
export SWAMP_DATASTORE='@myorg/my-store:{"endpoint":"https://storage.example.com","bucket":"my-data"}'
swamp datastore lock status --json # Should return null
```

For creating custom datastore implementations, see the `swamp-extension` skill.

### Custom Drivers

Custom execution drivers control where and how model methods run (SSH, Lambda,
Kubernetes, etc.). Drivers are configured per-definition, per-workflow, or
per-step via the `driver:` and `driverConfig:` YAML fields.

For creating custom driver implementations, see the `swamp-extension` skill.
See [references/troubleshooting.md](references/troubleshooting.md) for lock
internals and which commands acquire vs skip the lock.

### Environment Variable Override

Expand All @@ -350,6 +296,8 @@ export SWAMP_DATASTORE=filesystem:/tmp/swamp-data
export SWAMP_DATASTORE='@myorg/my-store:{"key":"val"}'
```

For custom datastore or driver implementations, see the `swamp-extension` skill.

## Extension Sources

Load extensions from external filesystem paths without copying files. Use this
Expand Down Expand Up @@ -410,7 +358,11 @@ swamp extension source rm "~/code/swamp-extensions/model/aws/*"

`swamp extension source add` fails with a clear error if the path contributes no
extensions, so misconfigured paths are caught at add time rather than silently
ignored.
ignored. After adding, verify the source loaded:

```bash
swamp extension source list --json # Confirm the new source appears
```

### Load Order

Expand Down
37 changes: 37 additions & 0 deletions .claude/skills/swamp-repo/references/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,40 @@ cp -r extensions.backup/* extensions/

**Note**: This loses all model data and workflow history. Only use as last
resort.

## Lock Internals

Write commands (create, edit, delete, run, gc) acquire the lock via
`requireInitializedRepo()`. Read-only commands (search, get, list, validate,
history) use `requireInitializedRepoReadOnly()` which skips the lock, allowing
them to run concurrently with write operations.

**Lock status output shape:**

```json
{
"holder": "user@hostname",
"hostname": "hostname",
"pid": 12345,
"acquiredAt": "2026-03-10T12:00:00.000Z",
"ttlMs": 30000
}
```

Returns `null` if no lock is held.

## Extension Datastore --skip-migration

`--skip-migration` on `swamp datastore setup extension` skips only the
local→remote push; the remote→local hydration step still runs, so a fresh
contributor can opt out of pushing their `.swamp/` without ending up with an
empty cache. Legacy type name `s3` is auto-remapped to `@swamp/s3-datastore`.

## Legacy Extension Layout Migration

If `swamp repo upgrade` detects extensions tracked at a legacy on-disk layout
(`extensions/<type>/…` or `.swamp/pulled-extensions/<type>/…`), it re-pulls each
one into the current per-extension subtree
(`.swamp/pulled-extensions/<ext-name>/<type>/…`) and sweeps the old files
automatically. This step requires registry access; on failure, the legacy files
are preserved and the error names the affected extensions.
Loading