@softspark/ai-toolkit 4.32.2 → 4.32.4

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/llms-full.txt CHANGED
@@ -84,7 +84,7 @@
84
84
  - **a11y-validate**: Accessibility validator: WCAG 2.1 AA, EN 301 549, EAA. Triggers: a11y, accessibility, WCAG, EAA, ARIA, contrast, keyboard, screen reader.
85
85
  - **agent-creator**: Creates new specialized agents with frontmatter, tools, delegation. Triggers: new agent, create agent, agent scaffold, specialized agent.
86
86
  - **analyze**: Analyzes code quality, complexity, patterns across codebase. Triggers: quality report, hotspot scan, code analysis, architecture signal.
87
- - **api-patterns**: REST/GraphQL API design: naming, versioning, pagination, idempotency, OpenAPI. Triggers: API design, REST, GraphQL, OpenAPI, Swagger, idempotency, rate limit.
87
+ - **api-patterns**: API design: naming, versioning, pagination, idempotency, OpenAPI, error contracts and safe retries. Triggers: API design, REST, GraphQL, OpenAPI, Swagger, error response, HTTP status, rate limit.
88
88
  - **app-builder**: App scaffolding: Next.js, Vite, Nuxt, Astro, FastAPI, Django, Laravel, RN, Flutter. Triggers: scaffold, bootstrap, new project, starter, dashboard, mobile app.
89
89
  - **architecture-audit**: Audits codebase for architectural friction, shallow modules; proposes RFCs. Triggers: improve architecture, shallow modules, deepen modules, reduce coupling.
90
90
  - **architecture-decision**: Architecture decisions in ADR/RFC/RFD format: context, constraints, options, recommendation. Triggers: ADR, RFC, RFD, trade-offs, design choice, pick between, evaluate approach.
@@ -7721,10 +7721,10 @@ title: "SOP: Post-Release Testing"
7721
7721
  category: procedures
7722
7722
  service: ai-toolkit
7723
7723
  tags: [sop, post-release, smoke-test, npm, sandbox, plugin-pack, provenance, isolation]
7724
- version: "1.2.0"
7724
+ version: "1.2.1"
7725
7725
  created: "2026-07-26"
7726
- last_updated: "2026-08-19"
7727
- description: "Smoke-test a published @softspark/ai-toolkit release from npm in an isolated HOME and npm prefix, without touching the maintainer's real install. Covers provenance, CLI, doctor, per-skill script resolution, scanner wiring, and the full plugin-pack lifecycle including the degraded-install path. Written for v4.18.0 and not run; v4.18.0 shipped a pack that broke every command it touched. First actually run on v4.22.0, which added Phases 4b and 4c after that release fixed four skills whose documented script path had never resolved and two that shipped a scanner nothing invoked."
7726
+ last_updated: "2026-09-06"
7727
+ description: "Smoke-test a published @softspark/ai-toolkit npm artifact in a disposable container or VM with its default HOME, no host settings or credential mounts, host-side configuration fingerprints, and retained evidence. Covers provenance, CLI, doctor, installed skill scripts, scanner wiring, and the plugin-pack lifecycle."
7728
7728
  ---
7729
7729
 
7730
7730
  # SOP: Post-Release Testing
@@ -7734,73 +7734,147 @@ actually install, from npm, rather than the working tree.
7734
7734
 
7735
7735
  Sibling procedures exist for `jira-mcp` and `legal-pl-pack`; this is the
7736
7736
  ai-toolkit equivalent. It complements
7737
- [Release Verification](sop-release-verification.md), which checks the toolkit
7738
- from the maintainer's own installed copy. The difference that matters: this one
7739
- never writes to the maintainer's `~/.claude` or `~/.softspark`.
7737
+ [Release Verification](sop-release-verification.md), whose cross-editor checks
7738
+ must use the same isolated published artifact. Neither procedure installs or
7739
+ updates the maintainer's working copy.
7740
7740
 
7741
7741
  **Time:** 10 minutes.
7742
7742
 
7743
7743
  ## Why isolation is the first step, not a detail
7744
7744
 
