@thedecipherist/claude-packs 0.0.0-stage → 1.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/CHANGELOG.md +680 -0
- package/LICENSE +21 -0
- package/README.md +316 -2
- package/bin/claude-packs.mjs +204 -0
- package/configurations/base/config.json +85 -0
- package/configurations/cpp/config.json +92 -0
- package/configurations/full-stack/config.json +152 -0
- package/configurations/go/config.json +96 -0
- package/configurations/node/config.json +100 -0
- package/configurations/python/config.json +97 -0
- package/configurations/synth-creator/config.json +148 -0
- package/global/hooks/gnu-shell.mjs +131 -0
- package/global/hooks/lib/program-read.mjs +196 -0
- package/global/hooks/lib/program-writes.mjs +177 -0
- package/global/hooks/lib/shell-writes.mjs +293 -0
- package/global/hooks/shell-traps.mjs +79 -0
- package/global/hooks/version-pin-guard.mjs +280 -0
- package/global/skills/latest-versions/SKILL.md +49 -0
- package/lib/backup.mjs +34 -0
- package/lib/claude-md.mjs +58 -0
- package/lib/config-cli.mjs +36 -0
- package/lib/configs.mjs +145 -0
- package/lib/coverage.mjs +86 -0
- package/lib/custom-packs.mjs +93 -0
- package/lib/doctor.mjs +115 -0
- package/lib/fix-plan.mjs +71 -0
- package/lib/git-tokens.mjs +64 -0
- package/lib/global.mjs +125 -0
- package/lib/hook-proof.mjs +28 -0
- package/lib/hook-timing.mjs +42 -0
- package/lib/hover-gate.mjs +29 -0
- package/lib/kit-lock.mjs +149 -0
- package/lib/layout.mjs +75 -0
- package/lib/logs.mjs +69 -0
- package/lib/manifest.mjs +24 -0
- package/lib/new.mjs +49 -0
- package/lib/once-only-report.mjs +54 -0
- package/lib/pack-manifest.mjs +20 -0
- package/lib/packs.mjs +107 -0
- package/lib/planner.mjs +59 -0
- package/lib/repeats.mjs +65 -0
- package/lib/repo-weight.mjs +28 -0
- package/lib/rules.mjs +40 -0
- package/lib/scan-detect.mjs +94 -0
- package/lib/scan.mjs +168 -0
- package/lib/selftest-cache.mjs +39 -0
- package/lib/settings.mjs +138 -0
- package/lib/shape-cli.mjs +76 -0
- package/lib/shape.mjs +4 -0
- package/lib/suggest.mjs +18 -0
- package/lib/switches.mjs +44 -0
- package/lib/symmetry-doctor.mjs +26 -0
- package/lib/sync.mjs +130 -0
- package/package.json +34 -4
- package/packs/ai/checks/boundary-computes-its-own-hash.json +30 -0
- package/packs/ai/checks/model-call-needs-boundary.json +29 -0
- package/packs/ai/checks/model-id-from-config.json +28 -0
- package/packs/ai/checks/model-output-validated.json +26 -0
- package/packs/ai/pack.json +38 -0
- package/packs/ai/rules/ai-input-sha-boundary.md +31 -0
- package/packs/ai/rules/llm-pipeline-security.md +26 -0
- package/packs/audio-core/checks/denormals-not-in-prepare.json +12 -0
- package/packs/audio-core/checks/dsp-without-apvts.json +12 -0
- package/packs/audio-core/checks/float-phase-or-rate.json +12 -0
- package/packs/audio-core/checks/juce-snap-to-zero-off.json +12 -0
- package/packs/audio-core/checks/keep-werror.json +12 -0
- package/packs/audio-core/checks/no-fast-math.json +14 -0
- package/packs/audio-core/checks/no-locale-change.json +12 -0
- package/packs/audio-core/checks/no-march-native.json +14 -0
- package/packs/audio-core/clang-tidy +28 -0
- package/packs/audio-core/hooks/lib/realtime-checks.mjs +56 -0
- package/packs/audio-core/hooks/param-id-lock.mjs +129 -0
- package/packs/audio-core/hooks/realtime-guard.mjs +67 -0
- package/packs/audio-core/pack.json +187 -0
- package/packs/audio-core/rules/audio-thread-realtime-safe.md +27 -0
- package/packs/audio-core/rules/audio-ui-thread-handoff.md +21 -0
- package/packs/audio-core/rules/boundary-tests-cross-the-boundary.md +16 -0
- package/packs/audio-core/rules/build-flags-safe.md +20 -0
- package/packs/audio-core/rules/cached-parameter-pointers.md +28 -0
- package/packs/audio-core/rules/clang-tidy-core-guidelines.md +21 -0
- package/packs/audio-core/rules/control-reaches-every-surface.md +23 -0
- package/packs/audio-core/rules/cpu-worst-case-per-block.md +26 -0
- package/packs/audio-core/rules/dc-block-after-asymmetry.md +22 -0
- package/packs/audio-core/rules/discrete-params-snap.md +19 -0
- package/packs/audio-core/rules/double-where-precision-matters.md +20 -0
- package/packs/audio-core/rules/filters-stable-under-modulation.md +29 -0
- package/packs/audio-core/rules/host-parameters-at-scale.md +24 -0
- package/packs/audio-core/rules/house-control-behaviours.md +34 -0
- package/packs/audio-core/rules/math-domain-guards.md +19 -0
- package/packs/audio-core/rules/modulated-delay-interpolation.md +22 -0
- package/packs/audio-core/rules/multiband-phase-coherent.md +22 -0
- package/packs/audio-core/rules/nonlinear-stages-antialiased.md +28 -0
- package/packs/audio-core/rules/note-ledger-and-pedals.md +22 -0
- package/packs/audio-core/rules/one-formula-per-value.md +20 -0
- package/packs/audio-core/rules/optimisations-are-null-tested.md +23 -0
- package/packs/audio-core/rules/oscillators-bandlimited.md +23 -0
- package/packs/audio-core/rules/output-limiter.md +23 -0
- package/packs/audio-core/rules/parameter-ids-never-change.md +20 -0
- package/packs/audio-core/rules/params-and-state-thread-safe.md +19 -0
- package/packs/audio-core/rules/params-snapshot-per-block.md +21 -0
- package/packs/audio-core/rules/patch-excludes-performance-controls.md +18 -0
- package/packs/audio-core/rules/per-sample-code-inlinable.md +22 -0
- package/packs/audio-core/rules/prepare-is-repeatable.md +23 -0
- package/packs/audio-core/rules/recursive-state-nan-guard.md +20 -0
- package/packs/audio-core/rules/reverb-loop-gain-bounded.md +24 -0
- package/packs/audio-core/rules/sample-accurate-midi.md +22 -0
- package/packs/audio-core/rules/sample-rate-and-block-size-from-host.md +23 -0
- package/packs/audio-core/rules/scoped-no-denormals.md +26 -0
- package/packs/audio-core/rules/smooth-continuous-parameters.md +22 -0
- package/packs/audio-core/rules/state-load-versioned-and-safe.md +22 -0
- package/packs/audio-core/rules/straight-on-and-aligned.md +21 -0
- package/packs/audio-core/rules/ui-matches-reference-look.md +21 -0
- package/packs/audio-core/rules/undo-one-gesture-one-step.md +21 -0
- package/packs/audio-core/rules/voice-steal-fades.md +21 -0
- package/packs/audio-core/rules/voice-sum-headroom.md +20 -0
- package/packs/audio-core/skills/analyse-reference-look/SKILL.md +21 -0
- package/packs/audio-core/skills/copy-and-prove/SKILL.md +98 -0
- package/packs/audio-core/skills/juce-realtime-audit/SKILL.md +22 -0
- package/packs/audio-core/skills/measure-tone/SKILL.md +20 -0
- package/packs/audio-core/skills/new-panel-control/SKILL.md +15 -0
- package/packs/audio-core/skills/prove-control/SKILL.md +23 -0
- package/packs/audio-core/skills/trace-parameter/SKILL.md +29 -0
- package/packs/audio-core/tools/lib/spectrum.mjs +112 -0
- package/packs/audio-core/tools/lib/wav.mjs +41 -0
- package/packs/audio-core/tools/tone-report.mjs +47 -0
- package/packs/base/checks/field-map-over-if-runs.json +25 -0
- package/packs/base/checks/lookup-over-if-chains.json +25 -0
- package/packs/base/checks/lookup-over-ternary-chains.json +20 -0
- package/packs/base/checks/no-code-after-midline-comment.json +12 -0
- package/packs/base/checks/one-walk-per-template.json +23 -0
- package/packs/base/checks/stub-reports-success.json +31 -0
- package/packs/base/checks/test-skip-on-failed-setup.json +17 -0
- package/packs/base/hooks/brief-guard.mjs +96 -0
- package/packs/base/hooks/code-shape.mjs +95 -0
- package/packs/base/hooks/dispatch-once.mjs +87 -0
- package/packs/base/hooks/file-size-guard.mjs +61 -0
- package/packs/base/hooks/folder-law.mjs +74 -0
- package/packs/base/hooks/git-guard.mjs +289 -0
- package/packs/base/hooks/lesson-checks.mjs +174 -0
- package/packs/base/hooks/lib/apply-edit.mjs +20 -0
- package/packs/base/hooks/lib/code-shapes.mjs +137 -0
- package/packs/base/hooks/lib/content.mjs +14 -0
- package/packs/base/hooks/lib/cpp-scan.mjs +94 -0
- package/packs/base/hooks/lib/dup-index.mjs +199 -0
- package/packs/base/hooks/lib/dup.mjs +127 -0
- package/packs/base/hooks/lib/elements.mjs +87 -0
- package/packs/base/hooks/lib/event-log.mjs +67 -0
- package/packs/base/hooks/lib/function-shapes.mjs +90 -0
- package/packs/base/hooks/lib/git-adds.mjs +20 -0
- package/packs/base/hooks/lib/git-guard-selftest.mjs +99 -0
- package/packs/base/hooks/lib/glob.mjs +33 -0
- package/packs/base/hooks/lib/hook-log.mjs +100 -0
- package/packs/base/hooks/lib/house.py +77 -0
- package/packs/base/hooks/lib/languages.mjs +66 -0
- package/packs/base/hooks/lib/layout.mjs +54 -0
- package/packs/base/hooks/lib/making-check-selftest.mjs +109 -0
- package/packs/base/hooks/lib/near-copies.mjs +76 -0
- package/packs/base/hooks/lib/program-read.mjs +196 -0
- package/packs/base/hooks/lib/program-writes.mjs +177 -0
- package/packs/base/hooks/lib/project.mjs +81 -0
- package/packs/base/hooks/lib/prose.mjs +11 -0
- package/packs/base/hooks/lib/pushed.mjs +201 -0
- package/packs/base/hooks/lib/repo-index.mjs +52 -0
- package/packs/base/hooks/lib/secret-patterns.mjs +18 -0
- package/packs/base/hooks/lib/selftest.mjs +45 -0
- package/packs/base/hooks/lib/shape-code.mjs +126 -0
- package/packs/base/hooks/lib/shape.mjs +294 -0
- package/packs/base/hooks/lib/shell-writes-selftest.mjs +65 -0
- package/packs/base/hooks/lib/shell-writes.mjs +293 -0
- package/packs/base/hooks/lib/turn.mjs +81 -0
- package/packs/base/hooks/lib/writes.mjs +71 -0
- package/packs/base/hooks/making-check.mjs +243 -0
- package/packs/base/hooks/making.mjs +106 -0
- package/packs/base/hooks/once-only.mjs +150 -0
- package/packs/base/hooks/placement-law.mjs +84 -0
- package/packs/base/hooks/repo-litter.mjs +75 -0
- package/packs/base/hooks/reuse-hint.mjs +75 -0
- package/packs/base/hooks/run-hooks.mjs +132 -0
- package/packs/base/hooks/secrets-guard.mjs +99 -0
- package/packs/base/hooks/shape-law.mjs +133 -0
- package/packs/base/hooks/suite-once.mjs +80 -0
- package/packs/base/hooks/template-law.mjs +148 -0
- package/packs/base/hooks/untrusted-boundary.mjs +53 -0
- package/packs/base/pack.json +214 -0
- package/packs/base/rules/a-control-is-seen-to-fire.md +27 -0
- package/packs/base/rules/behaviour-lives-with-its-kind.md +51 -0
- package/packs/base/rules/bug-fix-starts-red.md +25 -0
- package/packs/base/rules/field-map-over-if-runs.md +47 -0
- package/packs/base/rules/finished-work-lands.md +17 -0
- package/packs/base/rules/git-right-first-time.md +19 -0
- package/packs/base/rules/instances-by-index-identities-by-id.md +54 -0
- package/packs/base/rules/lookup-over-if-chains.md +49 -0
- package/packs/base/rules/making-line-first.md +14 -0
- package/packs/base/rules/open-items-tagged.md +17 -0
- package/packs/base/rules/plan-and-logs.md +22 -0
- package/packs/base/rules/references-use-anchors.md +19 -0
- package/packs/base/rules/refusals-are-judged.md +18 -0
- package/packs/base/rules/reuse-before-writing.md +15 -0
- package/packs/base/rules/secrets-never-committed.md +16 -0
- package/packs/base/rules/skill-writing.md +23 -0
- package/packs/base/rules/split-before-the-limit.md +14 -0
- package/packs/base/rules/subagent-dispatch.md +26 -0
- package/packs/base/rules/test-only-what-changed.md +17 -0
- package/packs/base/rules/test-the-template-once.md +22 -0
- package/packs/base/rules/untrusted-content-boundary.md +15 -0
- package/packs/base/skills/add-lesson-check/SKILL.md +26 -0
- package/packs/base/skills/fix-from-scan/SKILL.md +25 -0
- package/packs/base/skills/land-branch/SKILL.md +24 -0
- package/packs/base/skills/make-it-a-template/SKILL.md +23 -0
- package/packs/base/skills/pdf-to-md/SKILL.md +25 -0
- package/packs/base/skills/pick-tests/SKILL.md +20 -0
- package/packs/base/skills/pressure-test-skill/SKILL.md +23 -0
- package/packs/base/skills/prove-instances-identical/SKILL.md +37 -0
- package/packs/base/tools/shape-symmetry-selftest.mjs +66 -0
- package/packs/base/tools/shape-symmetry.mjs +178 -0
- package/packs/base/tools/test-verdict.mjs +75 -0
- package/packs/ci/checks/ci-permissions-stated.json +18 -0
- package/packs/ci/checks/ci-tools-pinned.json +14 -0
- package/packs/ci/pack.json +21 -0
- package/packs/ci/rules/ci-covers-what-ships.md +20 -0
- package/packs/ci/rules/generated-files-have-no-diff.md +15 -0
- package/packs/content-site/checks/captcha-is-not-constant.json +27 -0
- package/packs/content-site/checks/img-has-size.json +20 -0
- package/packs/content-site/checks/page-head-complete.json +26 -0
- package/packs/content-site/pack.json +22 -0
- package/packs/content-site/rules/content-has-one-source.md +23 -0
- package/packs/content-site/rules/media-is-sized.md +24 -0
- package/packs/content-site/rules/page-head-is-complete.md +26 -0
- package/packs/content-site/rules/public-forms-are-defended.md +27 -0
- package/packs/content-site/skills/publish-a-page/SKILL.md +21 -0
- package/packs/cpp/checks/cpp-clamp-before-cast.json +16 -0
- package/packs/cpp/checks/cpp-find-with-the-library.json +12 -0
- package/packs/cpp/checks/cpp-hardened-test-build.json +18 -0
- package/packs/cpp/checks/cpp-m-pi-not-standard.json +23 -0
- package/packs/cpp/checks/cpp-no-atoi.json +16 -0
- package/packs/cpp/checks/cpp-no-const-cast.json +16 -0
- package/packs/cpp/checks/cpp-no-float-loop-counter.json +16 -0
- package/packs/cpp/checks/cpp-no-getenv-in-product.json +22 -0
- package/packs/cpp/checks/cpp-no-mutable-global.json +20 -0
- package/packs/cpp/checks/cpp-no-mutable-local-static.json +23 -0
- package/packs/cpp/checks/cpp-no-unchecked-fwrite.json +17 -0
- package/packs/cpp/checks/cpp-no-using-namespace-in-header.json +19 -0
- package/packs/cpp/checks/cpp-no-zero-size-array.json +23 -0
- package/packs/cpp/checks/cpp-numbers-pi.json +16 -0
- package/packs/cpp/pack.json +22 -0
- package/packs/cpp/rules/cpp-absent-and-failed-are-types.md +24 -0
- package/packs/cpp/rules/cpp-builds-everywhere.md +26 -0
- package/packs/cpp/rules/cpp-faults-only-in-the-test-build.md +21 -0
- package/packs/cpp/rules/cpp-find-with-the-library.md +19 -0
- package/packs/cpp/rules/cpp-gates-share-one-reader.md +22 -0
- package/packs/cpp/rules/cpp-headers-declare.md +22 -0
- package/packs/cpp/rules/cpp-numbers-and-casts.md +22 -0
- package/packs/cpp/rules/cpp-repeats-become-templates.md +33 -0
- package/packs/cpp/rules/cpp-static-analysis-runs.md +22 -0
- package/packs/cpp/rules/cpp-thread-contracts-are-code.md +23 -0
- package/packs/cpp/skills/cpp-extract-template/SKILL.md +38 -0
- package/packs/docker/checks/alpine-with-native-build.json +13 -0
- package/packs/docker/checks/compose-db-needs-auth.json +14 -0
- package/packs/docker/checks/compose-image-pinned.json +14 -0
- package/packs/docker/checks/compose-no-hardcoded-ip.json +12 -0
- package/packs/docker/checks/compose-no-host-bind-for-data.json +18 -0
- package/packs/docker/checks/compose-no-plaintext-secret.json +13 -0
- package/packs/docker/checks/compose-no-swarm-ignored-keys.json +13 -0
- package/packs/docker/checks/compose-overlay-not-bridge.json +13 -0
- package/packs/docker/checks/compose-service-needs-healthcheck.json +11 -0
- package/packs/docker/checks/compose-service-needs-init.json +11 -0
- package/packs/docker/checks/copy-needs-chown-with-user.json +17 -0
- package/packs/docker/checks/copy-source-before-deps.json +13 -0
- package/packs/docker/checks/docker-exec-form.json +16 -0
- package/packs/docker/checks/dockerfile-needs-healthcheck.json +17 -0
- package/packs/docker/checks/dockerfile-needs-user.json +21 -0
- package/packs/docker/checks/dockerignore-has-the-basics.json +21 -0
- package/packs/docker/checks/gitattributes-forces-lf.json +17 -0
- package/packs/docker/checks/health-checks-nothing.json +25 -0
- package/packs/docker/checks/no-crlf-in-scripts.json +15 -0
- package/packs/docker/checks/no-latest-base.json +13 -0
- package/packs/docker/checks/no-secret-in-image.json +13 -0
- package/packs/docker/checks/no-sensitive-file-copy.json +13 -0
- package/packs/docker/checks/node-env-before-install.json +13 -0
- package/packs/docker/checks/npm-ci-not-install.json +13 -0
- package/packs/docker/pack.json +46 -0
- package/packs/docker/rules/compose-pinned-and-closed.md +21 -0
- package/packs/docker/rules/compose-swarm-safe.md +26 -0
- package/packs/docker/rules/docker-exec-form.md +19 -0
- package/packs/docker/rules/dockerfile-multistage.md +13 -0
- package/packs/docker/rules/dockerfile-production.md +25 -0
- package/packs/docker/skills/docker-diagnose/SKILL.md +23 -0
- package/packs/dynamic-data/checks/draft-on-the-server.json +27 -0
- package/packs/dynamic-data/checks/guard-does-its-job.json +28 -0
- package/packs/dynamic-data/checks/key-is-not-a-display-name.json +28 -0
- package/packs/dynamic-data/checks/no-code-from-data.json +29 -0
- package/packs/dynamic-data/checks/no-collection-from-request.json +27 -0
- package/packs/dynamic-data/checks/no-pipeline-from-stored-text.json +27 -0
- package/packs/dynamic-data/checks/no-regexp-from-stored-config.json +27 -0
- package/packs/dynamic-data/checks/no-template-from-stored-text.json +27 -0
- package/packs/dynamic-data/checks/save-takes-named-paths.json +27 -0
- package/packs/dynamic-data/pack.json +23 -0
- package/packs/dynamic-data/rules/a-list-is-a-saved-query.md +23 -0
- package/packs/dynamic-data/rules/definitions-are-validated-data.md +24 -0
- package/packs/dynamic-data/rules/every-dynamic-surface-has-a-boundary.md +29 -0
- package/packs/dynamic-data/rules/fields-have-owners.md +22 -0
- package/packs/dynamic-data/rules/imports-drop-nothing.md +26 -0
- package/packs/dynamic-data/rules/one-definition-many-surfaces.md +24 -0
- package/packs/dynamic-data/rules/one-fact-one-place.md +28 -0
- package/packs/dynamic-data/rules/rules-live-in-the-engine.md +29 -0
- package/packs/dynamic-data/rules/saves-are-patches.md +28 -0
- package/packs/dynamic-data/rules/tenant-costs-one-document.md +22 -0
- package/packs/dynamic-data/skills/design-a-definition/SKILL.md +24 -0
- package/packs/fastify/checks/api-routes-versioned.json +28 -0
- package/packs/fastify/checks/cookie-host-prefix.json +24 -0
- package/packs/fastify/checks/hijack-needs-try.json +28 -0
- package/packs/fastify/checks/no-cast-at-route-boundary.json +24 -0
- package/packs/fastify/checks/no-db-in-route-file.json +28 -0
- package/packs/fastify/checks/no-err-message-to-client.json +24 -0
- package/packs/fastify/checks/no-regexp-from-input.json +24 -0
- package/packs/fastify/checks/no-trust-proxy-true.json +25 -0
- package/packs/fastify/checks/one-error-body.json +26 -0
- package/packs/fastify/checks/origin-from-config-not-host.json +31 -0
- package/packs/fastify/checks/password-needs-slow-hash.json +30 -0
- package/packs/fastify/checks/sec-headers-present.json +28 -0
- package/packs/fastify/checks/secrets-compared-constant-time.json +24 -0
- package/packs/fastify/checks/sse-needs-error-listener.json +28 -0
- package/packs/fastify/checks/user-bytes-need-disposition.json +29 -0
- package/packs/fastify/pack.json +41 -0
- package/packs/fastify/rules/credentials-and-input.md +23 -0
- package/packs/fastify/rules/security-one-switch.md +28 -0
- package/packs/fastify/rules/streams-and-hijacks.md +22 -0
- package/packs/fastify/rules/tests-use-inject.md +13 -0
- package/packs/fastify/rules/three-layers.md +20 -0
- package/packs/fastify/rules/trust-config-not-headers.md +24 -0
- package/packs/full-stack/checks/no-express-no-vite.json +23 -0
- package/packs/full-stack/hooks/stack-guard.mjs +90 -0
- package/packs/full-stack/pack.json +76 -0
- package/packs/full-stack/rules/stack-is-fastify-and-nextjs.md +20 -0
- package/packs/go/checks/go-exec-result-ignored.json +15 -0
- package/packs/go/checks/go-unmarshal-error-ignored.json +15 -0
- package/packs/go/pack.json +21 -0
- package/packs/go/rules/go-errors-are-handled.md +22 -0
- package/packs/gpu-painter/checks/dawn-backends-and-validation.json +9 -0
- package/packs/gpu-painter/checks/dawn-no-spontaneous.json +10 -0
- package/packs/gpu-painter/checks/dawn-present-on-render-thread.json +17 -0
- package/packs/gpu-painter/checks/gpu-no-frame-stalls.json +12 -0
- package/packs/gpu-painter/checks/no-opengl-link.json +11 -0
- package/packs/gpu-painter/checks/no-opengl.json +13 -0
- package/packs/gpu-painter/hooks/browser-guard.py +196 -0
- package/packs/gpu-painter/pack.json +91 -0
- package/packs/gpu-painter/rules/dawn-build-and-shaders.md +27 -0
- package/packs/gpu-painter/rules/dawn-device-and-render-thread.md +26 -0
- package/packs/gpu-painter/rules/gpu-antialiasing.md +20 -0
- package/packs/gpu-painter/rules/gpu-blend-order.md +22 -0
- package/packs/gpu-painter/rules/gpu-bloom.md +20 -0
- package/packs/gpu-painter/rules/gpu-frame-budget.md +25 -0
- package/packs/gpu-painter/rules/gpu-frame-pacing-and-power.md +27 -0
- package/packs/gpu-painter/rules/gpu-frame-work.md +30 -0
- package/packs/gpu-painter/rules/gpu-golden-images.md +21 -0
- package/packs/gpu-painter/rules/gpu-hdr-and-tonemap.md +23 -0
- package/packs/gpu-painter/rules/gpu-picking-on-cpu.md +19 -0
- package/packs/gpu-painter/rules/gpu-render-lifecycle.md +25 -0
- package/packs/gpu-painter/rules/gpu-text-atlas.md +24 -0
- package/packs/gpu-painter/rules/gpu-travellers-from-snapshot.md +24 -0
- package/packs/gpu-painter/rules/hover-every-pressable.md +25 -0
- package/packs/gpu-painter/skills/gpu-capture/SKILL.md +15 -0
- package/packs/gpu-painter/skills/gpu-frame-bench/SKILL.md +14 -0
- package/packs/gpu-painter/skills/gpu-golden-check/SKILL.md +13 -0
- package/packs/gpu-painter/skills/gpu-golden-update/SKILL.md +16 -0
- package/packs/gpu-painter/skills/gpu-lifecycle-stress/SKILL.md +15 -0
- package/packs/gpu-painter/skills/hover-state/SKILL.md +33 -0
- package/packs/hook-proof/checks/hook-catch-must-not-allow.json +16 -0
- package/packs/hook-proof/checks/hook-command-no-pipe.json +16 -0
- package/packs/hook-proof/checks/hook-exit-1-does-not-block.json +17 -0
- package/packs/hook-proof/checks/hook-no-or-true.json +18 -0
- package/packs/hook-proof/checks/hook-refusal-on-stderr.json +17 -0
- package/packs/hook-proof/pack.json +38 -0
- package/packs/hook-proof/rules/a-refusal-is-exit-2.md +28 -0
- package/packs/hook-proof/skills/prove-a-hook/SKILL.md +21 -0
- package/packs/host-agent/checks/file-path-from-param.json +27 -0
- package/packs/host-agent/checks/integrity-check-optional.json +27 -0
- package/packs/host-agent/checks/quoted-value-into-config.json +24 -0
- package/packs/host-agent/checks/secret-on-argv.json +28 -0
- package/packs/host-agent/checks/ssh-verifies-host-key.json +27 -0
- package/packs/host-agent/checks/system-file-written-in-place.json +26 -0
- package/packs/host-agent/checks/tmp-path-predictable.json +27 -0
- package/packs/host-agent/pack.json +22 -0
- package/packs/host-agent/rules/root-on-other-machines.md +27 -0
- package/packs/html-ui/checks/email-html-escapes.json +25 -0
- package/packs/html-ui/checks/external-link-rel.json +21 -0
- package/packs/html-ui/checks/no-duplicate-escape.json +26 -0
- package/packs/html-ui/checks/no-inline-client-script.json +21 -0
- package/packs/html-ui/checks/no-inline-style.json +23 -0
- package/packs/html-ui/pack.json +33 -0
- package/packs/html-ui/rules/email-html-escapes.md +19 -0
- package/packs/html-ui/rules/server-html-escapes-everything.md +22 -0
- package/packs/http-api/checks/api-path-versioned.json +31 -0
- package/packs/http-api/checks/authz-from-request-body.json +26 -0
- package/packs/http-api/checks/client-calls-a-version.json +28 -0
- package/packs/http-api/checks/client-ip-not-leftmost-xff.json +28 -0
- package/packs/http-api/checks/cors-needs-origin.json +26 -0
- package/packs/http-api/checks/csp-not-switched-off.json +28 -0
- package/packs/http-api/checks/debug-route-not-shipped.json +26 -0
- package/packs/http-api/checks/encrypted-name-plaintext-value.json +26 -0
- package/packs/http-api/checks/err-text-stays-server-side.json +27 -0
- package/packs/http-api/checks/failure-is-not-empty.json +28 -0
- package/packs/http-api/checks/gate-is-not-a-todo.json +27 -0
- package/packs/http-api/checks/guard-fails-open.json +28 -0
- package/packs/http-api/checks/hmac-over-reserialised-body.json +26 -0
- package/packs/http-api/checks/jwt-verify-pins-algorithm.json +26 -0
- package/packs/http-api/checks/middleware-skips-without-user.json +26 -0
- package/packs/http-api/checks/next-api-route-versioned.json +47 -0
- package/packs/http-api/checks/no-security-off-switch.json +28 -0
- package/packs/http-api/checks/oauth-state-signed.json +26 -0
- package/packs/http-api/checks/one-time-code-compared-raw.json +26 -0
- package/packs/http-api/checks/query-cast-is-not-validation.json +28 -0
- package/packs/http-api/checks/queue-action-from-client.json +26 -0
- package/packs/http-api/checks/rate-limit-one-module.json +28 -0
- package/packs/http-api/checks/role-checked-in-one-guard.json +27 -0
- package/packs/http-api/checks/route-body-needs-schema.json +31 -0
- package/packs/http-api/checks/route-scopes-to-the-caller.json +31 -0
- package/packs/http-api/checks/secret-compared-constant-time-any.json +28 -0
- package/packs/http-api/checks/secret-in-job-record.json +27 -0
- package/packs/http-api/checks/server-fetches-tenant-url.json +30 -0
- package/packs/http-api/checks/short-code-needs-limit.json +26 -0
- package/packs/http-api/checks/user-url-through-safe-fetch.json +28 -0
- package/packs/http-api/checks/webhook-dedupes-event-id.json +30 -0
- package/packs/http-api/pack.json +45 -0
- package/packs/http-api/rules/adapters-one-db-gateway.md +18 -0
- package/packs/http-api/rules/apis-are-versioned.md +27 -0
- package/packs/http-api/rules/credentials-handled-safely.md +22 -0
- package/packs/http-api/rules/handlers-own-the-work.md +17 -0
- package/packs/http-api/rules/health-and-correlation.md +17 -0
- package/packs/http-api/rules/one-error-contract.md +17 -0
- package/packs/http-api/rules/routes-are-thin.md +17 -0
- package/packs/http-api/rules/routes-scope-to-the-caller.md +26 -0
- package/packs/http-api/rules/routes-validate-and-answer.md +25 -0
- package/packs/http-api/skills/change-an-api/SKILL.md +20 -0
- package/packs/http-api/skills/secure-a-route/SKILL.md +21 -0
- package/packs/instrument-shell/checks/no-raw-struct-blob.json +23 -0
- package/packs/instrument-shell/pack.json +22 -0
- package/packs/instrument-shell/rules/fold-keeps-every-route.md +24 -0
- package/packs/instrument-shell/rules/quiet-announces-itself.md +22 -0
- package/packs/instrument-shell/rules/render-the-extremes.md +25 -0
- package/packs/instrument-shell/rules/seams-are-declared.md +27 -0
- package/packs/instrument-shell/rules/session-blob-append-only.md +25 -0
- package/packs/instrument-shell/skills/gates-from-commit-one/SKILL.md +20 -0
- package/packs/instrument-shell/skills/hit-the-painted-control/SKILL.md +18 -0
- package/packs/js-ts/checks/async-callback-unguarded.json +26 -0
- package/packs/js-ts/checks/background-loop-needs-stop.json +28 -0
- package/packs/js-ts/checks/child-process-error-handler.json +28 -0
- package/packs/js-ts/checks/entry-registers-shutdown.json +31 -0
- package/packs/js-ts/checks/fetch-needs-timeout.json +30 -0
- package/packs/js-ts/checks/job-only-in-memory.json +28 -0
- package/packs/js-ts/checks/json-only-through-helper.json +29 -0
- package/packs/js-ts/checks/line-under-200-chars.json +34 -0
- package/packs/js-ts/checks/localhost-default-in-server.json +29 -0
- package/packs/js-ts/checks/no-any.json +27 -0
- package/packs/js-ts/checks/no-cast-escape-hatches.json +24 -0
- package/packs/js-ts/checks/no-console-in-app.json +31 -0
- package/packs/js-ts/checks/no-dynamic-import-node-builtin.json +25 -0
- package/packs/js-ts/checks/no-inline-binary.json +20 -0
- package/packs/js-ts/checks/no-inline-zod-outside-schemas.json +27 -0
- package/packs/js-ts/checks/no-local-sleep.json +25 -0
- package/packs/js-ts/checks/no-nested-ternary.json +20 -0
- package/packs/js-ts/checks/no-secret-in-log.json +24 -0
- package/packs/js-ts/checks/no-shell-string-interpolation.json +24 -0
- package/packs/js-ts/checks/no-swallowed-errors.json +25 -0
- package/packs/js-ts/checks/no-ts-enum.json +20 -0
- package/packs/js-ts/checks/process-env-only-in-config.json +31 -0
- package/packs/js-ts/checks/race-leaves-work-running.json +23 -0
- package/packs/js-ts/checks/reject-as-catch-all-exists.json +24 -0
- package/packs/js-ts/checks/secret-has-no-fallback.json +24 -0
- package/packs/js-ts/checks/secret-needs-crypto-random.json +24 -0
- package/packs/js-ts/checks/server-close-awaited.json +27 -0
- package/packs/js-ts/checks/session-user-typed-once.json +24 -0
- package/packs/js-ts/checks/switch-is-a-table.json +24 -0
- package/packs/js-ts/checks/test-imports-the-source.json +19 -0
- package/packs/js-ts/checks/test-name-says-behaviour.json +16 -0
- package/packs/js-ts/checks/tsconfig-flags.json +21 -0
- package/packs/js-ts/checks/void-needs-catch.json +24 -0
- package/packs/js-ts/checks/zod-string-needs-max.json +25 -0
- package/packs/js-ts/checks/zod-v4-formats.json +23 -0
- package/packs/js-ts/pack.json +84 -0
- package/packs/js-ts/rules/await-handled-at-a-boundary.md +66 -0
- package/packs/js-ts/rules/env-through-config.md +36 -0
- package/packs/js-ts/rules/errors-never-swallowed.md +33 -0
- package/packs/js-ts/rules/files-under-300-lines.md +18 -0
- package/packs/js-ts/rules/guard-clauses-over-nesting.md +34 -0
- package/packs/js-ts/rules/js-repeats-become-templates.md +26 -0
- package/packs/js-ts/rules/json-only-through-one-helper.md +62 -0
- package/packs/js-ts/rules/named-constants-not-magic-numbers.md +34 -0
- package/packs/js-ts/rules/no-any.md +34 -0
- package/packs/js-ts/rules/no-console.md +30 -0
- package/packs/js-ts/rules/no-floating-promises.md +31 -0
- package/packs/js-ts/rules/no-param-mutation.md +28 -0
- package/packs/js-ts/rules/no-unsafe-assertions.md +30 -0
- package/packs/js-ts/rules/one-logger.md +24 -0
- package/packs/js-ts/rules/outbound-calls-have-a-limit.md +20 -0
- package/packs/js-ts/rules/parallel-independent-awaits.md +29 -0
- package/packs/js-ts/rules/process-lifecycle.md +47 -0
- package/packs/js-ts/rules/schema-single-source-of-truth.md +36 -0
- package/packs/js-ts/rules/secrets-stay-secret.md +22 -0
- package/packs/js-ts/rules/small-functions.md +20 -0
- package/packs/js-ts/rules/test-names-describe-behavior.md +28 -0
- package/packs/js-ts/rules/tests-can-fail.md +19 -0
- package/packs/js-ts/rules/tsconfig-strict.md +32 -0
- package/packs/js-ts/rules/typed-exports.md +27 -0
- package/packs/js-ts/rules/types-once-at-the-edge.md +18 -0
- package/packs/js-ts/rules/unions-over-enums.md +29 -0
- package/packs/js-ts/rules/zod-at-route-boundaries.md +40 -0
- package/packs/midi/checks/active-sensing-no-pulse.json +24 -0
- package/packs/midi/checks/clock-not-at-sample-zero.json +23 -0
- package/packs/midi/checks/midi-realtime-first.json +27 -0
- package/packs/midi/checks/no-tempo-writeback.json +23 -0
- package/packs/midi/checks/position-not-integrated.json +25 -0
- package/packs/midi/checks/stub-playhead-advances.json +27 -0
- package/packs/midi/checks/sysex-length-literal.json +23 -0
- package/packs/midi/checks/sysex-not-on-audio.json +24 -0
- package/packs/midi/checks/sysex-survives-realtime.json +27 -0
- package/packs/midi/pack.json +22 -0
- package/packs/midi/rules/clock-is-a-pulse-stream.md +30 -0
- package/packs/midi/rules/imports-count-every-loss.md +25 -0
- package/packs/midi/rules/measure-the-clock-in-audio.md +30 -0
- package/packs/midi/rules/sync-is-a-mode.md +29 -0
- package/packs/midi/rules/sysex-is-a-record.md +29 -0
- package/packs/midi/skills/clock-probe/SKILL.md +23 -0
- package/packs/midi/skills/clock-probe/clock-law.md +417 -0
- package/packs/midi/skills/does-it-sync/SKILL.md +19 -0
- package/packs/mongo/checks/bulk-over-many.json +28 -0
- package/packs/mongo/checks/created-at-immutable.json +25 -0
- package/packs/mongo/checks/driver-outside-gateway.json +24 -0
- package/packs/mongo/checks/key-lookup-is-hashed.json +24 -0
- package/packs/mongo/checks/mongoclient-cached-and-named.json +34 -0
- package/packs/mongo/checks/mongoclient-outside-gateway.json +24 -0
- package/packs/mongo/checks/no-count-plus-one-ids.json +25 -0
- package/packs/mongo/checks/no-db-write-in-loop.json +25 -0
- package/packs/mongo/checks/no-drop-in-code.json +27 -0
- package/packs/mongo/checks/no-empty-deletemany.json +26 -0
- package/packs/mongo/checks/no-find-reads.json +26 -0
- package/packs/mongo/checks/no-input-spread-into-write.json +24 -0
- package/packs/mongo/checks/no-mongoose.json +23 -0
- package/packs/mongo/checks/no-negation-delete.json +26 -0
- package/packs/mongo/checks/no-non-null-after-findone.json +25 -0
- package/packs/mongo/checks/objectid-equals.json +26 -0
- package/packs/mongo/checks/update-then-reread.json +24 -0
- package/packs/mongo/checks/watch-not-poll.json +25 -0
- package/packs/mongo/pack.json +52 -0
- package/packs/mongo/rules/deletes-name-what-dies.md +21 -0
- package/packs/mongo/rules/driver-only-in-gateway.md +26 -0
- package/packs/mongo/rules/keys-hashed-input-picked.md +21 -0
- package/packs/mongo/rules/one-client-one-pool.md +32 -0
- package/packs/mongo/rules/reads-aggregate-writes-bulk.md +25 -0
- package/packs/mongo/rules/writes-are-atomic.md +27 -0
- package/packs/multi-tenant/checks/role-sees-all-tenants.json +26 -0
- package/packs/multi-tenant/checks/tenant-filter-from-url.json +25 -0
- package/packs/multi-tenant/pack.json +22 -0
- package/packs/multi-tenant/rules/no-role-crosses-a-tenant.md +21 -0
- package/packs/multi-tenant/skills/prove-tenant-isolation/SKILL.md +19 -0
- package/packs/nginx/checks/modsec-no-blanket-off.json +16 -0
- package/packs/nginx/checks/nginx-csp-no-unsafe.json +15 -0
- package/packs/nginx/checks/nginx-headers-always.json +15 -0
- package/packs/nginx/checks/nginx-keepalive-http11.json +20 -0
- package/packs/nginx/checks/nginx-logs-to-stdout.json +15 -0
- package/packs/nginx/checks/nginx-no-crlf.json +17 -0
- package/packs/nginx/checks/nginx-resolver-ttl.json +19 -0
- package/packs/nginx/pack.json +43 -0
- package/packs/nginx/rules/modsecurity-tuning.md +22 -0
- package/packs/nginx/rules/nginx-production.md +26 -0
- package/packs/nginx/skills/waf-rollout/SKILL.md +20 -0
- package/packs/python/checks/py-no-bare-except.json +18 -0
- package/packs/python/checks/py-no-eval.json +18 -0
- package/packs/python/checks/py-no-mutable-default.json +18 -0
- package/packs/python/checks/py-no-shell-true.json +18 -0
- package/packs/python/checks/py-no-star-import.json +18 -0
- package/packs/python/checks/py-no-swallowed-exception.json +18 -0
- package/packs/python/checks/py-none-by-is.json +18 -0
- package/packs/python/checks/py-open-with-with.json +18 -0
- package/packs/python/checks/py-requests-timeout.json +18 -0
- package/packs/python/checks/py-subprocess-output-checked.json +18 -0
- package/packs/python/checks/py-yaml-safe-load.json +18 -0
- package/packs/python/pack.json +26 -0
- package/packs/python/rules/python-errors-and-resources.md +26 -0
- package/packs/python/rules/python-repeats-become-templates.md +27 -0
- package/packs/python/skills/python-extract-template/SKILL.md +35 -0
- package/packs/react/checks/dialog-needs-role.json +28 -0
- package/packs/react/checks/effect-not-for-derived-state.json +24 -0
- package/packs/react/checks/icon-button-needs-name.json +24 -0
- package/packs/react/checks/label-needs-a-field.json +24 -0
- package/packs/react/checks/ui-failed-fetch-says-so.json +23 -0
- package/packs/react/checks/ui-ok-branch-has-an-else.json +23 -0
- package/packs/react/pack.json +20 -0
- package/packs/react/rules/react-accessible-controls.md +20 -0
- package/packs/react/rules/react-state-and-effects.md +23 -0
- package/packs/reverse-engineering/checks/ear-constant-tagged.json +23 -0
- package/packs/reverse-engineering/checks/no-default-on-distrust.json +24 -0
- package/packs/reverse-engineering/checks/no-rom-table-literal.json +29 -0
- package/packs/reverse-engineering/checks/prose-never-decides.json +22 -0
- package/packs/reverse-engineering/hooks/firmware-out-of-git.mjs +49 -0
- package/packs/reverse-engineering/pack.json +35 -0
- package/packs/reverse-engineering/rules/a-negative-names-what-was-scanned.md +19 -0
- package/packs/reverse-engineering/rules/account-every-term.md +20 -0
- package/packs/reverse-engineering/rules/addresses-name-their-space.md +21 -0
- package/packs/reverse-engineering/rules/every-law-has-a-source.md +18 -0
- package/packs/reverse-engineering/rules/findings-are-withdrawn-in-place.md +17 -0
- package/packs/reverse-engineering/rules/firmware-stays-out.md +18 -0
- package/packs/reverse-engineering/rules/names-before-code.md +19 -0
- package/packs/reverse-engineering/rules/reproduction-or-original.md +18 -0
- package/packs/reverse-engineering/rules/two-sources-before-naming.md +21 -0
- package/packs/reverse-engineering/skills/bank-census/SKILL.md +18 -0
- package/packs/reverse-engineering/skills/gather-sources/SKILL.md +21 -0
- package/packs/reverse-engineering/skills/menu-map/SKILL.md +28 -0
- package/packs/reverse-engineering/skills/names-first/SKILL.md +41 -0
- package/packs/reverse-engineering/skills/re-deliverables/SKILL.md +21 -0
- package/packs/reverse-engineering/skills/tripwire-the-law/SKILL.md +19 -0
- package/packs/reverse-engineering/tools/lib/unwrap.mjs +115 -0
- package/packs/reverse-engineering/tools/names-sweep.mjs +264 -0
- package/packs/shell/checks/sh-mktemp.json +18 -0
- package/packs/shell/checks/sh-no-backticks.json +18 -0
- package/packs/shell/checks/sh-no-eval.json +18 -0
- package/packs/shell/checks/sh-no-parse-ls.json +18 -0
- package/packs/shell/checks/sh-no-pipe-to-shell.json +18 -0
- package/packs/shell/checks/sh-no-program-in-heredoc.json +18 -0
- package/packs/shell/checks/sh-quote-arguments.json +18 -0
- package/packs/shell/checks/sh-rm-guarded.json +18 -0
- package/packs/shell/checks/sh-strict-mode.json +20 -0
- package/packs/shell/pack.json +28 -0
- package/packs/shell/rules/shell-repeats-become-templates.md +23 -0
- package/packs/shell/rules/shell-strict-and-quoted.md +27 -0
- package/packs/shell/skills/shell-extract-template/SKILL.md +32 -0
- package/packs/shell-hooks/checks/gnu-only-in-shell.json +18 -0
- package/packs/shell-hooks/checks/hook-command-anchored.json +12 -0
- package/packs/shell-hooks/checks/hook-json-by-tool.json +18 -0
- package/packs/shell-hooks/checks/no-bash-c-with-variable.json +20 -0
- package/packs/shell-hooks/pack.json +36 -0
- package/packs/shell-hooks/rules/hooks-portable-anchored-quoted.md +26 -0
- package/packs/sound-design/checks/audio-seed-fixed.json +23 -0
- package/packs/sound-design/checks/mix-is-a-crossfade.json +30 -0
- package/packs/sound-design/checks/no-hash-in-the-signal.json +30 -0
- package/packs/sound-design/checks/no-literal-key-anchor.json +30 -0
- package/packs/sound-design/checks/test-compares-a-function-with-itself.json +22 -0
- package/packs/sound-design/pack.json +22 -0
- package/packs/sound-design/rules/algorithms-are-data.md +26 -0
- package/packs/sound-design/rules/meter-before-engine.md +27 -0
- package/packs/sound-design/rules/neutral-is-exact.md +26 -0
- package/packs/sound-design/rules/test-off-the-easy-point.md +28 -0
- package/packs/sound-design/rules/unreachable-is-said.md +25 -0
- package/packs/sound-design/rules/waveforms-and-octaves.md +24 -0
- package/packs/sound-design/skills/choose-observable/SKILL.md +18 -0
- package/packs/sound-design/skills/measure-a-law/SKILL.md +18 -0
- package/packs/sound-design/skills/measure-reverb/SKILL.md +19 -0
- package/packs/sound-design/skills/spread-probe/SKILL.md +18 -0
- package/packs/stellix/checks/no-keyboard-focus.json +12 -0
- package/packs/stellix/checks/one-seeded-random.json +16 -0
- package/packs/stellix/checks/world-never-includes-painter.json +12 -0
- package/packs/stellix/checks/world-no-libm.json +15 -0
- package/packs/stellix/checks/world-no-unordered.json +10 -0
- package/packs/stellix/hooks/no-shipped-images.mjs +88 -0
- package/packs/stellix/pack.json +61 -0
- package/packs/stellix/rules/stellix-deterministic-world.md +29 -0
- package/packs/stellix/rules/stellix-reset-generated.md +24 -0
- package/packs/stellix/rules/stellix-world-snapshot.md +27 -0
- package/packs/stellix/rules/world-continuous-collision.md +26 -0
- package/packs/stellix/rules/world-fp-determinism.md +28 -0
- package/packs/stored-text/checks/no-raw-html-from-data.json +31 -0
- package/packs/stored-text/checks/stored-text-libs-only-in-renderer.json +31 -0
- package/packs/stored-text/checks/stored-text-renderer-complete.json +24 -0
- package/packs/stored-text/checks/stored-text-through-renderer.json +25 -0
- package/packs/stored-text/pack.json +41 -0
- package/packs/stored-text/rules/stored-text-renders-once.md +26 -0
- package/packs/stored-text/skills/render-stored-text/SKILL.md +24 -0
- package/packs/synth-creator/checks/timing-from-synthcore.json +24 -0
- package/packs/synth-creator/checks/ui-drawn-in-code.json +23 -0
- package/packs/synth-creator/hooks/build-guard.mjs +232 -0
- package/packs/synth-creator/hooks/build-sweep.mjs +166 -0
- package/packs/synth-creator/hooks/frozen-files.mjs +63 -0
- package/packs/synth-creator/hooks/idle-wake.mjs +90 -0
- package/packs/synth-creator/hooks/protect-vendor.mjs +174 -0
- package/packs/synth-creator/hooks/spec-lock.mjs +117 -0
- package/packs/synth-creator/hooks/stage-guard.mjs +50 -0
- package/packs/synth-creator/hooks/time-guard.mjs +292 -0
- package/packs/synth-creator/hooks/user-asks.mjs +165 -0
- package/packs/synth-creator/pack.json +136 -0
- package/packs/synth-creator/rules/copy-trees-read-only.md +25 -0
- package/packs/synth-creator/rules/debug-by-measurement.md +20 -0
- package/packs/synth-creator/rules/done-means-fresh-evidence.md +18 -0
- package/packs/synth-creator/rules/hooks-and-gates.md +21 -0
- package/packs/synth-creator/rules/long-work-in-the-background.md +16 -0
- package/packs/synth-creator/rules/timing-from-synthcore.md +16 -0
- package/packs/synth-creator/skills/build-step/SKILL.md +125 -0
- package/packs/synth-creator/skills/build-through-the-queue/SKILL.md +19 -0
- package/packs/synth-creator/tools/freeze.mjs +36 -0
- package/packs/tui/checks/tui-entry-restores-terminal.json +27 -0
- package/packs/tui/checks/tui-gates-on-tty.json +25 -0
- package/packs/tui/checks/tui-no-ris-reset.json +22 -0
- package/packs/tui/checks/tui-resize-listener-removed.json +26 -0
- package/packs/tui/checks/tui-width-is-state.json +33 -0
- package/packs/tui/pack.json +44 -0
- package/packs/tui/rules/tui-resize-and-screen.md +25 -0
- package/packs/tui/skills/build-tui/SKILL.md +21 -0
- package/packs/ui-craft/checks/ui-input-needs-autocomplete.json +23 -0
- package/packs/ui-craft/checks/ui-intl-for-dates.json +21 -0
- package/packs/ui-craft/checks/ui-no-ai-palette.json +22 -0
- package/packs/ui-craft/checks/ui-no-animate-layout.json +22 -0
- package/packs/ui-craft/checks/ui-no-assistant-palette.json +23 -0
- package/packs/ui-craft/checks/ui-no-bounce-easing.json +22 -0
- package/packs/ui-craft/checks/ui-no-custom-cursor.json +22 -0
- package/packs/ui-craft/checks/ui-no-emoji-as-ui.json +22 -0
- package/packs/ui-craft/checks/ui-no-empty-image.json +21 -0
- package/packs/ui-craft/checks/ui-no-eyebrow.json +21 -0
- package/packs/ui-craft/checks/ui-no-furniture-text.json +22 -0
- package/packs/ui-craft/checks/ui-no-gradient-text.json +22 -0
- package/packs/ui-craft/checks/ui-no-index-numbering.json +21 -0
- package/packs/ui-craft/checks/ui-no-lorem.json +22 -0
- package/packs/ui-craft/checks/ui-no-marketing-buzzword.json +22 -0
- package/packs/ui-craft/checks/ui-no-paste-block.json +21 -0
- package/packs/ui-craft/checks/ui-no-placeholder-names.json +21 -0
- package/packs/ui-craft/checks/ui-no-scroll-hijack.json +21 -0
- package/packs/ui-craft/checks/ui-no-side-tab.json +21 -0
- package/packs/ui-craft/checks/ui-no-stock-labels.json +22 -0
- package/packs/ui-craft/checks/ui-no-transition-all.json +22 -0
- package/packs/ui-craft/checks/ui-no-uppercase-table-header.json +21 -0
- package/packs/ui-craft/checks/ui-no-zebra-rows.json +22 -0
- package/packs/ui-craft/checks/ui-no-zoom-lock.json +21 -0
- package/packs/ui-craft/pack.json +43 -0
- package/packs/ui-craft/rules/apps-are-not-pages.md +26 -0
- package/packs/ui-craft/rules/data-tells-the-truth.md +26 -0
- package/packs/ui-craft/rules/dates-and-numbers.md +18 -0
- package/packs/ui-craft/rules/forms-never-fight.md +22 -0
- package/packs/ui-craft/rules/interface-copy.md +26 -0
- package/packs/ui-craft/rules/motion-is-rare.md +31 -0
- package/packs/ui-craft/rules/no-generated-look.md +37 -0
- package/packs/ui-craft/rules/page-holds-its-frame.md +28 -0
- package/packs/ui-craft/rules/page-proved-rendered.md +19 -0
- package/packs/ui-craft/rules/pictures-do-a-job.md +25 -0
- package/packs/ui-craft/rules/pointer-feedback.md +28 -0
- package/packs/ui-craft/rules/screen-answers-one-question.md +24 -0
- package/packs/ui-craft/rules/survives-real-data.md +23 -0
- package/packs/ui-craft/rules/touch-and-small-screens.md +19 -0
- package/packs/ui-craft/rules/type-space-colour.md +26 -0
- package/packs/ui-craft/rules/url-holds-the-state.md +19 -0
- package/packs/ui-craft/skills/app-screen/SKILL.md +33 -0
- package/packs/ui-craft/skills/build-from-reference/SKILL.md +28 -0
- package/packs/ui-craft/skills/chart-choice/SKILL.md +34 -0
- package/packs/ui-craft/skills/hover-state/SKILL.md +28 -0
- package/packs/ui-craft/skills/page-critique/SKILL.md +33 -0
- package/packs/ui-craft/skills/prove-page/SKILL.md +23 -0
- package/packs/ui-craft/skills/redesign-page/SKILL.md +19 -0
- package/packs/ui-craft/skills/ui-code-review/SKILL.md +22 -0
- package/packs/ui-craft/skills/write-the-page/SKILL.md +21 -0
- package/packs/ui-craft/tools/page-measure.mjs +41 -0
- package/packs/web/checks/a11y-img-needs-alt.json +26 -0
- package/packs/web/checks/a11y-no-bare-outline-none.json +21 -0
- package/packs/web/checks/a11y-no-clickable-div.json +26 -0
- package/packs/web/checks/a11y-no-positive-tabindex.json +26 -0
- package/packs/web/checks/client-no-api-key.json +29 -0
- package/packs/web/checks/client-no-browser-global-at-module-scope.json +28 -0
- package/packs/web/checks/client-no-server-import.json +31 -0
- package/packs/web/checks/client-no-window-location-nav.json +28 -0
- package/packs/web/checks/css-no-inline-style.json +30 -0
- package/packs/web/checks/ds-pages-compose-primitives.json +28 -0
- package/packs/web/checks/key-from-index.json +23 -0
- package/packs/web/checks/prodbuild-no-cdn-runtime-deps.json +21 -0
- package/packs/web/checks/prodbuild-no-dev-flags.json +21 -0
- package/packs/web/checks/prodbuild-no-remote-fonts.json +22 -0
- package/packs/web/checks/rcss-button-cursor.json +30 -0
- package/packs/web/checks/rcss-no-100vw.json +21 -0
- package/packs/web/checks/rcss-no-fixed-wide-width.json +21 -0
- package/packs/web/checks/rcss-viewport-meta.json +28 -0
- package/packs/web/checks/secret-not-in-web-storage.json +25 -0
- package/packs/web/checks/tw-no-raw-hex-in-markup.json +34 -0
- package/packs/web/checks/wp-hero-not-lazy.json +27 -0
- package/packs/web/checks/wp-img-needs-dimensions.json +26 -0
- package/packs/web/pack.json +73 -0
- package/packs/web/rules/accessibility.md +26 -0
- package/packs/web/rules/client-boundaries.md +23 -0
- package/packs/web/rules/production-build.md +22 -0
- package/packs/web/rules/secrets-not-in-the-browser.md +18 -0
- package/packs/web/rules/styles-live-in-stylesheets.md +23 -0
- package/packs/web/rules/tailwind-v4.md +23 -0
- package/packs/web/rules/ui-primitives-one-module.md +30 -0
- package/packs/web/rules/web-performance.md +21 -0
- package/packs/web/skills/design-direction/SKILL.md +30 -0
- package/packs/web/skills/design-review/SKILL.md +28 -0
- package/packs/web/skills/pick-rendering-mode/SKILL.md +21 -0
- package/packs/web/skills/preflight-build/SKILL.md +23 -0
- package/packs/web/skills/seo-audit/SKILL.md +22 -0
- package/packs/websocket/checks/no-token-in-query.json +26 -0
- package/packs/websocket/checks/stale-socket-deletes-new-entry.json +25 -0
- package/packs/websocket/checks/ws-identity-from-message.json +26 -0
- package/packs/websocket/pack.json +21 -0
- package/packs/websocket/rules/identity-comes-from-the-connection.md +24 -0
- package/packs/writing/checks/ascii-no-em-dash.json +17 -0
- package/packs/writing/checks/no-copula-dodging.json +18 -0
- package/packs/writing/checks/no-dramatic-colon.json +18 -0
- package/packs/writing/checks/no-not-x-but-y.json +18 -0
- package/packs/writing/checks/no-participial-opener.json +18 -0
- package/packs/writing/checks/no-pseudo-wisdom.json +18 -0
- package/packs/writing/checks/no-slop-words.json +18 -0
- package/packs/writing/checks/no-stock-connectors.json +18 -0
- package/packs/writing/checks/no-time-or-date.json +27 -0
- package/packs/writing/checks/no-trailing-ing.json +18 -0
- package/packs/writing/checks/no-vague-attribution.json +18 -0
- package/packs/writing/pack.json +43 -0
- package/packs/writing/rules/ascii-no-em-dash.md +21 -0
- package/packs/writing/rules/cut-the-padding.md +20 -0
- package/packs/writing/rules/direct-voice.md +22 -0
- package/packs/writing/rules/no-cargo-cult.md +16 -0
- package/packs/writing/rules/no-scaffolding.md +19 -0
- package/packs/writing/rules/no-stock-language.md +27 -0
- package/packs/writing/rules/no-time-or-date.md +18 -0
- package/packs/writing/rules/rhythm-like-talk.md +20 -0
- package/packs/writing/rules/write-from-your-own-corner.md +20 -0
- package/packs/writing/skills/argument-post/SKILL.md +28 -0
- package/packs/writing/skills/humanize/SKILL.md +28 -0
- package/packs/writing/skills/launch-post/SKILL.md +38 -0
- package/packs/writing/skills/pick-subreddit/SKILL.md +69 -0
- package/packs/writing/skills/post-voice/SKILL.md +22 -0
- package/packs/writing/skills/reddit-post/SKILL.md +63 -0
- package/packs/writing/skills/reddit-title/SKILL.md +23 -0
- package/packs/writing/skills/reply-moves/SKILL.md +40 -0
- package/packs/writing/skills/reply-stance/SKILL.md +23 -0
- package/packs/writing/skills/should-i-reply/SKILL.md +21 -0
- package/packs/zod/hooks/schemas-only.mjs +53 -0
- package/packs/zod/pack.json +44 -0
- package/packs/zod/rules/env-shapes-only.md +14 -0
- package/packs/zod/rules/zod-4-schemas.md +14 -0
- package/profiles/stellix.layout.json +315 -0
- package/profiles/sub37.layout.json +247 -0
- package/prompts/scan-review.md +40 -0
- package/prompts/survey.md +82 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modulated filters stay stable and accurate under audio-rate modulation
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Use a structure that stays stable under fast modulation for any filter the matrix, envelopes or LFOs can move: a trapezoidal (TPT/ZDF) SVF or ladder. Morph LP > BP > HP > notch by interpolating the *output mix* of one structure.
|
|
12
|
+
- Prewarp: `g = tan(π · fc / fs)`. Clamp `fc ≤ 0.49 · fs` before the `tan`.
|
|
13
|
+
- Recompute coefficients per sample when the cutoff is modulated (a fast `tan` approximation is fine if its error is ≤ 0.1% up to 0.45 · fs).
|
|
14
|
+
- Clamp resonance to its documented self-oscillation range. Give any zero-delay-feedback solver a fixed maximum iteration count and a fallback to the last estimate.
|
|
15
|
+
|
|
16
|
+
- Count anything a push, comet, note or thread can move as modulated. That includes Stellix's floor EQ handles (spec 7.2), which comets and notes bend by formula, so the EQ needs a modulation-safe structure (e.g. Cytomic SVF bell and shelf responses), not static biquads.
|
|
17
|
+
|
|
18
|
+
Never do:
|
|
19
|
+
- Use direct-form biquads for modulated filters. They're fine for static EQ only.
|
|
20
|
+
- Change filter type by switching or crossfading between different filter structures.
|
|
21
|
+
</constraints>
|
|
22
|
+
|
|
23
|
+
## Why
|
|
24
|
+
Cytomic's trapezoidal SVF stays stable and smooth when cutoff, Q and mix move at audio rate. In float32 its error on a 20 Hz bell is about −111 dB, against about −59 dB for a direct-form biquad (Cytomic, "SVF vs DF1"). Direct-form coefficients are most sensitive at low cutoff, where the poles crowd near z = 1.
|
|
25
|
+
|
|
26
|
+
## Check
|
|
27
|
+
- Sweep the cutoff 20 Hz ↔ 18 kHz with a 2 kHz sine LFO at maximum resonance for 10 s. Pass: every sample finite, peak ≤ +24 dBFS (house choice).
|
|
28
|
+
- Set fc = 0.4 · fs and measure the peak or −3 dB frequency. Pass: within ±1%. Passing fc = fs/2 and fc = 2 · fs gives finite coefficients.
|
|
29
|
+
- If an existing proven filter (such as Solera's) passes these, it stays as it is. The tests are the law, not a particular structure.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: params
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Host parameters stay bounded, collision-free, and recorded as gestures
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Keep the exported parameter count bounded (house cap: about 2048). For Stellix, export generic slot parameters (4 slots × a fixed number of moon slots, with meaning taken from the planet's kind) rather than the union of every kind's moons. IDs stay fixed and the count stays bounded.
|
|
12
|
+
- Test that no two parameter IDs collide after hashing. JUCE's VST3 ID is `String::hashCode() & 0x7fffffff` (with Studio One compatibility); the AU ID is the unmasked hash. Both wrappers only `jassert` on a collision.
|
|
13
|
+
- Wrap every drag: `beginChangeGesture()` on mouse-down, `setValueNotifyingHost()` while dragging, `endChangeGesture()` on mouse-up, so hosts record automation cleanly.
|
|
14
|
+
- Mark internal or derived values non-automatable, or keep them out of host parameters entirely.
|
|
15
|
+
- Put parameters in groups (`AudioProcessorParameterGroup`) by slot and planet, so host lists stay navigable.
|
|
16
|
+
|
|
17
|
+
Never do:
|
|
18
|
+
- Change an exported ID string after release (the `parameter-ids-never-change` lock guards this).
|
|
19
|
+
- Export per-kind moons whose existence depends on the slot's current kind.
|
|
20
|
+
</constraints>
|
|
21
|
+
|
|
22
|
+
## Check
|
|
23
|
+
- Test: every exported ID's VST3 and AU hash is unique, and the count is within the cap.
|
|
24
|
+
- pluginval at strictness 10, and `auval -v` finishing in under 30 s (VST time).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: ui, painter
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Every control behaves the house way
|
|
8
|
+
|
|
9
|
+
Taken from Solera and MegaSynth. Stellix shipped without double-click reset (B-163) because no list said what a control must do, and
|
|
10
|
+
later with dropdowns that stepped instead of opening and a page where only one control worked (B-210, B-211), because the gates walked
|
|
11
|
+
INIT and never pressed a dropdown.
|
|
12
|
+
|
|
13
|
+
<constraints>
|
|
14
|
+
Always do:
|
|
15
|
+
- Give every control (knob, slider, switch, segmented button, drag handle, and any on-screen object that holds a value) all of these, built once in the shared control piece:
|
|
16
|
+
1. Double click returns it to its parameter's default, the value INIT gives it.
|
|
17
|
+
2. Fine drag with a modifier key (Shift on Mac and Windows) for small steps.
|
|
18
|
+
3. The mouse wheel moves it by a fixed step.
|
|
19
|
+
4. Its value is readable while it is moved, in the parameter's own value-to-text.
|
|
20
|
+
5. It never takes keyboard focus, so the computer keyboard keeps playing notes.
|
|
21
|
+
6. One gesture is one undo step.
|
|
22
|
+
- Give every choice control (dropdown, select, menu, any control drawn with a chevron or that holds one of a list of values) a real list:
|
|
23
|
+
a press opens the list with every choice and the current one marked; choosing one sets it, and Escape or a press outside closes it.
|
|
24
|
+
It never steps to the next value on a press. The ‹ › arrows beside a list may step, as their own controls.
|
|
25
|
+
- Check a new or changed control against this list with the `new-panel-control` skill, and walk one control of each template through the real window in the behaviour gate.
|
|
26
|
+
- Walk one control of each template in the real window, on a loaded patch and not only on INIT: it moves its value and the sound or
|
|
27
|
+
the picture, and a choice control opens its list. Prove the rest by a read, not a walk (`test-the-template-once`): a table check that every
|
|
28
|
+
control is built from its template and its binding reaches a live parameter, which is what catches a control wired to nothing. The gate is red on a planted control that does nothing and on a planted dropdown
|
|
29
|
+
that steps instead of opening.
|
|
30
|
+
- When a project's reference synth (Solera, MegaSynth) does a behaviour differently, copy it and write down what was copied.
|
|
31
|
+
|
|
32
|
+
Never do:
|
|
33
|
+
- Draw a control by hand on one page instead of using the shared piece.
|
|
34
|
+
- Give one page a behaviour the others lack.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp, world
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Math functions are only ever given values inside their domain
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- `sqrt(std::max(0.0, x))`, `std::log(std::max(x, tiny))`, `acos` and `asin` on `std::clamp(x, -1, 1)`, and `x / d` only when `|d| > eps`, with a defined result otherwise.
|
|
12
|
+
- Handle the 0/0 cases explicitly: `sinc(0) = 1`, limiter or compressor gain after silence, RMS of an empty window.
|
|
13
|
+
|
|
14
|
+
Never do:
|
|
15
|
+
- Feed a parameter-derived value straight into `log`, `sqrt`, `pow` with a negative base, or a division.
|
|
16
|
+
</constraints>
|
|
17
|
+
|
|
18
|
+
## Check
|
|
19
|
+
Test: sweep every parameter to its extremes (cutoff 1 Hz and Nyquist − 1, gain +24 dB, resonance max, time 0) with silence, full-scale noise, a 1 Hz sine and a Nyquist-rate sine as input. Pass: all output finite.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Modulated delays read with a proper interpolator
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Read chorus, flanger, vibrato and modulated delay taps with cubic or Lagrange-3 interpolation, or better.
|
|
12
|
+
- Inside reverb tanks, allpass interpolation is allowed, since the pitch change there is tiny.
|
|
13
|
+
- Add the interpolator's own latency to the delay time. Signalsmith's figures: linear 0, cubic 1, Lagrange-n (n−1)/2.
|
|
14
|
+
- Size every delay line for its maximum time plus the interpolator's extra taps, at the highest sample rate, in `prepareToPlay`.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Read a moving tap with nearest-sample lookup (zipper noise).
|
|
18
|
+
- Use linear interpolation where its high-frequency loss matters: it adds time-varying low-pass filtering (Dattorro 1997, §1.3.7).
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
Delay a 10 kHz sine at 48 kHz by 10.5 samples. Linear interpolation loses about 2.0 dB; 4-point Lagrange or Catmull-Rom about 0.54 dB. Pass (house choice): ≤ 0.6 dB loss for chorus and flanger.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Multiband splits sum back flat, and dynamics detect in the log domain
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Split bands with 4th-order Linkwitz-Riley crossovers (two cascaded 2nd-order Butterworth sections). With 3 bands, run the low band through the second split's allpass, so the bands sum back flat in magnitude and coherent in phase.
|
|
12
|
+
- Detect level in dB: peak or RMS (about 10 ms), with attack and release one-pole smoothing applied in the dB domain and a soft knee (Giannoulis, Massberg & Reiss, JAES 2012).
|
|
13
|
+
- Move crossover points with the same modulation-safe rules as filters, since crossover moons can be pushed.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Split bands with plain Butterworth or first-order filters whose sum isn't flat.
|
|
17
|
+
- Smooth gain in the linear domain (uneven attack and release across levels).
|
|
18
|
+
</constraints>
|
|
19
|
+
|
|
20
|
+
## Check
|
|
21
|
+
- Test: with zero gain in every band, the summed output is flat within ±0.01 dB from 20 Hz to 20 kHz.
|
|
22
|
+
- Test: sweep a crossover point 10 octaves per second. No clicks (no sample jump over the smoothing threshold) and no NaN.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Nonlinear stages are antialiased, except deliberate crushers
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Give every static nonlinearity (drive, tanh, clipper, wavefolder, HEAT-style saturation) first-order ADAA, `(F(x[n]) − F(x[n−1])) / (x[n] − x[n−1])` with antiderivative F chosen so F(0) = 0, plus at least 2x oversampling. Use more oversampling where measurement says so.
|
|
12
|
+
- Handle the ill-conditioned case: when `|x[n] − x[n−1]| < eps`, use `f((x[n] + x[n−1]) / 2)`.
|
|
13
|
+
- Oversample only the nonlinear "island", not the whole chain. Pick the smallest factor the measurement allows: host rate, then 2x, then 4x, then 8x only with evidence.
|
|
14
|
+
- Use ADAA only on memoryless curves (tanh, soft clip, folder). Stages with memory (envelopes, feedback) need oversampling instead.
|
|
15
|
+
- Count ADAA's half-sample delay in the latency of that path. Inside a filter feedback loop, absorb it structurally (Parker, Zavalishin & Le Bivic, DAFx-16 §6.1). Never drop ADAA into a loop as-is.
|
|
16
|
+
- Treat bit reduction and sample-rate reduction (FireBloom's BITS, the BIT effect) as *intended* aliasing: run them at host rate without oversampling, feed them an already band-limited signal, and follow them with a DC blocker.
|
|
17
|
+
|
|
18
|
+
Never do:
|
|
19
|
+
- Run a hard clipper or folder at the base rate with no ADAA or oversampling.
|
|
20
|
+
</constraints>
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
In DAFx-16 Table 1, a hard clipper at gain 10 needs 12x oversampling alone to reach about 46.7 dB SNR; first-order ADAA gets there at about 4x.
|
|
24
|
+
|
|
25
|
+
## Check
|
|
26
|
+
- `tone-report` on sine probes at 1, 3, 5 and 7 kHz (plus 10 kHz at 96 kHz) through the stage at gain 10. A 1 kHz probe alone hides aliasing. Pass (house choice): SNR ≥ 45 dB at every probe.
|
|
27
|
+
- Unit test: constant input, and x[n] == x[n−1], give finite output equal to f(x) within 1e−6.
|
|
28
|
+
- Crushers: golden-file test per sample rate, and full resolution at rate 1 returns the input unchanged.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: audio
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Every note-on owes a note-off: one ledger tracks them all
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Keep one note ledger with a state per voice: held, sustained, sostenuto, releasing. Every note started by anyone (keys, DOUBLE/TRIPLE extras, arp, HARMONY answers, BEATS) is entered in it.
|
|
12
|
+
- Sustain (CC64 ≥ 64 down): a note-off while the pedal is down marks the note sustained, and pedal-up releases it. Sostenuto (CC66) latches only the notes down at the moment it's pressed.
|
|
13
|
+
- Flush the ledger (release every voice) on CC123 all-notes-off, CC120 all-sound-off, transport stop, `releaseResources`, patch load, reset and bypass.
|
|
14
|
+
- Use JUCE's `MPEInstrument` only as the parser and note tracker for MPE; keep the house 96-voice allocator. Smooth per-note pressure and slide (about 5 ms one-pole per note).
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Start a note anywhere without going through the ledger.
|
|
18
|
+
- Let a generated note (arp, harmony, double) outlive the key or event that started it without a scheduled note-off.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
Fuzz test: random streams of notes, CC64/CC66, CC120/CC123 and patch loads. At the end, every voice is idle and the ledger is empty. With MPE input, each voice's pressure follows only its own channel.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp, params, ui
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# A value the user sees and the sound uses comes from one formula
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Put each mapping (normalized value to Hz, dB, ms, ratio, semitones, note name, tempo-synced time) in one function, and call that same function from the DSP, the display text and the host's value-to-text.
|
|
12
|
+
- When a mapping changes, change it in that one place, and add a test that checks DSP and display agree at the ends and in the middle of the range.
|
|
13
|
+
|
|
14
|
+
Never do:
|
|
15
|
+
- Re-derive a display value in the editor ("cutoff = 20 * pow(1000, v)") next to a different formula in the DSP.
|
|
16
|
+
- Round or clamp differently in the display than in the sound.
|
|
17
|
+
</constraints>
|
|
18
|
+
|
|
19
|
+
## Check
|
|
20
|
+
`trace-parameter` reports any second formula it finds for the same value.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp, tests, bench
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Every optimisation and refactor of DSP is proven by a null test
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Before changing DSP code for speed or structure, save reference renders (golden files) of fixed test patches: notes, sweeps, every row of the matrix moving.
|
|
12
|
+
- After the change, render again and require a bit-identical result. If an exact match is impossible, report the maximum difference in dBFS and accept it only below a stated threshold (house choice: ≤ −120 dBFS for a pure refactor).
|
|
13
|
+
- Build DSP blocks so they don't depend on the parameter tree: they take a plain parameter struct, so the same sources compile into the plugin, the test executable and the Release benchmark target.
|
|
14
|
+
- Keep a "sound revision" string that changes only when the sound changes, separate from the state schema version. A changed sound gets new golden files *on purpose*, logged in the bugs/changes file.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Call a change "faster" or "the same sound" without both a benchmark and a null test.
|
|
18
|
+
- Regenerate golden files to make a failing null test pass, unless the sound change was intended and is logged.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
- A CTest render-diff test compares against the golden files.
|
|
23
|
+
- `.claude/checks/dsp-without-apvts.json` blocks DSP folders from reaching into the parameter tree.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Oscillator edges are band-limited
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Correct every discontinuity (saw reset, pulse edge, hard-sync reset, and each of a supersaw's stacked saws) with a band-limiting method: PolyBLEP at minimum; 4th-order B-spline polyBLEP, minBLEP or mipmapped wavetables for the top octaves.
|
|
12
|
+
- Keep the phase accumulator and its increment in `double`.
|
|
13
|
+
- It depends on what is being built. On an original design, the default stays clean. On a reproduction (`guards.instrument.kind`), the machine is the spec: a naive saw is the instrument, with its source cited and a golden-file test.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Write a naive `phase * 2 - 1` saw or `phase < pw` pulse straight to the output.
|
|
17
|
+
</constraints>
|
|
18
|
+
|
|
19
|
+
## Why
|
|
20
|
+
Välimäki, Pekonen & Nam (JASA 2012) measured how far up each method stays alias-free at 44.1 kHz: 2nd-order PolyBLEP to about 2.1 kHz fundamental, 4th-order Lagrange to about 5.1 kHz, 4th-order B-spline to about 7.8 kHz. Above that, a better method or oversampling is needed.
|
|
21
|
+
|
|
22
|
+
## Check
|
|
23
|
+
Render 2 s of the oscillator at 48 kHz with f0 = 110, 1000, 2000 and 4186 Hz, then run `node .claude/tools/tone-report.mjs <wav> <f0>`. Pass (thresholds are a house choice): the largest non-harmonic peak is below −60 dB re the fundamental up to 2 kHz, and below −40 dB at 4186 Hz.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# The output limiter never lets a sample past its ceiling and reports its latency
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Compute gain as the minimum over the look-ahead window with a sliding-window minimum (monotonic deque, O(1) per sample), then smooth the release.
|
|
12
|
+
- Link stereo: detect on max(|L|, |R|).
|
|
13
|
+
- Report the latency once, as a constant: `setLatencySamples(round(0.001 · fs) + oversamplerLatency)` in `prepareToPlay`.
|
|
14
|
+
- If the ceiling is ever advertised as dBTP, detect true peak with 4x oversampling (ITU-R BS.1770). A sample-peak limiter can overshoot by about 0.5 dB between samples.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Make the ceiling or look-ahead user controls (house law: −0.3 dBFS, 1 ms).
|
|
18
|
+
- Change the reported latency while running.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
- Test: a sweep plus an inter-sample-peak signal (fs/4 sine at 45° phase). Max sample ≤ −0.3 dBFS; if dBTP is claimed, true peak at 4x ≤ the ceiling.
|
|
23
|
+
- Null test: with the limiter idle, output minus input delayed by the reported latency is silent.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: params
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Parameter and control IDs never change once assigned
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Give every parameter a `juce::ParameterID { "id", versionHint }`. A newly added parameter gets the current version hint.
|
|
12
|
+
- Store and recall everything by ID, never by position or index, so lists can be reordered or sorted without breaking patches.
|
|
13
|
+
- When a control's meaning changes, add a new ID and migrate old patches in `setStateInformation`. The old ID stays readable.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Rename, reuse or delete an existing ID. Saved patches, host automation and every preset bank refer to it.
|
|
17
|
+
</constraints>
|
|
18
|
+
|
|
19
|
+
## Check
|
|
20
|
+
`.claude/hooks/param-id-lock.mjs` (PostToolUse) collects every parameter ID in the repo and compares it with `.claude/param-ids.lock.json`. A locked ID that disappeared fails the edit with the list of missing IDs. New IDs are added to the lock automatically. Run `node .claude/hooks/param-id-lock.mjs --init` once per repo to create the lock. It reads `juce::ParameterID` and `AudioParameter*` declarations in C++ by default. If control IDs also live in `panel.json`, add `.claude/param-ids.config.json` with `"extensions"` and `"patterns"` (regexes with one capture group) to cover them.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: params
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Parameters and state are safe to touch from any host thread
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Assume hosts call `setValue` on parameters from background threads while audio runs, and call `getStateInformation`/`setStateInformation` off the message thread.
|
|
12
|
+
- Make every value shared between those paths atomic, or copy it through the lock-free handoff.
|
|
13
|
+
|
|
14
|
+
Never do:
|
|
15
|
+
- Change the process locale (`setlocale`, `std::locale::global`). It breaks number formatting inside the host. (`.claude/checks/no-locale-change.json` blocks it.)
|
|
16
|
+
</constraints>
|
|
17
|
+
|
|
18
|
+
## Check
|
|
19
|
+
ThreadSanitizer test: N threads set parameters and save state in a loop while the audio thread renders. Pass: no TSan reports, and `setlocale(LC_ALL, nullptr)` is unchanged after plugin init.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: audio
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Each block reads its parameters once, into a plain snapshot
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- At the start of each block, copy the parameters into a plain-data snapshot with relaxed atomic loads. Use a dirty bitset set by `parameterValueChanged`, so only changed values are copied when there are thousands.
|
|
12
|
+
- Make the world, the voices and the DSP read only from that snapshot within the block, so every value is consistent for the whole block and the world stays deterministic.
|
|
13
|
+
- Ramp continuous values inside the block with the per-sample smoothers.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Read parameter atomics directly in the middle of the world tick or a voice loop. A host write mid-block makes one block see two values.
|
|
17
|
+
</constraints>
|
|
18
|
+
|
|
19
|
+
## Check
|
|
20
|
+
- ThreadSanitizer stress test: the UI and host automation write 4k parameters while audio renders. No races.
|
|
21
|
+
- `juce-realtime-audit` reports no parameter reads outside the snapshot step.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: params
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# A patch stores every setting except the performance controls
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Store every sound setting in a patch, effect choices included (reverb room, delay program, routing).
|
|
12
|
+
|
|
13
|
+
Never do:
|
|
14
|
+
- Store MAIN volume, octave, the mod wheel or the pitch wheel in a patch. Those belong to the player and the session, not the sound, so loading a patch never changes them.
|
|
15
|
+
</constraints>
|
|
16
|
+
|
|
17
|
+
## Check
|
|
18
|
+
Test: set MAIN volume, octave, mod wheel and pitch wheel to non-default values, save a patch, change all four again, and load the patch. Assert all four kept their current values and that none of the four IDs appear in the saved data.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp, audio
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Per-sample code can be inlined: no virtual calls per sample
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Dispatch by type once per block (or once per voice per block), then run a tight, non-virtual per-sample loop. Oscillator type, filter mode and effect choice are switched at block level.
|
|
12
|
+
- Use templates, `final` classes, or a `switch` over a small enum hoisted outside the sample loop when one interface has several implementations.
|
|
13
|
+
- Keep per-voice state contiguous (struct-of-arrays or one array of voice structs), not pointers to separately allocated objects.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Call a `virtual` function, a `std::function`, or through a function pointer inside the per-sample loop of 96 voices.
|
|
17
|
+
- Use `-march=native` in a build you ship. Users' CPUs differ from yours. (`.claude/checks/no-march-native.json` blocks it.)
|
|
18
|
+
</constraints>
|
|
19
|
+
|
|
20
|
+
## Check
|
|
21
|
+
- The benchmark from `cpu-worst-case-per-block.md` shows the gain when the loop is restructured; keep the faster version only if its null test passes.
|
|
22
|
+
- Manual review: grep the per-sample loops for `->` calls on interface pointers.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: audio, dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# `prepareToPlay` can run any number of times and always leaves a clean state
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Treat `prepareToPlay` as callable repeatedly, with or without `releaseResources` in between, and with a new sample rate or block size each time.
|
|
12
|
+
- Re-prepare and reset every DSP object unconditionally: filters, delay lines, reverb tanks, smoothers (`reset(sampleRate, ramp)`), voices and oversamplers.
|
|
13
|
+
- Size scratch buffers with margin for blocks larger than announced, and split larger blocks internally.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Skip work because "already prepared". A changed rate must rebuild everything rate-dependent.
|
|
17
|
+
- Leak or double-allocate when `prepareToPlay` is called twice without `releaseResources`.
|
|
18
|
+
</constraints>
|
|
19
|
+
|
|
20
|
+
## Check
|
|
21
|
+
Tests:
|
|
22
|
+
1. Prepare at 48 kHz/512, then 96 kHz/64, then 44.1 kHz/1024 with no release in between. Render each time; pass when the output matches a freshly constructed processor and ASan reports no leaks.
|
|
23
|
+
2. Prepare at N, process blocks of 2N under ASan. Pass: no reports.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# A NaN or Inf can never live in recursive state
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Once per block, check the state of every recursive structure (filter integrators, delay feedback, reverb tank, ZDF solver) with `std::isfinite`. On failure, reset that state (or the whole voice) to zero, and bump a debug counter.
|
|
12
|
+
- Debug builds: `jassert(std::isfinite(x))` after each stage of a voice.
|
|
13
|
+
|
|
14
|
+
Never do:
|
|
15
|
+
- Rely on `std::clamp`, `jlimit` or a soft clipper to remove a NaN. They pass NaN through unchanged.
|
|
16
|
+
- Zero only the output while a NaN stays in a filter state. It keeps re-emerging forever.
|
|
17
|
+
</constraints>
|
|
18
|
+
|
|
19
|
+
## Check
|
|
20
|
+
Test: inject a NaN into a filter state mid-block. Pass: the next block's output is finite and the reset counter went up by one.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Reverb feedback can never exceed unity gain
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Make FDN mixing matrices orthogonal (unitary). Keep per-line gains below 1, computed from RT60 per line length: `g = 10^(−3 · L / (fs · T60))`. Damping filters have |H| ≤ 1 at every frequency.
|
|
12
|
+
- Keep allpass and lattice coefficients within [0, 0.9999999].
|
|
13
|
+
- Use mutually prime delay lengths, scaled by sample rate.
|
|
14
|
+
- Modulate tank delays slowly (around 1 Hz, quadrature LFOs) with small excursion. Dattorro's plate uses 16 samples at 29761 Hz, scaled to fs.
|
|
15
|
+
- Make freeze/infinite mode exactly unity gain with the unitary check, never "slightly above 1".
|
|
16
|
+
|
|
17
|
+
Never do:
|
|
18
|
+
- Tune a "bigger" hall by raising feedback toward or past 1. Lengthen the lines or change the damping.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
- Unit test: for random vectors x, the norm of M·x equals the norm of x to within 1e-6.
|
|
23
|
+
- At maximum decay, impulse-response energy in successive 100 ms windows must never rise after 200 ms.
|
|
24
|
+
- Measured RT60 within ±10% of the setting (house choice).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: audio
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# MIDI events land on their exact sample
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Render the block in segments split at each MIDI event's `samplePosition`: render up to the event, apply it, continue. (`juce::Synthesiser::renderNextBlock` does this; a custom voice manager must do the same.)
|
|
12
|
+
- Apply note-on, note-off, pitch bend, mod wheel, aftertouch and CC at their offset, not at the block start.
|
|
13
|
+
|
|
14
|
+
- Generate MIDI (arp, WaveArp, matrix notes) into a member `MidiBuffer` pre-sized with `ensureSize()` in `prepareToPlay`, then `swapWith` the host buffer.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Add to a `MidiBuffer` while iterating over it.
|
|
18
|
+
- Loop over the `MidiBuffer` first and then render the whole block. Every note then snaps to the block start, so timing jitter grows with buffer size and arps or matrix retriggers drift.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
Test: send a note-on at sample offset 100 in a 512-sample block, and assert the first non-zero output sample is at index 100 (± the voice's known attack latency). Repeat at block sizes 64 and 2048.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: audio, dsp
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Sample rate and block size always come from the host
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Derive every time-based value (delay samples, LFO increments, envelope coefficients, smoothing ramps, tempo-synced rates) from the `sampleRate` given to `prepareToPlay()`, and recompute it there.
|
|
12
|
+
- Handle any `buffer.getNumSamples()`, including 0, and blocks of varying size on every call.
|
|
13
|
+
- Program defensively for a block *larger* than `maximumExpectedSamplesPerBlock`: process it in chunks no bigger than what you prepared. JUCE's own docs warn that buggy hosts can exceed it.
|
|
14
|
+
- Test at 44.1, 48, 96 and 192 kHz.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Write `44100`, `48000`, `96000` (or `44100.0f` etc.) in DSP code as a rate.
|
|
18
|
+
- Assume the block size equals the prepared maximum, or is a power of two.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
- The realtime-guard hook flags literal sample rates inside audio-thread bodies.
|
|
23
|
+
- Test: render the same patch at 44.1 and 96 kHz and assert that the delay time in milliseconds and the LFO period in milliseconds match. Render with block sizes 1, 7, 64 and 4096 and assert identical output.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: audio
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Every `processBlock` starts with `ScopedNoDenormals`
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Make `juce::ScopedNoDenormals noDenormals;` the first line of every `processBlock` (and `processBlockBypassed` if it processes audio).
|
|
12
|
+
|
|
13
|
+
- Use `ScopedNoDenormals` on *every* thread that runs DSP: worker threads that render voices, offline renders, and test and benchmark executables. The flag belongs to one thread only.
|
|
14
|
+
- Define `JUCE_DSP_ENABLE_SNAP_TO_ZERO=0` in CMake. JUCE's `JUCE_SNAP_TO_ZERO` only does anything on Intel (it's a no-op on Arm), so `juce::dsp` filters otherwise give block-size-dependent output on x86 and not on Apple Silicon.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Rely on calling `FloatVectorOperations::disableDenormalisedNumberSupport()` in `prepareToPlay()`. It sets the flush-to-zero flags of the CPU register on the *calling* thread (JUCE source: MXCSR on Intel, FPCR on Arm), and hosts may call `prepareToPlay` on a different thread from the audio callback.
|
|
18
|
+
- Add tiny DC offsets (`+ 1e-20f`) as the denormal fix in new code. Use the scoped flag; it covers every filter, reverb tank and feedback path at once.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Why
|
|
22
|
+
Decaying feedback (reverb tails, filter states, delay feedback after the note stops) drifts into denormal range, and on some CPUs each denormal operation is many times slower. The symptom is a CPU spike when the sound goes *quiet*.
|
|
23
|
+
|
|
24
|
+
## Check
|
|
25
|
+
- The realtime-guard hook blocks any edit that leaves a `processBlock` body without `ScopedNoDenormals`.
|
|
26
|
+
- `.claude/checks/juce-snap-to-zero-off.json` blocks removing the define once it's in `CMakeLists.txt`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: dsp, audio
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Every continuous parameter is smoothed per sample
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Give each continuous control (gain, cutoff, resonance, mix, pan, drive, matrix-driven values) a `juce::SmoothedValue` or an equivalent one-pole smoother.
|
|
12
|
+
- Call `reset(sampleRate, rampSeconds)` in `prepareToPlay()`, `setTargetValue()` once per block, and `getNextValue()` per sample.
|
|
13
|
+
- Use multiplicative smoothing (`ValueSmoothingTypes::Multiplicative`) for frequency and gain in dB, where linear ramps sound uneven.
|
|
14
|
+
- Call `setCurrentAndTargetValue()` when a patch loads, so a preset change doesn't sweep.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Apply a new parameter value as a step at the block boundary (zipper noise, clicks).
|
|
18
|
+
- Smooth stepped controls (waveform choice, on/off, octave). Crossfade those instead when switching causes a click.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
Test: hold a sine, jump a parameter from minimum to maximum, and assert the largest sample-to-sample difference in the output stays under a set threshold.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: params
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Loading state is versioned and can never crash
|
|
8
|
+
|
|
9
|
+
<constraints>
|
|
10
|
+
Always do:
|
|
11
|
+
- Write a `version` attribute on the root of every saved state and patch.
|
|
12
|
+
- In `setStateInformation` and patch loading: null-check the XML or JSON, check the root tag, read the version, migrate older versions forward step by step, then apply.
|
|
13
|
+
- Ignore unknown IDs (from a newer build), and keep defaults for IDs missing in old data.
|
|
14
|
+
- Load on the message thread, then hand values to the engine through the parameter system.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Dereference the result of `getXmlFromBinary()` or a JSON parse without checking it.
|
|
18
|
+
- Assume the saved data was written by the current build.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
Test: load an empty block, random bytes, a v1 patch and a patch with an unknown extra ID, and assert no crash, sane defaults, and the known values restored.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: ui
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# A UI is drawn straight on, and everything aligns: basic UX comes before the picture
|
|
6
|
+
|
|
7
|
+
<constraints>
|
|
8
|
+
Always do:
|
|
9
|
+
- Draw the object straight on and flat, as if from infinitely far away. Depth comes from shading under one light, never from shifted shapes.
|
|
10
|
+
- Align everything horizontally and vertically. Controls in a row share one centre line, and controls in a column share one centre line.
|
|
11
|
+
- Treat whatever looks grouped as a group: the same size, the same spacing, shared edges, and even gaps.
|
|
12
|
+
- Give a control its size from its kind, never its instance. A table row holds position and parameter.
|
|
13
|
+
- Give a round control's parts one centre: cap, skirt, pointer and ticks.
|
|
14
|
+
- Keep text level, and mirror what is symmetrical: rack ears, slots, screw holes.
|
|
15
|
+
- Treat a photograph as evidence of the design, not as the design. Start from what is known of the object: a panel is a flat rectangle. Snap what you measure to the grid it implies.
|
|
16
|
+
|
|
17
|
+
Never do:
|
|
18
|
+
- Copy what belongs to the photograph: the camera's angle, the lens, the lighting, a bend, wear, a missing part. One bend moves everything near it.
|
|
19
|
+
- Keep a measured offset as design when it is smaller than the design's own spacing. It is error.
|
|
20
|
+
- Let a look gate reward a flaw. Mask what is damaged, and check alignment, sizes and centres on their own: a whole-picture score passes while every knob is wrong.
|
|
21
|
+
</constraints>
|