Skip to content

Commit 50003d2

Browse files
committed
release: align subtree and tag guidance
Why: - Add a socket-specific subtrees release mode aligned with maintain-project-repo standard flow. - Keep SpeakSwiftlyServer pull-only from socket while allowing apple-dev-skills push-out sync. - Move generated maintain-project-repo standard tags after CI and review-comment gates. Verification: - sh -n plugins/productivity-skills/skills/maintain-project-repo/assets/repo-maintenance/release.sh - uv run pytest - uv run scripts/validate_socket_metadata.py
1 parent 412d90c commit 50003d2

11 files changed

Lines changed: 170 additions & 30 deletions

File tree

AGENTS.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Use this file for durable repo-local guidance that Codex should follow before ch
1313

1414
### Where To Look First
1515

16-
- Start with [README.md](./README.md), [CONTRIBUTING.md](./CONTRIBUTING.md), [ROADMAP.md](./ROADMAP.md), and [`docs/maintainers/subtree-workflow.md`](./docs/maintainers/subtree-workflow.md).
16+
- Start with [README.md](./README.md), [CONTRIBUTING.md](./CONTRIBUTING.md), [ROADMAP.md](./ROADMAP.md), [`docs/maintainers/subtree-workflow.md`](./docs/maintainers/subtree-workflow.md), and [`docs/maintainers/release-modes.md`](./docs/maintainers/release-modes.md).
1717
- Use [`docs/maintainers/plugin-packaging-strategy.md`](./docs/maintainers/plugin-packaging-strategy.md) when the question is about the root marketplace or the independent-plugin packaging stance.
1818
- When a task is really about one child repo's own behavior, read that child repo's docs before reading broadly across the superproject.
1919

@@ -27,12 +27,14 @@ Use this file for durable repo-local guidance that Codex should follow before ch
2727
- Prefer small, focused commits over broad mixed changes.
2828
- For ordinary fixes in monorepo-owned child directories, edit the relevant copy under `plugins/` directly in `socket`.
2929
- For `apple-dev-skills` and `SpeakSwiftlyServer`, keep subtree sync operations explicit and isolated from unrelated edits.
30+
- Treat `plugins/SpeakSwiftlyServer` as a downstream mirror of the standalone SpeakSwiftlyServer checkout. Build, validate, tag, release, and live-refresh SpeakSwiftlyServer from its own checkout, then subtree-pull the merged child state into `socket`; do not subtree-push SpeakSwiftlyServer changes from `socket` unless Gale explicitly overrides that one-off rule.
3031
- When a child repo gains, removes, or moves plugin packaging, update [`.agents/plugins/marketplace.json`](./.agents/plugins/marketplace.json), [README.md](./README.md), and the root maintainer docs in the same pass.
3132

3233
### Subtree Sync And Branch Accounting Gates
3334