7745
- The toolkit installs into `$HOME`. Testing a release against your own HOME
7746
- means the test either pollutes your working setup or, worse, passes because of
7747
- state your setup already had. Both make the result meaningless.
7745
+ The toolkit writes settings beneath the current user's home directory. Run the
7746
+ published artifact in a disposable Docker container or VM with its normal HOME.
7747
+ Do not override host HOME, CODEX_HOME, or another editor's configuration root as
7748
+ a substitute for isolation. Do not expose the host home, credentials, SSH agent,
7749
+ Docker socket, or existing toolkit installation to the test environment.
7750
+
7751
+ ## Phase 1: Create and verify an isolated test environment
7748
7752
 
7749
- Every command below runs against a throwaway HOME and a throwaway npm prefix.
7750
- Nothing is global.
7753
+ The recipe below uses Docker. A disposable VM is equivalent only when host shared
7754
+ folders and authentication forwarding are absent. The host needs Docker and
7755
+ Python 3; the container prerequisites are installed separately below.
7751
7756
 
7752
- ## Phase 1: Sandbox
7757
+ **Host terminal:** keep this terminal open for Phases 7 and 8. The fingerprint
7758
+ reads only these toolkit-managed settings files and records hashes and presence,
7759
+ never their contents. Add a path only after verifying that the tested installer
7760
+ actually manages it.
7753
7761
 
7754
7762
  ```bash
7755
- SB=$(mktemp -d)
7756
- mkdir -p "$SB/home" "$SB/npm"
7757
- export HOME="$SB/home"
7758
- AT="$SB/npm/bin/ai-toolkit"
7759
- echo "sandbox: $SB"
7763
+ set -o pipefail
7764
+ VERSION="X.Y.Z"
7765
+ EVIDENCE=$(mktemp -d "${TMPDIR:-/tmp}/ai-toolkit-release-${VERSION}.XXXXXX")
7766
+ SMOKE_CONTAINER=$(python3 -c 'import uuid; print("ai-toolkit-smoke-" + uuid.uuid4().hex)')
7767
+
7768
+ fingerprint_host() {
7769
+ python3 - <<'PY'
7770
+ import hashlib
7771
+ import json
7772
+ import os
7773
+ from pathlib import Path
7774
+
7775
+ home = Path.home()
7776
+ managed = [
7777
+ ".claude/settings.json",
7778
+ ".claude.json",
7779
+ ".softspark/ai-toolkit/plugins.json",
7780
+ ".codex/config.toml",
7781
+ ".cursor/mcp.json",
7782
+ ".gemini/settings.json",
7783
+ ".config/opencode/opencode.json",
7784
+ ]
7785
+ rows = {}
7786
+ for relative in managed:
7787
+ path = home / relative
7788
+ row = {"exists": path.exists() or path.is_symlink()}
7789
+ if path.is_symlink():
7790
+ row["link_sha256"] = hashlib.sha256(os.readlink(path).encode()).hexdigest()
7791
+ if path.is_file():
7792
+ row["sha256"] = hashlib.sha256(path.read_bytes()).hexdigest()
7793
+ rows[relative] = row
7794
+ print(json.dumps({
7795
+ "host_home_sha256": hashlib.sha256(str(home).encode()).hexdigest(),
7796
+ "files": rows,
7797
+ }, sort_keys=True, indent=2))
7798
+ PY
7799
+ }
7800
+
7801
+ fingerprint_host > "$EVIDENCE/host-before.json"
7802
+ docker run -d --name "$SMOKE_CONTAINER" \
7803
+ --label "org.softspark.release-smoke=$SMOKE_CONTAINER" \
7804
+ --env "VERSION=$VERSION" \
7805
+ node:22-bookworm sleep infinity
7806
+ docker inspect "$SMOKE_CONTAINER" > "$EVIDENCE/container-before.json"
7807
+ python3 - "$EVIDENCE/container-before.json" <<'PY'
7808
+ import json
7809
+ import sys
7810
+
7811
+ container = json.load(open(sys.argv[1], encoding="utf-8"))[0]
7812
+ assert container["Mounts"] == [], "Smoke container must have no mounts"
7813
+ host = container["HostConfig"]
7814
+ assert not host["Privileged"], "Privileged containers are forbidden"
7815
+ assert host["NetworkMode"] != "host", "Do not share the host network namespace"
7816
+ assert host["PidMode"] != "host", "Do not share host processes"
7817
+ PY
7818
+ docker exec "$SMOKE_CONTAINER" bash -lc \
7819
+ 'test "$HOME" = "$(getent passwd "$(id -u)" | cut -d: -f6)"'
7820
+ docker exec "$SMOKE_CONTAINER" bash -lc \
7821
+ 'apt-get update && apt-get install -y --no-install-recommends python3 python3-yaml git coreutils jq bats shellcheck ca-certificates curl util-linux' \
7822
+ 2>&1 | tee "$EVIDENCE/bootstrap.log"
7823
+ ```
7824
+
7825
+ Install any additional prerequisite declared by the pack under test only inside
7826
+ the container. GNU coreutils supplies timeout; util-linux supplies the session
7827
+ recorder. Use docker cp for evidence transfer, not host temporary-directory bind
7828
+ mounts: a remote Docker daemon may not see the host's /private/tmp.
7829
+
7830
+ **Enter the container, then run Phases 2 through 6 there:**
7831
+
7832
+ ```bash
7833
+ docker exec -it "$SMOKE_CONTAINER" bash
7760
7834
  ```
