Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5e0f038
Add spec for retry strategy
bitc0der May 24, 2026
5752171
Simplify spec for retry
bitc0der May 24, 2026
5b4e5dc
Fix the spec with retry loop
bitc0der May 24, 2026
2099fec
Implement retry for pg listen
bitc0der May 24, 2026
724ec0f
Implement postgres listen retry
bitc0der May 24, 2026
e52ec72
Simplify postgres listener
bitc0der May 24, 2026
208de16
Implement Kafka and RMQ retry
bitc0der May 24, 2026
ddb0498
Simplify publisher
bitc0der May 24, 2026
ad4119f
Update docs with retry
bitc0der May 24, 2026
7d503be
Add Postgres and RMQ tests
bitc0der May 24, 2026
57c5a65
Add Kafka retry tests
bitc0der May 24, 2026
caa26c7
Fix on review
bitc0der May 24, 2026
b22fec3
Avoid Task.Delay
bitc0der May 24, 2026
bc08818
Archive retry spec
bitc0der May 24, 2026
fa54c8f
Simplify OutboxPublisherService.cs
bitc0der May 24, 2026
78a33a4
Bump version
bitc0der May 24, 2026
9396c97
Update CHANGELOG.md
bitc0der May 24, 2026
84ecdf6
Merge pull request #24 from bitc0der/retry
bitc0der May 24, 2026
783b8e1
Compress CHANGELOG.md
bitc0der May 24, 2026
ec63164
Add recovery config spec
bitc0der Jun 2, 2026
71051c0
Add cleanup metric spec
bitc0der Jun 2, 2026
3ceb25d
Update OpenSpec env
bitc0der Jun 2, 2026
8dad082
Cleanup
bitc0der Jun 2, 2026
66d3201
Implement per-plugin recovery options conf
bitc0der Jun 2, 2026
ff4973b
Bump
bitc0der Jun 2, 2026
4cdfea3
Archive the spec
bitc0der Jun 2, 2026
573a8f4
Bump nuget refs
bitc0der Jun 2, 2026
3ea7f63
Merge pull request #25 from bitc0der/recover-per-plugin
bitc0der Jun 2, 2026
f2d68ff
Minor cleanup
bitc0der Jun 2, 2026
79bf2dd
perf(outbox): batch publish acks and cache reflection hot paths
bitc0der Aug 2, 2026
fa7187b
chore(claude): add commit skill for generating conventional commit me…
bitc0der Aug 2, 2026
bb466a2
chore(gemini): remove OpenSpec opsx commands and skills
bitc0der Aug 2, 2026
913b464
perf: fix LZ4 buffer sizing, precompute change-type tags, bound consu…
bitc0der Aug 2, 2026
8e118a5
chore: bump nuget package versions
bitc0der Aug 2, 2026
42554de
docs: add architecture review task list
bitc0der Aug 2, 2026
0077fea
perf(efcore): compile and cache EntityChange factory per entity type
bitc0der Aug 2, 2026
25deaf1
fix(postgresql): wait for in-flight notification tasks before shutdown
bitc0der Aug 2, 2026
d821f23
perf(postgresql): use NpgsqlDataSource instead of connection-per-call
bitc0der Aug 2, 2026
ebdd169
perf(core): parallelize ChangePublisher.InitializeAsync across entity…
bitc0der Aug 2, 2026
9d645e4
perf(efcore): use HashSet for _trackedEntityTypes lookup
bitc0der Aug 2, 2026
0044057
perf(efcore): write outbox rows in parallel per SaveChanges
bitc0der Aug 2, 2026
9387845
perf(core): avoid per-message allocation in ChangeSubscriber dispatch
bitc0der Aug 2, 2026
871d1c6
perf(postgresql): route PostgreSqlRepository through compiled propert…
bitc0der Aug 2, 2026
096f051
perf: replace Enum.Parse<ChangeType> with a switch on 3 hot paths
bitc0der Aug 2, 2026
dfa57e4
perf(lz4): use MemoryStream.GetBuffer() instead of ToArray()
bitc0der Aug 2, 2026
3f57b45
perf(messagepack): use ContractlessStandardResolver instead of Typeless
bitc0der Aug 2, 2026
54e59b3
perf(rabbitmq): avoid ToString().ToLower() in default routing key
bitc0der Aug 2, 2026
28c6e2a
docs: add 0.0.21-pre-release changelog entry
bitc0der Aug 2, 2026
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
5 changes: 4 additions & 1 deletion .agent/skills/openspec-apply-change/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.3.1"
generatedBy: "1.4.0"
---