3435
- Treat subtree sync completion and branch accounting as hard gates, not follow-up cleanup.
3536
- Before claiming a subtree-managed task is done, verify whether the corresponding child-repo work also needs an explicit `git subtree pull` or `git subtree push` in `socket`, and either perform that sync or say plainly why no sync is required.
37+
- In `subtrees` release mode, treat `socket` like a standard protected-main release: validate, branch or PR when needed, clear CI and PR comments before tagging, merge to `main`, fast-forward local `main`, tag the superproject from reviewed `main`, push the tag, create the GitHub release, and only add the subtree accounting gates that determine whether each child repo needs pull-only sync, push-out sync, or no subtree action.
3638
- Before claiming a release, publish, merge, or cleanup step is done, enumerate every local branch that is still not contained by local `main` and account for each one explicitly as one of: already preserved elsewhere, intentionally still in progress, newly archived, newly merged, or safe to delete.
3739
- Do not say work is "on main", "merged", "recovered", "preserved", or "safe to clean up" until commit reachability has been verified in the exact repository and remote that statement refers to.
3840
- Do not delete local branches, remote branches, worktrees, archive refs, or temporary rescue refs until the branch-accounting pass has been completed and any non-`main` history is either merged or preserved on an explicit archive ref.
@@ -85,10 +87,9 @@ uv run scripts/validate_socket_metadata.py
8587
git subtree pull --prefix=plugins/apple-dev-skills apple-dev-skills main
8688
git subtree push --prefix=plugins/apple-dev-skills apple-dev-skills main
8789
git subtree pull --prefix=plugins/SpeakSwiftlyServer speak-swiftly-server main
88-
git subtree push --prefix=plugins/SpeakSwiftlyServer speak-swiftly-server main
8990
```
9091

91-
Use these commands only when the work is intentionally publishing or syncing one of the remaining subtree-managed child repos.
92+
Use these commands only when the work is intentionally publishing or syncing one of the remaining subtree-managed child repos. `SpeakSwiftlyServer` is intentionally pull-only from `socket` by default.
9293

9394
### Shared Version Workflow
9495

@@ -104,6 +105,8 @@ scripts/release.sh custom 1.2.3
104105

105106
`patch`, `minor`, and `major` assume every maintained version surface already shares one common semantic version. If versions are split, align them first with `custom <x.y.z>`.
106107

108+
For full release sequencing, use [`docs/maintainers/release-modes.md`](./docs/maintainers/release-modes.md). Use `standard` when only the `socket` superproject changes. Use `subtrees` when the release also needs subtree pull/push accounting.
109+
107110
## Review and Delivery
108111

109112
### Review Expectations

CONTRIBUTING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ If the change is really about one child repository's own skills, packaging, test
3737

3838
### Making Changes
3939

40-
Keep changes bounded to one coherent root concern at a time, such as docs-only root alignment, marketplace-path or manifest-alignment fixes, root validation improvements, or root subtree-workflow documentation updates. For ordinary work in monorepo-owned child directories, edit the copy in the relevant directory under `plugins/` directly from this checkout. For `apple-dev-skills` and `SpeakSwiftlyServer`, keep subtree pull and push operations explicit and separate from unrelated edits.
40+
Keep changes bounded to one coherent root concern at a time, such as docs-only root alignment, marketplace-path or manifest-alignment fixes, root validation improvements, or root subtree-workflow documentation updates. For ordinary work in monorepo-owned child directories, edit the copy in the relevant directory under `plugins/` directly from this checkout. For `apple-dev-skills`, keep subtree pull and push operations explicit and separate from unrelated edits. For `SpeakSwiftlyServer`, treat `socket` as a pull-only mirror of the standalone release checkout unless maintainers explicitly approve a one-off push from `socket`.
4141

4242
### Asking For Review
4343

@@ -118,6 +118,8 @@ scripts/release.sh major
118118
scripts/release.sh custom 1.2.3
119119
```
120120

121+
Use the release modes in [`docs/maintainers/release-modes.md`](./docs/maintainers/release-modes.md) when preparing the actual release. Use `standard` for root-only releases and `subtrees` when a release also needs subtree pull/push accounting.
122+
121123
If the changed surface also introduces or expands Python-backed repo checks, add the required tools to the repo-local `uv` dev group and document the corresponding `uv run pytest`, `uv run ruff check .`, and `uv run mypy .` commands where that repo's contributors will actually look.
122124

123125
When editing docs, also review the rendered Markdown structure and cross-links for the files you changed.

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Only `apple-dev-skills` and `SpeakSwiftlyServer` still use subtree sync workflow
7878

7979
Treat Gale's local `socket` checkout as the normal day-to-day checkout on `main`. Work in the monorepo copy first, and use the relevant directory under [`plugins/`](./plugins/) for child-repository changes unless the task is explicitly about the root marketplace or root maintainer docs. Reach for a feature branch or a dedicated worktree only when the change needs extra isolation.
8080

81-
Keep root docs and marketplace wiring in sync with packaging changes in the same pass. For monorepo-owned child directories, edit the relevant directory under [`plugins/`](./plugins/) directly and commit in `socket`. For `apple-dev-skills` and `SpeakSwiftlyServer`, keep subtree sync operations explicit and isolated. When a coordinated versioning pass bumps maintained child versions, update the child repo metadata in `socket` and keep the corresponding child docs aligned at the same time.
81+
Keep root docs and marketplace wiring in sync with packaging changes in the same pass. For monorepo-owned child directories, edit the relevant directory under [`plugins/`](./plugins/) directly and commit in `socket`. For `apple-dev-skills` and `SpeakSwiftlyServer`, keep subtree sync operations explicit and isolated. `SpeakSwiftlyServer` is pull-only from `socket` by default: release and validate it in its standalone checkout, then pull the released state down here.
8282

8383
### Shared Versioning
8484

@@ -96,6 +96,8 @@ scripts/release.sh custom 1.2.3
9696