7761
7835
 
7762
- Record the real state now, so Phase 7 can prove it is unchanged:
7836
+ Inside that container shell:
7763
7837
 
7764
7838
  ```bash
7765
- python3 -c "
7766
- import json, pathlib
7767
- p = pathlib.Path('$SB/../real-before.json')
7768
- import os
7769
- home = pathlib.Path(os.path.expanduser('~'))
7770
- " 2>/dev/null
7771
- # Simpler: note what exists today.
7772
- cat ~/.softspark/ai-toolkit/plugins.json 2>/dev/null
7839
+ SB=/tmp/ai-toolkit-smoke
7840
+ AT="$SB/npm/bin/ai-toolkit"
7841
+ mkdir -p "$SB/npm" "$SB/evidence"
7842
+ export SB AT
7843
+ exec script -q -e -a "$SB/evidence/session.log" -c 'bash --noprofile --norc'
7773
7844
  ```
7774
7845
 
7846
+ Keep HOME at the container user's default. VERSION was passed when the container
7847
+ was created; SB and the npm prefix are disposable container paths. No command in
7848
+ Phases 2 through 6 runs in the host shell.
7849
+
7775
7850
  ## Phase 2: Provenance
7776
7851
 
7777
7852
  Do this before installing anything: an unsigned publish is a release-blocking
7778
7853
  regression, and there is no point smoke-testing a build you would have to redo.
7779
7854
 
7780
7855
  ```bash
7781
- VERSION="X.Y.Z"
7782
- npm view "@softspark/ai-toolkit@${VERSION}" --json \
7783
- | python3 -c "
7856
+ npm view "@softspark/ai-toolkit@${VERSION}" --json > "$SB/evidence/npm-view.json"
7857
+ python3 -c "
7784
7858
  import json, sys
7785
- d = json.load(sys.stdin); att = d['dist'].get('attestations', {})
7859
+ d = json.load(open(sys.argv[1], encoding='utf-8')); att = d['dist'].get('attestations', {})
7786
7860
  pt = att.get('provenance', {}).get('predicateType')
7787
7861
  assert pt == 'https://slsa.dev/provenance/v1', f'NO PROVENANCE: {pt}'
7788
7862
  print('PROVENANCE OK:', att['url'])
7789
- "
7863
+ " "$SB/evidence/npm-view.json"
7790
7864
  ```
7791
7865
 
7792
7866
  ## Phase 3: Install from npm
7793
7867
 
7794
7868
  ```bash
7795
7869
  npm install -g --prefix "$SB/npm" "@softspark/ai-toolkit@${VERSION}"
7796
- "$AT" --version # must equal VERSION
7870
+ "$AT" --version | tee "$SB/evidence/version.txt" # must equal VERSION
7797
7871
  "$AT" --help >/dev/null && echo "help OK"
7798
7872
  ```
7799
7873
 
7800
7874
  ## Phase 4: Core surfaces
7801
7875
 