Implement tasks from an OpenSpec change.
Expand All @@ -30,6 +30,7 @@ Implement tasks from an OpenSpec change.
```
Parse the JSON to understand:
- `schemaName`: The workflow being used (e.g., "spec-driven")
- `planningHome`, `changeRoot`, and `actionContext`: planning scope and edit constraints
- Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)

3. **Get apply instructions**
Expand All @@ -49,6 +50,8 @@ Implement tasks from an OpenSpec change.
- If `state: "all_done"`: congratulate, suggest archive
- Otherwise: proceed to implementation

**Workspace guard:** If status JSON reports `actionContext.mode: "workspace-planning"` and `allowedEditRoots` is empty, explain that full workspace apply is not supported in this slice. Treat linked repos and folders as read-only context, ask the user to select an affected area through an explicit implementation workflow, and STOP before editing files.

4. **Read context files**

Read every file path listed under `contextFiles` from the apply instructions output.
Expand Down
17 changes: 10 additions & 7 deletions .agent/skills/openspec-archive-change/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.3.1"
generatedBy: "1.4.0"
---

Archive a completed change in the experimental workflow.
Expand All @@ -30,8 +30,11 @@ Archive a completed change in the experimental workflow.

Parse the JSON to understand:
- `schemaName`: The workflow being used
- `planningHome`, `changeRoot`, `artifactPaths`, and `actionContext`: path and scope context
- `artifacts`: List of artifacts with their status (`done` or other)

If status reports `actionContext.mode: "workspace-planning"`, explain that workspace archive is not supported in this slice and STOP. Do not move workspace changes into repo-local archives or edit linked repos.

**If any artifacts are not `done`:**
- Display warning listing incomplete artifacts
- Use **AskUserQuestion tool** to confirm user wants to proceed
Expand All @@ -52,7 +55,7 @@ Archive a completed change in the experimental workflow.

4. **Assess delta spec sync state**

Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.
Use `artifactPaths.specs.existingOutputPaths` from status JSON to check for delta specs. If none exist, proceed without sync prompt.

**If delta specs exist:**
- Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`
Expand All @@ -67,19 +70,19 @@ Archive a completed change in the experimental workflow.

5. **Perform the archive**

Create the archive directory if it doesn't exist:
Create an `archive` directory under `planningHome.changesDir` if it doesn't exist:
```bash
mkdir -p openspec/changes/archive
mkdir -p "<planningHome.changesDir>/archive"
```

Generate target name using current date: `YYYY-MM-DD-<change-name>`

**Check if target already exists:**
- If yes: Fail with error, suggest renaming existing archive or using different date
- If no: Move the change directory to archive
- If no: Move `changeRoot` to the archive directory

```bash
mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
mv "<changeRoot>" "<planningHome.changesDir>/archive/YYYY-MM-DD-<name>"
```

6. **Display summary**
Expand All @@ -98,7 +101,7 @@ Archive a completed change in the experimental workflow.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** ✓ Synced to main specs (or "No delta specs" or "Sync skipped")

All artifacts complete. All tasks complete.
Expand Down
11 changes: 5 additions & 6 deletions .agent/skills/openspec-explore/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.3.1"
generatedBy: "1.4.0"
---

Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
Expand Down Expand Up @@ -102,11 +102,10 @@ Think freely. When insights crystallize, you might offer:

