voidmachine 0.0.0 → 4.0.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/LICENSE +21 -0
- package/README.md +123 -4
- package/bin/void-harness.mjs +12 -0
- package/bin/void-machine.mjs +12 -0
- package/core-assets/.claude-plugin/plugin.json +253 -0
- package/core-assets/.gitkeep +0 -0
- package/core-assets/PHILOSOPHY.md +218 -0
- package/core-assets/PROJECT-DOCTRINE.template.md +14 -0
- package/core-assets/adapters/security/manifest.yaml +96 -0
- package/core-assets/agents/.gitkeep +0 -0
- package/core-assets/agents/accessibility-specialist.md +59 -0
- package/core-assets/agents/api-integration-engineer.md +59 -0
- package/core-assets/agents/code-explorer.md +94 -0
- package/core-assets/agents/code-explorer.source +7 -0
- package/core-assets/agents/data-migration-engineer.md +59 -0
- package/core-assets/agents/devex-docs-engineer.md +57 -0
- package/core-assets/agents/doctrine-critic.md +91 -0
- package/core-assets/agents/doctrine-critic.source +11 -0
- package/core-assets/agents/domain-architect.md +56 -0
- package/core-assets/agents/experience-designer.md +59 -0
- package/core-assets/agents/frontend-engineer.md +60 -0
- package/core-assets/agents/independent-code-reviewer.md +61 -0
- package/core-assets/agents/migration-planner.md +97 -0
- package/core-assets/agents/migration-planner.source +7 -0
- package/core-assets/agents/observability-sre-engineer.md +59 -0
- package/core-assets/agents/pdf-specialist.md +58 -0
- package/core-assets/agents/performance-engineer.md +58 -0
- package/core-assets/agents/product-challenger.md +55 -0
- package/core-assets/agents/security-engineer.md +66 -0
- package/core-assets/agents/silent-failure-hunter.md +94 -0
- package/core-assets/agents/silent-failure-hunter.source +8 -0
- package/core-assets/agents/solution-architect.md +57 -0
- package/core-assets/agents/test-qa-engineer.md +60 -0
- package/core-assets/agents/type-design-analyzer.md +93 -0
- package/core-assets/agents/type-design-analyzer.source +8 -0
- package/core-assets/agents/visual-craft-director.md +62 -0
- package/core-assets/codex/hooks.json +157 -0
- package/core-assets/contract-history/visual-craft-director/v2.yaml +43 -0
- package/core-assets/data/catalog.v3.json +10479 -0
- package/core-assets/data/certification.json +1800 -0
- package/core-assets/data/identity.json +8 -0
- package/core-assets/data/model.json +4226 -0
- package/core-assets/enforce/ci-enforce.sh +183 -0
- package/core-assets/hooks/_checks.sh +145 -0
- package/core-assets/hooks/_hooklib.sh +163 -0
- package/core-assets/hooks/_syntax-worker.cjs +503 -0
- package/core-assets/hooks/_void-hook.mjs +5459 -0
- package/core-assets/hooks/activation-meter.sh +13 -0
- package/core-assets/hooks/anti-ai-slop-grep.sh +38 -0
- package/core-assets/hooks/auto-format.sh +9 -0
- package/core-assets/hooks/axe-precommit.sh +35 -0
- package/core-assets/hooks/block-dangerous-bash.sh +10 -0
- package/core-assets/hooks/block-protected-push.sh +81 -0
- package/core-assets/hooks/boundary-direction-check.sh +10 -0
- package/core-assets/hooks/control-character-grep.sh +10 -0
- package/core-assets/hooks/fowler-refactors.txt +71 -0
- package/core-assets/hooks/large-cl-grep.sh +9 -0
- package/core-assets/hooks/llm-cost-precommit.sh +55 -0
- package/core-assets/hooks/migration-lint.sh +58 -0
- package/core-assets/hooks/migration-pr-template.sh +55 -0
- package/core-assets/hooks/no-ai-design-slop.sh +10 -0
- package/core-assets/hooks/no-any-grep.sh +10 -0
- package/core-assets/hooks/no-as-cast-grep.sh +10 -0
- package/core-assets/hooks/no-console-log-grep.sh +10 -0
- package/core-assets/hooks/no-null-grep.sh +10 -0
- package/core-assets/hooks/no-only-no-skip.sh +10 -0
- package/core-assets/hooks/outcome-meter.sh +13 -0
- package/core-assets/hooks/pre-PR-review-evidence.sh +47 -0
- package/core-assets/hooks/protect-sensitive-files.sh +10 -0
- package/core-assets/hooks/refactor-named-grep.sh +49 -0
- package/core-assets/hooks/secret-in-content.sh +10 -0
- package/core-assets/hooks/sessionstart-context.sh +9 -0
- package/core-assets/hooks/stop-typecheck.sh +9 -0
- package/core-assets/hooks/tdd-guard.md +90 -0
- package/core-assets/hooks/tdd-guard.sh +10 -0
- package/core-assets/hooks/test-name-lint.sh +10 -0
- package/core-assets/hooks/tidying-commit-prefix.sh +37 -0
- package/core-assets/hooks/trim-large-output.sh +9 -0
- package/core-assets/hooks/tsc-noemit-precommit.sh +22 -0
- package/core-assets/hooks/ubiquitous-language-lint.sh +58 -0
- package/core-assets/hooks/viewport-screenshot-gate.sh +48 -0
- package/core-assets/modules/.gitkeep +0 -0
- package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/.source +7 -0
- package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/SKILL.md +164 -0
- package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/harness.yaml +14 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/.source +7 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/SKILL.md +178 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/harness.yaml +14 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/.source +8 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/SKILL.md +209 -0
- package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/.source +7 -0
- package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/SKILL.md +194 -0
- package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/.source +5 -0
- package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/SKILL.md +160 -0
- package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-package-extraction/.source +5 -0
- package/core-assets/packs/pack-monorepo/skills/void-package-extraction/SKILL.md +70 -0
- package/core-assets/packs/pack-monorepo/skills/void-package-extraction/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-service-package/.source +5 -0
- package/core-assets/packs/pack-monorepo/skills/void-service-package/SKILL.md +122 -0
- package/core-assets/packs/pack-monorepo/skills/void-service-package/harness.yaml +14 -0
- package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/.source +7 -0
- package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/SKILL.md +116 -0
- package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/SKILL.md +162 -0
- package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/SKILL.md +161 -0
- package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/SKILL.md +176 -0
- package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/SKILL.md +129 -0
- package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/harness.yaml +14 -0
- package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/.source +5 -0
- package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/SKILL.md +107 -0
- package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/.source +5 -0
- package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/SKILL.md +153 -0
- package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/.source +5 -0
- package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/SKILL.md +204 -0
- package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/.source +8 -0
- package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/SKILL.md +266 -0
- package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/harness.yaml +14 -0
- package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/.source +5 -0
- package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/SKILL.md +178 -0
- package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-accessibility-check/.source +8 -0
- package/core-assets/packs/pack-react/skills/void-accessibility-check/SKILL.md +136 -0
- package/core-assets/packs/pack-react/skills/void-accessibility-check/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-client-vs-server-component/.source +5 -0
- package/core-assets/packs/pack-react/skills/void-client-vs-server-component/SKILL.md +116 -0
- package/core-assets/packs/pack-react/skills/void-client-vs-server-component/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-form-pattern/.source +7 -0
- package/core-assets/packs/pack-react/skills/void-form-pattern/SKILL.md +157 -0
- package/core-assets/packs/pack-react/skills/void-form-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-react/skills/void-state-architecture/.source +5 -0
- package/core-assets/packs/pack-react/skills/void-state-architecture/SKILL.md +160 -0
- package/core-assets/packs/pack-react/skills/void-state-architecture/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-background-job-pattern/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-background-job-pattern/SKILL.md +214 -0
- package/core-assets/packs/pack-server/skills/void-background-job-pattern/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/SKILL.md +168 -0
- package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-env-validation/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-env-validation/SKILL.md +131 -0
- package/core-assets/packs/pack-server/skills/void-env-validation/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/.source +6 -0
- package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/SKILL.md +149 -0
- package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-server-action/.source +7 -0
- package/core-assets/packs/pack-server/skills/void-server-action/SKILL.md +181 -0
- package/core-assets/packs/pack-server/skills/void-server-action/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-testing-server-modules/.source +7 -0
- package/core-assets/packs/pack-server/skills/void-testing-server-modules/SKILL.md +73 -0
- package/core-assets/packs/pack-server/skills/void-testing-server-modules/harness.yaml +14 -0
- package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/.source +7 -0
- package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/SKILL.md +205 -0
- package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/harness.yaml +14 -0
- package/core-assets/policies/core.yaml +95 -0
- package/core-assets/policies/ui.yaml +23 -0
- package/core-assets/profiles/base.yaml +29 -0
- package/core-assets/profiles/expo-config.yaml +36 -0
- package/core-assets/profiles/expo.yaml +35 -0
- package/core-assets/profiles/monorepo.yaml +33 -0
- package/core-assets/profiles/nextjs-config.yaml +31 -0
- package/core-assets/profiles/nextjs.yaml +31 -0
- package/core-assets/profiles/node-server.yaml +31 -0
- package/core-assets/profiles/pwa.yaml +33 -0
- package/core-assets/profiles/react.yaml +39 -0
- package/core-assets/profiles/sql.yaml +39 -0
- package/core-assets/profiles/typescript.yaml +39 -0
- package/core-assets/skills/.gitkeep +0 -0
- package/core-assets/skills/void-accessibility/.source +15 -0
- package/core-assets/skills/void-accessibility/SKILL.md +275 -0
- package/core-assets/skills/void-accessibility/harness.yaml +17 -0
- package/core-assets/skills/void-api-and-interface-design/.source +13 -0
- package/core-assets/skills/void-api-and-interface-design/SKILL.md +231 -0
- package/core-assets/skills/void-api-and-interface-design/harness.yaml +16 -0
- package/core-assets/skills/void-async-safety/.source +13 -0
- package/core-assets/skills/void-async-safety/SKILL.md +287 -0
- package/core-assets/skills/void-async-safety/harness.yaml +16 -0
- package/core-assets/skills/void-audit/.source +15 -0
- package/core-assets/skills/void-audit/SKILL.md +83 -0
- package/core-assets/skills/void-audit/harness.yaml +14 -0
- package/core-assets/skills/void-autopilot/.source +21 -0
- package/core-assets/skills/void-autopilot/SKILL.md +358 -0
- package/core-assets/skills/void-autopilot/harness.yaml +14 -0
- package/core-assets/skills/void-brainstorm/.source +14 -0
- package/core-assets/skills/void-brainstorm/SKILL.md +271 -0
- package/core-assets/skills/void-brainstorm/harness.yaml +14 -0
- package/core-assets/skills/void-checkpoint/.source +39 -0
- package/core-assets/skills/void-checkpoint/SKILL.md +227 -0
- package/core-assets/skills/void-checkpoint/harness.yaml +14 -0
- package/core-assets/skills/void-claude-md/.source +15 -0
- package/core-assets/skills/void-claude-md/SKILL.md +180 -0
- package/core-assets/skills/void-claude-md/harness.yaml +14 -0
- package/core-assets/skills/void-code-review/.source +14 -0
- package/core-assets/skills/void-code-review/SKILL.md +232 -0
- package/core-assets/skills/void-code-review/harness.yaml +15 -0
- package/core-assets/skills/void-commit-discipline/.source +9 -0
- package/core-assets/skills/void-commit-discipline/SKILL.md +211 -0
- package/core-assets/skills/void-commit-discipline/harness.yaml +15 -0
- package/core-assets/skills/void-context/.source +15 -0
- package/core-assets/skills/void-context/SKILL.md +167 -0
- package/core-assets/skills/void-context/harness.yaml +14 -0
- package/core-assets/skills/void-debug/.source +11 -0
- package/core-assets/skills/void-debug/SKILL.md +211 -0
- package/core-assets/skills/void-debug/harness.yaml +14 -0
- package/core-assets/skills/void-decide/.source +9 -0
- package/core-assets/skills/void-decide/SKILL.md +147 -0
- package/core-assets/skills/void-decide/harness.yaml +14 -0
- package/core-assets/skills/void-devex-audit/.source +8 -0
- package/core-assets/skills/void-devex-audit/SKILL.md +113 -0
- package/core-assets/skills/void-devex-audit/harness.yaml +15 -0
- package/core-assets/skills/void-doctor/.source +15 -0
- package/core-assets/skills/void-doctor/SKILL.md +83 -0
- package/core-assets/skills/void-doctor/harness.yaml +14 -0
- package/core-assets/skills/void-domain-driven-design/.source +13 -0
- package/core-assets/skills/void-domain-driven-design/SKILL.md +292 -0
- package/core-assets/skills/void-domain-driven-design/harness.yaml +15 -0
- package/core-assets/skills/void-frontend-design/.source +19 -0
- package/core-assets/skills/void-frontend-design/SKILL.md +274 -0
- package/core-assets/skills/void-frontend-design/harness.yaml +17 -0
- package/core-assets/skills/void-functional/.source +14 -0
- package/core-assets/skills/void-functional/SKILL.md +312 -0
- package/core-assets/skills/void-functional/harness.yaml +15 -0
- package/core-assets/skills/void-graph/.source +15 -0
- package/core-assets/skills/void-graph/SKILL.md +80 -0
- package/core-assets/skills/void-graph/harness.yaml +14 -0
- package/core-assets/skills/void-hexagonal-architecture/.source +12 -0
- package/core-assets/skills/void-hexagonal-architecture/SKILL.md +276 -0
- package/core-assets/skills/void-hexagonal-architecture/harness.yaml +15 -0
- package/core-assets/skills/void-implement/.source +39 -0
- package/core-assets/skills/void-implement/SKILL.md +183 -0
- package/core-assets/skills/void-implement/harness.yaml +14 -0
- package/core-assets/skills/void-learn/.source +13 -0
- package/core-assets/skills/void-learn/SKILL.md +226 -0
- package/core-assets/skills/void-learn/harness.yaml +14 -0
- package/core-assets/skills/void-llm-cost-discipline/.source +13 -0
- package/core-assets/skills/void-llm-cost-discipline/SKILL.md +299 -0
- package/core-assets/skills/void-llm-cost-discipline/harness.yaml +15 -0
- package/core-assets/skills/void-make-pdf/.source +9 -0
- package/core-assets/skills/void-make-pdf/SKILL.md +52 -0
- package/core-assets/skills/void-make-pdf/harness.yaml +15 -0
- package/core-assets/skills/void-merge/.source +8 -0
- package/core-assets/skills/void-merge/SKILL.md +111 -0
- package/core-assets/skills/void-merge/harness.yaml +14 -0
- package/core-assets/skills/void-migrations/.source +13 -0
- package/core-assets/skills/void-migrations/SKILL.md +264 -0
- package/core-assets/skills/void-migrations/harness.yaml +17 -0
- package/core-assets/skills/void-observability/.source +12 -0
- package/core-assets/skills/void-observability/SKILL.md +245 -0
- package/core-assets/skills/void-observability/harness.yaml +15 -0
- package/core-assets/skills/void-plan/.source +15 -0
- package/core-assets/skills/void-plan/SKILL.md +239 -0
- package/core-assets/skills/void-plan/harness.yaml +14 -0
- package/core-assets/skills/void-plan-review/.source +12 -0
- package/core-assets/skills/void-plan-review/SKILL.md +128 -0
- package/core-assets/skills/void-plan-review/harness.yaml +15 -0
- package/core-assets/skills/void-qa/.source +15 -0
- package/core-assets/skills/void-qa/SKILL.md +103 -0
- package/core-assets/skills/void-qa/harness.yaml +15 -0
- package/core-assets/skills/void-refactor/.source +9 -0
- package/core-assets/skills/void-refactor/SKILL.md +220 -0
- package/core-assets/skills/void-refactor/harness.yaml +15 -0
- package/core-assets/skills/void-retrospective/.source +9 -0
- package/core-assets/skills/void-retrospective/SKILL.md +71 -0
- package/core-assets/skills/void-retrospective/harness.yaml +15 -0
- package/core-assets/skills/void-security-audit/.source +12 -0
- package/core-assets/skills/void-security-audit/SKILL.md +138 -0
- package/core-assets/skills/void-security-audit/harness.yaml +15 -0
- package/core-assets/skills/void-security-guidance/.source +12 -0
- package/core-assets/skills/void-security-guidance/SKILL.md +255 -0
- package/core-assets/skills/void-security-guidance/harness.yaml +15 -0
- package/core-assets/skills/void-source-driven-development/.source +12 -0
- package/core-assets/skills/void-source-driven-development/SKILL.md +158 -0
- package/core-assets/skills/void-source-driven-development/harness.yaml +15 -0
- package/core-assets/skills/void-tdd/.source +15 -0
- package/core-assets/skills/void-tdd/SKILL.md +394 -0
- package/core-assets/skills/void-tdd/harness.yaml +15 -0
- package/core-assets/skills/void-testing/.source +19 -0
- package/core-assets/skills/void-testing/SKILL.md +301 -0
- package/core-assets/skills/void-testing/harness.yaml +17 -0
- package/core-assets/skills/void-ticket/.source +18 -0
- package/core-assets/skills/void-ticket/SKILL.md +239 -0
- package/core-assets/skills/void-ticket/harness.yaml +14 -0
- package/core-assets/skills/void-typescript-strict/.source +10 -0
- package/core-assets/skills/void-typescript-strict/SKILL.md +294 -0
- package/core-assets/skills/void-typescript-strict/harness.yaml +17 -0
- package/core-assets/skills/void-ui-review/.source +12 -0
- package/core-assets/skills/void-ui-review/SKILL.md +97 -0
- package/core-assets/skills/void-ui-review/harness.yaml +15 -0
- package/core-assets/skills/void-verify/.source +12 -0
- package/core-assets/skills/void-verify/SKILL.md +184 -0
- package/core-assets/skills/void-verify/harness.yaml +15 -0
- package/core-assets/specialists/accessibility-specialist.source +11 -0
- package/core-assets/specialists/accessibility-specialist.yaml +30 -0
- package/core-assets/specialists/api-integration-engineer.source +11 -0
- package/core-assets/specialists/api-integration-engineer.yaml +30 -0
- package/core-assets/specialists/data-migration-engineer.source +11 -0
- package/core-assets/specialists/data-migration-engineer.yaml +30 -0
- package/core-assets/specialists/devex-docs-engineer.source +11 -0
- package/core-assets/specialists/devex-docs-engineer.yaml +29 -0
- package/core-assets/specialists/domain-architect.source +11 -0
- package/core-assets/specialists/domain-architect.yaml +28 -0
- package/core-assets/specialists/experience-designer.source +15 -0
- package/core-assets/specialists/experience-designer.yaml +38 -0
- package/core-assets/specialists/frontend-engineer.source +11 -0
- package/core-assets/specialists/frontend-engineer.yaml +32 -0
- package/core-assets/specialists/independent-code-reviewer.source +10 -0
- package/core-assets/specialists/independent-code-reviewer.yaml +37 -0
- package/core-assets/specialists/migrations.json +15 -0
- package/core-assets/specialists/observability-sre-engineer.source +11 -0
- package/core-assets/specialists/observability-sre-engineer.yaml +30 -0
- package/core-assets/specialists/pdf-specialist.source +11 -0
- package/core-assets/specialists/pdf-specialist.yaml +29 -0
- package/core-assets/specialists/performance-engineer.source +11 -0
- package/core-assets/specialists/performance-engineer.yaml +29 -0
- package/core-assets/specialists/product-challenger.source +10 -0
- package/core-assets/specialists/product-challenger.yaml +27 -0
- package/core-assets/specialists/security-engineer.source +13 -0
- package/core-assets/specialists/security-engineer.yaml +41 -0
- package/core-assets/specialists/solution-architect.source +13 -0
- package/core-assets/specialists/solution-architect.yaml +32 -0
- package/core-assets/specialists/test-qa-engineer.source +14 -0
- package/core-assets/specialists/test-qa-engineer.yaml +35 -0
- package/core-assets/specialists/visual-craft-director.source +17 -0
- package/core-assets/specialists/visual-craft-director.yaml +60 -0
- package/core-assets/templates/github/dependency-audit.mjs +54 -0
- package/core-assets/templates/github/void-dependency-audit.yml +35 -0
- package/core-assets/templates/github/void-security.yml +85 -0
- package/dist/main.js +57001 -0
- package/package.json +66 -4
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-learn
|
|
3
|
+
description: Capture a lesson when it appears — a stated project rule, a recurring/deja-vu fix, an end-of-cycle pattern, or a harness gap. Routes to PROJECT-DOCTRINE, a GitHub issue, or nothing. HITL strict. Also the single door for harness feedback. Fires on "the harness should have X", "this hook is a false positive", "that skill is missing", a DX papercut worth filing, or any explicit request to send feedback about the harness itself.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# learn — voidcorp craftsman edition
|
|
7
|
+
|
|
8
|
+
One intent — *capture a lesson before its context evaporates* — with three destinations. This skill replaces the former `compounding` + `capture-rule` + `harness-evolution` trio, which were three doors to the same action separated by ~200 lines of mutual boundary-policing. Here the first step is the routing decision; the three behaviors follow unchanged, each keeping its own strict Human-In-The-Loop gate.
|
|
9
|
+
|
|
10
|
+
It writes nothing on its own. It names the lesson, decides where it belongs, and runs the matching capture — proposing every write and waiting for an explicit yes.
|
|
11
|
+
|
|
12
|
+
**Attribution**: see `.source` (inherits compounding, capture-rule, harness-evolution).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 0 — Recognize the signal (auto-trigger)
|
|
17
|
+
|
|
18
|
+
Engage the moment any of these appears — you should not need to be asked:
|
|
19
|
+
|
|
20
|
+
- **A stated rule** — imperative future ("always X", "never Y", "from now on Z"), a preference ("we don't do Y here", "I prefer X"), an anti-pattern callout ("stop doing Y"), or a memory request ("remember that Z", "n'oublie pas que").
|
|
21
|
+
- **A recurring / deja-vu fix** — mid-work you catch yourself solving something *already seen*. That recognition means a pattern exists and was never captured.
|
|
22
|
+
- **An end-of-cycle pattern** — a feature, bugfix, or refactor just merged; before the next task, spend two minutes extracting the reusable lesson.
|
|
23
|
+
- **A harness gap** — "the harness should have caught this", a skill is missing, a rule is wrong, a hook false-positives, two skills overlap.
|
|
24
|
+
|
|
25
|
+
Do NOT engage for: one-off task instructions ("fix this bug"), questions ("how do I X?"), information without imperative ("the API returns Z"), or vague future intent ("we might want X someday"). When unsure whether a signal is persistent, ask before capturing — better to skip than to spam the doctrine.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Step 1 — Route (the one decision that matters)
|
|
30
|
+
|
|
31
|
+
Name the lesson as a **generalization**, not the instance. Instance: "I fixed the null deref in `CheckoutSummary`." Pattern: "X always fails when Y." If you cannot state it in one sentence, it is an instance — drop it (see *When to drop*).
|
|
32
|
+
|
|
33
|
+
Then decide the scope with one question: **"If I started a new unrelated project tomorrow, would this lesson still apply?"**
|
|
34
|
+
|
|
35
|
+
| Answer | Scope | Destination | Branch |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| No — only this codebase | Project rule | `.void/PROJECT-DOCTRINE.md` | **A** |
|
|
38
|
+
| Yes — every voidcorp project | Harness gap | GitHub issue on `voidcorp-core/void-machine` | **B** |
|
|
39
|
+
| True but trivial / one-off | Disposable | nowhere | drop |
|
|
40
|
+
|
|
41
|
+
**When the scope is genuinely ambiguous, ASK — never guess:**
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
This could go two places:
|
|
45
|
+
1. .void/PROJECT-DOCTRINE.md (this project only)
|
|
46
|
+
2. the harness itself (universal — a GitHub issue on void-machine)
|
|
47
|
+
Which scope did you mean?
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Wait for the answer. A universal rule must never land in a project doctrine, and a project quirk must never reach the tracker.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Branch A — Project rule → `.void/PROJECT-DOCTRINE.md` (HITL strict)
|
|
55
|
+
|
|
56
|
+
`PROJECT-DOCTRINE.md` is imported into every session via `@.void/PROJECT-DOCTRINE.md` in `CLAUDE.md`, so a captured rule takes effect on the next message. **Never write the file before confirmation.**
|
|
57
|
+
|
|
58
|
+
### 1. Propose the wording in chat
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Proposed rule capture:
|
|
62
|
+
Target file: .void/PROJECT-DOCTRINE.md
|
|
63
|
+
Section: <the heading it goes under, verbatim; "new: <table name>" if created>
|
|
64
|
+
Wording: <verbatim rule, imperative present>
|
|
65
|
+
Why: <the user's reason, quoted; skip if none given>
|
|
66
|
+
Enforced by: <skill / hook that materializes it, or "manual review / code-review">
|
|
67
|
+
Confirm? (yes / change wording / change section / skip)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 2. Wait for an explicit yes
|
|
71
|
+
|
|
72
|
+
Accept `yes / ok / go / vas-y / confirme / c'est ça`. Anything else — a question, silence, "maybe" — STOP and ask again. Silence is not consent.
|
|
73
|
+
|
|
74
|
+
### 3. Write
|
|
75
|
+
|
|
76
|
+
Append to the correct section of `.void/PROJECT-DOCTRINE.md`:
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
- **<rule subject>**: <verbatim wording>.
|
|
80
|
+
- **Why**: <reason>.
|
|
81
|
+
- **Enforced by**: <skill / hook / manual review>.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Choose the section by meaning, then place it by what the file already holds (see *Section routing*).
|
|
85
|
+
|
|
86
|
+
### 4. Confirm in chat
|
|
87
|
+
|
|
88
|
+
State the file path and section, and note it is active from the next message via the import; remind the user to `git add .void/PROJECT-DOCTRINE.md` when ready. Commit as `docs(doctrine):` (never automatically).
|
|
89
|
+
|
|
90
|
+
### Section routing
|
|
91
|
+
|
|
92
|
+
This table is the only list of section kinds a project doctrine has. `docs/PROJECT-DOCTRINE-FORMAT.md` illustrates the shape of each one and uses the same names; it does not own a list of its own.
|
|
93
|
+
|
|
94
|
+
| Section | Use for |
|
|
95
|
+
|---|---|
|
|
96
|
+
| **Project context** | Domain facts (users are TPE/PME French dirigeants; prod on Vercel + Neon). |
|
|
97
|
+
| **Domain language** | A term this team uses with one precise meaning, so the agent uses the same word. |
|
|
98
|
+
| **Quality bar** | What "done"/"shipped" means (anti-rustine, ASCII-only, no half-built features). |
|
|
99
|
+
| **Hard rules** | Concrete, enforceable rules (@repo/core/logger not console.log, Zod at every boundary). |
|
|
100
|
+
| **Forbidden patterns** | What this codebase paid for and will not reintroduce; reference the incident/ADR. |
|
|
101
|
+
| **Trade-offs already decided** | Pointers to the project's decision records the agent must not re-litigate. |
|
|
102
|
+
| **Open questions** | What the team has not decided yet, so the agent asks instead of guessing. |
|
|
103
|
+
| **Project-specific skill routing** | "On THIS project, skill X triggers under Y" (apps/checkout/ → tdd strict). |
|
|
104
|
+
|
|
105
|
+
Pick the kind from the rule's meaning first. If it fits several kinds, ask rather than guess.
|
|
106
|
+
|
|
107
|
+
Then place it by the file's own level-2 headings, which the project owns and may word differently: the installed file is a stub, so its sections appear as they are used, and a hand-written one may predate this table.
|
|
108
|
+
|
|
109
|
+
- **One heading names that kind**, whatever its wording (`Project-specific hard rules` is Hard rules, `Trade-offs already decided (link to ADRs)` is Trade-offs), so append under it. Never create a second heading for a kind the file already has.
|
|
110
|
+
- **No heading names it**: create the table's name as a new level-2 heading.
|
|
111
|
+
- **Two headings could hold it, or a heading matches no row plainly**: ask. Never pick the closest string.
|
|
112
|
+
|
|
113
|
+
The mapping is explicit, never inferred silently: the proposal names the target heading verbatim, so the human confirms where the rule lands along with its wording.
|
|
114
|
+
|
|
115
|
+
### Conflict handling
|
|
116
|
+
|
|
117
|
+
Before writing, scan for a duplicate or contradiction. On a **duplicate**, offer skip / replace / keep-both. On a **direct conflict**, present existing vs new and ask replace / refine-both / skip; if replace, show the removal+addition diff before editing. Never silently merge or overwrite.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Branch B — Harness gap → a GitHub issue (HITL strict)
|
|
122
|
+
|
|
123
|
+
This branch is also where harness **feedback** lands, whatever words it arrives in: a skill that
|
|
124
|
+
is missing, a hook that fired on something legitimate, a rule nobody wrote down, a papercut in
|
|
125
|
+
the CLI or the docs. Infer the gap from the recent conversation, and ask one short clarifying
|
|
126
|
+
question only when it is genuinely unclear — the friction is fresh, and re-interviewing the user
|
|
127
|
+
about something they just lived is how a capture becomes more expensive than the gap.
|
|
128
|
+
|
|
129
|
+
The gap goes **straight to a `voidcorp-core/void-machine` issue** — there is no per-project `proposed/` queue; the pre-filter is your judgment before you open it. File ONLY when it clears BOTH tests:
|
|
130
|
+
|
|
131
|
+
- **Agnostic** — helps any consumer, not just this project. A project quirk belongs in `PROJECT-DOCTRINE.md` (Branch A), never on the tracker.
|
|
132
|
+
- **Harness-worthy** — it would change a skill, hook, pack, CLI, or doctrine line; not a one-off preference, not already covered by an existing skill.
|
|
133
|
+
|
|
134
|
+
Calibrate against the ADR sweep behind issue #34 (a full audit that rejected everything but one narrow correction). When in doubt, do NOT file — a quiet, closeable tracker beats one buried in project-flavored noise.
|
|
135
|
+
|
|
136
|
+
Draft the issue, show it to the user, and on confirmation:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
gh issue create --repo voidcorp-core/void-machine \
|
|
140
|
+
--title "<area>: <concise gap>" \
|
|
141
|
+
--label enhancement \
|
|
142
|
+
--body "<what happened, evidence, source-project context (repo, SHA, path), shape of the fix>"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The tracker **is** the triage zone: taking the issue promotes it, closing it declines it. No `promoted/` / `discarded/` bookkeeping, no `feedback push` step. A promoted issue becomes a normal PR (usually an audit note + SKILL.md + matrix row) citing the originating project. Nothing merges without human review. If `gh` is missing or unauthenticated, say so and stop — do not silently swallow the failure.
|
|
146
|
+
|
|
147
|
+
### Outbound audit (obsolescence detection)
|
|
148
|
+
|
|
149
|
+
The obsolescence side runs from the CLI, not from prose here: `void-machine audit` (and `--all-projects` / `--push`, #72) reads canonical `.void/runs/*/events.jsonl` journals plus legacy history and reports skills that are active / stale / never-fired, plus expensive/should-have-fired via `void-graph`. This skill's job in audit mode is to **interpret** that report and, per proposal, draft a deprecation/fusion PR — hand-authored, HITL. The audit never removes a skill, edits a SKILL.md, or touches doctrine automatically.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Branch C — the end-of-cycle ritual (feeds A, B, or drop)
|
|
154
|
+
|
|
155
|
+
At a cycle close or a deja-vu recurrence, run the two-minute extraction, then route:
|
|
156
|
+
|
|
157
|
+
1. **Name the pattern, not the instance** (Step 1's generalization test).
|
|
158
|
+
2. **Decide scope** — project rule (→ A), harness gap (→ B), or disposable (→ drop).
|
|
159
|
+
3. **Route to the matching branch** and stop. This ritual adds the *occasion* and the *triage*; the write happens in A or B under their gates.
|
|
160
|
+
|
|
161
|
+
Do not run it on an unfinished cycle — wait until the work is verified done (`void-verify`). The merge that closes the cycle is the natural trigger.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## When to drop (anti-capitalization)
|
|
166
|
+
|
|
167
|
+
Capitalizing trivial instances is worse than capturing nothing: it bloats the doctrine, dilutes the signal, and trains everyone to skim past it. Drop when the lesson:
|
|
168
|
+
|
|
169
|
+
- is a one-off that will not recur (a typo, a one-time migration quirk);
|
|
170
|
+
- is already covered by an existing skill, rule, or hook (re-check first);
|
|
171
|
+
- cannot be stated as a generalization;
|
|
172
|
+
- is "nice to know" but changes no future behavior.
|
|
173
|
+
|
|
174
|
+
A clean doctrine is the asset. Every entry earns its place by changing what happens next time.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## HITL is absolute
|
|
179
|
+
|
|
180
|
+
- Nothing is written to `PROJECT-DOCTRINE.md` or filed as an issue without an explicit human yes.
|
|
181
|
+
- This skill OPENS issues/PRs; it never merges them.
|
|
182
|
+
- Usage telemetry is LOCAL only (`.void/runs/*/events.jsonl`); no network call sends it anywhere.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Anti-rules
|
|
187
|
+
|
|
188
|
+
- MUST NOT write to `PROJECT-DOCTRINE.md` before confirmation, or capture a one-off instruction as a persistent rule.
|
|
189
|
+
- MUST NOT add a project rule that contradicts `PHILOSOPHY.md` (that is an ADR, written through the `void-decide` skill, not a doctrine entry).
|
|
190
|
+
- MUST NOT open or promote a harness PR without confirmation, or auto-merge one.
|
|
191
|
+
- MUST NOT capitalize a trivial/one-off instance, or run the ritual on an unfinished cycle.
|
|
192
|
+
- MUST NOT send usage data anywhere outside the machine.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Composition with other skills
|
|
197
|
+
|
|
198
|
+
- **`void-verify`** — upstream: a cycle is not "closed" until the work is verified.
|
|
199
|
+
- **`void-commit-discipline`** — a captured project rule commits as `docs(doctrine):`; a recurring review finding is a strong deja-vu signal.
|
|
200
|
+
- **`void-code-review`** — a finding that recurs across PRs wants capturing; the reviewer flags PRs violating a fresh rule.
|
|
201
|
+
- **`void-claude-md`** — governs the doc a rule lands in.
|
|
202
|
+
- **`void-decide`** — a structural decision with a rejected alternative is an ADR, not a doctrine line.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Verification
|
|
207
|
+
|
|
208
|
+
- [ ] The signal was recognized and the lesson stated as a generalization, not an instance.
|
|
209
|
+
- [ ] Scope decided explicitly (project rule / harness gap / disposable); ambiguity surfaced to the user.
|
|
210
|
+
- [ ] Branch A: explicit confirmation, right section under the heading the file already has for that kind, `Why` present, no unhandled conflict, only `PROJECT-DOCTRINE.md` edited.
|
|
211
|
+
- [ ] Branch B: cleared the agnostic + harness-worthy bar, issue confirmed before `gh issue create`, source context included.
|
|
212
|
+
- [ ] Nothing auto-written to doctrine; nothing merged without review.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Final rule
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
Signal appears → name the lesson as a pattern → decide scope →
|
|
220
|
+
project rule → propose → wait for yes → write PROJECT-DOCTRINE.md → confirm
|
|
221
|
+
harness gap → clears the bar → draft → confirm → gh issue create
|
|
222
|
+
disposable → drop it
|
|
223
|
+
Otherwise → it is not learn.
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The doctrine evolves deliberately, one explicit step at a time — and the harness compounds because each cycle's *pattern* is routed, never the raw instance dumped in.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Harness metadata for this skill. Not part of the Agent Skills
|
|
2
|
+
# specification, and never copied into a consumer project: the SKILL.md
|
|
3
|
+
# beside it stays portable and validates against the official six fields.
|
|
4
|
+
# Read by this repository's graph, and by the installer for `runtimes`.
|
|
5
|
+
kind: action
|
|
6
|
+
owner: folpe
|
|
7
|
+
runtimes: [claude, codex]
|
|
8
|
+
enforcement:
|
|
9
|
+
floor: ci
|
|
10
|
+
inline:
|
|
11
|
+
claude: active
|
|
12
|
+
codex: active
|
|
13
|
+
hermes: ci-only
|
|
14
|
+
eval_targets: [claude/anthropic/opus]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Sources for `void-llm-cost-discipline` skill (see `docs/plans/skill-audits/void-llm-cost-discipline.md` for full audit):
|
|
2
|
+
|
|
3
|
+
- Anthropic prompt caching docs — https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching — foundation (cache_control, hit rate signals, TTL options)
|
|
4
|
+
- Anthropic batch API — https://docs.anthropic.com/en/docs/build-with-claude/batch-processing — 50% discount for non-interactive workloads
|
|
5
|
+
- Anthropic model card pricing — https://docs.anthropic.com/en/docs/about-claude/pricing — Opus 4.7 / Sonnet 4.6 / Haiku 4.5 cost ratios
|
|
6
|
+
- gstack /claude-api skill — SDK mechanics, composed (we extend, not replace)
|
|
7
|
+
- gstack /benchmark-models — escalation for model selection
|
|
8
|
+
- OpenAI batch API docs — https://platform.openai.com/docs/api-reference/batch — tactical reference for OpenAI consumers
|
|
9
|
+
- LangChain model-router patterns — partially kept (model selection logic)
|
|
10
|
+
|
|
11
|
+
Strategy: original + adapt. Discipline layer on top of claude-api SDK mechanics.
|
|
12
|
+
|
|
13
|
+
Companion hook: llm-cost-precommit.
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-llm-cost-discipline
|
|
3
|
+
description: Sonnet default (Opus needs comment), prompt caching for >1024-token prompts, batch API for non-interactive, max_tokens declared, bounded retries, no full prompts in logs. Use on LLM API calls.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# llm-cost-discipline — voidcorp craftsman edition
|
|
7
|
+
|
|
8
|
+
LLM costs scale with usage. A 1k-token system prompt re-billed on every call is 90% waste with caching. Opus everywhere is 5× Sonnet for marginal gains. Unbounded retries on a refusal burn tokens. This skill makes cost a first-class design concern at every LLM call site.
|
|
9
|
+
|
|
10
|
+
**Attribution**: see `.source`. Composed with the `claude-api` skill (SDK mechanics). Foundation: Anthropic prompt caching docs + batch API + model card pricing.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Model selection — Sonnet default
|
|
15
|
+
|
|
16
|
+
| Model | When |
|
|
17
|
+
|---|---|
|
|
18
|
+
| **Sonnet 4.6** | DEFAULT. Everyday agentic work, code generation, chat, multi-step reasoning. Cost-effective and capable. |
|
|
19
|
+
| **Haiku 4.5** | High-volume classification, extraction, retrieval-grade Q&A. ~3× cheaper than Sonnet. |
|
|
20
|
+
| **Opus 4.7** | Only when justified at the call site with a comment. High-stakes reasoning, hard QA, complex code generation where Sonnet is insufficient. ~5× Sonnet cost. |
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// allowed
|
|
24
|
+
await anthropic.messages.create({
|
|
25
|
+
model: 'claude-sonnet-4-6',
|
|
26
|
+
max_tokens: 1024,
|
|
27
|
+
...
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// allowed (with justification)
|
|
31
|
+
// using Opus because legal-document drafting needs the reasoning depth
|
|
32
|
+
await anthropic.messages.create({
|
|
33
|
+
model: 'claude-opus-4-7',
|
|
34
|
+
max_tokens: 4096,
|
|
35
|
+
...
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// banned (Opus without comment)
|
|
39
|
+
await anthropic.messages.create({
|
|
40
|
+
model: 'claude-opus-4-7',
|
|
41
|
+
max_tokens: 1024,
|
|
42
|
+
...
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The companion hook `llm-cost-precommit` warns on `model: 'opus'` without `// using Opus because` in the diff.
|
|
47
|
+
|
|
48
|
+
### When to escalate
|
|
49
|
+
|
|
50
|
+
If you cannot decide which model fits without testing, benchmark the candidate models on the actual prompts — run the same prompt through each and compare cost + quality before committing.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Prompt caching — ENABLED for >1024 tokens at >1/hour rate
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
await anthropic.messages.create({
|
|
58
|
+
model: 'claude-sonnet-4-6',
|
|
59
|
+
max_tokens: 1024,
|
|
60
|
+
system: [
|
|
61
|
+
{
|
|
62
|
+
type: 'text',
|
|
63
|
+
text: longSystemPrompt, // 5k tokens of system prompt
|
|
64
|
+
cache_control: { type: 'ephemeral' }, // CACHE THIS
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
messages: [...],
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The cache hit reduces per-call cost by ~90% for cached blocks. Default TTL is 5 minutes; opt into 1-hour caching for stable system prompts.
|
|
72
|
+
|
|
73
|
+
### What to cache
|
|
74
|
+
|
|
75
|
+
- System prompt (especially if > 1024 tokens)
|
|
76
|
+
- Tool definitions
|
|
77
|
+
- RAG context that is shared across requests in a session
|
|
78
|
+
- Few-shot examples
|
|
79
|
+
|
|
80
|
+
### What NOT to cache
|
|
81
|
+
|
|
82
|
+
- User-specific content unless the cache key is also user-specific
|
|
83
|
+
- Content containing user PII without explicit per-user scoping (composes with `void-security-guidance`)
|
|
84
|
+
|
|
85
|
+
The companion hook `llm-cost-precommit` warns on `system` / `tools` arrays > 1024 tokens without `cache_control`.
|
|
86
|
+
|
|
87
|
+
Composes with the `claude-api` skill for cache mechanics.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Batch API for non-interactive workloads
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// banned (1000 individual real-time calls for overnight processing)
|
|
95
|
+
for (const doc of largeBatch) {
|
|
96
|
+
await anthropic.messages.create({ model: 'claude-sonnet-4-6', ... });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// allowed (50% discount via batch)
|
|
100
|
+
const batch = await anthropic.messages.batches.create({
|
|
101
|
+
requests: largeBatch.map(doc => ({
|
|
102
|
+
custom_id: doc.id,
|
|
103
|
+
params: {
|
|
104
|
+
model: 'claude-sonnet-4-6',
|
|
105
|
+
max_tokens: 1024,
|
|
106
|
+
messages: [{ role: 'user', content: docPrompt(doc) }],
|
|
107
|
+
},
|
|
108
|
+
})),
|
|
109
|
+
});
|
|
110
|
+
// poll until complete (24h SLA, usually faster)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
50% discount when latency budget allows. No excuse not to use it for overnight processing, bulk analysis, async classification, periodic reports.
|
|
114
|
+
|
|
115
|
+
### Heuristic
|
|
116
|
+
|
|
117
|
+
- User-facing interactive (chat, agent UI) → real-time, streaming
|
|
118
|
+
- Background, batch-processable, latency budget > 1 hour → batch API
|
|
119
|
+
- Mixed → batch the background portion; real-time the user-facing portion
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Token budgets — declared per call site
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// banned (max_tokens unset)
|
|
127
|
+
await anthropic.messages.create({ model: '...', messages: [...] });
|
|
128
|
+
|
|
129
|
+
// allowed (explicit budget)
|
|
130
|
+
await anthropic.messages.create({
|
|
131
|
+
model: 'claude-sonnet-4-6',
|
|
132
|
+
max_tokens: 1024, // explicit cap
|
|
133
|
+
// estimated input: ~3000 tokens system + ~500 user → ~3500 in
|
|
134
|
+
messages: [...],
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Default budgets per task class:
|
|
139
|
+
|
|
140
|
+
| Task | `max_tokens` default |
|
|
141
|
+
|---|---|
|
|
142
|
+
| Chat reply | 1024 |
|
|
143
|
+
| Classification / structured extraction | 256 |
|
|
144
|
+
| Code generation | 4096 |
|
|
145
|
+
| Long-form generation | 4096 |
|
|
146
|
+
| Tool-use orchestration | 1024 |
|
|
147
|
+
|
|
148
|
+
Override per call site with rationale.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Retries — bounded with backoff + jitter
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// banned (unbounded)
|
|
156
|
+
while (true) {
|
|
157
|
+
try { return await anthropic.messages.create(...); }
|
|
158
|
+
catch { /* retry */ }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// allowed (composed with async-safety)
|
|
162
|
+
await withRetry(
|
|
163
|
+
() => anthropic.messages.create(...),
|
|
164
|
+
{
|
|
165
|
+
maxAttempts: 3,
|
|
166
|
+
backoff: 'exponential-with-jitter',
|
|
167
|
+
// do NOT retry on these:
|
|
168
|
+
skipRetryOn: (err) => err.type === 'invalid_request_error' || err.type === 'prompt_injection_refusal',
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Banned
|
|
174
|
+
|
|
175
|
+
- Unbounded retries
|
|
176
|
+
- Retrying on `invalid_request_error` (the request is malformed; retrying does nothing)
|
|
177
|
+
- Retrying on prompt-injection refusal (different failure mode; treat as expected failure)
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Fallback model for critical paths
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
async function generateInvoiceDraft(input: InvoiceInput): Promise<Result<Draft, ...>> {
|
|
185
|
+
const primary = 'claude-opus-4-7';
|
|
186
|
+
const fallback = 'claude-sonnet-4-6';
|
|
187
|
+
try {
|
|
188
|
+
return await callLlm(primary, input);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
if (isQuotaOrOutage(err)) {
|
|
191
|
+
logger.warn({ primary, fallback, err }, 'llm_fallback');
|
|
192
|
+
return await callLlm(fallback, input);
|
|
193
|
+
}
|
|
194
|
+
throw err;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Document the fallback at the call site. If no fallback is justified, document why ("acceptable to fail; user retries manually").
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Streaming — for user-facing interactive only
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// chat / agent UI → stream
|
|
207
|
+
const stream = await anthropic.messages.stream(...);
|
|
208
|
+
for await (const event of stream) { /* send to UI */ }
|
|
209
|
+
|
|
210
|
+
// batch / programmatic → no stream
|
|
211
|
+
const response = await anthropic.messages.create(...);
|
|
212
|
+
return parseStructured(response.content);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Streaming overhead is wasted on machine consumers.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Structured logging per LLM call
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// composes with void-observability
|
|
223
|
+
logger.info({
|
|
224
|
+
model: 'claude-sonnet-4-6',
|
|
225
|
+
inputTokens: response.usage.input_tokens,
|
|
226
|
+
outputTokens: response.usage.output_tokens,
|
|
227
|
+
cacheCreationInputTokens: response.usage.cache_creation_input_tokens,
|
|
228
|
+
cacheReadInputTokens: response.usage.cache_read_input_tokens,
|
|
229
|
+
latencyMs: Date.now() - startMs,
|
|
230
|
+
endpoint: 'checkout_classifier',
|
|
231
|
+
}, 'llm_call');
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
NEVER log the full prompt content (PII / secret risk, composes with `void-security-guidance`).
|
|
235
|
+
|
|
236
|
+
The Sentry / Vercel Analytics integration in `pack-nextjs` aggregates cache hit rate, model mix, cost-per-endpoint into a cost dashboard.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## LLM I/O is untrusted (composes with void-security-guidance)
|
|
241
|
+
|
|
242
|
+
- Prompt injection: user-controlled text is data, not instructions. Separate system from user clearly. Defense in depth: tool invocations re-validate at the tool boundary.
|
|
243
|
+
- Output hallucination: validate with Zod if parsing structured. Never `eval()`, never `innerHTML`, never SQL / shell with LLM output.
|
|
244
|
+
|
|
245
|
+
See `void-security-guidance` skill for full LLM trust-boundary patterns.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Composition with other skills
|
|
250
|
+
|
|
251
|
+
- **With the `claude-api` skill**: SDK mechanics live there; this skill = the discipline.
|
|
252
|
+
- **With `void-observability`**: cost-per-call structured logs feed the dashboard.
|
|
253
|
+
- **With `void-security-guidance`**: prompt content NEVER in plain logs. LLM I/O untrusted.
|
|
254
|
+
- **With `void-async-safety`**: retries with backoff + jitter. LLM call failures handled with idempotency discipline.
|
|
255
|
+
- **With `void-hexagonal-architecture`**: LLM SDK at an adapter behind `LlmPort`. In-memory adapter for tests.
|
|
256
|
+
- **With `void-code-review`**: dimension `performance` includes LLM cost surface.
|
|
257
|
+
- **Model comparison**: escalation for "which model is best for this surface?" — benchmark the candidates on real prompts (cost + quality).
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Companion hooks
|
|
262
|
+
|
|
263
|
+
- `llm-cost-precommit` (pre-commit on files matching `<config.paths.ai>` or importing `@anthropic-ai/sdk`) — warns on Opus without justifying comment, missing `max_tokens`, missing `cache_control` on qualifying prompts. See `../../hooks/`.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Anti-rules
|
|
268
|
+
|
|
269
|
+
- MUST NOT decide which provider (Anthropic vs OpenAI vs Gemini) — that is a project-level ADR.
|
|
270
|
+
- MUST NOT impose a model-router abstraction by default.
|
|
271
|
+
- MUST NOT silently allow Opus without justifying comment.
|
|
272
|
+
- MUST NOT permit unbounded retries.
|
|
273
|
+
- MUST NOT permit `max_tokens` unset.
|
|
274
|
+
- MUST NOT log full prompt content.
|
|
275
|
+
- MUST NOT cache prompts containing user-specific PII without per-user cache keys.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## When you are stuck
|
|
280
|
+
|
|
281
|
+
| Problem | Solution |
|
|
282
|
+
|---|---|
|
|
283
|
+
| Sonnet seems insufficient | Quantify it: benchmark Sonnet vs Opus on the actual prompts (cost + quality) before upgrading. |
|
|
284
|
+
| Cache hit rate low | Prompt structure problem — variable content interleaved with stable. Restructure to put stable blocks first with `cache_control`. |
|
|
285
|
+
| Cost budget exceeded | Audit via cost dashboard. Top 3 endpoints. Apply caching, batching, model downgrade where quality allows. |
|
|
286
|
+
| Token budget too small | Validate via void-observability — what's the actual output size? Adjust budget OR truncate the input intelligently. |
|
|
287
|
+
| Latency too high | Streaming for user-facing. Batch for background. |
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Final rule
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
Every LLM call → Sonnet by default, cache >1024 tokens, batch non-interactive, max_tokens set, retries bounded,
|
|
295
|
+
fallback declared, structured cost logs, no prompt content in logs.
|
|
296
|
+
Otherwise → it is not voidcorp llm-cost-discipline.
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The discipline is small. The savings compound. A single agentic feature can save 70%+ via caching + Sonnet default + batch.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Harness metadata for this skill. Not part of the Agent Skills
|
|
2
|
+
# specification, and never copied into a consumer project: the SKILL.md
|
|
3
|
+
# beside it stays portable and validates against the official six fields.
|
|
4
|
+
# Read by this repository's graph, and by the installer for `runtimes`.
|
|
5
|
+
kind: standard
|
|
6
|
+
activation: always
|
|
7
|
+
owner: folpe
|
|
8
|
+
runtimes: [claude, codex]
|
|
9
|
+
enforcement:
|
|
10
|
+
floor: ci
|
|
11
|
+
inline:
|
|
12
|
+
claude: pretooluse
|
|
13
|
+
codex: pretooluse
|
|
14
|
+
hermes: ci-only
|
|
15
|
+
eval_targets: [claude/anthropic/opus]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Sources for `void-make-pdf` skill (see `docs/plans/skill-audits/void-make-pdf.md` for full audit):
|
|
2
|
+
|
|
3
|
+
- gstack /make-pdf (v1.57.10, ~/.claude/skills/gstack/make-pdf/) — REBUILT (DEV-391): kept the load-bearing pipeline (marked md->HTML, the HTML sanitizer for untrusted embedded HTML, the print-CSS design intent: metric-compatible sans stack for cross-OS diacritics, break-avoid). REJECTED: its dependency on the gstack browse daemon (browseClient.ts).
|
|
4
|
+
- marked (^14) + puppeteer-core (^23) — the state-of-the-art md->PDF pipeline (researched, e.g. simonhaenisch/md-to-pdf, the marked+Puppeteer pattern). puppeteer-core drives the SYSTEM Chrome via `page.pdf()` — no bundled Chromium download. `page.pdf()` gives page-number footers (pageNumber/totalPages), printBackground, and precise margins that the raw `--headless --print-to-pdf` CLI flag cannot.
|
|
5
|
+
- Puppeteer PDFOptions docs — https://pptr.dev/api/puppeteer.pdfoptions (source-driven: the displayHeaderFooter + footerTemplate page-number mechanism).
|
|
6
|
+
|
|
7
|
+
Strategy: rebuild (REBUILD class), state-of-the-art. Engine in apps/make-pdf/ (@voidcorp/make-pdf): pure render + print-css modules, an impure pdf module (puppeteer) with injectable findChrome, an async CLI. 13 unit tests + a dogfood PDF (observed: 67 KB, page-number footer, French accents, table with €, code block).
|
|
8
|
+
|
|
9
|
+
Enabler: adding these deps required the DEV-393-follow-up floor fix (ci-enforce allows a lockfile change accompanied by a manifest change) — see docs/DECISIONS.md (2026-07-10). No hand-rolled parser (rejected as a band-aid), no lockfile hand-edit.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: void-make-pdf
|
|
3
|
+
description: Turn a markdown file into a publication-quality PDF — marked + puppeteer-core on the system Chrome, with page-number footers. No gstack daemon. For signed deliverables (DECLIK audits).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# make-pdf — voidcorp craftsman edition
|
|
7
|
+
|
|
8
|
+
Render a markdown file to a clean, paginated PDF with page-number footers. State-of-the-art pipeline: **`marked`** parses the markdown, **`puppeteer-core`** drives the **system** Chrome/Chromium and prints via `page.pdf()`. No gstack browse daemon; no bundled Chromium download (`puppeteer-core` uses the browser already on the machine).
|
|
9
|
+
|
|
10
|
+
For French-language signed deliverables (DECLIK Audit Pulse), it keeps diacritics, tables, and code intact, never splits a table or heading across a page, and numbers the pages.
|
|
11
|
+
|
|
12
|
+
The engine lives in `apps/make-pdf/` (`@voidcorp/make-pdf`). This skill tells the agent how to drive it.
|
|
13
|
+
|
|
14
|
+
**Attribution**: see `.source`. Distilled from gstack `/void-make-pdf` (its `marked` pipeline + print-CSS intent + HTML sanitizer), rebuilt on `puppeteer-core` + the system Chrome instead of the browse daemon — the standard `marked` + Puppeteer approach.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Run it
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm --filter @voidcorp/make-pdf make-pdf <input.md> [output.pdf] [--a4|--legal] [--margins=1in] [--title="..."]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- `output.pdf` defaults to the input's basename with a `.pdf` extension.
|
|
25
|
+
- Default page format is US Letter; `--a4` / `--legal` switch it. `--margins` overrides the 1in default.
|
|
26
|
+
- The title defaults to the first `# H1`, else "Document"; `--title` overrides.
|
|
27
|
+
|
|
28
|
+
## What it does
|
|
29
|
+
|
|
30
|
+
1. `marked` parses the markdown to HTML.
|
|
31
|
+
2. A conservative sanitizer strips dangerous embedded HTML (`<script>`/`<iframe>`/`on*`/`javascript:` — untrusted markdown can carry raw HTML, a real trust boundary).
|
|
32
|
+
3. The body is wrapped with an inlined content stylesheet: a metric-compatible sans stack (Helvetica / Liberation Sans / Arial — renders French accents on every OS) and `break-inside: avoid` on tables / figures / code.
|
|
33
|
+
4. `puppeteer-core` launches the system Chrome, `page.setContent` loads the HTML, and `page.pdf()` prints it with `printBackground`, precise margins, and a **page-number footer** (`<span class="pageNumber"></span> / <span class="totalPages"></span>`).
|
|
34
|
+
|
|
35
|
+
## Requirements & failure modes
|
|
36
|
+
|
|
37
|
+
- **System Chrome or Chromium** must be installed (macOS: Google Chrome / Chromium / Edge; Linux: `google-chrome` / `chromium`). Set `CHROME_PATH` to override. If none is found, the CLI exits non-zero with an explicit message — never a silent failure.
|
|
38
|
+
- **Relative images** in the markdown resolve against the CWD at print time; use absolute paths or run from the markdown's directory.
|
|
39
|
+
|
|
40
|
+
## Anti-rules
|
|
41
|
+
|
|
42
|
+
- MUST NOT depend on the gstack browse daemon or any gstack runtime.
|
|
43
|
+
- MUST NOT bundle/download a Chromium (use `puppeteer-core` + the system browser).
|
|
44
|
+
- MUST NOT fail silently when Chrome is absent — the error is explicit.
|
|
45
|
+
- MUST NOT trust raw HTML embedded in markdown — the sanitizer runs unconditionally. (It matches `javascript:` literally; the output is printed, never live-rendered, so a surviving entity-encoded scheme is inert — harden before any live-render reuse.)
|
|
46
|
+
|
|
47
|
+
## Composition
|
|
48
|
+
|
|
49
|
+
Downstream: a generated deliverable is reviewed by the read-only `pdf-specialist` agent for faithful
|
|
50
|
+
rendering, pagination, accessibility, and artifact evidence. The renderer owns production; the
|
|
51
|
+
specialist judges the output and never edits it. `void-verify` carries that observed proof into the
|
|
52
|
+
final gate.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Harness metadata for this skill. Not part of the Agent Skills
|
|
2
|
+
# specification, and never copied into a consumer project: the SKILL.md
|
|
3
|
+
# beside it stays portable and validates against the official six fields.
|
|
4
|
+
# Read by this repository's graph, and by the installer for `runtimes`.
|
|
5
|
+
kind: action
|
|
6
|
+
activation: on-demand
|
|
7
|
+
owner: folpe
|
|
8
|
+
runtimes: [claude, codex]
|
|
9
|
+
enforcement:
|
|
10
|
+
floor: ci
|
|
11
|
+
inline:
|
|
12
|
+
claude: active
|
|
13
|
+
codex: active
|
|
14
|
+
hermes: ci-only
|
|
15
|
+
eval_targets: [claude/anthropic/opus]
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Sources for `void-merge` skill (see `docs/plans/skill-audits/void-merge.md` for full audit):
|
|
2
|
+
|
|
3
|
+
- No upstream source. Written from the seven pull requests merged by hand in this repository on
|
|
4
|
+
2026-08-19, and from the four cases a naive "merge everything green" would have failed on.
|
|
5
|
+
- gstack `/land-and-deploy` — ADJACENT, not a source: it merges one named PR and then watches a
|
|
6
|
+
deployment. This skill drains a queue and never deploys.
|
|
7
|
+
- GitHub branch protection semantics (`mergeStateStatus`: BEHIND, BLOCKED, DIRTY, CLEAN) —
|
|
8
|
+
the state machine the skill reads rather than reimplements.
|