7802
7876
  ```bash
7803
- "$AT" install # full global install into the sandbox HOME
7877
+ "$AT" install # global install inside the container's default HOME
7804
7878
  "$AT" doctor # must end: Errors: 0 | Warnings: 0
7805
7879
  "$AT" status
7806
7880
  "$AT" plugin list # pack count must match app/plugins/
@@ -7838,8 +7912,13 @@ for D in "$HOME"/.claude/skills/*/; do
7838
7912
  rel=${ref##*\$\{CLAUDE_SKILL_DIR\}/}
7839
7913
  printf '%-22s %-10s %-26s ' "$s" "$interp" "$rel"
7840
7914
  [ -f "$D/$rel" ] || { echo 'PATH DOES NOT RESOLVE'; continue; }
7841
- out=$(CLAUDE_SKILL_DIR="$D" timeout 20 "$interp" "$D/$rel" --help </dev/null 2>&1 | head -1)
7842
- printf 'rc=%s %s\n' "$?" "$(echo "$out" | cut -c1-40)"
7915
+ if out=$(CLAUDE_SKILL_DIR="$D" timeout 20 "$interp" "$D/$rel" --help </dev/null 2>&1); then
7916
+ rc=0
7917
+ else
7918
+ rc=$?
7919
+ fi
7920
+ printf '%s\n' "$out" > "$SB/evidence/skill-$s.log"
7921
+ printf 'rc=%s %s\n' "$rc" "$(printf '%s\n' "$out" | head -1 | cut -c1-40)"
7843
7922
  done
7844
7923
  ```
7845
7924
 
@@ -7980,37 +8059,59 @@ again, pointing its source-override variable at a dead URL:
7980
8059
  - [ ] `plugin status` says the pack is inert and names the fix
7981
8060
  - [ ] Re-installing without the broken source recovers
7982
8061
 
7983
- ## Phase 7: Prove the real environment is untouched
8062
+ ## Phase 7: Verify the host configuration
8063
+
8064
+ Exit the recorded container shell. This returns to the unchanged host terminal
8065
+ from Phase 1. Run fingerprint_host there, not through docker exec and not in a
8066
+ shell that changed HOME:
7984
8067
 
7985
8068
  ```bash
7986
- python3 -c "
7987
- import json, pathlib
7988
- d = json.loads(pathlib.Path.home().joinpath('.softspark/ai-toolkit/plugins.json').read_text())
7989
- print('plugins.json:', d['targets']['claude'])
7990
- p = pathlib.Path.home() / '.claude/settings.json'
7991
- print('pack hook leaked into real settings:', '<pack>' in json.dumps(json.loads(p.read_text()).get('hooks', {})) if p.exists() else False)
7992
- print('pack paths in real ~/.softspark:', len(list(pathlib.Path.home().joinpath('.softspark').rglob('*<pack>*'))))
7993
- "
8069
+ fingerprint_host > "$EVIDENCE/host-after.json"
8070
+ cmp -s "$EVIDENCE/host-before.json" "$EVIDENCE/host-after.json" || {
8071
+ diff -u "$EVIDENCE/host-before.json" "$EVIDENCE/host-after.json"
8072
+ echo "Host configuration changed: investigate before accepting the release."
8073
+ exit 1
8074
+ }
8075
+ docker inspect "$SMOKE_CONTAINER" > "$EVIDENCE/container-after.json"
7994
8076
  ```
7995
8077
 
7996
- All three must show the pre-test state.
8078
+ The fingerprints must match. This proves the enumerated managed settings stayed
8079
+ unchanged; the recorded container configuration separately proves there were no
8080
+ host mounts or shared host namespaces. Do not claim to have hashed the whole
8081
+ home directory, or print settings contents to demonstrate isolation.
7997
8082
 
7998
- ## Phase 8: Clean up
8083
+ ## Phase 8: Preserve evidence and remove only the owned container
7999
8084
 
8000
- `guard-destructive.sh` blocks `rm -rf` on a `PreToolUse` hook, so removal goes
8001
- through an enumerated delete that reports what it removed:
8085
+ Run on the host, after leaving the container shell. Confirm ownership before any
8086
+ cleanup, then copy the recorded session, npm provenance metadata, and CLI version.
8087
+ Keep the host evidence directory for the release record.
8002
8088
 