If the user mentions a change or you detect one is relevant:

1. **Read existing artifacts for context**
- `openspec/changes/<name>/proposal.md`
- `openspec/changes/<name>/design.md`
- `openspec/changes/<name>/tasks.md`
- etc.
1. **Resolve and read existing artifacts for context**
- Run `openspec status --change "<name>" --json`.
- Use `changeRoot`, `artifactPaths`, and `actionContext` from the status JSON.
- Read existing files from `artifactPaths.<artifact>.existingOutputPaths`.

2. **Reference them naturally in conversation**
- "Your design mentions using Redis, but we just realized SQLite fits better..."
Expand Down
9 changes: 5 additions & 4 deletions .agent/skills/openspec-propose/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ compatibility: Requires openspec CLI.
metadata:
author: openspec
version: "1.0"
generatedBy: "1.3.1"
generatedBy: "1.4.0"
---

Propose a new change - create the change and generate all artifacts in one step.
Expand Down Expand Up @@ -37,7 +37,7 @@ When ready to implement, run /opsx:apply
```bash
openspec new change "<name>"
```
This creates a scaffolded change at `openspec/changes/<name>/` with `.openspec.yaml`.
This creates a scaffolded change in the planning home resolved by the CLI with `.openspec.yaml`.

3. **Get the artifact build order**
```bash
Expand All @@ -46,6 +46,7 @@ When ready to implement, run /opsx:apply
Parse the JSON to get:
- `applyRequires`: array of artifact IDs needed before implementation (e.g., `["tasks"]`)
- `artifacts`: list of all artifacts with their status and dependencies
- `planningHome`, `changeRoot`, `artifactPaths`, and `actionContext`: path and scope context. Use these instead of assuming repo-local paths.

4. **Create artifacts in sequence until apply-ready**

Expand All @@ -63,10 +64,10 @@ When ready to implement, run /opsx:apply
- `rules`: Artifact-specific rules (constraints for you - do NOT include in output)
- `template`: The structure to use for your output file
- `instruction`: Schema-specific guidance for this artifact type
- `outputPath`: Where to write the artifact
- `resolvedOutputPath`: Resolved path or pattern to write the artifact
- `dependencies`: Completed artifacts to read for context
- Read any completed dependency files for context
- Create the artifact file using `template` as the structure
- Create the artifact file using `template` as the structure and write it to `resolvedOutputPath`
- Apply `context` and `rules` as constraints - but do NOT copy them into the file
- Show brief progress: "Created <artifact-id>"

Expand Down
3 changes: 3 additions & 0 deletions .agent/workflows/opsx-apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Implement tasks from an OpenSpec change.
```
Parse the JSON to understand:
- `schemaName`: The workflow being used (e.g., "spec-driven")
- `planningHome`, `changeRoot`, and `actionContext`: planning scope and edit constraints
- Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)

3. **Get apply instructions**
Expand All @@ -42,6 +43,8 @@ Implement tasks from an OpenSpec change.
- If `state: "all_done"`: congratulate, suggest archive
- Otherwise: proceed to implementation

**Workspace guard:** If status JSON reports `actionContext.mode: "workspace-planning"` and `allowedEditRoots` is empty, explain that full workspace apply is not supported in this slice. Treat linked repos and folders as read-only context, ask the user to select an affected area through an explicit implementation workflow, and STOP before editing files.

4. **Read context files**

Read every file path listed under `contextFiles` from the apply instructions output.
Expand Down
21 changes: 12 additions & 9 deletions .agent/workflows/opsx-archive.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ Archive a completed change in the experimental workflow.

Parse the JSON to understand:
- `schemaName`: The workflow being used
- `planningHome`, `changeRoot`, `artifactPaths`, and `actionContext`: path and scope context
- `artifacts`: List of artifacts with their status (`done` or other)