9797
Use [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the maintainer workflow boundary and [`ROADMAP.md`](./ROADMAP.md) for root planning and historical notes.
9898

99+
Use [`docs/maintainers/release-modes.md`](./docs/maintainers/release-modes.md) for the full release flow. `standard` is the normal `socket` release mode; `subtrees` is the standard mode plus explicit pull/push accounting for subtree-managed children.
100+
99101
### Validation
100102

101103
The current root validation surface is structural:
@@ -126,6 +128,7 @@ When a child repository or helper surface grows Python-backed validation beyond
126128
├── docs/
127129
│ └── maintainers/
128130
│ ├── plugin-packaging-strategy.md
131+
│ ├── release-modes.md
129132
│ └── subtree-workflow.md
130133
├── plugins/
131134
├── scripts/
@@ -153,13 +156,15 @@ The root superproject docs are:
153156
- [ROADMAP.md](./ROADMAP.md) for root planning and milestone tracking
154157
- [ACCESSIBILITY.md](./ACCESSIBILITY.md) for the root accessibility contract around docs, metadata, and maintainer automation
155158
- [`docs/maintainers/`](./docs/maintainers/) for the deeper maintainer references behind the mixed-monorepo and subtree model
159+
- [`docs/maintainers/release-modes.md`](./docs/maintainers/release-modes.md) for the `standard` and `subtrees` release modes
156160

157161
## Plugin Surfaces
158162

159163
Treat `socket` as the canonical home for the monorepo-owned child directories and as the subtree host for the remaining imported child repos.
160164

161165
- `agent-plugin-skills`, `cardhop-app`, `dotnet-skills`, `productivity-skills`, `rust-skills`, `spotify`, `things-app`, and `web-dev-skills` are monorepo-owned here.
162166
- `apple-dev-skills` and `SpeakSwiftlyServer` preserve explicit subtree sync paths.
167+
- `SpeakSwiftlyServer` is synchronized into `socket` by subtree pull after the standalone child release lands; do not subtree-push it from `socket` unless Gale explicitly asks for that exception.
163168
- `python-skills` is monorepo-owned here with no separate upstream GitHub release target.
164169
- Child repos may expose plugin packaging from their own repo roots whether they are monorepo-owned here or still preserve subtree sync.
165170
- `apple-dev-skills` packages from its child-repo root at `./plugins/apple-dev-skills`, and its Codex plugin manifest registers Xcode's built-in MCP bridge through a root `.mcp.json`.

ROADMAP.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
## Milestone Progress
2424

25-
- Milestone 2: subtree workflow hardening - Planned
25+
- Milestone 2: subtree workflow hardening - In Progress
2626
- Milestone 3: release and sync discipline - In Progress
2727

2828
## Milestone 2: subtree workflow hardening
@@ -34,28 +34,29 @@ In Progress
3434
### Scope
3535

3636
- [ ] Tighten the documented subtree add, pull, and push workflows without changing the child-repo ownership model.
37+
- [x] Define `standard` and `subtrees` release modes so umbrella releases follow the `maintain-project-repo` protected-main shape with subtree-specific accounting.
3738

3839
### Tickets
3940

40-
- [ ] Review subtree workflow docs against the current import and publish path.
41+
- [x] Review subtree workflow docs against the current import and publish path.
4142

4243
### Exit Criteria
4344

44-
- [ ] Root maintainer workflow docs describe the actual subtree sync path without stale or duplicate guidance.
45+
- [x] Root maintainer workflow docs describe the actual subtree sync path without stale or duplicate guidance.
4546

4647
## Milestone 3: release and sync discipline
4748

4849
### Status
4950

50-
Planned
51+
In Progress
5152

5253
### Scope
5354

5455
- [ ] Keep root release and synchronization guidance explicit when superproject-level changes ship.
5556

5657
### Tickets
5758

58-
- [ ] Document the expected root release and sync rhythm once the current subtree migration experiment stabilizes.
59+
- [x] Document the expected root release and sync rhythm once the current subtree migration experiment stabilizes.
5960
- [ ] Keep the root docs aligned with the current child packaging model during coordinated release-prep passes.
6061
- [x] Make coordinated semantic-version bumps across `socket` and the maintained child manifests explicit instead of relying on ad hoc release notes.
6162

@@ -71,6 +72,7 @@ Planned
7172

7273
## History
7374

75+
- Added explicit `standard` and `subtrees` release-mode guidance, including the pull-only `SpeakSwiftlyServer` rule for `socket` subtree sync.
7476
- Prepared the shared `v6.0.11` patch release after fixing `productivity-skills:maintain-project-repo` release-helper regressions for initial PR check discovery and approval-only review handling.
7577
- Added the placeholder `plugins/spotify` child repository, wired it into the root marketplace, and kept the superproject docs honest about that new monorepo-owned plugin surface.
7678
- Converted the former standalone `cardhop-mcp` checkout into the monorepo-owned `plugins/cardhop-app` child, added first-pass Codex plugin metadata plus a bundled MCP config, and recorded the new child as a normal `socket` marketplace entry.

docs/maintainers/release-modes.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Release Modes
2+
3+
This document names the release modes used by `socket` so maintainer work follows the same local-first shape as `productivity-skills:maintain-project-repo` while still respecting `socket`'s mixed monorepo and subtree responsibilities.
4+
5+
## Mode Summary
6+
7+
Use `standard` when the release belongs only to the `socket` superproject. Use `subtrees` when the release also needs explicit accounting for subtree-managed child repositories.
8+
9+
Both modes treat `socket` as the release owner for the umbrella repository:
10+
11+
1. make the intended commits
12+
2. validate the changed surface
13+
3. publish through a branch and pull request when the change is not already on `main`
14+
4. check CI and fix failures before continuing
15+
5. check PR comments and requested changes before continuing
16+
6. merge to `main`
17+
7. fast-forward local `main`
18+
8. create the `socket` tag locally from the reviewed `main`
19+
9. push the tag
20+
10. create the GitHub release from the existing tag
21+
11. verify `git log origin/main..main` is empty
22+
12. account for every local branch not contained by `main`
23+
24+
The difference is that `subtrees` adds a child-repository sync gate before tagging or before claiming the release is done.
25+
26+
## Standard Mode
27+
28+
Use `standard` for root docs, root marketplace metadata, root validation scripts, monorepo-owned child directories, and shared version bumps that do not need child-repository subtree synchronization.
29+
30+
Standard mode should feel like the protected-main flow from `maintain-project-repo`: changes land through the normal `socket` branch or local-main path, CI and review comments are cleared before tagging, local `main` is fast-forwarded after merge, and the tag is created from the reviewed `main` commit.
31+
32+
The root version helper remains a version-surface tool, not the full release driver:
33+
34+
```bash
35+
scripts/release.sh inventory
36+
scripts/release.sh patch
37+
scripts/release.sh minor
38+
scripts/release.sh major
39+
scripts/release.sh custom 1.2.3
40+
```
41+
42+
After a version bump lands on `main`, create the matching `vX.Y.Z` tag from `main`, push it, and create the GitHub release with `gh release create --verify-tag`.
43+
44+
## Subtrees Mode
45+
46+
Use `subtrees` when a `socket` release also changes, imports, refreshes, or depends on one of the remaining subtree-managed child repositories.
47+
48+
Subtrees mode is standard mode plus this extra gate:
49+
50+
1. identify each subtree-managed child touched by the release
51+
2. classify each touched child as `pull-only`, `push-out`, or `no subtree action`
52+
3. run the required subtree pull or push before tagging `socket`, or record why no subtree action is correct
53+
4. rerun root validation after any subtree operation
54+
5. re-check `git log origin/main..main` and `git branch --no-merged main` before cleanup or final status
55+
56+
This mode is not the same as `maintain-project-repo`'s `submodule` mode. `socket` is still the umbrella repository being released, not a child checkout waiting for a parent pointer update.
57+
58+
## Current Subtree Policy
59+
60+
| Child | Prefix | Remote | Direction | Rule |
61+
| --- | --- | --- | --- | --- |
62+
| `apple-dev-skills` | `plugins/apple-dev-skills` | `apple-dev-skills` | pull and push | Work may start in `socket`; push back with `git subtree push` when the child repo should receive the socket-authored change. |
63+
| `SpeakSwiftlyServer` | `plugins/SpeakSwiftlyServer` | `speak-swiftly-server` | pull-only | Build, validate, tag, release, and live-refresh in the standalone SpeakSwiftlyServer checkout, then pull the merged child state into `socket`. Do not subtree-push SpeakSwiftlyServer from `socket` unless Gale explicitly overrides this rule. |
64+
65+
## Subtrees Mode Checklist
66+
67+
Before opening or merging the `socket` release PR:
68+
69+
- verify which subtree-managed children are touched
70+
- for `SpeakSwiftlyServer`, verify the standalone checkout already owns the child release or say plainly that the socket sync is intentionally deferred
71+
- for `apple-dev-skills`, decide whether the socket commit must be pushed back to the child remote before the umbrella release
72+
- keep subtree sync commits isolated from unrelated docs, marketplace, or version-bump commits
73+
74+
Before tagging `socket`:
75+
76+
- confirm the subtree policy table above was followed
77+
- run `uv run scripts/validate_socket_metadata.py`
78+
- confirm local `main` is fast-forwarded to `origin/main`
79+
- confirm `git log origin/main..main` is empty
80+
- enumerate every local branch not contained by `main` and account for each one
81+
82+
After tagging:
83+
84+
- push the `socket` tag
85+
- create the GitHub release from the existing tag
86+
- verify the release object exists on GitHub
87+
- if a child release landed outside `socket`, verify `socket` either contains that child state or explicitly records why the sync is deferred

0 commit comments

Comments
 (0)