8003
8089
  ```bash
8004
- python3 -c "
8005
- import pathlib, shutil
8006
- sb = pathlib.Path('$SB')
8007
- assert sb.is_dir() and str(sb).startswith(('/tmp', '/var/folders')), sb
8008
- n = sum(1 for _ in sb.rglob('*') if _.is_file())
8009
- shutil.rmtree(sb)
8010
- print(f'removed {sb} ({n} files)')
8011
- "
8090
+ test "$(docker inspect --format '{{index .Config.Labels "org.softspark.release-smoke"}}' "$SMOKE_CONTAINER")" = "$SMOKE_CONTAINER" || {
8091
+ echo "Container ownership does not match; refusing cleanup."
8092
+ exit 1
8093
+ }
8094
+ docker logs "$SMOKE_CONTAINER" > "$EVIDENCE/container.log" 2>&1
8095
+ mkdir -p "$EVIDENCE/container"
8096
+ docker cp "$SMOKE_CONTAINER:/tmp/ai-toolkit-smoke/evidence/." "$EVIDENCE/container/" || {
8097
+ echo "Evidence transfer failed; keep the container and investigate."
8098
+ exit 1
8099
+ }
8100
+ test -f "$EVIDENCE/container/session.log" || {
8101
+ echo "Session evidence is missing; refusing cleanup."
8102
+ exit 1
8103
+ }
8104
+ docker stop "$SMOKE_CONTAINER"
8105
+ docker rm "$SMOKE_CONTAINER"
8106
+ printf 'Evidence retained: %s\n' "$EVIDENCE"
8012
8107
  ```
8013
8108
 
8109
+ There are no host bind mounts or named volumes to delete. Never bypass a
8110
+ destructive-command guard with Python, shutil.rmtree, another interpreter, or a
8111
+ different deletion tool. If a guard rejects cleanup, leave the owned container
8112
+ and evidence in place and report the rejection through the normal approval
8113
+ mechanism. Do not prune Docker resources or delete unrelated temporary files.
8114
+
8014
8115
  ## Success criteria
8015
8116
 
8016
8117
  | Area | Criterion |
@@ -8024,12 +8125,12 @@ print(f'removed {sb} ({n} files)')
8024
8125
  | Pack update | Current version silent; stale version updates and re-records |
8025
8126
  | Pack removal | Zero residue in `~/.softspark` and `settings.json`; re-install works |
8026
8127
  | Degraded path | Fetch failure is inert, loud in status, and recoverable |
8027
- | Isolation | Real `~/.claude` and `~/.softspark` byte-identical to pre-test |
8128
+ | Isolation | Host-side managed-settings fingerprints match; container has no host mounts or shared host namespaces |
8028
8129
 
8029
8130
  ## Related
8030
8131
 
8031
8132
  - [Release Preparation](sop-release.md) — run before tagging
8032
- - [Release Verification](sop-release-verification.md) — the maintainer-install checks
8133
+ - [Release Verification](sop-release-verification.md) — cross-editor checks of the isolated npm artifact
8033
8134
  - [rtk-pack Retirement](../history/completed/rtk-pack-retirement-20260727.md) — what happened the one time this SOP was written and not run
8034
8135
 
8035
8136
  ---
@@ -8142,9 +8243,9 @@ title: "SOP: Release Verification"
8142
8243
  category: procedures
8143
8244
  service: ai-toolkit
8144
8245
  tags: [sop, verification, release, smoke-test, install, update, qa, provenance, sarif, dsh]
8145
- version: "1.8.0"
8246
+ version: "1.8.1"
8146
8247
  created: "2026-04-08"
8147
- last_updated: "2026-09-01"
8248
+ last_updated: "2026-09-06"
8148
8249
  description: "End-to-end smoke test after installing or updating @softspark/ai-toolkit. Verifies CLI, native Codex and GitHub Copilot surfaces, explicit DSH lifecycle, Claude app export, doctor, validation, tests, eject, provenance, SARIF, and per-skill permissions."
8149
8250
  ---
8150
8251
 
@@ -8162,12 +8263,30 @@ Verifies all critical paths from the user's perspective.
8162
8263
 
8163
8264
  **Prerequisites:**
8164
8265
  - Node.js >= 18, Python 3, `bats`, git
8165
- - `@softspark/ai-toolkit` installed globally
8266
+ - The target version of `@softspark/ai-toolkit` installed in a disposable test environment
8166
8267
 
8167
8268
  **Time:** 10-15 minutes (full), 2 minutes (quick checklist)
8168
8269
 
8169
8270
  ---
8170
8271
 