If status reports `actionContext.mode: "workspace-planning"`, explain that workspace archive is not supported in this slice and STOP. Do not move workspace changes into repo-local archives or edit linked repos.

**If any artifacts are not `done`:**
- Display warning listing incomplete artifacts
- Prompt user for confirmation to continue
Expand All @@ -45,7 +48,7 @@ Archive a completed change in the experimental workflow.

4. **Assess delta spec sync state**

Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.
Use `artifactPaths.specs.existingOutputPaths` from status JSON to check for delta specs. If none exist, proceed without sync prompt.

**If delta specs exist:**
- Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`
Expand All @@ -60,19 +63,19 @@ Archive a completed change in the experimental workflow.

5. **Perform the archive**

Create the archive directory if it doesn't exist:
Create an `archive` directory under `planningHome.changesDir` if it doesn't exist:
```bash
mkdir -p openspec/changes/archive
mkdir -p "<planningHome.changesDir>/archive"
```

Generate target name using current date: `YYYY-MM-DD-<change-name>`

**Check if target already exists:**
- If yes: Fail with error, suggest renaming existing archive or using different date
- If no: Move the change directory to archive
- If no: Move `changeRoot` to the archive directory

```bash
mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
mv "<changeRoot>" "<planningHome.changesDir>/archive/YYYY-MM-DD-<name>"
```

6. **Display summary**
Expand All @@ -91,7 +94,7 @@ Archive a completed change in the experimental workflow.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** ✓ Synced to main specs

All artifacts complete. All tasks complete.
Expand All @@ -104,7 +107,7 @@ All artifacts complete. All tasks complete.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** No delta specs

All artifacts complete. All tasks complete.
Expand All @@ -117,7 +120,7 @@ All artifacts complete. All tasks complete.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** Sync skipped (user chose to skip)

**Warnings:**
Expand All @@ -134,7 +137,7 @@ Review the archive if this was not intentional.
## Archive Failed

**Change:** <change-name>
**Target:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Target:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/

Target archive directory already exists.

Expand Down
9 changes: 4 additions & 5 deletions .agent/workflows/opsx-explore.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,10 @@ Think freely. When insights crystallize, you might offer:

If the user mentions a change or you detect one is relevant:

1. **Read existing artifacts for context**
- `openspec/changes/<name>/proposal.md`
- `openspec/changes/<name>/design.md`
- `openspec/changes/<name>/tasks.md`
- etc.
1. **Resolve and read existing artifacts for context**
- Run `openspec status --change "<name>" --json`.
- Use `changeRoot`, `artifactPaths`, and `actionContext` from the status JSON.
- Read existing files from `artifactPaths.<artifact>.existingOutputPaths`.

2. **Reference them naturally in conversation**
- "Your design mentions using Redis, but we just realized SQLite fits better..."
Expand Down
7 changes: 4 additions & 3 deletions .agent/workflows/opsx-propose.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ When ready to implement, run /opsx:apply
```bash
openspec new change "<name>"
```
This creates a scaffolded change at `openspec/changes/<name>/` with `.openspec.yaml`.
This creates a scaffolded change in the planning home resolved by the CLI with `.openspec.yaml`.

3. **Get the artifact build order**
```bash
Expand All @@ -39,6 +39,7 @@ When ready to implement, run /opsx:apply
Parse the JSON to get:
- `applyRequires`: array of artifact IDs needed before implementation (e.g., `["tasks"]`)
- `artifacts`: list of all artifacts with their status and dependencies
- `planningHome`, `changeRoot`, `artifactPaths`, and `actionContext`: path and scope context. Use these instead of assuming repo-local paths.

4. **Create artifacts in sequence until apply-ready**

