@softspark/ai-toolkit 4.30.2 → 4.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/README.md +27 -28
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/agents/code-reviewer.md +14 -0
- package/app/agents/frontend-specialist.md +27 -24
- package/app/agents/infrastructure-validator.md +2 -2
- package/app/claude-app/skills/ai-toolkit-rules/SKILL.md +44 -1
- package/app/personas/frontend-lead.md +20 -12
- package/app/rules/claude-toolkit-rules.md +4 -1
- package/app/rules/edit-discipline.md +37 -0
- package/app/skills/app-builder/SKILL.md +37 -6
- package/app/skills/claude-toolkit-rules/SKILL.md +37 -0
- package/app/skills/design-engineering/SKILL.md +87 -102
- package/app/skills/design-engineering/reference/animation-recipes.md +67 -0
- package/app/skills/design-engineering/reference/component-craft.md +28 -0
- package/app/skills/documentation-standards/SKILL.md +1 -1
- package/app/skills/edit-discipline/SKILL.md +50 -0
- package/app/skills/git-conventions/SKILL.md +18 -0
- package/app/skills/output-mode/SKILL.md +41 -0
- package/app/skills/quality-gates/SKILL.md +23 -0
- package/app/skills/review/SKILL.md +10 -0
- package/kb/procedures/{ecosystem-sync-sop.md → sop-ecosystem-sync.md} +2 -2
- package/kb/procedures/{post-release-testing-sop.md → sop-post-release-testing.md} +3 -3
- package/kb/procedures/sop-pre-commit.md +96 -0
- package/kb/procedures/{release-preparation-sop.md → sop-release.md} +87 -26
- package/kb/reference/architecture-overview.md +1 -1
- package/kb/reference/copilot-compatibility.md +1 -1
- package/kb/reference/licensing.md +2 -2
- package/kb/reference/quick-wins-implementation-summary.md +1 -1
- package/kb/reference/supported-tools-registry.md +2 -2
- package/kb/troubleshooting/plugin-double-load.md +1 -1
- package/llms-full.txt +974 -806
- package/llms.txt +6 -5
- package/manifest.json +1 -1
- package/package.json +2 -1
- package/scripts/doctor.py +1 -1
- package/scripts/generate_toolkit_rules_skills.py +189 -0
- package/scripts/validate.py +1 -1
- /package/kb/procedures/{maintenance-sop.md → sop-maintenance.md} +0 -0
- /package/kb/procedures/{release-verification-sop.md → sop-release-verification.md} +0 -0
|
@@ -3,17 +3,17 @@ title: "SOP: Release Preparation"
|
|
|
3
3
|
category: procedures
|
|
4
4
|
service: ai-toolkit
|
|
5
5
|
tags: [sop, release, version, publish, changelog, semver, provenance, sarif, ecosystem, shellcheck]
|
|
6
|
-
version: "1.
|
|
6
|
+
version: "1.15.0"
|
|
7
7
|
created: "2026-04-10"
|
|
8
|
-
last_updated: "2026-
|
|
9
|
-
description: "Step-by-step checklist for preparing a new ai-toolkit release — ecosystem-sync drift check, version sync, changelog, artifact regeneration, validation, and tagging. Run BEFORE every git tag. Includes mandatory Provenance, SARIF,
|
|
8
|
+
last_updated: "2026-09-02"
|
|
9
|
+
description: "Step-by-step checklist for preparing a new ai-toolkit release — ecosystem-sync drift check, version sync, changelog, artifact regeneration, validation, branch CI, and tagging. Run BEFORE every git tag. Includes mandatory Provenance, SARIF, checksum-pin, ShellCheck, licensing, exact-tag assertions, and a green Ubuntu/macOS branch-CI gate before any release tag is created."
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# SOP: Release Preparation
|
|
13
13
|
|
|
14
14
|
Complete checklist for preparing a new `@softspark/ai-toolkit` release.
|
|
15
15
|
Run this **before** tagging. After tagging and publishing, run the
|
|
16
|
-
[Release Verification SOP](release-verification
|
|
16
|
+
[Release Verification SOP](sop-release-verification.md) to smoke-test.
|
|
17
17
|
|
|
18
18
|
**Pipeline:**
|
|
19
19
|
```
|
|
@@ -32,10 +32,10 @@ git tag → CI publish → Release Verification SOP
|
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
# 0. Ecosystem sync (mandatory for minor/major releases; optional for patch)
|
|
35
|
-
# Full procedure: kb/procedures/ecosystem-sync
|
|
35
|
+
# Full procedure: kb/procedures/sop-ecosystem-sync.md
|
|
36
36
|
python3 scripts/ecosystem_doctor.py --format text > /tmp/eco-report.txt
|
|
37
37
|
cat /tmp/eco-report.txt
|
|
38
|
-
# If drift detected: stop here, follow ecosystem-sync
|
|
38
|
+
# If drift detected: stop here, follow sop-ecosystem-sync.md Phase 2-4 to
|
|
39
39
|
# classify each drift (A-F), update generators as needed, refresh snapshot,
|
|
40
40
|
# THEN resume this SOP.
|
|
41
41
|
python3 scripts/ecosystem_doctor.py --update # after all drift resolved
|
|
@@ -68,16 +68,38 @@ python3 scripts/ecosystem_doctor.py --offline --check || { echo "STALE ecosystem
|
|
|
68
68
|
# 5c. Licensing gate — SPDX headers, LICENSE, NOTICE, manifest consistency
|
|
69
69
|
npx bats tests/test_licensing.bats || { echo "LICENSING GATE FAILED"; exit 1; }
|
|
70
70
|
|
|
71
|
-
# 6. Commit
|
|
71
|
+
# 6. Commit, push branch, and wait for the exact commit's full CI
|
|
72
72
|
git add -A && git commit -m "chore: release vX.Y.Z"
|
|
73
|
-
git
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
RELEASE_SHA=$(git rev-parse HEAD)
|
|
74
|
+
git push origin main || { echo "FAIL: release commit push failed"; exit 1; }
|
|
75
|
+
RUN_ID=""
|
|
76
|
+
for ATTEMPT in 1 2 3 4 5; do
|
|
77
|
+
RUN_ID=$(gh run list --workflow ci.yml --event push --commit "$RELEASE_SHA" \
|
|
78
|
+
--limit 1 --json databaseId --jq '.[0].databaseId')
|
|
79
|
+
[ -n "$RUN_ID" ] && break
|
|
80
|
+
echo "Waiting for CI run registration ($ATTEMPT/5)" >&2
|
|
81
|
+
[ "$ATTEMPT" -eq 5 ] || sleep 60
|
|
82
|
+
done
|
|
83
|
+
test -n "$RUN_ID" || { echo "FAIL: CI run not found for release commit"; exit 1; }
|
|
84
|
+
gh run watch "$RUN_ID" --exit-status \
|
|
85
|
+
|| { echo "FAIL: release commit CI failed"; exit 1; }
|
|
86
|
+
for OS in ubuntu-latest macos-latest; do
|
|
87
|
+
gh run view "$RUN_ID" --json jobs \
|
|
88
|
+
--jq ".jobs[] | select(.name == \"Bats test suite ($OS)\") | .conclusion" \
|
|
89
|
+
| grep -qx success || { echo "FAIL: $OS test job not green"; exit 1; }
|
|
90
|
+
done
|
|
91
|
+
test "$(git rev-parse HEAD)" = "$RELEASE_SHA" || { echo "FAIL: local HEAD changed during CI"; exit 1; }
|
|
92
|
+
git fetch origin main || { echo "FAIL: origin/main refresh failed"; exit 1; }
|
|
93
|
+
test "$(git rev-parse origin/main)" = "$RELEASE_SHA" || { echo "FAIL: origin/main changed during CI"; exit 1; }
|
|
94
|
+
|
|
95
|
+
# 6a. Only green branch CI authorizes tag creation
|
|
96
|
+
git tag vX.Y.Z "$RELEASE_SHA"
|
|
97
|
+
|
|
98
|
+
# 6b. Assert the tag before pushing it (v4.19.0 postmortem, Phase 7)
|
|
99
|
+
test "$(git rev-parse vX.Y.Z)" = "$RELEASE_SHA" || { echo "FAIL: tag not on tested release commit"; exit 1; }
|
|
77
100
|
git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" || { echo "FAIL: tag not on release commit"; exit 1; }
|
|
78
101
|
|
|
79
|
-
#
|
|
80
|
-
git push origin main
|
|
102
|
+
# 6c. Push the single tag by full ref. Never --tags.
|
|
81
103
|
git push origin refs/tags/vX.Y.Z
|
|
82
104
|
```
|
|
83
105
|
|
|
@@ -104,7 +126,7 @@ Output classifies every registered tool as **Clean**, **Drift**, or **Errored**.
|
|
|
104
126
|
|
|
105
127
|
### 0.2 Act on drift
|
|
106
128
|
|
|
107
|
-
For each drifting tool, follow [ecosystem-sync
|
|
129
|
+
For each drifting tool, follow [sop-ecosystem-sync.md](sop-ecosystem-sync.md) Phase 2-4:
|
|
108
130
|
|
|
109
131
|
| Drift class | Release impact |
|
|
110
132
|
|-------------|----------------|
|
|
@@ -173,7 +195,7 @@ The canonical version lives in `package.json`. These files **must** match:
|
|
|
173
195
|
|
|
174
196
|
| File | Field | When to update |
|
|
175
197
|
|------|-------|---------------|
|
|
176
|
-
| `kb/procedures/maintenance
|
|
198
|
+
| `kb/procedures/sop-maintenance.md` | frontmatter `version:` | If SOP content changed |
|
|
177
199
|
| `kb/reference/skills-catalog.md` | frontmatter `version:` | If skills added/removed |
|
|
178
200
|
| `kb/reference/agents-catalog.md` | frontmatter `version:` | If agents added/removed |
|
|
179
201
|
| `kb/reference/hooks-catalog.md` | frontmatter `version:` | If hooks changed |
|
|
@@ -493,23 +515,60 @@ git commit -m "chore: release vX.Y.Z"
|
|
|
493
515
|
|
|
494
516
|
---
|
|
495
517
|
|
|
496
|
-
## Phase 7: Tag and Push
|
|
518
|
+
## Phase 7: Push Branch, Verify CI, Tag, and Push Tag
|
|
497
519
|
|
|
498
520
|
```bash
|
|
499
|
-
git
|
|
521
|
+
RELEASE_SHA=$(git rev-parse HEAD)
|
|
522
|
+
git push origin main || { echo "FAIL: release commit push failed"; exit 1; }
|
|
523
|
+
|
|
524
|
+
# Bind the gate to the exact release commit. GitHub run registration is
|
|
525
|
+
# asynchronous, so retry at most five times and log every attempt.
|
|
526
|
+
RUN_ID=""
|
|
527
|
+
for ATTEMPT in 1 2 3 4 5; do
|
|
528
|
+
RUN_ID=$(gh run list --workflow ci.yml --event push --commit "$RELEASE_SHA" \
|
|
529
|
+
--limit 1 --json databaseId --jq '.[0].databaseId')
|
|
530
|
+
[ -n "$RUN_ID" ] && break
|
|
531
|
+
echo "Waiting for CI run registration ($ATTEMPT/5)" >&2
|
|
532
|
+
[ "$ATTEMPT" -eq 5 ] || sleep 60
|
|
533
|
+
done
|
|
534
|
+
test -n "$RUN_ID" || { echo "FAIL: CI run not found for release commit"; exit 1; }
|
|
535
|
+
gh run watch "$RUN_ID" --exit-status \
|
|
536
|
+
|| { echo "FAIL: release commit CI failed"; exit 1; }
|
|
537
|
+
|
|
538
|
+
# publish.yml is Ubuntu-only. Require both full CI matrix jobs before creating
|
|
539
|
+
# the tag so a green publish job cannot bypass a red macOS test.
|
|
540
|
+
for OS in ubuntu-latest macos-latest; do
|
|
541
|
+
gh run view "$RUN_ID" --json jobs \
|
|
542
|
+
--jq ".jobs[] | select(.name == \"Bats test suite ($OS)\") | .conclusion" \
|
|
543
|
+
| grep -qx success || { echo "FAIL: $OS test job not green"; exit 1; }
|
|
544
|
+
done
|
|
545
|
+
|
|
546
|
+
# Refuse to tag if either local or remote main moved while CI was running.
|
|
547
|
+
test "$(git rev-parse HEAD)" = "$RELEASE_SHA" \
|
|
548
|
+
|| { echo "FAIL: local HEAD changed during CI"; exit 1; }
|
|
549
|
+
git fetch origin main || { echo "FAIL: origin/main refresh failed"; exit 1; }
|
|
550
|
+
test "$(git rev-parse origin/main)" = "$RELEASE_SHA" \
|
|
551
|
+
|| { echo "FAIL: origin/main changed during CI"; exit 1; }
|
|
552
|
+
|
|
553
|
+
git tag vX.Y.Z "$RELEASE_SHA"
|
|
500
554
|
|
|
501
555
|
# Assert the tag before pushing it. Both checks are one line each and both
|
|
502
556
|
# have caught a real broken release.
|
|
503
|
-
test "$(git rev-parse vX.Y.Z)" = "$
|
|
504
|
-
|| { echo "FAIL: tag is not on
|
|
557
|
+
test "$(git rev-parse vX.Y.Z)" = "$RELEASE_SHA" \
|
|
558
|
+
|| { echo "FAIL: tag is not on the tested release commit"; exit 1; }
|
|
505
559
|
git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" \
|
|
506
560
|
|| { echo "FAIL: tag is not on the chore: release commit"; exit 1; }
|
|
507
561
|
|
|
508
|
-
# Push the
|
|
509
|
-
git push origin main
|
|
562
|
+
# Push the single release tag by its full ref.
|
|
510
563
|
git push origin refs/tags/vX.Y.Z
|
|
511
564
|
```
|
|
512
565
|
|
|
566
|
+
**Why branch CI comes before the tag (v4.30.2 postmortem).** The publish
|
|
567
|
+
workflow runs only on Ubuntu and can publish while the separate macOS matrix job
|
|
568
|
+
is red. `v4.30.2` exposed this with a macOS-only DSH timing failure. A release
|
|
569
|
+
commit must therefore pass the complete Ubuntu/macOS branch workflow before its
|
|
570
|
+
tag exists; a successful publish workflow is not a substitute for green CI.
|
|
571
|
+
|
|
513
572
|
**Why the assertions (v4.19.0 postmortem).** v4.19.0 was tagged on a commit
|
|
514
573
|
that contained only a KB document and still carried `package.json` version
|
|
515
574
|
`4.18.0`; the actual release sat in the commit above it under a recycled
|
|
@@ -532,7 +591,7 @@ This triggers `.github/workflows/publish.yml` which:
|
|
|
532
591
|
|
|
533
592
|
**Provenance is non-negotiable.** If `id-token: write` permission or the `--provenance` flag is missing from `publish.yml`, fix it BEFORE tagging — an unsigned release is a regression against the v2.8.0 standard.
|
|
534
593
|
|
|
535
|
-
**After CI completes:** Run the [Release Verification SOP](release-verification
|
|
594
|
+
**After CI completes:** Run the [Release Verification SOP](sop-release-verification.md)
|
|
536
595
|
to smoke-test the published package AND verify the provenance attestation landed on npm.
|
|
537
596
|
|
|
538
597
|
---
|
|
@@ -580,7 +639,9 @@ git push origin --delete vX.Y.Z
|
|
|
580
639
|
| 15a | Licensing gate | `npx bats tests/test_licensing.bats` | 7/7 — SPDX headers, LICENSE, NOTICE, npm `files`, manifest consistency |
|
|
581
640
|
| 16 | Tests | `git add -A kb/` if the KB changed, then `npm test` | All pass |
|
|
582
641
|
| 17 | Commit | `git commit` | Clean working tree |
|
|
583
|
-
| 18 |
|
|
584
|
-
| 18a |
|
|
585
|
-
|
|
|
586
|
-
|
|
|
642
|
+
| 18 | Push branch | `git push origin main` | Exact release commit is on `origin/main` |
|
|
643
|
+
| 18a | Full branch CI | `gh run watch "$RUN_ID" --exit-status` plus matrix job assertions | Ubuntu and macOS Bats jobs both conclude `success` |
|
|
644
|
+
| 19 | Tag | `git tag vX.Y.Z` | Tag exists only after green branch CI |
|
|
645
|
+
| 19a | Tag is on tested SHA | `test "$(git rev-parse vX.Y.Z)" = "$RELEASE_SHA"` | Exit 0 |
|
|
646
|
+
| 19b | Tag is on the release commit | `git show --no-patch --format=%s vX.Y.Z` | Reads `chore: release vX.Y.Z` |
|
|
647
|
+
| 20 | Push the single tag | `git push origin refs/tags/vX.Y.Z` | Publish CI triggered with `id-token: write`. Never `--tags`. |
|
|
@@ -228,7 +228,7 @@ Three tiers determine how to approach a task:
|
|
|
228
228
|
|------|-------|-----------|-------|
|
|
229
229
|
| Task | `disable-model-invocation: true` | User via `/skill` only | 32 |
|
|
230
230
|
| Hybrid | (neither) | User via `/skill` + agent knowledge | 31 |
|
|
231
|
-
| Knowledge | `user-invocable: false` | Claude auto-loads |
|
|
231
|
+
| Knowledge | `user-invocable: false` | Claude auto-loads | 51 |
|
|
232
232
|
|
|
233
233
|
## Multi-Agent Execution
|
|
234
234
|
|
|
@@ -159,7 +159,7 @@ running the generators directly:
|
|
|
159
159
|
|
|
160
160
|
- `scripts/generate_copilot.py` / `generate_copilot_hooks.py` contract tests
|
|
161
161
|
(`tests/test_copilot.bats`, `tests/test_copilot_hooks.bats`).
|
|
162
|
-
- Release layout check in `kb/procedures/release-verification
|
|
162
|
+
- Release layout check in `kb/procedures/sop-release-verification.md` asserts the
|
|
163
163
|
`.github/{agents,skills,instructions,prompts,hooks}` surfaces.
|
|
164
164
|
- `validate.py --strict` + `audit_skills.py --ci` in CI.
|
|
165
165
|
|
|
@@ -131,7 +131,7 @@ MIT remnant would need each contributor's agreement.
|
|
|
131
131
|
|
|
132
132
|
It is a test rather than a checklist line on purpose. This project has two
|
|
133
133
|
same-day postmortems about SOPs that existed and were skipped; CI does not skip.
|
|
134
|
-
[Release Preparation](../procedures/release
|
|
134
|
+
[Release Preparation](../procedures/sop-release.md) Phase 5c runs the
|
|
135
135
|
same gate before tagging so a failure surfaces before the tag, not after.
|
|
136
136
|
|
|
137
137
|
## If the licence ever changes again
|
|
@@ -144,5 +144,5 @@ source, cross-verify against a second independent copy, and only then write
|
|
|
144
144
|
## Related
|
|
145
145
|
|
|
146
146
|
- [`LICENSE`](../../LICENSE), [`NOTICE`](../../NOTICE)
|
|
147
|
-
- [Release Preparation SOP](../procedures/release
|
|
147
|
+
- [Release Preparation SOP](../procedures/sop-release.md) — Phase 5c
|
|
148
148
|
- [Distribution Model](distribution-model.md) — what ships and where
|
|
@@ -53,7 +53,7 @@ Updated baseline docs:
|
|
|
53
53
|
- `kb/reference/skills-catalog.md`
|
|
54
54
|
- `kb/reference/plugin-pack-conventions.md`
|
|
55
55
|
- `kb/reference/claude-ecosystem-benchmark-snapshot.md`
|
|
56
|
-
- `kb/procedures/maintenance
|
|
56
|
+
- `kb/procedures/sop-maintenance.md`
|
|
57
57
|
|
|
58
58
|
## Validation Evidence
|
|
59
59
|
|
|
@@ -285,13 +285,13 @@ See [DSH Compatibility](./dsh-compatibility.md) for commands, topology, subscrip
|
|
|
285
285
|
2. Delete its section from this document.
|
|
286
286
|
3. Delete its snapshot entry from `benchmarks/ecosystem-doctor-snapshot.json` (or let the next `--update` prune it — currently not pruned automatically).
|
|
287
287
|
4. Decide whether to keep the generator (`scripts/generate_<tool>_*.py`) for backwards compatibility or delete it.
|
|
288
|
-
5. Remove references from `README.md`, `manifest.json` `description` field, and `kb/procedures/maintenance
|
|
288
|
+
5. Remove references from `README.md`, `manifest.json` `description` field, and `kb/procedures/sop-maintenance.md` `Supported editors` line.
|
|
289
289
|
|
|
290
290
|
---
|
|
291
291
|
|
|
292
292
|
## Related
|
|
293
293
|
|
|
294
|
-
- [Ecosystem Sync SOP](../procedures/ecosystem-sync
|
|
294
|
+
- [Ecosystem Sync SOP](../procedures/sop-ecosystem-sync.md) — how to use the doctor
|
|
295
295
|
- [MCP Editor Compatibility](./mcp-editor-compatibility.md) — MCP-specific subset
|
|
296
296
|
- `scripts/ecosystem_tools.json` — source of truth
|
|
297
297
|
- `scripts/ecosystem_doctor.py` — drift detector
|