8272
+ ## Verification environment
8273
+
8274
+ Run installation, update, eject and editor smoke checks in a disposable
8275
+ container or VM with its own OS user and default home directory. Do not
8276
+ reassign `HOME` or `CODEX_HOME`, mount the operator's home/authentication
8277
+ directories, or alter the global installation used by an active session.
8278
+ Use the packed release candidate before publication and the exact npm version
8279
+ after publication; the installed package must be the source of runtime checks.
8280
+ Source validation and test commands still run from the matching release checkout.
8281
+
8282
+ A scratch project alone does not isolate home-scoped writes. In particular,
8283
+ the live Augment checks in Phase 9 write user settings. Execute them inside
8284
+ the disposable environment, retain logs outside it, and remove only resources
8285
+ created for this verification run. Do not treat a dry-run as proof that emitted
8286
+ files parse or that a second install is idempotent.
8287
+
8288
+ ---
8289
+
8171
8290
  ## Quick Checklist (TL;DR)
8172
8291
 
8173
8292
  The 14 core commands below must pass. Releases that change DSH must also complete Phase 10.
@@ -8262,9 +8381,11 @@ ai-toolkit status
8262
8381
  ```
8263
8382
 
8264
8383
  **Verify `--dry-run`:**
8265
- - [ ] Agents: 44
8266
- - [ ] Skills: 108
8267
- - [ ] Hooks merged into settings.json
8384
+ - [ ] Agent and skill totals match the target package's `app/agents/` and
8385
+ `app/skills/*/SKILL.md` inventory; compare with that release's validator
8386
+ output and README badges, not a number copied from an older release
8387
+ - [ ] Dry-run describes the planned hook merge; the isolated installed copy
8388
+ contains the expected hooks in settings.json
8268
8389
  - [ ] "Other AI Tools" lists documented global targets (with `--editors`): aider, antigravity, augment, cline, codex, copilot, cursor, gemini, opencode, roo, windsurf. Scope varies: Codex uses `$CODEX_HOME` (default `~/.codex`) plus `$HOME/.agents/skills`; Copilot uses `$COPILOT_HOME` (default `~/.copilot`); cursor has only `~/.cursor/hooks.json`; antigravity has the `~/.gemini/*/skills` pointer. Cursor and Antigravity rules remain project-only.
8269
8390
 
8270
8391
  **Verify `status`:**
@@ -8334,9 +8455,12 @@ python3 scripts/audit_skills.py --ci
8334
8455
  ```
8335
8456
 
8336
8457
  **Verify validate.py:**
8337
- - [ ] Agents: 44, Skills: 108, Tests: exactly the current README badge count
8338
- - [ ] Hook events: 14, Hook scripts: >= 30
8339
- - [ ] Plugin packs >= 10, KB documents >= 20
8458
+ - [ ] Agent, skill and Bats test totals match the current release inventory
8459
+ and README badges, as checked by the validator's metadata contracts
8460
+ - [ ] Hook events/scripts match `app/hooks.json` and the shipped hook files
8461
+ - [ ] Every shipped plugin pack and KB document passes its validator; compare
8462
+ inventory with the release checkout rather than requiring an obsolete
8463
+ fixed minimum number of packs or documents
8340
8464
  - [ ] `Errors: 0 | Warnings: 0` → `VALIDATION PASSED`
8341
8465
 
8342
8466
  **Verify audit_skills.py:**
@@ -8349,7 +8473,7 @@ python3 scripts/audit_skills.py --ci
8349
8473
  ## Phase 6: Tests (3-5 min)
8350
8474
 