Expand All @@ -56,10 +57,10 @@ When ready to implement, run /opsx:apply
- `rules`: Artifact-specific rules (constraints for you - do NOT include in output)
- `template`: The structure to use for your output file
- `instruction`: Schema-specific guidance for this artifact type
- `outputPath`: Where to write the artifact
- `resolvedOutputPath`: Resolved path or pattern to write the artifact
- `dependencies`: Completed artifacts to read for context
- Read any completed dependency files for context
- Create the artifact file using `template` as the structure
- Create the artifact file using `template` as the structure and write it to `resolvedOutputPath`
- Apply `context` and `rules` as constraints - but do NOT copy them into the file
- Show brief progress: "Created <artifact-id>"

Expand Down
3 changes: 3 additions & 0 deletions .claude/commands/opsx/apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Implement tasks from an OpenSpec change.
```
Parse the JSON to understand:
- `schemaName`: The workflow being used (e.g., "spec-driven")
- `planningHome`, `changeRoot`, and `actionContext`: planning scope and edit constraints
- Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)

3. **Get apply instructions**
Expand All @@ -45,6 +46,8 @@ Implement tasks from an OpenSpec change.
- If `state: "all_done"`: congratulate, suggest archive
- Otherwise: proceed to implementation

**Workspace guard:** If status JSON reports `actionContext.mode: "workspace-planning"` and `allowedEditRoots` is empty, explain that full workspace apply is not supported in this slice. Treat linked repos and folders as read-only context, ask the user to select an affected area through an explicit implementation workflow, and STOP before editing files.

4. **Read context files**

Read every file path listed under `contextFiles` from the apply instructions output.
Expand Down
21 changes: 12 additions & 9 deletions .claude/commands/opsx/archive.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ Archive a completed change in the experimental workflow.

Parse the JSON to understand:
- `schemaName`: The workflow being used
- `planningHome`, `changeRoot`, `artifactPaths`, and `actionContext`: path and scope context
- `artifacts`: List of artifacts with their status (`done` or other)

If status reports `actionContext.mode: "workspace-planning"`, explain that workspace archive is not supported in this slice and STOP. Do not move workspace changes into repo-local archives or edit linked repos.

**If any artifacts are not `done`:**
- Display warning listing incomplete artifacts
- Prompt user for confirmation to continue
Expand All @@ -48,7 +51,7 @@ Archive a completed change in the experimental workflow.

4. **Assess delta spec sync state**

Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.
Use `artifactPaths.specs.existingOutputPaths` from status JSON to check for delta specs. If none exist, proceed without sync prompt.

**If delta specs exist:**
- Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`
Expand All @@ -63,19 +66,19 @@ Archive a completed change in the experimental workflow.

5. **Perform the archive**

Create the archive directory if it doesn't exist:
Create an `archive` directory under `planningHome.changesDir` if it doesn't exist:
```bash
mkdir -p openspec/changes/archive
mkdir -p "<planningHome.changesDir>/archive"
```

Generate target name using current date: `YYYY-MM-DD-<change-name>`

**Check if target already exists:**
- If yes: Fail with error, suggest renaming existing archive or using different date
- If no: Move the change directory to archive
- If no: Move `changeRoot` to the archive directory

```bash
mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
mv "<changeRoot>" "<planningHome.changesDir>/archive/YYYY-MM-DD-<name>"
```

6. **Display summary**
Expand All @@ -94,7 +97,7 @@ Archive a completed change in the experimental workflow.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** ✓ Synced to main specs

All artifacts complete. All tasks complete.
Expand All @@ -107,7 +110,7 @@ All artifacts complete. All tasks complete.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** No delta specs

All artifacts complete. All tasks complete.
Expand All @@ -120,7 +123,7 @@ All artifacts complete. All tasks complete.

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Archived to:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/
**Specs:** Sync skipped (user chose to skip)

**Warnings:**
Expand All @@ -137,7 +140,7 @@ Review the archive if this was not intentional.
## Archive Failed

**Change:** <change-name>
**Target:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Target:** the archive path derived from `planningHome.changesDir`/YYYY-MM-DD-<name>/

Target archive directory already exists.

Expand Down
Loading
Loading