@softspark/ai-toolkit 4.19.0 → 4.20.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 +97 -0
- package/LICENSE +201 -21
- package/NOTICE +55 -0
- package/README.md +23 -13
- package/app/.claude-plugin/plugin.json +2 -2
- package/app/hooks/_hook-io.sh +4 -0
- package/app/hooks/_locate-toolkit.sh +4 -0
- package/app/hooks/_profile-check.sh +4 -0
- package/app/hooks/_search-capability.sh +4 -0
- package/app/hooks/_session-paths.sh +4 -0
- package/app/hooks/ai-toolkit-statusline.sh +4 -0
- package/app/hooks/commit-quality.sh +4 -0
- package/app/hooks/config-desync-guard.sh +4 -0
- package/app/hooks/governance-capture.sh +4 -0
- package/app/hooks/guard-config.sh +4 -0
- package/app/hooks/guard-destructive.sh +4 -0
- package/app/hooks/guard-path.sh +4 -0
- package/app/hooks/instructions-audit.sh +4 -0
- package/app/hooks/loop-guard.sh +4 -0
- package/app/hooks/mcp-health.sh +4 -0
- package/app/hooks/notify-waiting.sh +4 -0
- package/app/hooks/post-tool-use.sh +4 -0
- package/app/hooks/pre-compact-save.sh +4 -0
- package/app/hooks/pre-compact.sh +4 -0
- package/app/hooks/quality-check.sh +4 -0
- package/app/hooks/quality-gate.sh +4 -0
- package/app/hooks/revert-guard.sh +4 -0
- package/app/hooks/save-session.sh +4 -0
- package/app/hooks/search-tracker.sh +4 -0
- package/app/hooks/session-end.sh +4 -0
- package/app/hooks/session-start.sh +4 -0
- package/app/hooks/stop-search-check.sh +4 -0
- package/app/hooks/subagent-start.sh +4 -0
- package/app/hooks/subagent-stop.sh +4 -0
- package/app/hooks/test-cohesion.sh +4 -0
- package/app/hooks/track-usage.sh +4 -0
- package/app/hooks/user-prompt-submit.sh +4 -0
- package/app/plugins/README.md +15 -15
- package/app/plugins/enterprise-pack/hooks/output-style.sh +4 -0
- package/app/plugins/enterprise-pack/hooks/status-line.sh +4 -0
- package/app/plugins/memory-pack/hooks/observation-capture.sh +4 -0
- package/app/plugins/memory-pack/hooks/session-summary.sh +4 -0
- package/app/plugins/memory-pack/scripts/init_db.py +4 -0
- package/app/plugins/memory-pack/scripts/strip_private.py +4 -0
- package/app/skills/_lib/__init__.py +4 -0
- package/app/skills/_lib/detect_utils.py +4 -0
- package/app/skills/a11y-validate/scripts/a11y-scanner.py +4 -0
- package/app/skills/analyze/scripts/complexity.py +4 -0
- package/app/skills/brand-voice/scripts/measure.py +4 -0
- package/app/skills/build/scripts/detect-build.py +4 -0
- package/app/skills/ci/scripts/ci-detect.py +4 -0
- package/app/skills/commit/scripts/pre-commit-check.py +4 -0
- package/app/skills/cve-scan/scripts/cve_scan.py +4 -0
- package/app/skills/debug/scripts/error-parser.py +4 -0
- package/app/skills/deploy/scripts/pre_deploy_check.py +4 -0
- package/app/skills/docs/scripts/doc-inventory.py +4 -0
- package/app/skills/explain/scripts/dependency-graph.py +4 -0
- package/app/skills/explore/scripts/visualize.py +4 -0
- package/app/skills/fix/scripts/error-classifier.py +4 -0
- package/app/skills/health/scripts/health_check.py +4 -0
- package/app/skills/hipaa-validate/scripts/hipaa_scan.py +4 -0
- package/app/skills/lint/scripts/detect-linters.py +4 -0
- package/app/skills/migrate/scripts/migration-status.py +4 -0
- package/app/skills/plugin-creator/SKILL.md +18 -8
- package/app/skills/pr/scripts/pr-summary.py +4 -0
- package/app/skills/refactor/scripts/refactor-scan.py +4 -0
- package/app/skills/review/scripts/diff-analyzer.py +4 -0
- package/app/skills/rollback/scripts/rollback_info.py +4 -0
- package/app/skills/seo-validate/scripts/seo-scanner.py +4 -0
- package/app/skills/skill-creator/templates/reasoning-engine/search.py +4 -0
- package/app/skills/test/scripts/detect-runner.py +4 -0
- package/app/skills/write-a-prd/scripts/poll.js +4 -0
- package/benchmarks/ecosystem-doctor-snapshot.json +3 -3
- package/benchmarks/run.py +4 -0
- package/bin/ai-toolkit.js +4 -0
- package/kb/{planning/drop-cascade-hooks-after-sunset.md → history/completed/drop-cascade-hooks-after-sunset-20260710.md} +24 -0
- package/kb/{reference/language-packs.md → history/completed/language-packs-removed-20260727.md} +32 -7
- package/kb/{planning/mcp-context-trim-v4-prd.md → history/completed/mcp-context-trim-v4-prd-obsoleted-20260727.md} +43 -9
- package/kb/history/completed/no-op-plugin-packs-removed-20260727.md +127 -0
- package/kb/history/completed/tool-output-token-reduction-closed-20260727.md +190 -0
- package/kb/procedures/release-preparation-sop.md +83 -5
- package/kb/reference/comparison.md +1 -1
- package/kb/reference/enterprise-config-guide.md +1 -1
- package/kb/reference/licensing.md +148 -0
- package/kb/reference/plugin-pack-conventions.md +24 -16
- package/llms-full.txt +1181 -529
- package/llms.txt +6 -3
- package/manifest.json +1 -1
- package/package.json +3 -2
- package/scripts/_common.py +4 -0
- package/scripts/add_rule.py +4 -0
- package/scripts/audit_skills.py +4 -0
- package/scripts/benchmark_config.py +4 -0
- package/scripts/benchmark_ecosystem.py +4 -0
- package/scripts/check_deps.py +4 -0
- package/scripts/claude_app.py +4 -0
- package/scripts/codex_skill_adapter.py +4 -0
- package/scripts/compile_slm.py +4 -0
- package/scripts/config_cli.py +4 -0
- package/scripts/config_lock.py +4 -0
- package/scripts/config_merger.py +4 -0
- package/scripts/config_resolver.py +4 -0
- package/scripts/config_scaffold.py +5 -1
- package/scripts/config_validator.py +4 -0
- package/scripts/create_skill.py +4 -0
- package/scripts/dir_rules_shared.py +4 -0
- package/scripts/doctor.py +4 -0
- package/scripts/ecosystem_doctor.py +4 -0
- package/scripts/eject.py +4 -0
- package/scripts/emission.py +4 -0
- package/scripts/evaluate_skills.py +4 -0
- package/scripts/frontmatter.py +4 -0
- package/scripts/generate_agents_md.py +4 -0
- package/scripts/generate_aider_conf.py +4 -0
- package/scripts/generate_antigravity.py +4 -0
- package/scripts/generate_augment.py +4 -0
- package/scripts/generate_augment_agents.py +4 -0
- package/scripts/generate_augment_commands.py +4 -0
- package/scripts/generate_augment_hooks.py +4 -0
- package/scripts/generate_augment_rules.py +4 -0
- package/scripts/generate_augment_skills.py +4 -0
- package/scripts/generate_cline.py +4 -0
- package/scripts/generate_cline_rules.py +4 -0
- package/scripts/generate_cline_skills.py +4 -0
- package/scripts/generate_codex.py +4 -0
- package/scripts/generate_codex_agents.py +4 -0
- package/scripts/generate_codex_hooks.py +4 -0
- package/scripts/generate_codex_skills.py +4 -0
- package/scripts/generate_conventions.py +4 -0
- package/scripts/generate_copilot.py +4 -0
- package/scripts/generate_copilot_hooks.py +4 -0
- package/scripts/generate_cursor_agents.py +4 -0
- package/scripts/generate_cursor_hooks.py +4 -0
- package/scripts/generate_cursor_mdc.py +4 -0
- package/scripts/generate_cursor_rules.py +4 -0
- package/scripts/generate_cursor_skills.py +4 -0
- package/scripts/generate_devin_hooks.py +4 -0
- package/scripts/generate_gemini.py +4 -0
- package/scripts/generate_gemini_commands.py +4 -0
- package/scripts/generate_gemini_hooks.py +4 -0
- package/scripts/generate_gemini_skills.py +4 -0
- package/scripts/generate_language_rules_skills.py +4 -0
- package/scripts/generate_llms_txt.py +4 -0
- package/scripts/generate_opencode.py +4 -0
- package/scripts/generate_opencode_agents.py +4 -0
- package/scripts/generate_opencode_commands.py +4 -0
- package/scripts/generate_opencode_json.py +4 -0
- package/scripts/generate_opencode_plugin.py +4 -0
- package/scripts/generate_roo_modes.py +4 -0
- package/scripts/generate_roo_rules.py +4 -0
- package/scripts/generate_windsurf.py +4 -0
- package/scripts/generate_windsurf_rules.py +4 -0
- package/scripts/generate_windsurf_skills.py +4 -0
- package/scripts/generator_base.py +4 -0
- package/scripts/harvest_ecosystem.py +4 -0
- package/scripts/hook_sources.py +4 -0
- package/scripts/inject_hook_cli.py +4 -0
- package/scripts/inject_mcp_cli.py +4 -0
- package/scripts/inject_rule_cli.py +4 -0
- package/scripts/inject_section_cli.py +4 -0
- package/scripts/injection.py +4 -0
- package/scripts/install.py +4 -0
- package/scripts/install_git_hooks.py +4 -0
- package/scripts/install_steps/__init__.py +4 -0
- package/scripts/install_steps/ai_tools.py +4 -0
- package/scripts/install_steps/detect_language.py +4 -0
- package/scripts/install_steps/hooks.py +4 -0
- package/scripts/install_steps/install_state.py +4 -0
- package/scripts/install_steps/markers.py +4 -0
- package/scripts/install_steps/project_registry.py +4 -0
- package/scripts/install_steps/symlinks.py +4 -0
- package/scripts/instruction_core.py +4 -0
- package/scripts/mcp_editors.py +4 -0
- package/scripts/mcp_manager.py +4 -0
- package/scripts/mcp_sources.py +4 -0
- package/scripts/merge-hooks.py +4 -0
- package/scripts/migrate.py +4 -0
- package/scripts/output_filter_retirement.py +4 -0
- package/scripts/pack_codebase.py +4 -0
- package/scripts/paths.py +4 -0
- package/scripts/plugin.py +4 -0
- package/scripts/plugin_schema.py +4 -0
- package/scripts/projects_cli.py +4 -0
- package/scripts/propagate_global.py +4 -0
- package/scripts/remove_rule.py +4 -0
- package/scripts/rule_sources.py +4 -0
- package/scripts/secure_fs.py +4 -0
- package/scripts/session_state.py +4 -0
- package/scripts/session_token_stats.py +4 -0
- package/scripts/skill_pointer.py +4 -0
- package/scripts/stats.py +4 -0
- package/scripts/sync.py +4 -0
- package/scripts/test_cohesion.py +4 -0
- package/scripts/uninstall.py +4 -0
- package/scripts/update_projects.py +4 -0
- package/scripts/url_fetch.py +4 -0
- package/scripts/validate.py +4 -0
- package/scripts/version_check.py +4 -0
- package/app/plugins/csharp-pack/README.md +0 -11
- package/app/plugins/csharp-pack/plugin.json +0 -18
- package/app/plugins/frontend-pack/README.md +0 -14
- package/app/plugins/frontend-pack/plugin.json +0 -22
- package/app/plugins/java-pack/README.md +0 -11
- package/app/plugins/java-pack/plugin.json +0 -18
- package/app/plugins/kotlin-pack/README.md +0 -11
- package/app/plugins/kotlin-pack/plugin.json +0 -18
- package/app/plugins/research-pack/README.md +0 -14
- package/app/plugins/research-pack/plugin.json +0 -22
- package/app/plugins/ruby-pack/README.md +0 -11
- package/app/plugins/ruby-pack/plugin.json +0 -18
- package/app/plugins/rust-pack/README.md +0 -11
- package/app/plugins/rust-pack/plugin.json +0 -18
- package/app/plugins/security-pack/README.md +0 -15
- package/app/plugins/security-pack/plugin.json +0 -23
- package/app/plugins/swift-pack/README.md +0 -11
- package/app/plugins/swift-pack/plugin.json +0 -18
package/llms-full.txt
CHANGED
|
@@ -14,19 +14,22 @@
|
|
|
14
14
|
- [Best Practices](kb/best-practices/README.md)
|
|
15
15
|
- [No Hardcoded Counts in Secondary Docs](kb/best-practices/no-hardcoded-counts.md)
|
|
16
16
|
- [Plan: Deep Coverage v3.0 — 100% Native Surface Utilization](kb/history/completed/deep-coverage-v3-20260423.md)
|
|
17
|
+
- [Plan: Drop Cascade hooks after 2026-07-01 sunset](kb/history/completed/drop-cascade-hooks-after-sunset-20260710.md)
|
|
17
18
|
- [Plan: Ecosystem Deep Sweep — All 12 Supported Tools](kb/history/completed/ecosystem-deep-sweep-20260423.md)
|
|
18
19
|
- [Plan: Enterprise Config Inheritance — Multi-Repo Governance with `extends`](kb/history/completed/enterprise-config-inheritance-plan-20260412.md)
|
|
19
20
|
- [Spike: F2 MCP Context Trim — Hook Feasibility & Path Decision](kb/history/completed/f2-mcp-trim-spike-20260504.md)
|
|
21
|
+
- [Language Plugin Packs — REMOVED](kb/history/completed/language-packs-removed-20260727.md)
|
|
22
|
+
- [PRD: MCP Context Trim v4.0 — ABANDONED](kb/history/completed/mcp-context-trim-v4-prd-obsoleted-20260727.md)
|
|
20
23
|
- [Implementation Plan: Native Tool Output Filter](kb/history/completed/native-tool-output-filter-plan.md)
|
|
24
|
+
- [Removed: Nine Plugin Packs That Installed Nothing](kb/history/completed/no-op-plugin-packs-removed-20260727.md)
|
|
21
25
|
- [Plan: Offline-First SLM Profile — Lightweight Mode for Local Models](kb/history/completed/offline-slm-profile-plan-20260411.md)
|
|
22
26
|
- [Retirement: Native Tool-Output Filter](kb/history/completed/output-filter-retirement-20260726.md)
|
|
23
27
|
- [Plan: Output & Token Discipline](kb/history/completed/output-token-discipline-plan-20260504.md)
|
|
24
28
|
- [rtk Pack Integration](kb/history/completed/rtk-pack-integration-20260726.md)
|
|
25
29
|
- [Retirement: rtk-pack](kb/history/completed/rtk-pack-retirement-20260727.md)
|
|
30
|
+
- [Closed: Tool-Output Token Reduction](kb/history/completed/tool-output-token-reduction-closed-20260727.md)
|
|
26
31
|
- [How-To Guides](kb/howto/README.md)
|
|
27
32
|
- [Plan: Cloud Security Pack — Multi-Cloud Audit](kb/planning/cloud-security-pack-plan.md)
|
|
28
|
-
- [Plan: Drop Cascade hooks after 2026-07-01 sunset](kb/planning/drop-cascade-hooks-after-sunset.md)
|
|
29
|
-
- [PRD: MCP Context Trim v4.0](kb/planning/mcp-context-trim-v4-prd.md)
|
|
30
33
|
- [SOP: Ecosystem Sync](kb/procedures/ecosystem-sync-sop.md)
|
|
31
34
|
- [SOP: AI Toolkit Maintenance](kb/procedures/maintenance-sop.md)
|
|
32
35
|
- [SOP: Post-Release Testing](kb/procedures/post-release-testing-sop.md)
|
|
@@ -51,8 +54,8 @@
|
|
|
51
54
|
- [Hierarchical Override Pattern](kb/reference/hierarchical-override-pattern.md)
|
|
52
55
|
- [Hooks Catalog](kb/reference/hooks-catalog.md)
|
|
53
56
|
- [External Integrations](kb/reference/integrations.md)
|
|
54
|
-
- [Language Plugin Packs](kb/reference/language-packs.md)
|
|
55
57
|
- [Language Rules System](kb/reference/language-rules.md)
|
|
58
|
+
- [Licensing](kb/reference/licensing.md)
|
|
56
59
|
- [Manifest-Driven Install System](kb/reference/manifest-install.md)
|
|
57
60
|
- [MCP Editor Compatibility](kb/reference/mcp-editor-compatibility.md)
|
|
58
61
|
- [MCP Server Templates](kb/reference/mcp-templates.md)
|
|
@@ -458,6 +461,131 @@ Definition of "100% coverage" chosen: **each editor works at 100% of its native
|
|
|
458
461
|
|
|
459
462
|
---
|
|
460
463
|
|
|
464
|
+
## kb/history/completed/drop-cascade-hooks-after-sunset-20260710.md
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
title: "Plan: Drop Cascade hooks after 2026-07-01 sunset"
|
|
468
|
+
category: planning
|
|
469
|
+
service: ai-toolkit
|
|
470
|
+
tags:
|
|
471
|
+
- windsurf
|
|
472
|
+
- devin
|
|
473
|
+
- cascade
|
|
474
|
+
- hooks
|
|
475
|
+
- deprecation
|
|
476
|
+
- cleanup
|
|
477
|
+
doc_type: plan
|
|
478
|
+
status: completed
|
|
479
|
+
created: "2026-06-10"
|
|
480
|
+
last_updated: "2026-07-10"
|
|
481
|
+
completion: "100%"
|
|
482
|
+
trigger_date: "2026-07-01"
|
|
483
|
+
description: "Completed cleanup of the deprecated Windsurf Cascade hooks generator after the 2026-07-01 sunset; Devin CLI .devin/hooks.v1.json is now the sole live hook surface."
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
# Plan: Drop Cascade hooks after 2026-07-01 sunset
|
|
487
|
+
|
|
488
|
+
**Completed in v4.13.0 (2026-07-10).** The deprecated generator and install/test wiring were removed; the Devin hook generator remains.
|
|
489
|
+
|
|
490
|
+
> **Filed to history 2026-07-27.** The plan was finished in v4.13.0 but sat in
|
|
491
|
+
> `kb/planning/` for another two and a half weeks, where it read as open work.
|
|
492
|
+
> Before moving it, every claim in the Verification section below was re-run
|
|
493
|
+
> against the codebase:
|
|
494
|
+
>
|
|
495
|
+
> | Check | Result |
|
|
496
|
+
> |---|---|
|
|
497
|
+
> | `scripts/generate_windsurf_hooks.py` deleted | gone |
|
|
498
|
+
> | `grep -rn generate_windsurf_hooks scripts/ tests/` | no source references (one stale `.pyc` under gitignored `__pycache__`) |
|
|
499
|
+
> | `_HOOK_STEM_ALIAS = {"devin": "windsurf"}` retained in `validate.py` | present, line 882 |
|
|
500
|
+
> | windsurf `our_generators` in `scripts/ecosystem_tools.json` | Cascade generator absent, `generate_devin_hooks.py` present |
|
|
501
|
+
> | `kb/reference/supported-tools-registry.md` hooks-migration row | reads "Complete" in past tense |
|
|
502
|
+
> | `validate.py --strict` | 0 errors, 0 warnings |
|
|
503
|
+
>
|
|
504
|
+
> The work was real and complete. Only the filing was wrong.
|
|
505
|
+
>
|
|
506
|
+
> **Process note.** This is the second document found misfiled in
|
|
507
|
+
> `kb/planning/` on the same day; the other,
|
|
508
|
+
> [`mcp-context-trim-v4-prd-obsoleted-20260727.md`](mcp-context-trim-v4-prd-obsoleted-20260727.md),
|
|
509
|
+
> had gone obsolete because the platform shipped the fix first. A plan with a
|
|
510
|
+
> `trigger_date` needs a matching move-to-history step in the release that acts
|
|
511
|
+
> on it — otherwise `kb/planning/` accumulates work that is already done or no
|
|
512
|
+
> longer worth doing, and the next reader cannot tell which is which.
|
|
513
|
+
|
|
514
|
+
## Why this exists
|
|
515
|
+
|
|
516
|
+
Windsurf rebranded to Devin Desktop on 2026-06-02. The Cascade agent — and its
|
|
517
|
+
`.windsurf/hooks.json` hook surface (`agent_action_name`/`tool_info` format) — is
|
|
518
|
+
available **only through 2026-07-01**. Devin Local / Devin CLI do **not** read
|
|
519
|
+
`.windsurf/hooks.json` as a fallback.
|
|
520
|
+
|
|
521
|
+
v4.8.0 already shipped the replacement: `generate_devin_hooks.py` emits
|
|
522
|
+
`.devin/hooks.v1.json` in the Claude-compatible format Devin CLI uses. During the
|
|
523
|
+
transition **both** generators run at `profile=full` so pre-sunset Cascade users
|
|
524
|
+
keep working. After 2026-07-01 the Cascade half is dead code and must be removed
|
|
525
|
+
(Constitution Art. VI.1 — no dead code).
|
|
526
|
+
|
|
527
|
+
## Trigger
|
|
528
|
+
|
|
529
|
+
First ai-toolkit release **on or after 2026-07-01**. Do NOT do this earlier —
|
|
530
|
+
removing it before the sunset breaks Cascade users who are still on the old agent.
|
|
531
|
+
|
|
532
|
+
## Scope — remove the Cascade hooks surface
|
|
533
|
+
|
|
534
|
+
1. **Delete the generator:** `scripts/generate_windsurf_hooks.py`.
|
|
535
|
+
2. **Unwire the install step:** in `scripts/install_steps/ai_tools.py`, remove the
|
|
536
|
+
`_try_generator("generate_windsurf_hooks", cwd)` call (keep
|
|
537
|
+
`generate_devin_hooks`). Update the `profile=full` dry-run message to drop
|
|
538
|
+
`.windsurf/hooks.json (Cascade, deprecated)`.
|
|
539
|
+
3. **Tests:** remove the windsurf-`.windsurf/hooks.json` cases from
|
|
540
|
+
`tests/test_hooks_per_editor.bats` (output path, valid JSON, source tag,
|
|
541
|
+
`$HOME` prefix, idempotence, user-preservation, `pre_write_code` coverage) and
|
|
542
|
+
the `profile=full` assertion in `tests/test_install_profiles.bats`
|
|
543
|
+
(`windsurf + full emits .windsurf/hooks.json`). Keep all `.devin/hooks.v1.json`
|
|
544
|
+
tests. Adjust the README test-count badge to the new total.
|
|
545
|
+
4. **Registry:** in `scripts/ecosystem_tools.json` (windsurf entry), remove
|
|
546
|
+
`scripts/generate_windsurf_hooks.py` from `our_generators`; keep
|
|
547
|
+
`.windsurf/hooks.json` out of `config_paths` (it was never listed). Trim the
|
|
548
|
+
`status_note` hooks-migration paragraph to past tense ("Cascade hooks removed
|
|
549
|
+
in vX.Y.Z").
|
|
550
|
+
5. **Docs:** in `kb/reference/supported-tools-registry.md` drop the
|
|
551
|
+
`generate_windsurf_hooks.py` row and the "drop after 2026-07-01" note; in
|
|
552
|
+
`kb/reference/hooks-catalog.md` remove the Cascade row from the
|
|
553
|
+
Per-Editor Native Hooks table and the deprecation wording, leaving the Devin CLI
|
|
554
|
+
section as the windsurf-family hook surface.
|
|
555
|
+
6. **validate.py:** the `_HOOK_STEM_ALIAS = {"devin": "windsurf"}` mapping STAYS —
|
|
556
|
+
it is what keeps the `devin` hook generator counted as windsurf hooks in the
|
|
557
|
+
README-honesty check after the Cascade generator is gone.
|
|
558
|
+
7. **CHANGELOG / version:** minor bump, `Removed` entry, regen artifacts, full
|
|
559
|
+
release-preparation SOP gate.
|
|
560
|
+
|
|
561
|
+
## Verification
|
|
562
|
+
|
|
563
|
+
- `python3 scripts/validate.py --strict` — 0/0 (editor-hooks-honesty must still
|
|
564
|
+
report windsurf as hook-enabled via the `devin` generator alias).
|
|
565
|
+
- `python3 scripts/ecosystem_doctor.py --offline --check` — exit 0.
|
|
566
|
+
- `npm test` — 0 `not ok`; no test recreates the deleted
|
|
567
|
+
`generate_windsurf_hooks.py` generator.
|
|
568
|
+
- `grep -rn "generate_windsurf_hooks" scripts/ tests/` returns nothing
|
|
569
|
+
(Art. VI.1 orphan check — the deleted generator is fully unwired).
|
|
570
|
+
`.windsurf/hooks.json` intentionally remains referenced by the one-time
|
|
571
|
+
migration/strip cleanup (`scripts/install_steps/ai_tools.py`) and its test,
|
|
572
|
+
and in narrative docs (CHANGELOG, README, `kb/`, docstrings).
|
|
573
|
+
|
|
574
|
+
## Do NOT touch
|
|
575
|
+
|
|
576
|
+
- `generate_devin_hooks.py` and `.devin/hooks.v1.json` — the live replacement.
|
|
577
|
+
- The `.devin/`/`.windsurf/` rules + skills dual-emit (that fallback persists as
|
|
578
|
+
long as Devin Desktop reads legacy `.windsurf/` paths; this plan is hooks-only).
|
|
579
|
+
|
|
580
|
+
## Related
|
|
581
|
+
|
|
582
|
+
- `kb/reference/hooks-catalog.md` — Per-Editor Native Hooks + Devin CLI section
|
|
583
|
+
- `kb/reference/supported-tools-registry.md` — windsurf entry, hooks-migration row
|
|
584
|
+
- `kb/procedures/ecosystem-sync-sop.md` — class-D deprecation workflow
|
|
585
|
+
- `scripts/ecosystem_tools.json` — windsurf `status_note`
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
461
589
|
## kb/history/completed/ecosystem-deep-sweep-20260423.md
|
|
462
590
|
|
|
463
591
|
---
|
|
@@ -1780,110 +1908,389 @@ Estimate in the PRD: ~8 working days.
|
|
|
1780
1908
|
|
|
1781
1909
|
---
|
|
1782
1910
|
|
|
1783
|
-
## kb/history/completed/
|
|
1911
|
+
## kb/history/completed/language-packs-removed-20260727.md
|
|
1784
1912
|
|
|
1785
1913
|
---
|
|
1786
|
-
title: "
|
|
1914
|
+
title: "AI Toolkit - Language Plugin Packs (removed)"
|
|
1787
1915
|
category: planning
|
|
1788
1916
|
service: ai-toolkit
|
|
1789
|
-
tags:
|
|
1790
|
-
|
|
1791
|
-
- hooks
|
|
1792
|
-
- recovery
|
|
1793
|
-
- performance
|
|
1794
|
-
- claude-code
|
|
1795
|
-
doc_type: plan
|
|
1917
|
+
tags: [plugins, languages, rust, java, csharp, kotlin, swift, ruby, removed]
|
|
1918
|
+
doc_type: postmortem
|
|
1796
1919
|
status: completed
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1920
|
+
version: "1.1.0"
|
|
1921
|
+
created: "2026-03-29"
|
|
1922
|
+
last_updated: "2026-07-27"
|
|
1923
|
+
description: "REMOVED 2026-07-27 in v4.20.0. The six language packs wrapped skills that already ship in core, so installing one put zero files on disk. The skills themselves (rust-patterns, java-patterns, csharp-patterns, kotlin-patterns, swift-patterns, ruby-patterns) were never in the packs and are unaffected."
|
|
1924
|
+
---
|
|
1925
|
+
|
|
1926
|
+
# Language Plugin Packs — REMOVED
|
|
1927
|
+
|
|
1928
|
+
> **Removed 2026-07-27 in v4.20.0. Nothing was lost.**
|
|
1929
|
+
>
|
|
1930
|
+
> The six packs described below each declared exactly one skill —
|
|
1931
|
+
> `rust-patterns`, `java-patterns`, `csharp-patterns`, `kotlin-patterns`,
|
|
1932
|
+
> `swift-patterns`, `ruby-patterns` — and every one of those skills lives in
|
|
1933
|
+
> `app/skills/`, is part of the core install, and **still does**. The packs
|
|
1934
|
+
> owned no files of their own beyond a `README.md`.
|
|
1935
|
+
>
|
|
1936
|
+
> Because `ai-toolkit install` links every core skill, installing a language
|
|
1937
|
+
> pack put **zero** files on disk. Measured on both runtimes and all three
|
|
1938
|
+
> profiles: `(0 file items)` every time.
|
|
1939
|
+
>
|
|
1940
|
+
> **If you used one of these packs, you lose nothing.** The skill it named is
|
|
1941
|
+
> already installed and triggers on the same file types it always did — open a
|
|
1942
|
+
> `.rs` file and `rust-patterns` still loads.
|
|
1943
|
+
>
|
|
1944
|
+
> Full measurement and the rule that now prevents a repeat:
|
|
1945
|
+
> [`no-op-plugin-packs-removed-20260727.md`](no-op-plugin-packs-removed-20260727.md).
|
|
1946
|
+
>
|
|
1947
|
+
> The document below is preserved as written on 2026-03-29.
|
|
1948
|
+
|
|
1803
1949
|
---
|
|
1804
1950
|
|
|
1805
|
-
|
|
1951
|
+
## Overview
|
|
1806
1952
|
|
|
1807
|
-
|
|
1953
|
+
Language packs are domain-scoped plugin packs that provide knowledge skills for specific programming languages. Each pack contains a single knowledge skill with idiomatic patterns, error handling, testing conventions, common frameworks, and performance tips.
|
|
1808
1954
|
|
|
1809
|
-
|
|
1955
|
+
## Available Packs
|
|
1810
1956
|
|
|
1811
|
-
|
|
1957
|
+
| Pack | Skill | Language | Key Topics |
|
|
1958
|
+
|------|-------|----------|------------|
|
|
1959
|
+
| `rust-pack` | `rust-patterns` | Rust | Ownership, borrowing, Cargo, tokio, serde |
|
|
1960
|
+
| `java-pack` | `java-patterns` | Java | Records, sealed classes, Spring Boot, JUnit 5 |
|
|
1961
|
+
| `csharp-pack` | `csharp-patterns` | C# / .NET | Nullable refs, async/await, ASP.NET Core, EF Core |
|
|
1962
|
+
| `kotlin-pack` | `kotlin-patterns` | Kotlin | Coroutines, DSLs, sealed classes, Ktor, MockK |
|
|
1963
|
+
| `swift-pack` | `swift-patterns` | Swift / iOS | Protocol-oriented, SwiftUI, async/await, SPM |
|
|
1964
|
+
| `ruby-pack` | `ruby-patterns` | Ruby | Blocks, Rails conventions, RSpec, ActiveRecord |
|
|
1812
1965
|
|
|
1813
|
-
|
|
1814
|
-
- The 100-sample cold wrapper measures 63.565 ms p95 against the 75 ms gate.
|
|
1815
|
-
- The 8 MiB profile case measures 4.354 ms p95 and 8,792,932 peak traced
|
|
1816
|
-
bytes against the 150 ms and 41,943,040 byte gates.
|
|
1817
|
-
- The strict repository validator reports 44 agents, 108 skills, and 1477
|
|
1818
|
-
tests with zero errors or warnings.
|
|
1819
|
-
- Ruff, mypy, ShellCheck, skill audit, generated artifacts, and the final
|
|
1820
|
-
repository test gate pass for the changed surface.
|
|
1966
|
+
## Skill Content Sections
|
|
1821
1967
|
|
|
1822
|
-
|
|
1968
|
+
Each language skill follows a consistent structure:
|
|
1823
1969
|
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1970
|
+
1. **Project Structure** — standard directory layout and build tool configuration
|
|
1971
|
+
2. **Idioms / Code Style** — language-specific patterns and conventions
|
|
1972
|
+
3. **Error Handling** — error types, patterns, and best practices
|
|
1973
|
+
4. **Testing Patterns** — test frameworks, assertion libraries, mocking
|
|
1974
|
+
5. **Common Libraries / Frameworks** — ecosystem essentials
|
|
1975
|
+
6. **Performance Tips** — optimization techniques and profiling
|
|
1976
|
+
7. **Build / Package Management** — dependency management and CI
|
|
1830
1977
|
|
|
1831
|
-
|
|
1832
|
-
support replacing successful tool output through
|
|
1833
|
-
`PostToolUse.hookSpecificOutput.updatedToolOutput`. The transformer remains
|
|
1834
|
-
strictly post-execution and cannot alter the command, arguments, environment,
|
|
1835
|
-
working directory, permission decision, exit status, or signal.
|
|
1978
|
+
## How Knowledge Skills Work
|
|
1836
1979
|
|
|
1837
|
-
|
|
1838
|
-
transform an executed tool result, but they do not intercept MCP catalog
|
|
1839
|
-
metadata. [PATH: kb/history/completed/f2-mcp-trim-spike-20260504.md]
|
|
1840
|
-
[PATH: kb/planning/mcp-context-trim-v4-prd.md]
|
|
1980
|
+
These skills have `user-invocable: false` in their frontmatter, meaning they are NOT slash commands. Instead, Claude loads them contextually when the conversation topic matches the skill's description trigger.
|
|
1841
1981
|
|
|
1842
|
-
|
|
1982
|
+
For example, when a user asks "How do I handle errors in Rust?", Claude automatically loads `rust-patterns` to provide idiomatic Rust error handling guidance.
|
|
1843
1983
|
|
|
1844
|
-
|
|
1845
|
-
- The current safety guards run in `PreToolUse`. [PATH: app/hooks.json:37]
|
|
1846
|
-
- Hook runtime Python helpers are deployed explicitly.
|
|
1847
|
-
[PATH: scripts/install_steps/hooks.py:71]
|
|
1848
|
-
- Runtime hook schemas differ by editor.
|
|
1849
|
-
[PATH: kb/reference/hooks-catalog.md:571]
|
|
1850
|
-
- Existing output/token work intentionally uses native mechanisms.
|
|
1851
|
-
[PATH: kb/history/completed/output-token-discipline-plan-20260504.md]
|
|
1852
|
-
- Claude hook contract:
|
|
1853
|
-
<https://code.claude.com/docs/en/hooks>
|
|
1984
|
+
## Requesting New Language Packs
|
|
1854
1985
|
|
|
1855
|
-
|
|
1986
|
+
File an issue with the `language-pack` label. Include:
|
|
1987
|
+
- Language name
|
|
1988
|
+
- Key topics to cover
|
|
1989
|
+
- Popular frameworks/libraries to include
|
|
1856
1990
|
|
|
1857
|
-
|
|
1991
|
+
---
|
|
1858
1992
|
|
|
1859
|
-
-
|
|
1860
|
-
- Pure post-execution transformation of successful textual Bash output.
|
|
1861
|
-
- `off`, `observe`, and `safe` modes.
|
|
1862
|
-
- Claude Code integration through `PostToolUse.updatedToolOutput`.
|
|
1863
|
-
- Manual CLI for fixture inspection, status, recovery, and cleanup.
|
|
1864
|
-
- Two initial deterministic profiles:
|
|
1865
|
-
- `repeat-lines`: aggregate adjacent identical non-diagnostic lines and state
|
|
1866
|
-
their multiplicity.
|
|
1867
|
-
- `tap-success`: compact valid successful TAP while retaining plan,
|
|
1868
|
-
directives, comments, totals, duration, and all diagnostic material.
|
|
1869
|
-
- Byte and line savings, latency, outcome, profile ID, and profile version.
|
|
1870
|
-
- Exact, bounded, session-scoped raw recovery when `safe` mode is enabled.
|
|
1871
|
-
- Capability-gated adapters for additional runtimes after Phase 2.
|
|
1993
|
+
## kb/history/completed/mcp-context-trim-v4-prd-obsoleted-20260727.md
|
|
1872
1994
|
|
|
1873
|
-
|
|
1995
|
+
---
|
|
1996
|
+
title: "PRD: MCP Context Trim v4.0 — Local Proxy with Description Compression"
|
|
1997
|
+
category: planning
|
|
1998
|
+
service: ai-toolkit
|
|
1999
|
+
tags:
|
|
2000
|
+
- mcp
|
|
2001
|
+
- proxy
|
|
2002
|
+
- tool-descriptions
|
|
2003
|
+
- jsonrpc
|
|
2004
|
+
- tokens
|
|
2005
|
+
- v4
|
|
2006
|
+
doc_type: plan
|
|
2007
|
+
status: obsoleted
|
|
2008
|
+
created: "2026-05-04"
|
|
2009
|
+
last_updated: "2026-07-27"
|
|
2010
|
+
completion: "0% — never started, and no longer worth starting"
|
|
2011
|
+
target_milestone: "v4.0 (abandoned)"
|
|
2012
|
+
predecessor:
|
|
2013
|
+
- "kb/history/completed/output-token-discipline-plan-20260504.md"
|
|
2014
|
+
- "kb/history/completed/f2-mcp-trim-spike-20260504.md"
|
|
2015
|
+
description: "ABANDONED 2026-07-27. Local MCP proxy that would compress tool descriptions before they reach the model. Never built. Claude Code now defers MCP tool schemas by default — the catalog costs ~120 tokens of tool names, with schemas fetched on demand — so the 8-15k per-turn overhead this PRD was written to remove no longer exists. Kept as the record of a plan the platform solved first."
|
|
2016
|
+
---
|
|
2017
|
+
|
|
2018
|
+
# PRD: MCP Context Trim v4.0 — ABANDONED
|
|
2019
|
+
|
|
2020
|
+
> **Abandoned 2026-07-27, never implemented.**
|
|
2021
|
+
>
|
|
2022
|
+
> **Why:** the premise expired. This PRD is built on one measured claim — that
|
|
2023
|
+
> MCP tool descriptions sit in every turn's system prompt, costing 8–15k tokens
|
|
2024
|
+
> per turn. Claude Code now **defers MCP tool schemas by default**: the model
|
|
2025
|
+
> receives roughly 120 tokens of tool *names*, and full schemas are fetched on
|
|
2026
|
+
> demand through tool search when a task actually needs one.
|
|
2027
|
+
> ([Claude Code docs — context window](https://code.claude.com/docs/en/context-window),
|
|
2028
|
+
> `ENABLE_TOOL_SEARCH=auto|false` controls the older eager behaviour.)
|
|
2029
|
+
>
|
|
2030
|
+
> The overhead this proxy was designed to remove is already gone. Building it
|
|
2031
|
+
> now would add a supervised local daemon, an `.mcp.json` rewrite, a rollback
|
|
2032
|
+
> path and five pre-mortem failure modes in order to compress a 120-token
|
|
2033
|
+
> catalog.
|
|
2034
|
+
>
|
|
2035
|
+
> **How it was caught:** during the 2026-07-27 token-reduction review, a
|
|
2036
|
+
> measurement of 1189 real sessions put the median startup context at 22,175
|
|
2037
|
+
> tokens against ~7,850 in the documented reference shape. Attributing that gap
|
|
2038
|
+
> showed the excess was skill and agent descriptions and rule files — not MCP.
|
|
2039
|
+
> The MCP catalog was already deferred, exactly as the docs describe. Full
|
|
2040
|
+
> context: [`tool-output-token-reduction-closed-20260727.md`](tool-output-token-reduction-closed-20260727.md).
|
|
2041
|
+
>
|
|
2042
|
+
> **What survives:** nothing in the architecture below is reusable, because it
|
|
2043
|
+
> exists to solve a problem the host now solves. What survives is the process
|
|
2044
|
+
> note — this PRD sat in `kb/planning/` for nearly three months while the
|
|
2045
|
+
> platform shipped the fix, and nobody re-checked the premise. A plan blocked on
|
|
2046
|
+
> a host limitation should carry a re-validation date, not wait indefinitely.
|
|
2047
|
+
>
|
|
2048
|
+
> Everything below is the document as written on 2026-05-04. It is preserved
|
|
2049
|
+
> unedited so the reasoning stays auditable.
|
|
2050
|
+
|
|
2051
|
+
---
|
|
2052
|
+
|
|
2053
|
+
**Status:** Proposed *(as of 2026-05-04; see abandonment note above)*
|
|
2054
|
+
**Target milestone:** v4.0
|
|
2055
|
+
**Carved out of:** [`output-token-discipline-plan-20260504.md`](output-token-discipline-plan-20260504.md) (was Feature 2)
|
|
2056
|
+
**Spike basis:** [`f2-mcp-trim-spike-20260504.md`](f2-mcp-trim-spike-20260504.md)
|
|
1874
2057
|
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
-
|
|
1880
|
-
-
|
|
1881
|
-
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2058
|
+
## Problem
|
|
2059
|
+
|
|
2060
|
+
MCP server tool descriptions are injected into every model turn's system prompt. With ~100 tools across 7 typical servers, descriptions consume 8–15k tokens per turn — pure overhead, paid every message. Examples observed in users' configs:
|
|
2061
|
+
|
|
2062
|
+
- `dart-mcp-server` — ~30 tools with multi-paragraph descriptions
|
|
2063
|
+
- `filesystem` — verbose paths and example sections
|
|
2064
|
+
- `pencil` — "IMPORTANT" stanzas repeated across tools
|
|
2065
|
+
- `jira-mcp` — long `Use this tool to…` boilerplate
|
|
2066
|
+
|
|
2067
|
+
The v3.2.0 output-discipline plan attempted to solve this with a hook-based trimmer. The spike conducted 2026-05-04 proved Claude Code hooks do not expose `tools/list` metadata or the system-prompt tool catalog. The only viable architecture is a local MCP proxy.
|
|
2068
|
+
|
|
2069
|
+
## Goal
|
|
2070
|
+
|
|
2071
|
+
Reduce MCP-description overhead by ≥40% per server, with **zero** loss of parameter schemas, required fields, or discrimination signals (`not`, `never`, `only`, `except`, `unless`).
|
|
2072
|
+
|
|
2073
|
+
## Non-goals
|
|
2074
|
+
|
|
2075
|
+
- Modifying tool **call** behavior (only descriptions)
|
|
2076
|
+
- Compressing user-facing prompts or completions
|
|
2077
|
+
- Replacing or rewriting upstream MCP servers
|
|
2078
|
+
- Touching MCP servers we do not control
|
|
2079
|
+
|
|
2080
|
+
## Architecture
|
|
2081
|
+
|
|
2082
|
+
### Proxy topology
|
|
2083
|
+
|
|
2084
|
+
```
|
|
2085
|
+
Claude Code ──stdio──▶ ai-toolkit MCP proxy ──stdio/SSE──▶ upstream MCP server
|
|
2086
|
+
│
|
|
2087
|
+
└─ rewrites tools/list response
|
|
2088
|
+
passes through tools/call unchanged
|
|
2089
|
+
```
|
|
2090
|
+
|
|
2091
|
+
One proxy process per upstream server, supervised by `ai-toolkit mcp-trim daemon` (or equivalent). User's `~/.claude/.mcp.json` is rewritten by `ai-toolkit install` (opt-in) to point Claude Code at the proxy instead of upstream — proxy reads the original target from a sidecar config.
|
|
2092
|
+
|
|
2093
|
+
### Required components
|
|
2094
|
+
|
|
2095
|
+
| Component | Purpose |
|
|
2096
|
+
|-----------|---------|
|
|
2097
|
+
| `scripts/mcp_proxy_server.py` | JSON-RPC 2.0 proxy. Reads stdin, forwards to upstream over stdio or SSE, intercepts `tools/list` response, rewrites descriptions. Stdlib-only. |
|
|
2098
|
+
| `scripts/mcp_description_trimmer.py` | Pure function library: `trim(description: str) → str`. Reused from heuristics below. Stdlib-only. |
|
|
2099
|
+
| `scripts/mcp_proxy_config.py` | Reads `~/.softspark/ai-toolkit/mcp-proxy/servers.json`, validates upstream targets, generates supervisord/launchd config. |
|
|
2100
|
+
| `app/hooks/mcp-proxy-health.sh` | SessionStart hook — verifies all configured proxies responsive; fall through (warn, do not block) if any down. |
|
|
2101
|
+
| `app/skills/mcp-trim/SKILL.md` | Knowledge skill: how to enable, opt out, audit savings. |
|
|
2102
|
+
| `bin/ai-toolkit-mcp-trim` | CLI: `enable`, `disable`, `status`, `audit` (per-server token savings report). |
|
|
2103
|
+
| `tests/test_mcp_proxy.bats` | Integration tests with mock upstream MCP servers. |
|
|
2104
|
+
| `tests/test_mcp_trimmer.bats` | Unit tests for description trim heuristics on captured fixtures. |
|
|
2105
|
+
|
|
2106
|
+
### Compression heuristics (from spike)
|
|
2107
|
+
|
|
2108
|
+
Applied to each tool description in `tools/list` response:
|
|
2109
|
+
|
|
2110
|
+
- Drop example sections >40 chars
|
|
2111
|
+
- Collapse `Use this server to…` / `Use this tool to…` boilerplate to minimum form preserving intent
|
|
2112
|
+
- Drop duplicate occurrences of tool name in its own description
|
|
2113
|
+
- **Preserve bytewise:** `inputSchema.properties[*].description`, `required`, `enum` values, URL/path identifiers
|
|
2114
|
+
- **Never strip:** the words `not`, `never`, `only`, `except`, `unless` — these carry "when NOT to use" signals
|
|
2115
|
+
- Target: ≥40% length reduction, 0% schema loss
|
|
2116
|
+
|
|
2117
|
+
### Failure modes & rollback
|
|
2118
|
+
|
|
2119
|
+
| Scenario | Behavior |
|
|
2120
|
+
|----------|----------|
|
|
2121
|
+
| Proxy crashes mid-session | `mcp-proxy-health.sh` detects on next SessionStart, prints warning, suggests `ai-toolkit mcp-trim disable <server>` |
|
|
2122
|
+
| Upstream MCP server changes its tool catalog | Proxy passes through unchanged tools (no cached schema), warns once if a tool's description was previously trimmed |
|
|
2123
|
+
| Trimmer produces malformed JSON | Proxy falls through to upstream response unchanged, logs to `~/.softspark/ai-toolkit/mcp-proxy/error.log` |
|
|
2124
|
+
| User wants to bypass | `AI_TOOLKIT_MCP_TRIM_DISABLE=1` env var → proxies pass everything through unchanged |
|
|
2125
|
+
| User wants to fully uninstall | `ai-toolkit mcp-trim disable` reverts `~/.claude/.mcp.json` to original upstream targets |
|
|
2126
|
+
|
|
2127
|
+
### Migration of existing user `.mcp.json`
|
|
2128
|
+
|
|
2129
|
+
`ai-toolkit mcp-trim enable` does:
|
|
2130
|
+
|
|
2131
|
+
1. Backup `~/.claude/.mcp.json` → `~/.softspark/ai-toolkit/mcp-proxy/.mcp.json.bak.<timestamp>`
|
|
2132
|
+
2. Read each server entry, store in `~/.softspark/ai-toolkit/mcp-proxy/servers.json`
|
|
2133
|
+
3. Rewrite each entry to point at the local proxy (with sidecar `target` field)
|
|
2134
|
+
4. Spawn supervisor (per-OS: launchd on macOS, systemd on Linux, scheduled task on Windows)
|
|
2135
|
+
5. Verify each upstream reachable via proxy, abort + restore backup on any failure
|
|
2136
|
+
|
|
2137
|
+
## Out-of-scope decisions (rejected mid-spike)
|
|
2138
|
+
|
|
2139
|
+
| Option | Why rejected |
|
|
2140
|
+
|--------|--------------|
|
|
2141
|
+
| Pre-install rewrite of `.mcp.json` only | MCP spec sources descriptions from server runtime, not config — wouldn't take effect |
|
|
2142
|
+
| Source-side forks of MCP servers | Doesn't help users with custom servers; high maintenance |
|
|
2143
|
+
| F2-lite observability tool | User decision 2026-05-04: tracking token waste without trimming is half-value; do the full thing in v4.0 |
|
|
2144
|
+
| Hook-based interception | Spike proved hooks cannot reach `tools/list` |
|
|
2145
|
+
|
|
2146
|
+
## Success criteria
|
|
2147
|
+
|
|
2148
|
+
- ≥40% description-length reduction per server on the captured fixture set (jira, filesystem, dart, pencil)
|
|
2149
|
+
- Deep-equal `inputSchema` between trimmed and upstream — zero schema regression
|
|
2150
|
+
- Proxy adds <50ms per `tools/list` call (one-time per session)
|
|
2151
|
+
- Proxy adds <5ms per `tools/call` (passthrough overhead)
|
|
2152
|
+
- Round-trip correctness: every tool callable via proxy returns byte-identical result vs direct call
|
|
2153
|
+
- Zero MCP-skill regressions in `npm test` after enabling proxy in CI
|
|
2154
|
+
- Rollback (`ai-toolkit mcp-trim disable`) restores byte-identical original `.mcp.json`
|
|
2155
|
+
|
|
2156
|
+
## Open questions
|
|
2157
|
+
|
|
2158
|
+
1. Process supervision per-OS — launchd / systemd / scheduled-task wrappers, or a built-in `ai-toolkit-mcp-trimd` daemon binary?
|
|
2159
|
+
2. SSE-mode upstreams (e.g., rag-mcp at `http://localhost:8081/mcp/sse`) — proxy listens on SSE locally too, or stdio-only with internal SSE client?
|
|
2160
|
+
3. Description rewrites — static dictionary of "boilerplate phrases to drop" (faster, deterministic) vs LLM-based summarizer (more aggressive, less predictable)? Recommend static for v4.0, LLM as v4.1 stretch.
|
|
2161
|
+
4. Config path — `~/.softspark/ai-toolkit/mcp-proxy/` (matches existing convention) or `~/.claude/mcp-proxy/` (closer to MCP config)? Recommend the former.
|
|
2162
|
+
5. Telemetry — does this become an opt-in metric in `/briefing --tokens` ("MCP descriptions: 12.3k → 7.2k, saved 5.1k per turn")? Recommend yes.
|
|
2163
|
+
|
|
2164
|
+
## Pre-mortem (failure scenarios to design against)
|
|
2165
|
+
|
|
2166
|
+
1. **Proxy gets out of sync with upstream** — upstream adds a new tool, proxy doesn't know how to compress it → passthrough that tool's description unchanged, log warning
|
|
2167
|
+
2. **Compression breaks tool discriminability** — model picks wrong tool because trimmed description lost the "use only when X" qualifier → the `not/never/only/except/unless` blacklist must be exhaustive; add per-server allowlists for false positives
|
|
2168
|
+
3. **Multi-process race on `.mcp.json` rewrite** — two `ai-toolkit install` invocations clobber each other → file lock during enable/disable
|
|
2169
|
+
4. **Proxy supervisor fails to start on user's machine** — different distro / no systemd → ai-toolkit doctor must detect and report; degrade to "MCP proxy unavailable, falling through" with no functionality loss
|
|
2170
|
+
5. **User has custom MCP server we don't recognize** — must work without per-server schema; default heuristics must be safe enough for arbitrary servers
|
|
2171
|
+
|
|
2172
|
+
## Estimate
|
|
2173
|
+
|
|
2174
|
+
- Architecture spike + working proxy prototype: 2 days
|
|
2175
|
+
- Production proxy + supervisor + config + CLI: 3 days
|
|
2176
|
+
- Test suite + fixtures + CI integration: 2 days
|
|
2177
|
+
- Documentation + migration guide + release notes: 1 day
|
|
2178
|
+
|
|
2179
|
+
**Total: ~8 working days** (1.5–2 weeks calendar time at typical pace)
|
|
2180
|
+
|
|
2181
|
+
## Status
|
|
2182
|
+
|
|
2183
|
+
| Date | Status | Author |
|
|
2184
|
+
|------|--------|--------|
|
|
2185
|
+
| 2026-05-04 | PRD drafted from spike conclusions, carved out of v3.2.0 plan | claude |
|
|
2186
|
+
| 2026-07-27 | Abandoned without implementation. Claude Code began deferring MCP tool schemas by default, removing the per-turn overhead this proxy targeted. Moved from `kb/planning/` to `kb/history/completed/`. | claude |
|
|
2187
|
+
|
|
2188
|
+
---
|
|
2189
|
+
|
|
2190
|
+
## kb/history/completed/native-tool-output-filter-plan.md
|
|
2191
|
+
|
|
2192
|
+
---
|
|
2193
|
+
title: "Implementation Plan: Native Tool Output Filter"
|
|
2194
|
+
category: planning
|
|
2195
|
+
service: ai-toolkit
|
|
2196
|
+
tags:
|
|
2197
|
+
- output-filter
|
|
2198
|
+
- hooks
|
|
2199
|
+
- recovery
|
|
2200
|
+
- performance
|
|
2201
|
+
- claude-code
|
|
2202
|
+
doc_type: plan
|
|
2203
|
+
status: completed
|
|
2204
|
+
created: "2026-07-23"
|
|
2205
|
+
last_updated: "2026-07-23"
|
|
2206
|
+
completed: "2026-07-23"
|
|
2207
|
+
completion: "100% of approved Claude Code scope; other runtimes remain manual-only by capability decision"
|
|
2208
|
+
shipped_in: "Unreleased"
|
|
2209
|
+
description: "Approved implementation plan and completion evidence for the original dependency-free ai-toolkit tool-output filter, including conservative profiles, exact recovery, telemetry, runtime capability gates, and adjacent repairs."
|
|
2210
|
+
---
|
|
2211
|
+
|
|
2212
|
+
# Implementation Plan: Native Tool Output Filter
|
|
2213
|
+
|
|
2214
|
+
## Status
|
|
2215
|
+
|
|
2216
|
+
Completed on 2026-07-23 after user approval.
|
|
2217
|
+
|
|
2218
|
+
Completion evidence:
|
|
2219
|
+
|
|
2220
|
+
- 69 focused Python tests pass, including the production-wrapper benchmark.
|
|
2221
|
+
- The 100-sample cold wrapper measures 63.565 ms p95 against the 75 ms gate.
|
|
2222
|
+
- The 8 MiB profile case measures 4.354 ms p95 and 8,792,932 peak traced
|
|
2223
|
+
bytes against the 150 ms and 41,943,040 byte gates.
|
|
2224
|
+
- The strict repository validator reports 44 agents, 108 skills, and 1477
|
|
2225
|
+
tests with zero errors or warnings.
|
|
2226
|
+
- Ruff, mypy, ShellCheck, skill audit, generated artifacts, and the final
|
|
2227
|
+
repository test gate pass for the changed surface.
|
|
2228
|
+
|
|
2229
|
+
## Context
|
|
2230
|
+
|
|
2231
|
+
`ai-toolkit` currently controls assistant response length and reports real
|
|
2232
|
+
Claude session tokens, but it does not transform live tool output before that
|
|
2233
|
+
output reaches the model. The requested feature is an original, MIT-licensed,
|
|
2234
|
+
dependency-free implementation inside `ai-toolkit`. RTK is research input only:
|
|
2235
|
+
no runtime dependency, vendoring, translated code, copied filters, fixtures,
|
|
2236
|
+
regex tables, CLI names, or configuration keys.
|
|
2237
|
+
|
|
2238
|
+
The first native integration targets Claude Code because current Claude hooks
|
|
2239
|
+
support replacing successful tool output through
|
|
2240
|
+
`PostToolUse.hookSpecificOutput.updatedToolOutput`. The transformer remains
|
|
2241
|
+
strictly post-execution and cannot alter the command, arguments, environment,
|
|
2242
|
+
working directory, permission decision, exit status, or signal.
|
|
2243
|
+
|
|
2244
|
+
This feature is separate from MCP `tools/list` description trimming. Hooks can
|
|
2245
|
+
transform an executed tool result, but they do not intercept MCP catalog
|
|
2246
|
+
metadata. [PATH: kb/history/completed/f2-mcp-trim-spike-20260504.md]
|
|
2247
|
+
[PATH: kb/planning/mcp-context-trim-v4-prd.md]
|
|
2248
|
+
|
|
2249
|
+
Relevant local boundaries:
|
|
2250
|
+
|
|
2251
|
+
- Fixed lifecycle enforcement belongs in hooks. [PATH: CLAUDE.md:10]
|
|
2252
|
+
- The current safety guards run in `PreToolUse`. [PATH: app/hooks.json:37]
|
|
2253
|
+
- Hook runtime Python helpers are deployed explicitly.
|
|
2254
|
+
[PATH: scripts/install_steps/hooks.py:71]
|
|
2255
|
+
- Runtime hook schemas differ by editor.
|
|
2256
|
+
[PATH: kb/reference/hooks-catalog.md:571]
|
|
2257
|
+
- Existing output/token work intentionally uses native mechanisms.
|
|
2258
|
+
[PATH: kb/history/completed/output-token-discipline-plan-20260504.md]
|
|
2259
|
+
- Claude hook contract:
|
|
2260
|
+
<https://code.claude.com/docs/en/hooks>
|
|
2261
|
+
|
|
2262
|
+
## Scope
|
|
2263
|
+
|
|
2264
|
+
### Included
|
|
2265
|
+
|
|
2266
|
+
- Python standard library implementation under `scripts/`.
|
|
2267
|
+
- Pure post-execution transformation of successful textual Bash output.
|
|
2268
|
+
- `off`, `observe`, and `safe` modes.
|
|
2269
|
+
- Claude Code integration through `PostToolUse.updatedToolOutput`.
|
|
2270
|
+
- Manual CLI for fixture inspection, status, recovery, and cleanup.
|
|
2271
|
+
- Two initial deterministic profiles:
|
|
2272
|
+
- `repeat-lines`: aggregate adjacent identical non-diagnostic lines and state
|
|
2273
|
+
their multiplicity.
|
|
2274
|
+
- `tap-success`: compact valid successful TAP while retaining plan,
|
|
2275
|
+
directives, comments, totals, duration, and all diagnostic material.
|
|
2276
|
+
- Byte and line savings, latency, outcome, profile ID, and profile version.
|
|
2277
|
+
- Exact, bounded, session-scoped raw recovery when `safe` mode is enabled.
|
|
2278
|
+
- Capability-gated adapters for additional runtimes after Phase 2.
|
|
2279
|
+
|
|
2280
|
+
### Excluded
|
|
2281
|
+
|
|
2282
|
+
- RTK binaries, libraries, source code, filters, fixtures, configuration, or
|
|
2283
|
+
branding.
|
|
2284
|
+
- Command rewriting, `sh -c`, shell parsing, permission decisions, or command
|
|
2285
|
+
execution by the filter.
|
|
2286
|
+
- LLM-generated summaries or network calls.
|
|
2287
|
+
- Project-defined regex filters in the first release.
|
|
2288
|
+
- Failed commands, non-empty `stderr`, signals, TTY/streaming output, binary or
|
|
2289
|
+
invalid text, pipes, redirects, security scanners, dependency audits,
|
|
2290
|
+
deployment, migrations, permission failures, and destructive-command
|
|
2291
|
+
diagnostics.
|
|
2292
|
+
- `Read`, web results, arbitrary MCP results, and MCP `tools/list`.
|
|
2293
|
+
- Claims that byte reduction equals billed-token or whole-session savings.
|
|
1887
2294
|
|
|
1888
2295
|
## Architecture
|
|
1889
2296
|
|
|
@@ -2302,53 +2709,185 @@ the savings threshold, and all unsafe paths remain exact passthrough.
|
|
|
2302
2709
|
|
|
2303
2710
|
---
|
|
2304
2711
|
|
|
2305
|
-
## kb/history/completed/
|
|
2712
|
+
## kb/history/completed/no-op-plugin-packs-removed-20260727.md
|
|
2306
2713
|
|
|
2307
2714
|
---
|
|
2308
|
-
title: "
|
|
2715
|
+
title: "Removed: Nine Plugin Packs That Installed Nothing"
|
|
2309
2716
|
category: planning
|
|
2310
2717
|
service: ai-toolkit
|
|
2311
2718
|
tags:
|
|
2312
|
-
-
|
|
2313
|
-
-
|
|
2314
|
-
-
|
|
2315
|
-
-
|
|
2316
|
-
-
|
|
2317
|
-
|
|
2318
|
-
- context-optimization
|
|
2319
|
-
- privacy
|
|
2320
|
-
doc_type: plan
|
|
2719
|
+
- plugins
|
|
2720
|
+
- plugin-pack
|
|
2721
|
+
- measurement
|
|
2722
|
+
- postmortem
|
|
2723
|
+
- dead-code
|
|
2724
|
+
doc_type: postmortem
|
|
2321
2725
|
status: completed
|
|
2322
|
-
created: "2026-
|
|
2323
|
-
last_updated: "2026-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
description: "Lightweight profile for ai-toolkit optimized for Small Language Models (SLMs) running locally via Ollama, LM Studio, or similar. Compiles a minimal instruction set that fits within 4K-8K system prompt budgets while preserving critical safety guardrails. Targets air-gapped, privacy-first, and cost-sensitive development workflows."
|
|
2726
|
+
created: "2026-07-27"
|
|
2727
|
+
last_updated: "2026-07-27"
|
|
2728
|
+
shipped_in: "v4.20.0 (removal)"
|
|
2729
|
+
description: "Nine of eleven plugin packs installed zero files, because every asset they declared already ships in the core install. Measured across both runtimes and all three profiles. Records what was removed, what survived, why the authoring guidance produced the problem, and the check that now prevents a repeat."
|
|
2327
2730
|
---
|
|
2328
2731
|
|
|
2329
|
-
#
|
|
2732
|
+
# Removed: Nine Plugin Packs That Installed Nothing
|
|
2330
2733
|
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
**Created:** 2026-04-10
|
|
2335
|
-
**Origin:** Enterprise IP security requirements (air-gapped environments), cost-sensitive solo developers, and the growing adoption of local models (Ollama, LM Studio, llamafile). Current toolkit emits 20K+ token system prompts that exceed SLM context windows and degrade small model performance.
|
|
2336
|
-
**Estimated Effort:** 4-5 weeks (1 person)
|
|
2734
|
+
`csharp-pack`, `java-pack`, `kotlin-pack`, `ruby-pack`, `rust-pack`,
|
|
2735
|
+
`swift-pack`, `frontend-pack`, `research-pack`, `security-pack` — removed in
|
|
2736
|
+
v4.20.0. `memory-pack` and `enterprise-pack` stay.
|
|
2337
2737
|
|
|
2338
|
-
|
|
2738
|
+
## The measurement
|
|
2339
2739
|
|
|
2340
|
-
|
|
2740
|
+
`ai-toolkit install` into a throwaway `HOME`, then `plugin install <pack>`, on
|
|
2741
|
+
each runtime. The number is what `plugin install` itself reports:
|
|
2341
2742
|
|
|
2342
|
-
|
|
2743
|
+
| Pack | claude | codex |
|
|
2744
|
+
|---|---:|---:|
|
|
2745
|
+
| `csharp-pack` | 0 | 0 |
|
|
2746
|
+
| `java-pack` | 0 | 0 |
|
|
2747
|
+
| `kotlin-pack` | 0 | 0 |
|
|
2748
|
+
| `ruby-pack` | 0 | 0 |
|
|
2749
|
+
| `rust-pack` | 0 | 0 |
|
|
2750
|
+
| `swift-pack` | 0 | 0 |
|
|
2751
|
+
| `research-pack` | 0 | 0 |
|
|
2752
|
+
| `security-pack` | 0 | 0 |
|
|
2753
|
+
| `frontend-pack` | 0 | **1** |
|
|
2754
|
+
| **`memory-pack`** | **4** | **4** |
|
|
2755
|
+
| **`enterprise-pack`** | **2** | **2** |
|
|
2756
|
+
|
|
2757
|
+
Cross-checked against the filesystem, not just the reported count: after core
|
|
2758
|
+
install (108 skills, 44 agents, 4742 characters of hook config), installing
|
|
2759
|
+
`rust-pack`, `security-pack`, `research-pack` or any language pack produced
|
|
2760
|
+
`+0` skills, `+0` agents, `+0` bytes of `settings.json` and `+0` files under
|
|
2761
|
+
`~/.softspark`.
|
|
2762
|
+
|
|
2763
|
+
Profiles make no difference. `minimal`, `standard` and `strict` all install the
|
|
2764
|
+
same 108 skills and 44 agents, and packs add `+0` to each.
|
|
2343
2765
|
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
-
|
|
2766
|
+
## Why
|
|
2767
|
+
|
|
2768
|
+
Every one of the nine declared only assets that already ship in core:
|
|
2769
|
+
|
|
2770
|
+
| Pack | Declared | All present in core? |
|
|
2771
|
+
|---|---|---|
|
|
2772
|
+
| `rust-pack` | `rust-patterns` | yes |
|
|
2773
|
+
| `security-pack` | `review`, `security-patterns`, `panic`, `security-auditor`, `security-architect`, `code-reviewer` | yes |
|
|
2774
|
+
| `research-pack` | `docs`, `research-mastery`, `plan`, `technical-researcher`, `fact-checker`, `search-specialist` | yes |
|
|
2775
|
+
|
|
2776
|
+
Since `ai-toolkit install` links every core skill and agent, a manifest that
|
|
2777
|
+
names only core assets resolves to a set of things already installed. There is
|
|
2778
|
+
nothing left to do, so nothing is done.
|
|
2779
|
+
|
|
2780
|
+
Eight of the nine owned no file but `README.md`. `security-pack`'s two hooks
|
|
2781
|
+
were core's `guard-destructive.sh` and `quality-gate.sh`; `research-pack`'s was
|
|
2782
|
+
core's `user-prompt-submit.sh`.
|
|
2783
|
+
|
|
2784
|
+
## The one that was not quite zero
|
|
2785
|
+
|
|
2786
|
+
`frontend-pack` installed exactly one file, on codex only:
|
|
2787
|
+
`plugin-frontend-pack-post-tool-use.sh`. The pack owned no such file — it
|
|
2788
|
+
declared core's `post-tool-use.sh`, which core's codex surface does not install,
|
|
2789
|
+
so the pack copied it in under a pack-prefixed name.
|
|
2790
|
+
|
|
2791
|
+
That is a generic hook wearing a domain label, not frontend functionality. It
|
|
2792
|
+
was removed with the pack. **If `post-tool-use` should run on codex, it belongs
|
|
2793
|
+
in the core codex hook set**, and adding it there is a separate, honest change —
|
|
2794
|
+
not a side effect of installing a pack named after a UI framework.
|
|
2795
|
+
|
|
2796
|
+
## The authoring rule that caused this
|
|
2797
|
+
|
|
2798
|
+
`app/skills/plugin-creator/SKILL.md` told pack authors:
|
|
2799
|
+
|
|
2800
|
+
> **MUST** reference existing toolkit assets before duplicating — packs extend,
|
|
2801
|
+
> they do not fork
|
|
2802
|
+
|
|
2803
|
+
Read literally against a core install that ships everything, that instruction
|
|
2804
|
+
produces a no-op every time. It was correct about avoiding forks and silent
|
|
2805
|
+
about the pack needing to add anything. Nine packs followed it exactly.
|
|
2806
|
+
|
|
2807
|
+
The rule now reads that a pack **must install something the core install does
|
|
2808
|
+
not**, with the verification spelled out, and the validation checklist carries a
|
|
2809
|
+
line item requiring a non-zero file count on every runtime the pack claims.
|
|
2810
|
+
|
|
2811
|
+
## What survived, and what users lose
|
|
2812
|
+
|
|
2813
|
+
**Nothing.** Every skill and agent the nine packs named is a core asset, still
|
|
2814
|
+
present, still installed, still triggering on the same conditions. A Rust
|
|
2815
|
+
developer who had `rust-pack` installed keeps `rust-patterns`, because it was
|
|
2816
|
+
never in the pack.
|
|
2817
|
+
|
|
2818
|
+
The two remaining packs are the two that own files:
|
|
2819
|
+
|
|
2820
|
+
- `memory-pack` — two hooks, `init_db.py`, `strip_private.py`, and its own
|
|
2821
|
+
`mem-search` skill. Verified working the same day: driving
|
|
2822
|
+
`observation-capture.sh` with a real payload wrote a row to the SQLite store.
|
|
2823
|
+
- `enterprise-pack` — `status-line.sh` and `output-style.sh`, both its own.
|
|
2824
|
+
|
|
2825
|
+
## Process note
|
|
2826
|
+
|
|
2827
|
+
The removal was nearly made on a wrong measurement. The first pass concluded
|
|
2828
|
+
"nine no-ops on every editor" after testing only four packs on the claude
|
|
2829
|
+
surface. `tests/test_plugin.bats` contradicted it by asserting that
|
|
2830
|
+
`frontend-pack` creates a file on codex — the test was right and the
|
|
2831
|
+
measurement was incomplete. The full 11 × 2 matrix was only then run.
|
|
2832
|
+
|
|
2833
|
+
The existing test suite caught an error in a fresh measurement. That is worth
|
|
2834
|
+
remembering next time a test looks like it is merely in the way of a cleanup.
|
|
2835
|
+
|
|
2836
|
+
## Related
|
|
2837
|
+
|
|
2838
|
+
- [Plugin Pack Conventions](../../reference/plugin-pack-conventions.md) — the rule this postmortem installed
|
|
2839
|
+
- [Language Packs (removed)](language-packs-removed-20260727.md) — the reference doc for six of the nine
|
|
2840
|
+
- [rtk-pack Retirement](rtk-pack-retirement-20260727.md) — the pack removed the day before, for a different reason
|
|
2841
|
+
|
|
2842
|
+
---
|
|
2843
|
+
|
|
2844
|
+
## kb/history/completed/offline-slm-profile-plan-20260411.md
|
|
2845
|
+
|
|
2846
|
+
---
|
|
2847
|
+
title: "Plan: Offline-First SLM Profile — Lightweight Mode for Local Models"
|
|
2848
|
+
category: planning
|
|
2849
|
+
service: ai-toolkit
|
|
2850
|
+
tags:
|
|
2851
|
+
- offline
|
|
2852
|
+
- slm
|
|
2853
|
+
- small-language-models
|
|
2854
|
+
- ollama
|
|
2855
|
+
- lm-studio
|
|
2856
|
+
- profile
|
|
2857
|
+
- context-optimization
|
|
2858
|
+
- privacy
|
|
2859
|
+
doc_type: plan
|
|
2860
|
+
status: completed
|
|
2861
|
+
created: "2026-04-10"
|
|
2862
|
+
last_updated: "2026-04-11"
|
|
2863
|
+
completion: "100%"
|
|
2864
|
+
completed: "2026-04-11"
|
|
2865
|
+
description: "Lightweight profile for ai-toolkit optimized for Small Language Models (SLMs) running locally via Ollama, LM Studio, or similar. Compiles a minimal instruction set that fits within 4K-8K system prompt budgets while preserving critical safety guardrails. Targets air-gapped, privacy-first, and cost-sensitive development workflows."
|
|
2866
|
+
---
|
|
2867
|
+
|
|
2868
|
+
# Plan: Offline-First SLM Profile — Lightweight Mode for Local Models
|
|
2869
|
+
|
|
2870
|
+
**Status:** Completed
|
|
2871
|
+
**Completion:** 100%
|
|
2872
|
+
**Completed:** 2026-04-11
|
|
2873
|
+
**Created:** 2026-04-10
|
|
2874
|
+
**Origin:** Enterprise IP security requirements (air-gapped environments), cost-sensitive solo developers, and the growing adoption of local models (Ollama, LM Studio, llamafile). Current toolkit emits 20K+ token system prompts that exceed SLM context windows and degrade small model performance.
|
|
2875
|
+
**Estimated Effort:** 4-5 weeks (1 person)
|
|
2876
|
+
|
|
2877
|
+
---
|
|
2878
|
+
|
|
2879
|
+
## 1. Objective
|
|
2880
|
+
|
|
2881
|
+
Create a `--profile offline-slm` install profile and a `scripts/compile_slm.py` compiler that produces a minimal, high-signal instruction set optimized for Small Language Models (8B-32B parameters). The compiled output preserves critical safety guardrails while stripping agent orchestration, multi-agent coordination, and complex skill routing that SLMs cannot handle.
|
|
2882
|
+
|
|
2883
|
+
**Key design principles:**
|
|
2884
|
+
- **Token budget** — compiled output fits within 4K tokens (system prompt), with optional 8K mode for larger SLMs
|
|
2885
|
+
- **Safety-preserved** — Constitution Articles I-V always included (non-negotiable)
|
|
2886
|
+
- **Single-agent focus** — no multi-agent orchestration, no /swarm, no /teams
|
|
2887
|
+
- **Deterministic compilation** — same input → same output, no LLM involved in compilation
|
|
2888
|
+
- **Model-aware** — detects model size from Ollama API or manual flag and adjusts verbosity
|
|
2889
|
+
- **Platform-agnostic** — outputs plain markdown consumable by any local inference engine
|
|
2890
|
+
- **Hooks stripped** — SLM providers don't support lifecycle hooks; rules compile into system prompt
|
|
2352
2891
|
|
|
2353
2892
|
---
|
|
2354
2893
|
|
|
@@ -4338,6 +4877,201 @@ designed for.
|
|
|
4338
4877
|
|
|
4339
4878
|
---
|
|
4340
4879
|
|
|
4880
|
+
## kb/history/completed/tool-output-token-reduction-closed-20260727.md
|
|
4881
|
+
|
|
4882
|
+
---
|
|
4883
|
+
title: "Closed: Tool-Output Token Reduction — Three Attempts, One Ceiling"
|
|
4884
|
+
category: planning
|
|
4885
|
+
service: ai-toolkit
|
|
4886
|
+
tags:
|
|
4887
|
+
- token-reduction
|
|
4888
|
+
- measurement
|
|
4889
|
+
- postmortem
|
|
4890
|
+
- prompt-caching
|
|
4891
|
+
- context-window
|
|
4892
|
+
- closed-line-of-work
|
|
4893
|
+
doc_type: postmortem
|
|
4894
|
+
status: completed
|
|
4895
|
+
created: "2026-07-27"
|
|
4896
|
+
last_updated: "2026-07-27"
|
|
4897
|
+
description: "Closes the tool-output token-reduction line of work after a third measurement. Decomposes 1189 real sessions by cost: 84% is context being fed to the model, 14.7% is responses. Tool output is a small lever by construction and three independent attempts have now hit the same ceiling. Records what shipped (a 20.2% rag-mcp response trim, worth 0.49% of cost), what was killed by its own kill number, and the three measurement errors made on the way."
|
|
4898
|
+
---
|
|
4899
|
+
|
|
4900
|
+
# Closed: Tool-Output Token Reduction
|
|
4901
|
+
|
|
4902
|
+
**Read this before proposing a fourth attempt.**
|
|
4903
|
+
|
|
4904
|
+
Three independent efforts have tried to cut tokens by shrinking what tools
|
|
4905
|
+
return. All three were competently built. All three measured out near zero.
|
|
4906
|
+
|
|
4907
|
+
| Attempt | Shipped | Measured saving |
|
|
4908
|
+
|---|---|---:|
|
|
4909
|
+
| [Native tool-output filter](output-filter-retirement-20260726.md) | v4.16.0, removed v4.17.0 | **0.0000%** |
|
|
4910
|
+
| [rtk-pack](rtk-pack-retirement-20260727.md) | v4.18.0, removed v4.19.0 | **0.0615%** |
|
|
4911
|
+
| This review's only clean win (rag-mcp response trim) | rag-mcp, 2026-07-27 | **0.49%** |
|
|
4912
|
+
|
|
4913
|
+
This is not three unlucky implementations. It is one structural fact, measured
|
|
4914
|
+
three different ways.
|
|
4915
|
+
|
|
4916
|
+
## Where the money actually is
|
|
4917
|
+
|
|
4918
|
+
1189 sessions with traffic, 83,352 assistant turns, priced at Opus list rates:
|
|
4919
|
+
|
|
4920
|
+
| Component | Share of cost |
|
|
4921
|
+
|---|---:|
|
|
4922
|
+
| `cache_read` | **63.1%** |
|
|
4923
|
+
| `cache_creation` | 20.9% |
|
|
4924
|
+
| `output` | 14.7% |
|
|
4925
|
+
| `input` (uncached) | 1.3% |
|
|
4926
|
+
|
|
4927
|
+
**84% of cost is feeding context to the model.** Responses are 14.7%. That
|
|
4928
|
+
closes "make the model write less" as a serious lever — the whole `brand-voice`
|
|
4929
|
+
concise mode plays for a seventh of the bill.
|
|
4930
|
+
|
|
4931
|
+
Cache hit rate is **97.4%**. Published guidance treats 80–95% as the achievable
|
|
4932
|
+
band, so there is nothing to win in cache tuning either.
|
|
4933
|
+
|
|
4934
|
+
Session shape: median 29 turns (mean 70.1), median peak context 71,276 tokens
|
|
4935
|
+
(mean 114,712), median startup context 22,175 tokens.
|
|
4936
|
+
|
|
4937
|
+
## Why tool output cannot be the lever
|
|
4938
|
+
|
|
4939
|
+
Decomposed by amplification — every tool result is re-read on every turn that
|
|
4940
|
+
follows it, so a result's true cost is its size times the turns remaining:
|
|
4941
|
+
|
|
4942
|
+
| Category | Share of `cache_read` |
|
|
4943
|
+
|---|---:|
|
|
4944
|
+
| Fixed startup prelude | 12.4% |
|
|
4945
|
+
| `Read` results | 15.6% |
|
|
4946
|
+
| `Bash` results | 6.7% |
|
|
4947
|
+
| `rag-mcp` results | 3.8% |
|
|
4948
|
+
| Unattributed (assistant text, thinking, user messages, reminders) | ~61% |
|
|
4949
|
+
|
|
4950
|
+
Every tool in the toolbox, amplified across every turn, is **26.1%** of
|
|
4951
|
+
`cache_read`, and it is not compressible without losing what it says. The
|
|
4952
|
+
original Phase 0 calculation reached the same place from the other direction:
|
|
4953
|
+
tool results are 4.54% of input-token volume, so 4.54% is the arithmetic
|
|
4954
|
+
ceiling for any mechanism operating on them.
|
|
4955
|
+
|
|
4956
|
+
Raw tool-result bytes, 113 MB across 1308 session files:
|
|
4957
|
+
|
|
4958
|
+
| Tool | Share of bytes |
|
|
4959
|
+
|---|---:|
|
|
4960
|
+
| `Read` | 62.2% |
|
|
4961
|
+
| `Bash` | 26.1% |
|
|
4962
|
+
| `rag-mcp` (3 tools) | 7.6% |
|
|
4963
|
+
| everything else | <2% each |
|
|
4964
|
+
|
|
4965
|
+
## What shipped
|
|
4966
|
+
|
|
4967
|
+
**rag-mcp response compaction** — `compact_payload()` in
|
|
4968
|
+
`app/rag-mcp-server/routes/kb_search.py`, applied to `smart_query`,
|
|
4969
|
+
`hybrid_search_kb` and `get_document`, plus both sides of the smart_query cache
|
|
4970
|
+
so a hit and a miss return identical bytes.
|
|
4971
|
+
|
|
4972
|
+
Verified by running the shipped function over 1356 real responses captured from
|
|
4973
|
+
session logs: **20.2% smaller, with no field the agent acts on removed.**
|
|
4974
|
+
That is 0.77% of `cache_read`, **0.49% of total cost**.
|
|
4975
|
+
|
|
4976
|
+
It drops request echo (`use_hyde`/`use_crag`/`use_multi_hop`), null result
|
|
4977
|
+
columns, `_from_cache: false`, `total_documents_used` when it equals the result
|
|
4978
|
+
count, and the part of `source_documents_used` that merely repeats
|
|
4979
|
+
`results[].kb_id`. It deliberately keeps `file_path` (addresses Read/Edit, where
|
|
4980
|
+
`kb_id` addresses get_document), `routing` (the only signal for which pipeline
|
|
4981
|
+
ran), `score: 0.0`, and empty result sets. 16 unit tests, most of them asserting
|
|
4982
|
+
what must survive rather than what gets removed.
|
|
4983
|
+
|
|
4984
|
+
## What was killed, and by what
|
|
4985
|
+
|
|
4986
|
+
A kill number was published before the work: *if the shipped changes do not cut
|
|
4987
|
+
`cache_read` by 3%, stop and do not proceed to the behavioural changes.*
|
|
4988
|
+
|
|
4989
|
+
Result: **0.79%.** The threshold was not met, and the remaining items were not
|
|
4990
|
+
built. The kill number did its job — this is the first of the three attempts
|
|
4991
|
+
where it bound before code was written rather than after it shipped.
|
|
4992
|
+
|
|
4993
|
+
## Three measurement errors, and what they cost
|
|
4994
|
+
|
|
4995
|
+
Recorded because each one nearly produced a wrong decision, and because two of
|
|
4996
|
+
them are the same class of error that produced the previous two failures.
|
|
4997
|
+
|
|
4998
|
+
**1. Duplicate reads: 11.1% was actually 0.1%.** The first pass keyed duplicate
|
|
4999
|
+
detection on `file_path` alone, counting re-reads of *different ranges* of the
|
|
5000
|
+
same file as waste. Re-keyed on `(file_path, offset, limit)`:
|
|
5001
|
+
|
|
5002
|
+
| Key | Duplicates | Bytes | Share of `Read` |
|
|
5003
|
+
|---|---:|---:|---:|
|
|
5004
|
+
| path only (wrong) | 1754 | 7,787,530 | 11.1% |
|
|
5005
|
+
| path + offset + limit (right) | **36** | **90,975** | **0.1%** |
|
|
5006
|
+
|
|
5007
|
+
A whole planned deliverable — a session-scoped dedup hook, with a designed
|
|
5008
|
+
mitigation for the post-compaction re-read hazard — rested on that 11.1%. It
|
|
5009
|
+
does not exist.
|
|
5010
|
+
|
|
5011
|
+
**2. A 58% "trim" that was deleting document content.** An aggressive variant of
|
|
5012
|
+
the rag-mcp compaction measured 58% smaller. It was whitelisting top-level keys
|
|
5013
|
+
and thereby dropping `content` — which for `get_document` *is* the document,
|
|
5014
|
+
30.5% of all bytes those endpoints return. Not a trim; data loss that looked
|
|
5015
|
+
like a win. The honest figure is 20.2%.
|
|
5016
|
+
|
|
5017
|
+
**3. "77.5% of the rag-mcp response is overhead."** Roughly half of that
|
|
5018
|
+
non-content mass is `kb_id`, `file_path`, `title` and `score` — fields the agent
|
|
5019
|
+
uses. Removable overhead is about 20%, not 77%.
|
|
5020
|
+
|
|
5021
|
+
The common thread: **every one of these errors made the opportunity look bigger
|
|
5022
|
+
than it is, and every one was caught only by decomposing before building.** The
|
|
5023
|
+
filter retirement drew the same conclusion about premise validation; rtk-pack
|
|
5024
|
+
drew it about installing the artifact. This adds a third: decompose the metric
|
|
5025
|
+
before trusting its headline.
|
|
5026
|
+
|
|
5027
|
+
## What is left, and why it was not taken
|
|
5028
|
+
|
|
5029
|
+
| Option | Value | Why not |
|
|
5030
|
+
|---|---:|---|
|
|
5031
|
+
| Model routing | tens of % | Ruled out by the maintainer — Opus 5 stays |
|
|
5032
|
+
| Trim the toolkit's own startup prelude | ~2.5% of cost | Ruled out — costs skill/agent discoverability |
|
|
5033
|
+
| `Read` with ranges instead of whole files | up to 10.4% of `cache_read` | The only remaining item of size, and **not quality-neutral**: it is a behavioural change whose effect on correctness cannot be measured automatically |
|
|
5034
|
+
| Unattributed ~61% of `cache_read` | unknown | Assistant text, thinking blocks, user messages, system reminders — no clean cut available |
|
|
5035
|
+
|
|
5036
|
+
For the record, the startup prelude was measured rather than guessed. Median
|
|
5037
|
+
startup context is 22,175 tokens against ~7,850 in the documented reference
|
|
5038
|
+
shape, and the gap is the toolkit's own:
|
|
5039
|
+
|
|
5040
|
+
| Component | Count | ~tokens |
|
|
5041
|
+
|---|---:|---:|
|
|
5042
|
+
| skill descriptions | 108 | 5,051 |
|
|
5043
|
+
| agent descriptions | 44 | 2,750 |
|
|
5044
|
+
| project rules | 5 | 3,802 |
|
|
5045
|
+
| global rules | 6 | 3,133 |
|
|
5046
|
+
| `CLAUDE.md` files | 3 | 2,338 |
|
|
5047
|
+
| **total** | | **17,076** |
|
|
5048
|
+
|
|
5049
|
+
The tool built to reduce tokens is the single largest addition to every
|
|
5050
|
+
session's context. That is worth knowing, and it is still only 2.5% of cost,
|
|
5051
|
+
because the prelude is 12.4% of `cache_read` and only part of it is removable.
|
|
5052
|
+
|
|
5053
|
+
## The rule this leaves behind
|
|
5054
|
+
|
|
5055
|
+
**Do not open a fourth tool-output token-reduction effort without first
|
|
5056
|
+
producing a measurement that beats 4.54%.** That is the ceiling on this workload
|
|
5057
|
+
and it has now been approached from three directions. Any proposal in this space
|
|
5058
|
+
must state, before any code, which share of *input token volume* it addresses —
|
|
5059
|
+
not which share of tool output, not which share of Bash bytes.
|
|
5060
|
+
|
|
5061
|
+
If token cost genuinely needs to come down, the levers that are actually large
|
|
5062
|
+
are model selection and turn count. Both are policy decisions, not engineering
|
|
5063
|
+
projects, and neither is in this line of work.
|
|
5064
|
+
|
|
5065
|
+
## Related
|
|
5066
|
+
|
|
5067
|
+
- [Output Filter Retirement](output-filter-retirement-20260726.md) — attempt one, 0.0000%
|
|
5068
|
+
- [rtk-pack Retirement](rtk-pack-retirement-20260727.md) — attempt two, 0.0615%
|
|
5069
|
+
- [rtk Pack Integration](rtk-pack-integration-20260726.md) — the Phase 0 ceiling calculation
|
|
5070
|
+
- [MCP Context Trim v4.0 — abandoned](mcp-context-trim-v4-prd-obsoleted-20260727.md) — a fourth idea in this space, killed by the platform shipping the fix first
|
|
5071
|
+
- [Output & Token Discipline](output-token-discipline-plan-20260504.md) — the plan all of this descends from
|
|
5072
|
+
|
|
5073
|
+
---
|
|
5074
|
+
|
|
4341
5075
|
## kb/howto/README.md
|
|
4342
5076
|
|
|
4343
5077
|
---
|
|
@@ -5438,354 +6172,90 @@ Examples:
|
|
|
5438
6172
|
3. **AWS credential scope too broad** — User provides admin-level AWS profile. Mitigation: `credentials test` checks actual permissions, WARN if write access detected, suggest read-only IAM policy in docs.
|
|
5439
6173
|
4. **Three providers = 3x maintenance** — Each provider's CLI evolves independently. Mitigation: abstract provider interface, single test matrix, version tracking per provider.
|
|
5440
6174
|
5. **Terraform parsing incomplete** — HCL syntax is complex (modules, variables, conditionals). Mitigation: wrap `terraform show -json` instead of parsing HCL. Fallback to flat regex for projects without `terraform` CLI.
|
|
5441
|
-
6. **SARIF adoption low** — Users may not know how to use SARIF with GitHub. Mitigation: provide copy-paste GitHub Actions workflow in docs and `--explain` for onboarding.
|
|
5442
|
-
|
|
5443
|
-
---
|
|
5444
|
-
|
|
5445
|
-
## 12. Council Review Summary (2026-04-10)
|
|
5446
|
-
|
|
5447
|
-
**Verdict:** CONDITIONAL FOR — implement with scope reduction.
|
|
5448
|
-
**Confidence:** MEDIUM (weighted score: FOR 3.1 vs AGAINST 2.9)
|
|
5449
|
-
|
|
5450
|
-
**Key insights applied to this plan:**
|
|
5451
|
-
- [x] Timeline revised from 3-4 → 5-6 weeks
|
|
5452
|
-
- [x] ~~Azure deferred to Milestone 3~~ → **reinstated: full 3-provider delivery**
|
|
5453
|
-
- [x] SARIF v2.1.0 output added — essential for GitHub Advanced Security integration
|
|
5454
|
-
- [x] Incremental scan mode added (`--changed`) — how developers actually use security tools
|
|
5455
|
-
- [x] `terraform show -json` wrapper instead of HCL parsing — realistic path
|
|
5456
|
-
- [x] Single config file `.cloud-security.json` (merged ignore + context)
|
|
5457
|
-
- [x] `credentials init` interactive wizard — reduce onboarding friction
|
|
5458
|
-
- [x] `--explain <rule-id>` for on-demand remediation guidance
|
|
5459
|
-
- [x] Static mode as default — zero-setup first experience
|
|
5460
|
-
|
|
5461
|
-
**Deferred to v2:**
|
|
5462
|
-
- Kubernetes/container security (separate pack candidate)
|
|
5463
|
-
- Secret scanning with entropy detection
|
|
5464
|
-
- Compliance framework mapping (SOC2, PCI-DSS, NIST 800-53)
|
|
5465
|
-
- Visual security dashboard in browser
|
|
5466
|
-
- GitHub PR comment integration beyond SARIF
|
|
5467
|
-
- Vendored YAML subset parser for CloudFormation YAML static scanning
|
|
5468
|
-
|
|
5469
|
-
**Council strongest agreement:** False positive resolver is the killer feature and primary differentiator vs Checkov/Trivy/Prowler. No existing tool combines deterministic scanning with context-aware resolution.
|
|
5470
|
-
|
|
5471
|
-
---
|
|
5472
|
-
|
|
5473
|
-
## 13. Orchestration Review Summary (2026-04-10)
|
|
5474
|
-
|
|
5475
|
-
**Agents:** tech-lead, security-architect, product-manager, code-reviewer (4 parallel)
|
|
5476
|
-
|
|
5477
|
-
**Verdict:** Plan structurally complete (14/14 elements). Three P0 security blockers identified and resolved.
|
|
5478
|
-
|
|
5479
|
-
**Applied changes:**
|
|
5480
|
-
|
|
5481
|
-
| # | Action | Source | Priority | Applied? |
|
|
5482
|
-
|---|--------|--------|----------|----------|
|
|
5483
|
-
| 1 | Programmatic Bash allowlist | security-architect | P0 | Yes — allowlist.sh + agent integration |
|
|
5484
|
-
| 2 | CI hardening (mktemp/trap/SARIF validation) | security-architect | P0 | Yes — CI examples rewritten |
|
|
5485
|
-
| 3 | Suppression governance (justification + diff detection) | security-architect | P0 | Yes — schema + SUPPRESSION_CHANGED finding |
|
|
5486
|
-
| 4 | Recursive descent parser for Firestore | code-reviewer | P1 | Yes — replaced regex approach, +1d estimate |
|
|
5487
|
-
| 5 | SARIF `driver.rules[]` for GitHub annotations | code-reviewer | P1 | Yes — schema + success criteria |
|
|
5488
|
-
| 6 | Task 4.1→3.2 numbering fix | tech-lead | P1 | Yes — renumbered |
|
|
5489
|
-
| 7 | `terraform plan` execution risk documented | security-architect | P1 | Yes — only `show -json` allowed |
|
|
5490
|
-
| 8 | `credentials init` deferred to M2 | code-reviewer | P2 | Yes — saves 1.5d in M1 |
|
|
5491
|
-
| 9 | False positive resolver budgeted +2d/provider | code-reviewer | P2 | Yes — estimate updated |
|
|
5492
|
-
| 10 | `SUPPRESSION_CHANGED` finding type | security-architect | P2 | Yes — in governance section |
|
|
5493
|
-
|
|
5494
|
-
**Market positioning (product-manager):**
|
|
5495
|
-
- Not competing with Checkov on check count (40 vs 3000)
|
|
5496
|
-
- Competing on: zero-noise (false positive resolver), zero-setup (static-first), IDE-native (10 platforms), AI interpretation
|
|
5497
|
-
- Target: developers in ai-toolkit ecosystem, not enterprise security teams
|
|
5498
|
-
- Value as ecosystem feature, not standalone product
|
|
5499
|
-
|
|
5500
|
-
**Timeline revision (code-reviewer):**
|
|
5501
|
-
- 1 person: 6-7 weeks realistic (was 5-6)
|
|
5502
|
-
- 2 people: 4-5 weeks (parallel GCP + AWS tracks)
|
|
5503
|
-
- All 3 providers ship in 6 weeks — no conditional gates
|
|
5504
|
-
|
|
5505
|
-
---
|
|
5506
|
-
|
|
5507
|
-
## 14. Next Actions
|
|
5508
|
-
|
|
5509
|
-
1. [ ] Approve plan
|
|
5510
|
-
2. [ ] Implement `credentials` CLI command (1.1) + Bash allowlist
|
|
5511
|
-
3. [ ] Create `cloud-security-auditor` agent (1.2)
|
|
5512
|
-
4. [ ] Implement SARIF formatter + incremental scan (1.3)
|
|
5513
|
-
5. [ ] Implement `firebase-rules-audit` — recursive descent parser (2.1)
|
|
5514
|
-
6. [ ] Implement `cloud-functions-audit` + false positive resolver GCP (2.2, 2.3)
|
|
5515
|
-
7. [ ] Implement `aws-security-audit` + `terraform show -json` wrapper (3.1)
|
|
5516
|
-
8. [ ] Implement orchestrator + plugin pack + `credentials init` (3.2, 1.1b)
|
|
5517
|
-
9. [ ] Implement `azure-security-audit` + false positive resolver Azure (4.1)
|
|
5518
|
-
10. [ ] Full test suite (70+) + documentation + release
|
|
5519
|
-
|
|
5520
|
-
---
|
|
5521
|
-
|
|
5522
|
-
**Last Updated:** 2026-04-10
|
|
5523
|
-
**Council Reviewed:** 2026-04-10
|
|
5524
|
-
**Orchestration Reviewed:** 2026-04-10 (4 agents: tech-lead, security-architect, product-manager, code-reviewer)
|
|
5525
|
-
|
|
5526
|
-
---
|
|
5527
|
-
|
|
5528
|
-
## kb/planning/drop-cascade-hooks-after-sunset.md
|
|
5529
|
-
|
|
5530
|
-
---
|
|
5531
|
-
title: "Plan: Drop Cascade hooks after 2026-07-01 sunset"
|
|
5532
|
-
category: planning
|
|
5533
|
-
service: ai-toolkit
|
|
5534
|
-
tags:
|
|
5535
|
-
- windsurf
|
|
5536
|
-
- devin
|
|
5537
|
-
- cascade
|
|
5538
|
-
- hooks
|
|
5539
|
-
- deprecation
|
|
5540
|
-
- cleanup
|
|
5541
|
-
doc_type: plan
|
|
5542
|
-
status: completed
|
|
5543
|
-
created: "2026-06-10"
|
|
5544
|
-
last_updated: "2026-07-10"
|
|
5545
|
-
completion: "100%"
|
|
5546
|
-
trigger_date: "2026-07-01"
|
|
5547
|
-
description: "Completed cleanup of the deprecated Windsurf Cascade hooks generator after the 2026-07-01 sunset; Devin CLI .devin/hooks.v1.json is now the sole live hook surface."
|
|
5548
|
-
---
|
|
5549
|
-
|
|
5550
|
-
# Plan: Drop Cascade hooks after 2026-07-01 sunset
|
|
5551
|
-
|
|
5552
|
-
**Completed in v4.13.0 (2026-07-10).** The deprecated generator and install/test wiring were removed; the Devin hook generator remains.
|
|
5553
|
-
|
|
5554
|
-
## Why this exists
|
|
5555
|
-
|
|
5556
|
-
Windsurf rebranded to Devin Desktop on 2026-06-02. The Cascade agent — and its
|
|
5557
|
-
`.windsurf/hooks.json` hook surface (`agent_action_name`/`tool_info` format) — is
|
|
5558
|
-
available **only through 2026-07-01**. Devin Local / Devin CLI do **not** read
|
|
5559
|
-
`.windsurf/hooks.json` as a fallback.
|
|
5560
|
-
|
|
5561
|
-
v4.8.0 already shipped the replacement: `generate_devin_hooks.py` emits
|
|
5562
|
-
`.devin/hooks.v1.json` in the Claude-compatible format Devin CLI uses. During the
|
|
5563
|
-
transition **both** generators run at `profile=full` so pre-sunset Cascade users
|
|
5564
|
-
keep working. After 2026-07-01 the Cascade half is dead code and must be removed
|
|
5565
|
-
(Constitution Art. VI.1 — no dead code).
|
|
5566
|
-
|
|
5567
|
-
## Trigger
|
|
5568
|
-
|
|
5569
|
-
First ai-toolkit release **on or after 2026-07-01**. Do NOT do this earlier —
|
|
5570
|
-
removing it before the sunset breaks Cascade users who are still on the old agent.
|
|
5571
|
-
|
|
5572
|
-
## Scope — remove the Cascade hooks surface
|
|
5573
|
-
|
|
5574
|
-
1. **Delete the generator:** `scripts/generate_windsurf_hooks.py`.
|
|
5575
|
-
2. **Unwire the install step:** in `scripts/install_steps/ai_tools.py`, remove the
|
|
5576
|
-
`_try_generator("generate_windsurf_hooks", cwd)` call (keep
|
|
5577
|
-
`generate_devin_hooks`). Update the `profile=full` dry-run message to drop
|
|
5578
|
-
`.windsurf/hooks.json (Cascade, deprecated)`.
|
|
5579
|
-
3. **Tests:** remove the windsurf-`.windsurf/hooks.json` cases from
|
|
5580
|
-
`tests/test_hooks_per_editor.bats` (output path, valid JSON, source tag,
|
|
5581
|
-
`$HOME` prefix, idempotence, user-preservation, `pre_write_code` coverage) and
|
|
5582
|
-
the `profile=full` assertion in `tests/test_install_profiles.bats`
|
|
5583
|
-
(`windsurf + full emits .windsurf/hooks.json`). Keep all `.devin/hooks.v1.json`
|
|
5584
|
-
tests. Adjust the README test-count badge to the new total.
|
|
5585
|
-
4. **Registry:** in `scripts/ecosystem_tools.json` (windsurf entry), remove
|
|
5586
|
-
`scripts/generate_windsurf_hooks.py` from `our_generators`; keep
|
|
5587
|
-
`.windsurf/hooks.json` out of `config_paths` (it was never listed). Trim the
|
|
5588
|
-
`status_note` hooks-migration paragraph to past tense ("Cascade hooks removed
|
|
5589
|
-
in vX.Y.Z").
|
|
5590
|
-
5. **Docs:** in `kb/reference/supported-tools-registry.md` drop the
|
|
5591
|
-
`generate_windsurf_hooks.py` row and the "drop after 2026-07-01" note; in
|
|
5592
|
-
`kb/reference/hooks-catalog.md` remove the Cascade row from the
|
|
5593
|
-
Per-Editor Native Hooks table and the deprecation wording, leaving the Devin CLI
|
|
5594
|
-
section as the windsurf-family hook surface.
|
|
5595
|
-
6. **validate.py:** the `_HOOK_STEM_ALIAS = {"devin": "windsurf"}` mapping STAYS —
|
|
5596
|
-
it is what keeps the `devin` hook generator counted as windsurf hooks in the
|
|
5597
|
-
README-honesty check after the Cascade generator is gone.
|
|
5598
|
-
7. **CHANGELOG / version:** minor bump, `Removed` entry, regen artifacts, full
|
|
5599
|
-
release-preparation SOP gate.
|
|
5600
|
-
|
|
5601
|
-
## Verification
|
|
5602
|
-
|
|
5603
|
-
- `python3 scripts/validate.py --strict` — 0/0 (editor-hooks-honesty must still
|
|
5604
|
-
report windsurf as hook-enabled via the `devin` generator alias).
|
|
5605
|
-
- `python3 scripts/ecosystem_doctor.py --offline --check` — exit 0.
|
|
5606
|
-
- `npm test` — 0 `not ok`; no test recreates the deleted
|
|
5607
|
-
`generate_windsurf_hooks.py` generator.
|
|
5608
|
-
- `grep -rn "generate_windsurf_hooks" scripts/ tests/` returns nothing
|
|
5609
|
-
(Art. VI.1 orphan check — the deleted generator is fully unwired).
|
|
5610
|
-
`.windsurf/hooks.json` intentionally remains referenced by the one-time
|
|
5611
|
-
migration/strip cleanup (`scripts/install_steps/ai_tools.py`) and its test,
|
|
5612
|
-
and in narrative docs (CHANGELOG, README, `kb/`, docstrings).
|
|
5613
|
-
|
|
5614
|
-
## Do NOT touch
|
|
5615
|
-
|
|
5616
|
-
- `generate_devin_hooks.py` and `.devin/hooks.v1.json` — the live replacement.
|
|
5617
|
-
- The `.devin/`/`.windsurf/` rules + skills dual-emit (that fallback persists as
|
|
5618
|
-
long as Devin Desktop reads legacy `.windsurf/` paths; this plan is hooks-only).
|
|
5619
|
-
|
|
5620
|
-
## Related
|
|
5621
|
-
|
|
5622
|
-
- `kb/reference/hooks-catalog.md` — Per-Editor Native Hooks + Devin CLI section
|
|
5623
|
-
- `kb/reference/supported-tools-registry.md` — windsurf entry, hooks-migration row
|
|
5624
|
-
- `kb/procedures/ecosystem-sync-sop.md` — class-D deprecation workflow
|
|
5625
|
-
- `scripts/ecosystem_tools.json` — windsurf `status_note`
|
|
5626
|
-
|
|
5627
|
-
---
|
|
5628
|
-
|
|
5629
|
-
## kb/planning/mcp-context-trim-v4-prd.md
|
|
5630
|
-
|
|
5631
|
-
---
|
|
5632
|
-
title: "PRD: MCP Context Trim v4.0 — Local Proxy with Description Compression"
|
|
5633
|
-
category: planning
|
|
5634
|
-
service: ai-toolkit
|
|
5635
|
-
tags:
|
|
5636
|
-
- mcp
|
|
5637
|
-
- proxy
|
|
5638
|
-
- tool-descriptions
|
|
5639
|
-
- jsonrpc
|
|
5640
|
-
- tokens
|
|
5641
|
-
- v4
|
|
5642
|
-
doc_type: plan
|
|
5643
|
-
status: proposed
|
|
5644
|
-
created: "2026-05-04"
|
|
5645
|
-
last_updated: "2026-05-04"
|
|
5646
|
-
completion: "0%"
|
|
5647
|
-
target_milestone: "v4.0"
|
|
5648
|
-
predecessor:
|
|
5649
|
-
- "kb/history/completed/output-token-discipline-plan-20260504.md"
|
|
5650
|
-
- "kb/history/completed/f2-mcp-trim-spike-20260504.md"
|
|
5651
|
-
description: "Local MCP proxy server that compresses tool descriptions before they reach the model. Carved out of the v3.2.0 output-token-discipline plan (Feature 2), deferred after the 2026-05-04 spike showed Claude Code hooks cannot modify tools/list metadata. Targets ~8-15k token reduction per session for users with many MCP servers."
|
|
5652
|
-
---
|
|
5653
|
-
|
|
5654
|
-
# PRD: MCP Context Trim v4.0
|
|
5655
|
-
|
|
5656
|
-
**Status:** Proposed
|
|
5657
|
-
**Target milestone:** v4.0
|
|
5658
|
-
**Carved out of:** [`output-token-discipline-plan-20260504.md`](../history/completed/output-token-discipline-plan-20260504.md) (was Feature 2)
|
|
5659
|
-
**Spike basis:** [`f2-mcp-trim-spike-20260504.md`](../history/completed/f2-mcp-trim-spike-20260504.md)
|
|
5660
|
-
|
|
5661
|
-
## Problem
|
|
5662
|
-
|
|
5663
|
-
MCP server tool descriptions are injected into every model turn's system prompt. With ~100 tools across 7 typical servers, descriptions consume 8–15k tokens per turn — pure overhead, paid every message. Examples observed in users' configs:
|
|
5664
|
-
|
|
5665
|
-
- `dart-mcp-server` — ~30 tools with multi-paragraph descriptions
|
|
5666
|
-
- `filesystem` — verbose paths and example sections
|
|
5667
|
-
- `pencil` — "IMPORTANT" stanzas repeated across tools
|
|
5668
|
-
- `jira-mcp` — long `Use this tool to…` boilerplate
|
|
5669
|
-
|
|
5670
|
-
The v3.2.0 output-discipline plan attempted to solve this with a hook-based trimmer. The spike conducted 2026-05-04 proved Claude Code hooks do not expose `tools/list` metadata or the system-prompt tool catalog. The only viable architecture is a local MCP proxy.
|
|
5671
|
-
|
|
5672
|
-
## Goal
|
|
5673
|
-
|
|
5674
|
-
Reduce MCP-description overhead by ≥40% per server, with **zero** loss of parameter schemas, required fields, or discrimination signals (`not`, `never`, `only`, `except`, `unless`).
|
|
5675
|
-
|
|
5676
|
-
## Non-goals
|
|
5677
|
-
|
|
5678
|
-
- Modifying tool **call** behavior (only descriptions)
|
|
5679
|
-
- Compressing user-facing prompts or completions
|
|
5680
|
-
- Replacing or rewriting upstream MCP servers
|
|
5681
|
-
- Touching MCP servers we do not control
|
|
5682
|
-
|
|
5683
|
-
## Architecture
|
|
5684
|
-
|
|
5685
|
-
### Proxy topology
|
|
5686
|
-
|
|
5687
|
-
```
|
|
5688
|
-
Claude Code ──stdio──▶ ai-toolkit MCP proxy ──stdio/SSE──▶ upstream MCP server
|
|
5689
|
-
│
|
|
5690
|
-
└─ rewrites tools/list response
|
|
5691
|
-
passes through tools/call unchanged
|
|
5692
|
-
```
|
|
5693
|
-
|
|
5694
|
-
One proxy process per upstream server, supervised by `ai-toolkit mcp-trim daemon` (or equivalent). User's `~/.claude/.mcp.json` is rewritten by `ai-toolkit install` (opt-in) to point Claude Code at the proxy instead of upstream — proxy reads the original target from a sidecar config.
|
|
5695
|
-
|
|
5696
|
-
### Required components
|
|
5697
|
-
|
|
5698
|
-
| Component | Purpose |
|
|
5699
|
-
|-----------|---------|
|
|
5700
|
-
| `scripts/mcp_proxy_server.py` | JSON-RPC 2.0 proxy. Reads stdin, forwards to upstream over stdio or SSE, intercepts `tools/list` response, rewrites descriptions. Stdlib-only. |
|
|
5701
|
-
| `scripts/mcp_description_trimmer.py` | Pure function library: `trim(description: str) → str`. Reused from heuristics below. Stdlib-only. |
|
|
5702
|
-
| `scripts/mcp_proxy_config.py` | Reads `~/.softspark/ai-toolkit/mcp-proxy/servers.json`, validates upstream targets, generates supervisord/launchd config. |
|
|
5703
|
-
| `app/hooks/mcp-proxy-health.sh` | SessionStart hook — verifies all configured proxies responsive; fall through (warn, do not block) if any down. |
|
|
5704
|
-
| `app/skills/mcp-trim/SKILL.md` | Knowledge skill: how to enable, opt out, audit savings. |
|
|
5705
|
-
| `bin/ai-toolkit-mcp-trim` | CLI: `enable`, `disable`, `status`, `audit` (per-server token savings report). |
|
|
5706
|
-
| `tests/test_mcp_proxy.bats` | Integration tests with mock upstream MCP servers. |
|
|
5707
|
-
| `tests/test_mcp_trimmer.bats` | Unit tests for description trim heuristics on captured fixtures. |
|
|
5708
|
-
|
|
5709
|
-
### Compression heuristics (from spike)
|
|
5710
|
-
|
|
5711
|
-
Applied to each tool description in `tools/list` response:
|
|
6175
|
+
6. **SARIF adoption low** — Users may not know how to use SARIF with GitHub. Mitigation: provide copy-paste GitHub Actions workflow in docs and `--explain` for onboarding.
|
|
5712
6176
|
|
|
5713
|
-
|
|
5714
|
-
- Collapse `Use this server to…` / `Use this tool to…` boilerplate to minimum form preserving intent
|
|
5715
|
-
- Drop duplicate occurrences of tool name in its own description
|
|
5716
|
-
- **Preserve bytewise:** `inputSchema.properties[*].description`, `required`, `enum` values, URL/path identifiers
|
|
5717
|
-
- **Never strip:** the words `not`, `never`, `only`, `except`, `unless` — these carry "when NOT to use" signals
|
|
5718
|
-
- Target: ≥40% length reduction, 0% schema loss
|
|
6177
|
+
---
|
|
5719
6178
|
|
|
5720
|
-
|
|
6179
|
+
## 12. Council Review Summary (2026-04-10)
|
|
5721
6180
|
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
| Proxy crashes mid-session | `mcp-proxy-health.sh` detects on next SessionStart, prints warning, suggests `ai-toolkit mcp-trim disable <server>` |
|
|
5725
|
-
| Upstream MCP server changes its tool catalog | Proxy passes through unchanged tools (no cached schema), warns once if a tool's description was previously trimmed |
|
|
5726
|
-
| Trimmer produces malformed JSON | Proxy falls through to upstream response unchanged, logs to `~/.softspark/ai-toolkit/mcp-proxy/error.log` |
|
|
5727
|
-
| User wants to bypass | `AI_TOOLKIT_MCP_TRIM_DISABLE=1` env var → proxies pass everything through unchanged |
|
|
5728
|
-
| User wants to fully uninstall | `ai-toolkit mcp-trim disable` reverts `~/.claude/.mcp.json` to original upstream targets |
|
|
6181
|
+
**Verdict:** CONDITIONAL FOR — implement with scope reduction.
|
|
6182
|
+
**Confidence:** MEDIUM (weighted score: FOR 3.1 vs AGAINST 2.9)
|
|
5729
6183
|
|
|
5730
|
-
|
|
6184
|
+
**Key insights applied to this plan:**
|
|
6185
|
+
- [x] Timeline revised from 3-4 → 5-6 weeks
|
|
6186
|
+
- [x] ~~Azure deferred to Milestone 3~~ → **reinstated: full 3-provider delivery**
|
|
6187
|
+
- [x] SARIF v2.1.0 output added — essential for GitHub Advanced Security integration
|
|
6188
|
+
- [x] Incremental scan mode added (`--changed`) — how developers actually use security tools
|
|
6189
|
+
- [x] `terraform show -json` wrapper instead of HCL parsing — realistic path
|
|
6190
|
+
- [x] Single config file `.cloud-security.json` (merged ignore + context)
|
|
6191
|
+
- [x] `credentials init` interactive wizard — reduce onboarding friction
|
|
6192
|
+
- [x] `--explain <rule-id>` for on-demand remediation guidance
|
|
6193
|
+
- [x] Static mode as default — zero-setup first experience
|
|
5731
6194
|
|
|
5732
|
-
|
|
6195
|
+
**Deferred to v2:**
|
|
6196
|
+
- Kubernetes/container security (separate pack candidate)
|
|
6197
|
+
- Secret scanning with entropy detection
|
|
6198
|
+
- Compliance framework mapping (SOC2, PCI-DSS, NIST 800-53)
|
|
6199
|
+
- Visual security dashboard in browser
|
|
6200
|
+
- GitHub PR comment integration beyond SARIF
|
|
6201
|
+
- Vendored YAML subset parser for CloudFormation YAML static scanning
|
|
5733
6202
|
|
|
5734
|
-
|
|
5735
|
-
2. Read each server entry, store in `~/.softspark/ai-toolkit/mcp-proxy/servers.json`
|
|
5736
|
-
3. Rewrite each entry to point at the local proxy (with sidecar `target` field)
|
|
5737
|
-
4. Spawn supervisor (per-OS: launchd on macOS, systemd on Linux, scheduled task on Windows)
|
|
5738
|
-
5. Verify each upstream reachable via proxy, abort + restore backup on any failure
|
|
6203
|
+
**Council strongest agreement:** False positive resolver is the killer feature and primary differentiator vs Checkov/Trivy/Prowler. No existing tool combines deterministic scanning with context-aware resolution.
|
|
5739
6204
|
|
|
5740
|
-
|
|
6205
|
+
---
|
|
5741
6206
|
|
|
5742
|
-
|
|
5743
|
-
|--------|--------------|
|
|
5744
|
-
| Pre-install rewrite of `.mcp.json` only | MCP spec sources descriptions from server runtime, not config — wouldn't take effect |
|
|
5745
|
-
| Source-side forks of MCP servers | Doesn't help users with custom servers; high maintenance |
|
|
5746
|
-
| F2-lite observability tool | User decision 2026-05-04: tracking token waste without trimming is half-value; do the full thing in v4.0 |
|
|
5747
|
-
| Hook-based interception | Spike proved hooks cannot reach `tools/list` |
|
|
6207
|
+
## 13. Orchestration Review Summary (2026-04-10)
|
|
5748
6208
|
|
|
5749
|
-
|
|
6209
|
+
**Agents:** tech-lead, security-architect, product-manager, code-reviewer (4 parallel)
|
|
5750
6210
|
|
|
5751
|
-
|
|
5752
|
-
- Deep-equal `inputSchema` between trimmed and upstream — zero schema regression
|
|
5753
|
-
- Proxy adds <50ms per `tools/list` call (one-time per session)
|
|
5754
|
-
- Proxy adds <5ms per `tools/call` (passthrough overhead)
|
|
5755
|
-
- Round-trip correctness: every tool callable via proxy returns byte-identical result vs direct call
|
|
5756
|
-
- Zero MCP-skill regressions in `npm test` after enabling proxy in CI
|
|
5757
|
-
- Rollback (`ai-toolkit mcp-trim disable`) restores byte-identical original `.mcp.json`
|
|
6211
|
+
**Verdict:** Plan structurally complete (14/14 elements). Three P0 security blockers identified and resolved.
|
|
5758
6212
|
|
|
5759
|
-
|
|
6213
|
+
**Applied changes:**
|
|
5760
6214
|
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
6215
|
+
| # | Action | Source | Priority | Applied? |
|
|
6216
|
+
|---|--------|--------|----------|----------|
|
|
6217
|
+
| 1 | Programmatic Bash allowlist | security-architect | P0 | Yes — allowlist.sh + agent integration |
|
|
6218
|
+
| 2 | CI hardening (mktemp/trap/SARIF validation) | security-architect | P0 | Yes — CI examples rewritten |
|
|
6219
|
+
| 3 | Suppression governance (justification + diff detection) | security-architect | P0 | Yes — schema + SUPPRESSION_CHANGED finding |
|
|
6220
|
+
| 4 | Recursive descent parser for Firestore | code-reviewer | P1 | Yes — replaced regex approach, +1d estimate |
|
|
6221
|
+
| 5 | SARIF `driver.rules[]` for GitHub annotations | code-reviewer | P1 | Yes — schema + success criteria |
|
|
6222
|
+
| 6 | Task 4.1→3.2 numbering fix | tech-lead | P1 | Yes — renumbered |
|
|
6223
|
+
| 7 | `terraform plan` execution risk documented | security-architect | P1 | Yes — only `show -json` allowed |
|
|
6224
|
+
| 8 | `credentials init` deferred to M2 | code-reviewer | P2 | Yes — saves 1.5d in M1 |
|
|
6225
|
+
| 9 | False positive resolver budgeted +2d/provider | code-reviewer | P2 | Yes — estimate updated |
|
|
6226
|
+
| 10 | `SUPPRESSION_CHANGED` finding type | security-architect | P2 | Yes — in governance section |
|
|
5766
6227
|
|
|
5767
|
-
|
|
6228
|
+
**Market positioning (product-manager):**
|
|
6229
|
+
- Not competing with Checkov on check count (40 vs 3000)
|
|
6230
|
+
- Competing on: zero-noise (false positive resolver), zero-setup (static-first), IDE-native (10 platforms), AI interpretation
|
|
6231
|
+
- Target: developers in ai-toolkit ecosystem, not enterprise security teams
|
|
6232
|
+
- Value as ecosystem feature, not standalone product
|
|
5768
6233
|
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
5. **User has custom MCP server we don't recognize** — must work without per-server schema; default heuristics must be safe enough for arbitrary servers
|
|
6234
|
+
**Timeline revision (code-reviewer):**
|
|
6235
|
+
- 1 person: 6-7 weeks realistic (was 5-6)
|
|
6236
|
+
- 2 people: 4-5 weeks (parallel GCP + AWS tracks)
|
|
6237
|
+
- All 3 providers ship in 6 weeks — no conditional gates
|
|
5774
6238
|
|
|
5775
|
-
|
|
6239
|
+
---
|
|
5776
6240
|
|
|
5777
|
-
|
|
5778
|
-
- Production proxy + supervisor + config + CLI: 3 days
|
|
5779
|
-
- Test suite + fixtures + CI integration: 2 days
|
|
5780
|
-
- Documentation + migration guide + release notes: 1 day
|
|
6241
|
+
## 14. Next Actions
|
|
5781
6242
|
|
|
5782
|
-
|
|
6243
|
+
1. [ ] Approve plan
|
|
6244
|
+
2. [ ] Implement `credentials` CLI command (1.1) + Bash allowlist
|
|
6245
|
+
3. [ ] Create `cloud-security-auditor` agent (1.2)
|
|
6246
|
+
4. [ ] Implement SARIF formatter + incremental scan (1.3)
|
|
6247
|
+
5. [ ] Implement `firebase-rules-audit` — recursive descent parser (2.1)
|
|
6248
|
+
6. [ ] Implement `cloud-functions-audit` + false positive resolver GCP (2.2, 2.3)
|
|
6249
|
+
7. [ ] Implement `aws-security-audit` + `terraform show -json` wrapper (3.1)
|
|
6250
|
+
8. [ ] Implement orchestrator + plugin pack + `credentials init` (3.2, 1.1b)
|
|
6251
|
+
9. [ ] Implement `azure-security-audit` + false positive resolver Azure (4.1)
|
|
6252
|
+
10. [ ] Full test suite (70+) + documentation + release
|
|
5783
6253
|
|
|
5784
|
-
|
|
6254
|
+
---
|
|
5785
6255
|
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
6256
|
+
**Last Updated:** 2026-04-10
|
|
6257
|
+
**Council Reviewed:** 2026-04-10
|
|
6258
|
+
**Orchestration Reviewed:** 2026-04-10 (4 agents: tech-lead, security-architect, product-manager, code-reviewer)
|
|
5789
6259
|
|
|
5790
6260
|
---
|
|
5791
6261
|
|
|
@@ -6770,10 +7240,10 @@ title: "SOP: Release Preparation"
|
|
|
6770
7240
|
category: procedures
|
|
6771
7241
|
service: ai-toolkit
|
|
6772
7242
|
tags: [sop, release, version, publish, changelog, semver, provenance, sarif, ecosystem, shellcheck]
|
|
6773
|
-
version: "1.
|
|
7243
|
+
version: "1.13.0"
|
|
6774
7244
|
created: "2026-04-10"
|
|
6775
7245
|
last_updated: "2026-07-27"
|
|
6776
|
-
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, and checksum-pin checks added in v2.8.0, the single-run npm test discipline added in v1.8.0, the ecosystem-sync gate added in v1.9.0, the registry-vs-generators drift gate added in v1.10.0,
|
|
7246
|
+
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, and checksum-pin checks added in v2.8.0, the single-run npm test discipline added in v1.8.0, the ecosystem-sync gate added in v1.9.0, the registry-vs-generators drift gate added in v1.10.0, the mandatory pre-tag ShellCheck gate added in v1.11.0 (publish.yml does not run ShellCheck, so a hook lint failure can publish while reddening main CI — see the v4.5.1 postmortem in Phase 5), the pre-push tag assertions added in v1.12.0 after v4.19.0 was tagged on the wrong commit (Phase 7), and the licensing gate added in v1.13.0 with the move to Apache-2.0 (Phase 5c)."
|
|
6777
7247
|
---
|
|
6778
7248
|
|
|
6779
7249
|
# SOP: Release Preparation
|
|
@@ -6832,10 +7302,20 @@ python3 scripts/audit_skills.py --permissions # review Bash/Write/Edit footpri
|
|
|
6832
7302
|
# 5b. Ecosystem gate — snapshot must be current before tag
|
|
6833
7303
|
python3 scripts/ecosystem_doctor.py --offline --check || { echo "STALE ecosystem snapshot — re-run doctor"; exit 1; }
|
|
6834
7304
|
|
|
7305
|
+
# 5c. Licensing gate — SPDX headers, LICENSE, NOTICE, manifest consistency
|
|
7306
|
+
npx bats tests/test_licensing.bats || { echo "LICENSING GATE FAILED"; exit 1; }
|
|
7307
|
+
|
|
6835
7308
|
# 6. Commit + tag + push
|
|
6836
7309
|
git add -A && git commit -m "chore: release vX.Y.Z"
|
|
6837
7310
|
git tag vX.Y.Z
|
|
6838
|
-
|
|
7311
|
+
|
|
7312
|
+
# 6a. Assert the tag before pushing it (v4.19.0 postmortem, Phase 7)
|
|
7313
|
+
test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)" || { echo "FAIL: tag not on HEAD"; exit 1; }
|
|
7314
|
+
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; }
|
|
7315
|
+
|
|
7316
|
+
# 6b. Branch first, then the single tag by full ref. Never --tags.
|
|
7317
|
+
git push origin main
|
|
7318
|
+
git push origin refs/tags/vX.Y.Z
|
|
6839
7319
|
```
|
|
6840
7320
|
|
|
6841
7321
|
---
|
|
@@ -7099,6 +7579,46 @@ python3 scripts/validate.py --strict && python3 scripts/audit_skills.py --ci &&
|
|
|
7099
7579
|
- Missing frontmatter → add to new KB docs
|
|
7100
7580
|
- Broken symlink → `ai-toolkit doctor --fix`
|
|
7101
7581
|
|
|
7582
|
+
### Phase 5c: Licensing Gate (v4.20.0+)
|
|
7583
|
+
|
|
7584
|
+
The project is Apache-2.0. Attribution only works if the artefact actually
|
|
7585
|
+
carries it, and every part of that is mechanically checkable.
|
|
7586
|
+
|
|
7587
|
+
```bash
|
|
7588
|
+
# The whole gate, enforced in CI. Run it here so a failure is caught before tagging.
|
|
7589
|
+
npx bats tests/test_licensing.bats
|
|
7590
|
+
```
|
|
7591
|
+
|
|
7592
|
+
The seven assertions, and why each exists:
|
|
7593
|
+
|
|
7594
|
+
| Check | Fails when |
|
|
7595
|
+
|---|---|
|
|
7596
|
+
| Every shipped source file carries an SPDX header | A new `.py`/`.sh`/`.js`/`.bats` file was added without one — the common case, and the reason this is a test rather than a habit |
|
|
7597
|
+
| Headers name Apache-2.0 and nothing else | A file was copied in from an MIT/GPL source with its own header intact |
|
|
7598
|
+
| **No** markdown file carries an SPDX header | Someone "helpfully" ran the header script over `app/skills/` — headers there sit above parsed frontmatter and bill every session for it |
|
|
7599
|
+
| `LICENSE` is the complete Apache 2.0 text | The file was truncated or replaced with a summary |
|
|
7600
|
+
| `NOTICE` carries attribution, the source URL, §4(d) and the MIT-era notice | The attribution mechanism was gutted |
|
|
7601
|
+
| `LICENSE` **and** `NOTICE` ship in the npm package | `package.json` `files` lost an entry — a NOTICE that never reaches the consumer cannot satisfy §4(d) |
|
|
7602
|
+
| Every manifest declaring a licence declares Apache-2.0 | `package.json`, `manifest.json`, `plugin.json` and `package-lock.json` drifted apart |
|
|
7603
|
+
|
|
7604
|
+
**Adding source files in this release?** The header goes *after* the shebang,
|
|
7605
|
+
never before it. Short SPDX form:
|
|
7606
|
+
|
|
7607
|
+
```
|
|
7608
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
7609
|
+
# Copyright 2024-2026 Lukasz Krzemien (biuro@softspark.eu)
|
|
7610
|
+
# Source: https://github.com/softspark/ai-toolkit
|
|
7611
|
+
```
|
|
7612
|
+
|
|
7613
|
+
`//` for JavaScript. Full convention and the reasoning behind the markdown
|
|
7614
|
+
exclusion: [Licensing](../reference/licensing.md).
|
|
7615
|
+
|
|
7616
|
+
**Changing the licence itself?** Do not hand-type the licence text. Take it
|
|
7617
|
+
verbatim from a published copy and cross-verify against a second independent
|
|
7618
|
+
copy before writing `LICENSE` — a rendered or summarised licence is not the
|
|
7619
|
+
licence. Prior releases stay under their original terms; a licence change
|
|
7620
|
+
applies going forward and revokes nothing already granted.
|
|
7621
|
+
|
|
7102
7622
|
### Phase 5a: Supply-Chain Hardening Verification (v2.8.0+)
|
|
7103
7623
|
|
|
7104
7624
|
These checks enforce the security standard introduced in v2.8.0. Do NOT tag a release until all pass.
|
|
@@ -7172,8 +7692,33 @@ git commit -m "chore: release vX.Y.Z"
|
|
|
7172
7692
|
|
|
7173
7693
|
```bash
|
|
7174
7694
|
git tag vX.Y.Z
|
|
7175
|
-
|
|
7176
|
-
|
|
7695
|
+
|
|
7696
|
+
# Assert the tag before pushing it. Both checks are one line each and both
|
|
7697
|
+
# have caught a real broken release.
|
|
7698
|
+
test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)" \
|
|
7699
|
+
|| { echo "FAIL: tag is not on HEAD"; exit 1; }
|
|
7700
|
+
git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" \
|
|
7701
|
+
|| { echo "FAIL: tag is not on the chore: release commit"; exit 1; }
|
|
7702
|
+
|
|
7703
|
+
# Push the branch, then the single release tag by its full ref.
|
|
7704
|
+
git push origin main
|
|
7705
|
+
git push origin refs/tags/vX.Y.Z
|
|
7706
|
+
```
|
|
7707
|
+
|
|
7708
|
+
**Why the assertions (v4.19.0 postmortem).** v4.19.0 was tagged on a commit
|
|
7709
|
+
that contained only a KB document and still carried `package.json` version
|
|
7710
|
+
`4.18.0`; the actual release sat in the commit above it under a recycled
|
|
7711
|
+
`fix:` message. `publish.yml` fired, tried to publish a version already on
|
|
7712
|
+
npm, and failed. Nothing on npm, a tag pointing at the wrong tree, and the
|
|
7713
|
+
only way out was rewriting a pushed commit. Both assertions above catch this
|
|
7714
|
+
in under a second. Run them.
|
|
7715
|
+
|
|
7716
|
+
**Never `git push --tags`.** It pushes every local tag at once, and GitHub
|
|
7717
|
+
suppresses tag-triggered workflow runs when many tags arrive in a single push
|
|
7718
|
+
— the workflow silently does not fire and nothing publishes. Push the single
|
|
7719
|
+
release tag by its full ref, as above. (Sibling evidence: this is exactly how
|
|
7720
|
+
rag-mcp's `1.0.3` image build was skipped, when a `--tags` push carried 37
|
|
7721
|
+
tags at once.)
|
|
7177
7722
|
|
|
7178
7723
|
This triggers `.github/workflows/publish.yml` which:
|
|
7179
7724
|
1. Runs `validate.py --strict`
|
|
@@ -7227,10 +7772,13 @@ git push origin --delete vX.Y.Z
|
|
|
7227
7772
|
| 13 | ShellCheck hooks | `shellcheck --severity=warning app/hooks/*.sh` | Exit 0, no output (mirrors ci.yml; publish.yml does NOT run it) |
|
|
7228
7773
|
| 14 | Provenance flag check | `grep -- '--provenance' .github/workflows/publish.yml` | Present |
|
|
7229
7774
|
| 15 | Checksum-pin backfill | `sources.json` entries all have `sha256` | No unpinned URL sources |
|
|
7775
|
+
| 15a | Licensing gate | `npx bats tests/test_licensing.bats` | 7/7 — SPDX headers, LICENSE, NOTICE, npm `files`, manifest consistency |
|
|
7230
7776
|
| 16 | Tests | `git add -A kb/` if the KB changed, then `npm test` | All pass |
|
|
7231
7777
|
| 17 | Commit | `git commit` | Clean working tree |
|
|
7232
7778
|
| 18 | Tag | `git tag vX.Y.Z` | Tag exists |
|
|
7233
|
-
|
|
|
7779
|
+
| 18a | Tag is on HEAD | `test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)"` | Exit 0 |
|
|
7780
|
+
| 18b | Tag is on the release commit | `git show --no-patch --format=%s vX.Y.Z` | Reads `chore: release vX.Y.Z` |
|
|
7781
|
+
| 19 | Push branch, then the single tag | `git push origin main && git push origin refs/tags/vX.Y.Z` | CI triggered with `id-token: write`. Never `--tags`. |
|
|
7234
7782
|
|
|
7235
7783
|
---
|
|
7236
7784
|
|
|
@@ -9245,7 +9793,7 @@ description: "Feature comparison of ai-toolkit vs other Claude Code toolkits and
|
|
|
9245
9793
|
| Session persistence | Yes | Yes | No | No |
|
|
9246
9794
|
| Architecture notes | **Yes** | No | No | No |
|
|
9247
9795
|
| KB/RAG integration | **Yes** | No | No | Yes |
|
|
9248
|
-
| License |
|
|
9796
|
+
| License | **Apache-2.0** (NOTICE attribution, change notices, patent grant) | MIT | MIT | MIT |
|
|
9249
9797
|
|
|
9250
9798
|
For live benchmark data, see the [ecosystem benchmark snapshot](claude-ecosystem-benchmark-snapshot.md).
|
|
9251
9799
|
|
|
@@ -10319,7 +10867,7 @@ Base configs can define non-overridable constraints via the `enforce` block:
|
|
|
10319
10867
|
{
|
|
10320
10868
|
"enforce": {
|
|
10321
10869
|
"minHookProfile": "standard",
|
|
10322
|
-
"requiredPlugins": ["
|
|
10870
|
+
"requiredPlugins": ["memory-pack"],
|
|
10323
10871
|
"forbidOverride": ["constitution", "guard-destructive"],
|
|
10324
10872
|
"requiredAgents": ["security-auditor"]
|
|
10325
10873
|
}
|
|
@@ -12052,63 +12600,6 @@ ai-toolkit add-rule ./jira-rules.md
|
|
|
12052
12600
|
|
|
12053
12601
|
---
|
|
12054
12602
|
|
|
12055
|
-
## kb/reference/language-packs.md
|
|
12056
|
-
|
|
12057
|
-
---
|
|
12058
|
-
title: "AI Toolkit - Language Plugin Packs"
|
|
12059
|
-
category: reference
|
|
12060
|
-
service: ai-toolkit
|
|
12061
|
-
tags: [plugins, languages, rust, java, csharp, kotlin, swift, ruby]
|
|
12062
|
-
version: "1.0.0"
|
|
12063
|
-
created: "2026-03-29"
|
|
12064
|
-
last_updated: "2026-03-29"
|
|
12065
|
-
description: "6 language-specific plugin packs providing knowledge skills for Rust, Java, C#, Kotlin, Swift, and Ruby."
|
|
12066
|
-
---
|
|
12067
|
-
|
|
12068
|
-
# Language Plugin Packs
|
|
12069
|
-
|
|
12070
|
-
## Overview
|
|
12071
|
-
|
|
12072
|
-
Language packs are domain-scoped plugin packs that provide knowledge skills for specific programming languages. Each pack contains a single knowledge skill with idiomatic patterns, error handling, testing conventions, common frameworks, and performance tips.
|
|
12073
|
-
|
|
12074
|
-
## Available Packs
|
|
12075
|
-
|
|
12076
|
-
| Pack | Skill | Language | Key Topics |
|
|
12077
|
-
|------|-------|----------|------------|
|
|
12078
|
-
| `rust-pack` | `rust-patterns` | Rust | Ownership, borrowing, Cargo, tokio, serde |
|
|
12079
|
-
| `java-pack` | `java-patterns` | Java | Records, sealed classes, Spring Boot, JUnit 5 |
|
|
12080
|
-
| `csharp-pack` | `csharp-patterns` | C# / .NET | Nullable refs, async/await, ASP.NET Core, EF Core |
|
|
12081
|
-
| `kotlin-pack` | `kotlin-patterns` | Kotlin | Coroutines, DSLs, sealed classes, Ktor, MockK |
|
|
12082
|
-
| `swift-pack` | `swift-patterns` | Swift / iOS | Protocol-oriented, SwiftUI, async/await, SPM |
|
|
12083
|
-
| `ruby-pack` | `ruby-patterns` | Ruby | Blocks, Rails conventions, RSpec, ActiveRecord |
|
|
12084
|
-
|
|
12085
|
-
## Skill Content Sections
|
|
12086
|
-
|
|
12087
|
-
Each language skill follows a consistent structure:
|
|
12088
|
-
|
|
12089
|
-
1. **Project Structure** — standard directory layout and build tool configuration
|
|
12090
|
-
2. **Idioms / Code Style** — language-specific patterns and conventions
|
|
12091
|
-
3. **Error Handling** — error types, patterns, and best practices
|
|
12092
|
-
4. **Testing Patterns** — test frameworks, assertion libraries, mocking
|
|
12093
|
-
5. **Common Libraries / Frameworks** — ecosystem essentials
|
|
12094
|
-
6. **Performance Tips** — optimization techniques and profiling
|
|
12095
|
-
7. **Build / Package Management** — dependency management and CI
|
|
12096
|
-
|
|
12097
|
-
## How Knowledge Skills Work
|
|
12098
|
-
|
|
12099
|
-
These skills have `user-invocable: false` in their frontmatter, meaning they are NOT slash commands. Instead, Claude loads them contextually when the conversation topic matches the skill's description trigger.
|
|
12100
|
-
|
|
12101
|
-
For example, when a user asks "How do I handle errors in Rust?", Claude automatically loads `rust-patterns` to provide idiomatic Rust error handling guidance.
|
|
12102
|
-
|
|
12103
|
-
## Requesting New Language Packs
|
|
12104
|
-
|
|
12105
|
-
File an issue with the `language-pack` label. Include:
|
|
12106
|
-
- Language name
|
|
12107
|
-
- Key topics to cover
|
|
12108
|
-
- Popular frameworks/libraries to include
|
|
12109
|
-
|
|
12110
|
-
---
|
|
12111
|
-
|
|
12112
12603
|
## kb/reference/language-rules.md
|
|
12113
12604
|
|
|
12114
12605
|
---
|
|
@@ -12356,6 +12847,159 @@ Per-language content delivered as a knowledge skill is the same Markdown that ot
|
|
|
12356
12847
|
|
|
12357
12848
|
---
|
|
12358
12849
|
|
|
12850
|
+
## kb/reference/licensing.md
|
|
12851
|
+
|
|
12852
|
+
---
|
|
12853
|
+
title: "Licensing"
|
|
12854
|
+
category: reference
|
|
12855
|
+
service: ai-toolkit
|
|
12856
|
+
tags: [licence, apache-2.0, spdx, notice, attribution, headers, mit]
|
|
12857
|
+
version: "1.0.0"
|
|
12858
|
+
created: "2026-07-27"
|
|
12859
|
+
last_updated: "2026-07-27"
|
|
12860
|
+
description: "ai-toolkit is Apache-2.0 from v4.20.0. What that obliges a redistributor to do, why NOTICE is the point, the SPDX header convention and which files deliberately do not get one, how MIT-era contributions are handled, and the CI gate that enforces all of it."
|
|
12861
|
+
---
|
|
12862
|
+
|
|
12863
|
+
# Licensing
|
|
12864
|
+
|
|
12865
|
+
ai-toolkit is licensed under the **Apache License 2.0** from v4.20.0. Releases up
|
|
12866
|
+
to and including v4.20.0 were published under MIT and remain available under MIT.
|
|
12867
|
+
The change applies going forward and revokes nothing already granted.
|
|
12868
|
+
|
|
12869
|
+
Canonical files: [`LICENSE`](../../LICENSE) (verbatim Apache-2.0 text) and
|
|
12870
|
+
[`NOTICE`](../../NOTICE) (attribution).
|
|
12871
|
+
|
|
12872
|
+
## Why Apache-2.0, given MIT already required attribution
|
|
12873
|
+
|
|
12874
|
+
This is the part most often got wrong. MIT already says:
|
|
12875
|
+
|
|
12876
|
+
> The above copyright notice and this permission notice shall be included in all
|
|
12877
|
+
> copies or substantial portions of the Software.
|
|
12878
|
+
|
|
12879
|
+
So attribution was never the new thing. What Apache-2.0 adds:
|
|
12880
|
+
|
|
12881
|
+
| Mechanism | MIT | Apache-2.0 |
|
|
12882
|
+
|---|---|---|
|
|
12883
|
+
| Copyright notice must be preserved | yes | yes |
|
|
12884
|
+
| **`NOTICE` contents must travel into redistributions** (§4d) | — | **yes** |
|
|
12885
|
+
| **Modified files must carry a notice saying they changed** (§4b) | — | **yes** |
|
|
12886
|
+
| Express patent grant, terminated by patent litigation (§3) | — | yes |
|
|
12887
|
+
| No rights to the licensor's names or marks (§6) | — | yes |
|
|
12888
|
+
|
|
12889
|
+
**`NOTICE` is the reason for the change.** It is the only mechanism in a
|
|
12890
|
+
permissive licence that forces a redistributor to reproduce your attribution —
|
|
12891
|
+
project name, copyright, source URL — somewhere their users can see it. Without
|
|
12892
|
+
it, MIT and Apache-2.0 are close to equivalent in practice.
|
|
12893
|
+
|
|
12894
|
+
Consequence for packaging: `NOTICE` is listed in `package.json` `files`. A NOTICE
|
|
12895
|
+
that does not reach the consumer cannot satisfy §4(d), so that entry is a
|
|
12896
|
+
licensing requirement, not housekeeping, and is asserted in CI.
|
|
12897
|
+
|
|
12898
|
+
## What a fork owes
|
|
12899
|
+
|
|
12900
|
+
Fork it, modify it, ship it commercially. Three obligations:
|
|
12901
|
+
|
|
12902
|
+
1. **Carry the `NOTICE`** into your distribution (§4d).
|
|
12903
|
+
2. **Say which files you changed** (§4b).
|
|
12904
|
+
3. **Do not use the "ai-toolkit" or "SoftSpark" names or marks** as if endorsed (§6).
|
|
12905
|
+
|
|
12906
|
+
## Source header convention
|
|
12907
|
+
|
|
12908
|
+
Short SPDX form, three lines, always **after** the shebang — an interpreter
|
|
12909
|
+
directive must stay on line 1 — and after a Python `coding:` line if present:
|
|
12910
|
+
|
|
12911
|
+
```bash
|
|
12912
|
+
#!/usr/bin/env bash
|
|
12913
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
12914
|
+
# Copyright 2024-2026 Lukasz Krzemien (biuro@softspark.eu)
|
|
12915
|
+
# Source: https://github.com/softspark/ai-toolkit
|
|
12916
|
+
#
|
|
12917
|
+
# guard-path.sh — the file's own description continues here.
|
|
12918
|
+
```
|
|
12919
|
+
|
|
12920
|
+
`//` for JavaScript. SPDX was chosen over the 13-line Apache APPENDIX boilerplate
|
|
12921
|
+
because it is machine-readable — licence scanners, GitHub and SBOM tooling parse
|
|
12922
|
+
it — and because 13 lines on top of every source file buries the description that a
|
|
12923
|
+
reader of a hook actually needs.
|
|
12924
|
+
|
|
12925
|
+
### Which files get a header
|
|
12926
|
+
|
|
12927
|
+
| Included | Count |
|
|
12928
|
+
|---|---:|
|
|
12929
|
+
| `scripts/**/*.py` | 109 |
|
|
12930
|
+
| `tests/*.bats` | 77 |
|
|
12931
|
+
| `app/hooks/*.sh` | 32 |
|
|
12932
|
+
| `app/skills/**/*.py`, `**/*.js` | 27 |
|
|
12933
|
+
| `app/plugins/**/*.sh`, `**/*.py` | 6 |
|
|
12934
|
+
| `bin/*.js`, `benchmarks/**/*.py` | 2 |
|
|
12935
|
+
| **total** | **253** |
|
|
12936
|
+
|
|
12937
|
+
These are a snapshot, not a contract — the CI gate checks that *every* matching
|
|
12938
|
+
file has a header, so the count moves with the codebase and nothing needs
|
|
12939
|
+
updating here when it does.
|
|
12940
|
+
|
|
12941
|
+
### Which files deliberately do not, and why
|
|
12942
|
+
|
|
12943
|
+
**No markdown file carries a header.** Not `app/skills/*/SKILL.md`, not
|
|
12944
|
+
`app/agents/*.md`, not `app/rules/`, not `kb/`. Two reasons, both concrete:
|
|
12945
|
+
|
|
12946
|
+
1. **Frontmatter.** Skill and agent files open with parsed YAML. A header above
|
|
12947
|
+
it breaks parsing; a header below it is invisible where it matters.
|
|
12948
|
+
2. **Token cost.** Skill and agent descriptions load into the system prompt of
|
|
12949
|
+
every session — measured at 5,051 and 2,750 tokens respectively. A four-line
|
|
12950
|
+
header across 108 skills and 45 agents would be a permanent per-session cost,
|
|
12951
|
+
billed on every conversation forever, for a notice Apache only *recommends*.
|
|
12952
|
+
`LICENSE` and `NOTICE` carry the full terms; the headers are a convenience.
|
|
12953
|
+
|
|
12954
|
+
This exclusion is asserted in CI, so a well-meant sweep of the header script over
|
|
12955
|
+
`app/skills/` fails the build rather than silently taxing every session.
|
|
12956
|
+
|
|
12957
|
+
## MIT-era contributions
|
|
12958
|
+
|
|
12959
|
+
Contributions made while the project was MIT-licensed remain the copyright of
|
|
12960
|
+
their authors and were received under MIT terms. Three contributors other than
|
|
12961
|
+
the maintainer appear in the history.
|
|
12962
|
+
|
|
12963
|
+
MIT explicitly permits sublicensing, so those contributions are redistributed
|
|
12964
|
+
here under Apache-2.0 **with the original MIT notice preserved verbatim** in
|
|
12965
|
+
`NOTICE`, which is what MIT requires. This is standard practice for an MIT to
|
|
12966
|
+
Apache-2.0 move and needs no contributor sign-off. A "clean" Apache-2.0 with no
|
|
12967
|
+
MIT remnant would need each contributor's agreement.
|
|
12968
|
+
|
|
12969
|
+
*This is a description of what the project does, not legal advice.*
|
|
12970
|
+
|
|
12971
|
+
## Enforcement
|
|
12972
|
+
|
|
12973
|
+
`tests/test_licensing.bats`, seven assertions, run by `npm test` in CI:
|
|
12974
|
+
|
|
12975
|
+
- every shipped source file carries an SPDX header
|
|
12976
|
+
- headers name Apache-2.0 and nothing else
|
|
12977
|
+
- **no** markdown file carries a header
|
|
12978
|
+
- `LICENSE` is the complete Apache 2.0 text, appendix included
|
|
12979
|
+
- `NOTICE` carries attribution, the source URL, §4(d) and the MIT-era notice
|
|
12980
|
+
- `LICENSE` and `NOTICE` both appear in `package.json` `files`
|
|
12981
|
+
- every manifest declaring a licence declares Apache-2.0
|
|
12982
|
+
|
|
12983
|
+
It is a test rather than a checklist line on purpose. This project has two
|
|
12984
|
+
same-day postmortems about SOPs that existed and were skipped; CI does not skip.
|
|
12985
|
+
[Release Preparation](../procedures/release-preparation-sop.md) Phase 5c runs the
|
|
12986
|
+
same gate before tagging so a failure surfaces before the tag, not after.
|
|
12987
|
+
|
|
12988
|
+
## If the licence ever changes again
|
|
12989
|
+
|
|
12990
|
+
Do not hand-type the licence text and do not paste a rendered copy — a
|
|
12991
|
+
markdown-formatted licence is not the licence. Take it verbatim from a published
|
|
12992
|
+
source, cross-verify against a second independent copy, and only then write
|
|
12993
|
+
`LICENSE`. That is how the Apache-2.0 text in this repository was installed.
|
|
12994
|
+
|
|
12995
|
+
## Related
|
|
12996
|
+
|
|
12997
|
+
- [`LICENSE`](../../LICENSE), [`NOTICE`](../../NOTICE)
|
|
12998
|
+
- [Release Preparation SOP](../procedures/release-preparation-sop.md) — Phase 5c
|
|
12999
|
+
- [Distribution Model](distribution-model.md) — what ships and where
|
|
13000
|
+
|
|
13001
|
+
---
|
|
13002
|
+
|
|
12359
13003
|
## kb/reference/manifest-install.md
|
|
12360
13004
|
|
|
12361
13005
|
---
|
|
@@ -13670,22 +14314,30 @@ ai-toolkit plugin status --editor all # show installed packs with r
|
|
|
13670
14314
|
|
|
13671
14315
|
## Current Experimental Packs
|
|
13672
14316
|
|
|
13673
|
-
| Pack | Domain |
|
|
13674
|
-
|
|
13675
|
-
| `
|
|
13676
|
-
| `
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
|
|
14317
|
+
| Pack | Domain | Owns | Installs (claude / codex) | Description |
|
|
14318
|
+
|------|--------|------|---------------------------|-------------|
|
|
14319
|
+
| `memory-pack` | memory | 2 hooks, 2 scripts, 1 skill | 4 / 4 files | SQLite persistent memory with FTS5 search |
|
|
14320
|
+
| `enterprise-pack` | enterprise | 2 hooks | 2 / 2 files | Status-line and output-style overlays |
|
|
14321
|
+
|
|
14322
|
+
Both packs ship content in this repository. Neither fetches anything at install
|
|
14323
|
+
time.
|
|
14324
|
+
|
|
14325
|
+
### The rule the table now enforces
|
|
14326
|
+
|
|
14327
|
+
**A pack must install files the core install does not.** `ai-toolkit install`
|
|
14328
|
+
links every core skill and agent, so a manifest naming only core assets resolves
|
|
14329
|
+
to nothing: `plugin install` reports `(0 file items)` and no file appears on
|
|
14330
|
+
disk. This is not a subtle degradation — it is a complete no-op, identical on
|
|
14331
|
+
every profile (`minimal`, `standard`, `strict`) and on both runtimes.
|
|
14332
|
+
|
|
14333
|
+
Nine packs were removed in v4.20.0 for failing this: `csharp`, `java`, `kotlin`,
|
|
14334
|
+
`ruby`, `rust`, `swift`, `frontend`, `research`, `security`. Every one declared
|
|
14335
|
+
only skills and agents that already ship in core, and eight of them owned nothing
|
|
14336
|
+
but a `README.md`. Full measurement:
|
|
14337
|
+
[`no-op-plugin-packs-removed-20260727.md`](../history/completed/no-op-plugin-packs-removed-20260727.md).
|
|
14338
|
+
|
|
14339
|
+
Before adding a pack, prove it does something: install core into a throwaway
|
|
14340
|
+
`HOME`, install the pack, and check that the reported file count is above zero.
|
|
13689
14341
|
|
|
13690
14342
|
**A pack that downloads a binary has been tried once and retired.** `rtk-pack`
|
|
13691
14343
|
(v4.18.0, removed in v4.19.0) fetched a checksum-pinned artifact in
|