8351
8475
  ```bash
8352
- # Run ONCE, capture to file, then parse. Full suite is 669+ bats cases —
8476
+ # Run ONCE, capture to file, then parse. Use the current release's Bats count;
8353
8477
  # re-running it per check (tail / grep ok / grep not ok piped separately)
8354
8478
  # wastes minutes every release. Always cache the output.
8355
8479
  npm test > /tmp/npm-test.log 2>&1
@@ -8362,7 +8486,7 @@ echo "exit: $exit"
8362
8486
 
8363
8487
  **Verify:**
8364
8488
  - [ ] `exit == 0`
8365
- - [ ] `ok == expected test count` (e.g., 945 on v3.0.0)
8489
+ - [ ] `ok == expected test count` from the current release's metadata contracts
8366
8490
  - [ ] `not ok == 0`
8367
8491
  - [ ] Bats runs tests in parallel (4 jobs)
8368
8492
  - [ ] Groups: agents, autodetect, cli, generators, guards, hooks, inject,
@@ -8473,7 +8597,7 @@ AI_TOOLKIT_STRICT_PIN=1 ai-toolkit update --dry-run
8473
8597
 
8474
8598
  These verify the native-surface generators shipped in v3.0.0 actually emit the right files for the right profiles, and that the tool registry stays in sync with shipped generators.
8475
8599
 
8476
- > **Safety warning HOME-scoped writes:** Running `--profile full` with `augment` in the editor list writes to `$HOME/.augment/settings.json` (Augment stores hooks under HOME, not per-project). Use `--dry-run` for verification unless you intend to carry ai-toolkit hook entries on this machine. The generator is marker-safe (only rewrites its own `_source: ai-toolkit` entries) but is still a side-effect.
8600
+ > Run this phase inside the disposable verification environment. `--profile full` with `augment` writes to `$HOME/.augment/settings.json`, so a temporary project on the operator's machine is insufficient. Dry-run checks cover the planned paths; Phases 9.4 and 9.5 must also exercise actual writes in isolation.
8477
8601
 
8478
8602
  ### 9.1 `--profile full` emits every native surface
8479
8603
 
@@ -8550,7 +8674,9 @@ The bats suite validates JSON shape at generation time. This re-checks that what
8550
8674
  D=/tmp/aitk-json-${RANDOM} && mkdir -p "$D" && cd "$D" && git init -q
8551
8675
  ai-toolkit install --local --editors cursor,windsurf,gemini,augment,codex,copilot --profile full >/dev/null 2>&1
8552
8676
  for f in .cursor/hooks.json .devin/hooks.v1.json .gemini/settings.json .codex/hooks.json .github/hooks/ai-toolkit.json "$HOME/.augment/settings.json"; do
8553
- [ -f "$f" ] && python3 -c "import json; json.load(open('$f'))" && echo "OK: $f"
8677
+ [ -f "$f" ] || { echo "MISSING: $f"; exit 1; }
8678
+ python3 -c 'import json, sys; json.load(open(sys.argv[1]))' "$f" || exit 1
8679
+ echo "OK: $f"
8554
8680
  done
8555
8681
  ```
8556
8682
 
@@ -8682,9 +8808,9 @@ title: "SOP: Release Preparation"
8682
8808
  category: procedures
8683
8809
  service: ai-toolkit
8684
8810
  tags: [sop, release, version, publish, changelog, semver, provenance, sarif, ecosystem, shellcheck]
8685
- version: "1.15.0"
8811
+ version: "1.15.1"
8686
8812
  created: "2026-04-10"
8687
- last_updated: "2026-09-02"
8813
+ last_updated: "2026-09-06"
8688
8814
  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."
8689
8815
  ---
8690
8816
 
@@ -8694,6 +8820,13 @@ Complete checklist for preparing a new `@softspark/ai-toolkit` release.
8694
8820
  Run this **before** tagging. After tagging and publishing, run the
8695
8821
  [Release Verification SOP](sop-release-verification.md) to smoke-test.
8696
8822
 
8823
+ Installation smoke uses a disposable container or VM with its own default
8824
+ home directory, as described in the verification SOP. Test the packed release
8825
+ candidate before publishing and the exact npm version afterward. Keep the
8826
+ operator's installed toolkit, editor settings and authentication directories
8827
+ outside that environment. Compare component counts with the current release
8828
+ inventory and validator output instead of historical constants in a checklist.
8829
+
8697
8830
  **Pipeline:**
