Skip to content

Commit e106201

Browse files
authored
Merge pull request #366 from sgbett/feat/358-per-gem-specs
refactor: move specs into per-gem directories
2 parents d34f4dc + 0ec11a4 commit e106201

File tree

196 files changed

+645
-87
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

196 files changed

+645
-87
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Plan: `/release` Skill for Gem Releases
2+
3+
**Issue:** #304
4+
**Previous release pain:** Missing v0.5.0 tag, building from wrong directory, manual changelog
5+
6+
---
7+
8+
## Gem Registry
9+
10+
| Key | Gem name | Version file | Tag prefix | Downstream deps |
11+
|-----|----------|-------------|------------|-----------------|
12+
| `sdk` | `bsv-sdk` | `gem/bsv-sdk/lib/bsv/version.rb` | `v` | `bsv-wallet`, `bsv-attest` |
13+
| `wallet` | `bsv-wallet` | `gem/bsv-wallet/lib/bsv/wallet_interface/version.rb` | `wallet-v` | `bsv-wallet-postgres` |
14+
| `wallet-postgres` | `bsv-wallet-postgres` | `gem/bsv-wallet-postgres/lib/bsv/wallet_postgres/version.rb` | `wallet-postgres-v` | none |
15+
| `attest` | `bsv-attest` | `gem/bsv-attest/lib/bsv/attest/version.rb` | `attest-v` | none |
16+
17+
Dependency chain: `bsv-sdk → bsv-wallet → bsv-wallet-postgres`
18+
19+
---
20+
21+
## Release Flow (16 steps)
22+
23+
### Step 0: Hard refusal
24+
Refuse if user requests releasing multiple gems at once. One at a time only.
25+
26+
### Step 1: Pre-flight checks
27+
- Dirty working tree → abort
28+
- Not on master → abort
29+
- Local master behind origin → abort
30+
31+
### Step 2: Select gem
32+
From `$ARGUMENTS` or prompt user. Show current versions.
33+
34+
### Step 3: Already-released checks
35+
- Version already tagged locally → abort
36+
- Version already on RubyGems (`gem search --remote --exact`) → abort
37+
38+
### Step 4: Choose version bump
39+
- Gather commits since last tag scoped to `gem/<dir>/`
40+
- Suggest bump based on conventional commits (`feat!:` → major, `feat:` → minor, else → patch)
41+
- User confirms or overrides
42+
43+
### Step 5: Downstream dependency check
44+
Only for gems with downstream dependents (sdk, wallet).
45+
46+
**Part A — Dependency floor check:**
47+
Read downstream gemspec, check `add_dependency` floor version. Soft warning if floor < new version.
48+
49+
**Part B — Interface compliance check (wallet only):**
50+
- Extract `def method_name` from `StorageAdapter` (methods raising `NotImplementedError`)
51+
- Extract `def method_name` from each downstream adapter (all `.rb` files in `lib/`)
52+
- Report any gaps. Default to abort; user can override.
53+
54+
### Step 6: Generate changelog draft
55+
- `git log <last_tag>..HEAD -- gem/<dir>/` grouped by conventional commit type
56+
- Map to Keep a Changelog sections (Added, Fixed, Changed, Breaking, Security)
57+
- British English throughout
58+
- Display for user review/edit
59+
60+
### Step 7: Bump version.rb
61+
Simple string replacement of `VERSION = 'x.y.z'` line.
62+
63+
### Step 8: Update CHANGELOG.md
64+
Prepend new section after the header, before the first existing `## X.Y.Z` entry.
65+
66+
### Step 9: Commit
67+
```
68+
git add gem/<dir>/lib/.../version.rb gem/<dir>/CHANGELOG.md
69+
git commit -m "chore: release <gem-name> v<version>"
70+
```
71+
72+
### Step 10: Tag
73+
`git tag <prefix><version>` using gem's prefix convention.
74+
75+
### Step 11: Push to master (with confirmation)
76+
```
77+
git push origin master
78+
git push origin <tag>
79+
```
80+
81+
### Step 12: Build gem
82+
`cd gem/<dir> && gem build <name>.gemspec` (must build from inside gem directory).
83+
84+
### Step 13: Sanity check
85+
Inspect `.gem` contents — verify `lib/`, `CHANGELOG.md`, `LICENSE` present, no unexpected files.
86+
87+
### Step 14: Prompt user to push to RubyGems
88+
Skill cannot push — credentials are manual. Display the command and wait for confirmation.
89+
90+
### Step 15: Create GitHub release
91+
```
92+
gh release create <tag> --title "<gem-name> <version>" --notes "<changelog>" --target master
93+
gh release upload <tag> gem/<dir>/<gem-name>-<version>.gem
94+
```
95+
96+
### Step 16: Summary
97+
Table with gem, version, tag, commit, RubyGems link, GitHub release link, next steps.
98+
99+
---
100+
101+
## Error Handling
102+
103+
**Hard aborts:** dirty tree, wrong branch, behind origin, already tagged, already on RubyGems, user declines confirmation.
104+
105+
**Soft warnings:** downstream floor not raised, interface compliance failure (default abort, overridable), sanity check anomalies, GitHub release creation failure.
106+
107+
**Recovery guidance:** at every abort, explain what state the release is in and how to continue or roll back.
108+
109+
---
110+
111+
## Rakefile Cleanup
112+
113+
Remove all four `Bundler::GemHelper.install_tasks` lines. The `/release` skill replaces the entire `release[remote]` workflow. Keep `rspec` and `docs:` tasks. Add comment directing to `/release`.
114+
115+
---
116+
117+
## CLAUDE.md Updates
118+
119+
- Update "Releasing Companion Gems" section to reference `/release` as canonical mechanism
120+
- Document tag prefix conventions for all four gems
121+
- Fix the `gem build` example in Commands section (currently references old path)
122+
123+
---
124+
125+
## Task Breakdown
126+
127+
1. **Create `.claude/commands/release.md`** — the skill file with full flow
128+
2. **Clean up Rakefile** — remove unsafe `install_tasks`, add comment
129+
3. **Update CLAUDE.md** — releasing docs, tag conventions, fix build example
130+
4. **Manual verification** — dry-run `/release` to test the flow
131+
132+
---
133+
134+
## Risks
135+
136+
| Risk | Mitigation |
137+
|------|-----------|
138+
| `gem search --remote` slow/unavailable | Timeout + soft warning |
139+
| `gh` CLI not authenticated | Check `gh auth status` in pre-flight |
140+
| No previous tag for a gem (e.g. attest) | Use earliest commit touching `gem/<dir>/` |
141+
| Interface check false positives (mixins) | Scan all `.rb` files in downstream `lib/` |
142+
| New gems added to monorepo | Update gem registry in skill file |
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Cross-SDK Compliance Review
2+
3+
## Problem
4+
5+
During development of the ruby SDK there was a period of time where /effort medium was the default setting.
6+
7+
### Manifestation
8+
9+
The consequences of insufficient effort are several issues that seemed to be due to a lack of rigour when analysing/re-implementing functionality that already exists in the typescript implementation; not recognising *why* some things were done a particular way. Of particular note 3 issues in https://github.com/sgbett/bsv-ruby-sdk/issues/305
10+
11+
The ruby SDK suffered from a systemic issue where we had been able to engineer code that passes all the tests but didn't quite implement the
12+
desired functionality correctly. We created an SDK that follows "the letter" of the tests, rather than "the spirit" of the specification.
13+
14+
The swift implementation may also have been impacted by the use of /effort medium.
15+
16+
### Solution: The Thirty-Five.
17+
18+
I'd like you to orchestrate a team of agents that is composed of 10 project-level agents, and 8 triumvirates. One triumvirate for each of the 8 phases articulated in the plan /opt/xcode/bsv-sdk/.claude/plans/20260404-swift-bsv-sdk.md - each of these phases broadly scopes an area of concern in the code to focus on. Areas of overlap should be considered carefully as these boundaries likely correspond to the principle of "separation of concerns" we should try to ensure that there are clean lines such that each of the 8 phases cover different areas of the codebase with little to no overlap, A final agent should run alongside and independently audit which triumvirate covered which sections of code to establish any gaps or significant areas of overlap that may warrant refactoring. The triumvirate agents should answer any questions the auditor has, without interference from the project-level agents.
19+
20+
This makes a total of 10 + (8 * 3) + 1 = 35 agents.
21+
22+
## Project Level: 1 x 10 agents
23+
24+
10 "project-level" members based on the specialist definitions in the .architecture/members.yml file these agents are tasked with analysis of the findings reported by the triumverates.
25+
26+
### Findings Analysis
27+
28+
For each finding the 10 project-level team agents should deliberate on what action, if any, should be taken.
29+
30+
The level of agreement determines how the finding should be handled:
31+
32+
* <7 AGREE = SEVERE AMBIGUITY ‼️ - Isolate for seperate examination
33+
* >7 AGREE = STRONG AGREE ✅ - Recommend action / No-Action, note disagreements
34+
* ALL AGREE = UNILATERAL - Recommend action / No-Action
35+
36+
Where action is recommended this should be clearly documented as:
37+
* Problem
38+
* Proposed Solution
39+
* Implementation Details
40+
* Acceptance Crtieria
41+
42+
Where no action is recommended this should be clearly documented as:
43+
* Potential Issue
44+
* Reason for no-action
45+
46+
Where ambiguity exists this should be clearly documented as:
47+
* Potential issues
48+
* Reasons for action
49+
* Reasons against action
50+
* Areas for further exploration
51+
52+
## Triumverates: 8 x 3 agents
53+
54+
For each of the 8 phases there should be a 3 agents with combined responsibility as triumvirate, to validate alignment of our implementation with (in order of precedence):
55+
* the typescript implementation
56+
* corresponding BRC's
57+
* other reference implementation
58+
* any other documentation, specification discovered ad-hoc that may be relevant
59+
60+
Each triumverate should draw out areas where our deviation may have introduced subtle bugs or incompatibilities. Each "Finding" should be assessed by the project level agents as a group to validate it and confirm the actions to be taken.
61+
62+
### Agent Roles
63+
64+
Within each triumvirate each agent has a specific focus:
65+
66+
#### Agent #phase-#1-dev - A developer, ruby & typescript expert, master of implementation.
67+
This agent should focus on qualitative difference in implementation between ruby and ts (using go/python as secondary sources) identifying code that needs to be changed and why.
68+
69+
#### Agent #phase-#2-docs - A domain specialist, detail focused, thorough.
70+
Conduct a deep dive on the documentation and available specifications, seeking out supplementary material on the internet for clarification if needed. The BRC's should be considered authoritative, any other documentation (e.g. in the ts-sdk, or published by the BSVA in their reference docs etc) used to corroborate. This agent should be able to answer any questions any other agent might have on implementation details.
71+
72+
#### Agent #phase-#3-truth - A mediator, logician, a seeker of truth.
73+
Cross-checks the other two agents work, offering alternative viewpoints, identifying ambiguity between implementation and documentation and surfacing issues. This agent may identify tension or ambiguity that exists in the reference material itself that could lead to misinterpretation - this should be raised as a point of critical concern for resolution before any attempt to resolve.
74+
75+
### The Auditor
76+
Meticulous, relentless
77+
By the end of the excercise, this guy knows **exactly** who is responsible for every bit of code.
78+
79+
#### Coverage Flags
80+
The auditor is seeking to ensure we have cood **Compliance** coverage. This could be considered analagous to test coverage.
81+
82+
**Complaince** is achevied when a triumverates gives attention to the inner workings of "func" calls, particularly where they are checking that this matches the reference implementation, analysis of why code works the way it does.
83+
**Usage** is when a triumverate looks at code because it needs to now how to use it, what results to expect, but is not concnered with how those results are obtained, or where concern for that is tangential to the momentary anlaysis.
84+
**Overlap** is where more than one triumverate is looking at code for **Compliance** purposes. **Usage** does not trigger overlap.
85+
**Gaps** is where no single triumverate looks at code for **Compliance**. **Usage** does not obiate gaps.
86+
87+
Both **Overlap** or **Gaps** may be indicative of an underlying design issue with regards scoping concern, and warrant seperate investigation.
88+
89+
#### Compliance Coverage
90+
The auditor should produce their own supplementary report on coverage across the codebase. A high level summary using a traffic light system, three percentage values:
91+
92+
* GREEN: % Compliance
93+
* YELLOW: % Overlap
94+
*RED: % Gaps
95+
96+
A very breif summary of Compliance, a single paragraph with key areas covered, followed by detailed sections for each logical cluster of overlap and/or gaps.
97+
98+
The auditor doeas not need validation from the project-level team, their findings should not be veto's they are an independant auditor.
99+
100+
## Summary
101+
102+
Orchestrate as a single team. All agents *can* confer if necessary, but *should* remain focused primilary on their area of concern, within their defined role. 80/20 rules.
103+
104+
This is a complex task, allow all the agents max effort.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
bundler-cache: true
4141

4242
- name: Run specs
43-
run: bundle exec rspec
43+
run: bundle exec rake
4444
env:
4545
COVERAGE: ${{ matrix.ruby-version == '3.4' && 'true' || '' }}
4646
DATABASE_URL: postgres://postgres:postgres@localhost:5432/bsv_wallet_test

.rspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
--require spec_helper
21
--format documentation
32
--colour

0 commit comments

Comments
 (0)