8698
8831
  ```
8699
8832
  Ecosystem Sync SOP (drift check + generator updates)
@@ -9686,9 +9819,9 @@ title: "AI Toolkit - Architecture Overview"
9686
9819
  category: reference
9687
9820
  service: ai-toolkit
9688
9821
  tags: [architecture, overview, design, structure]
9689
- version: "1.10.0"
9822
+ version: "1.10.1"
9690
9823
  created: "2026-03-23"
9691
- last_updated: "2026-09-01"
9824
+ last_updated: "2026-09-06"
9692
9825
  description: "Architecture of ai-toolkit: install ownership, runtime adapters, the explicit DSH target, skill tiers, and project integration."
9693
9826
  ---
9694
9827
 
@@ -9998,7 +10131,7 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
9998
10131
 
9999
10132
  ## Quality Hooks
10000
10133
 
10001
- 29 entries across 14 lifecycle events. See [hooks-catalog.md](hooks-catalog.md) for full details.
10134
+ 28 entries across 14 lifecycle events. See [hooks-catalog.md](hooks-catalog.md) for full details.
10002
10135
 
10003
10136
  | Hook | Trigger | Script | Action |
10004
10137
  |------|---------|--------|--------|
@@ -14066,7 +14199,7 @@ service: ai-toolkit
14066
14199
  tags: [rules, languages, coding-style, testing, patterns, security]
14067
14200
  version: "2.2.0"
14068
14201
  created: "2026-04-07"
14069
- last_updated: "2026-09-04"
14202
+ last_updated: "2026-09-06"
14070
14203
  description: "Reference for the language-specific rules system: 13 per-language rule sets shipped as knowledge skills, plus common rules installed as Claude Code path-scoped project rules."
14071
14204
  ---
14072
14205
 
@@ -14139,6 +14272,12 @@ app/rules/
14139
14272
 
14140
14273
  ## Rule Categories
14141
14274
 
14275
+ The common security rules distinguish safe, actionable failure messages from
14276
+ private diagnostics. Common testing rules cover API error contracts and prohibit
14277
+ overlapping runners that reset a shared database. The `api-patterns` skill carries
14278
+ the focused error-contract guidance; the `review` checklist checks the same
14279
+ failure boundaries. These are content rules, not new hooks or runtime permissions.
14280
+
14142
14281
  | Category | Filename | Content |
14143
14282
  |----------|----------|---------|
14144
14283
  | `coding-style` | `coding-style.md` | Naming, formatting, idiomatic constructs, linter config |
@@ -16265,7 +16404,7 @@ service: ai-toolkit
16265
16404
  tags: [skills, domain-knowledge, catalog, task-skills, hybrid-skills]
16266
16405
  version: "1.5.0"
16267
16406
  created: "2026-03-23"
16268
- last_updated: "2026-08-06"
16407
+ last_updated: "2026-09-06"
16269
16408
  description: "Complete skills catalog with task, hybrid, and knowledge skills. Includes Codex adaptation notes, effort levels, skill-scoped hooks, executable scripts, security auditor, and persona presets."
16270
16409
  ---
16271
16410
 
@@ -16383,7 +16522,7 @@ Hybrid skills combine slash-command invocation with domain knowledge that agents
16383
16522
  | Skill | Directory | Domain |
16384
16523
  |-------|-----------|--------|
16385
16524
  | **app-builder** | `skills/app-builder/` | Full-stack application architecture |
16386
- | **api-patterns** | `skills/api-patterns/` | REST/GraphQL design, versioning, error handling |
16525
+ | **api-patterns** | `skills/api-patterns/` | API design, versioning, actionable error contracts and safe retries; focused `reference/error-contracts.md` |
16387
16526
  | **database-patterns** | `skills/database-patterns/` | Schema design, indexing, query optimization |
16388
16527
  | **flutter-patterns** | `skills/flutter-patterns/` | Flutter/Dart architecture, state management |
16389
16528
  | **ecommerce-patterns** | `skills/ecommerce-patterns/` | E-commerce: catalog, cart, checkout, payments |
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.32.2",
2
+ "version": "4.32.4",
3
3
  "components": {
4
4
  "agents": {
5
5
  "description": "44 specialized agents (orchestrator, backend, frontend, security, devops, etc.)",
@@ -12,7 +12,7 @@
12
12
  ]
13
13
  },
14
14
  "skills": {
15
- "description": "109 skills (32 task + 31 hybrid + 46 knowledge)",
15
+ "description": "114 skills (32 task + 31 hybrid + 51 knowledge)",
16
16
  "path": "app/skills",
17
17
  "target": ".claude/skills",
18
18
  "type": "symlink",
@@ -137,7 +137,7 @@
137
137
  "default": true
138
138
  },
139
139
  "skills": {
140
- "description": "109 skills (task, hybrid, knowledge)",
140
+ "description": "114 skills (task, hybrid, knowledge)",
141
141
  "default": true
142
142
  },
143
143
  "rules-common": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@softspark/ai-toolkit",
3
- "version": "4.32.2",
4
- "description": "AI coding toolkit: 109 skills, 44 agents, 14 developer-tool integrations, recoverable native tool-output filtering, Claude Chat/Cowork export, safety constitution, SARIF audit, and signed npm provenance.",
3
+ "version": "4.32.4",
4
+ "description": "AI coding toolkit: 114 skills, 44 agents, 14 developer-tool integrations, Claude Chat/Cowork export, safety constitution, SARIF audit, and signed npm provenance.",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",