@ketecode/loom 0.0.0-stage → 0.2.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 +616 -2
- package/agents/accessibility-reviewer/AGENT.md +70 -0
- package/agents/accessibility-reviewer/evals/triggers.json +15 -0
- package/agents/agent-evaluator/AGENT.md +74 -0
- package/agents/agent-evaluator/evals/triggers.json +15 -0
- package/agents/architect/AGENT.md +82 -0
- package/agents/architect/evals/triggers.json +17 -0
- package/agents/billing-reviewer/AGENT.md +68 -0
- package/agents/billing-reviewer/evals/triggers.json +16 -0
- package/agents/code-reviewer/AGENT.md +51 -0
- package/agents/code-reviewer/evals/behavior.json +60 -0
- package/agents/code-reviewer/evals/triggers.json +14 -0
- package/agents/code-simplifier/AGENT.md +74 -0
- package/agents/code-simplifier/evals/triggers.json +15 -0
- package/agents/cpp-build-resolver/AGENT.md +73 -0
- package/agents/cpp-build-resolver/evals/triggers.json +16 -0
- package/agents/cpp-reviewer/AGENT.md +59 -0
- package/agents/cpp-reviewer/evals/triggers.json +16 -0
- package/agents/csharp-build-resolver/AGENT.md +84 -0
- package/agents/csharp-build-resolver/evals/triggers.json +17 -0
- package/agents/csharp-reviewer/AGENT.md +88 -0
- package/agents/csharp-reviewer/evals/triggers.json +17 -0
- package/agents/dart-build-resolver/AGENT.md +80 -0
- package/agents/dart-build-resolver/evals/triggers.json +17 -0
- package/agents/dart-reviewer/AGENT.md +66 -0
- package/agents/dart-reviewer/evals/triggers.json +17 -0
- package/agents/database-reviewer/AGENT.md +72 -0
- package/agents/database-reviewer/evals/triggers.json +16 -0
- package/agents/django-reviewer/AGENT.md +61 -0
- package/agents/django-reviewer/evals/triggers.json +15 -0
- package/agents/doc-updater/AGENT.md +92 -0
- package/agents/doc-updater/evals/triggers.json +14 -0
- package/agents/e2e-runner/AGENT.md +88 -0
- package/agents/e2e-runner/evals/triggers.json +16 -0
- package/agents/fastapi-reviewer/AGENT.md +63 -0
- package/agents/fastapi-reviewer/evals/triggers.json +15 -0
- package/agents/flutter-reviewer/AGENT.md +70 -0
- package/agents/flutter-reviewer/evals/triggers.json +15 -0
- package/agents/fsharp-build-resolver/AGENT.md +81 -0
- package/agents/fsharp-build-resolver/evals/triggers.json +15 -0
- package/agents/fsharp-reviewer/AGENT.md +77 -0
- package/agents/fsharp-reviewer/evals/triggers.json +15 -0
- package/agents/go-build-resolver/AGENT.md +85 -0
- package/agents/go-build-resolver/evals/triggers.json +16 -0
- package/agents/go-reviewer/AGENT.md +66 -0
- package/agents/go-reviewer/evals/triggers.json +16 -0
- package/agents/healthcare-reviewer/AGENT.md +65 -0
- package/agents/healthcare-reviewer/evals/triggers.json +16 -0
- package/agents/i18n-reviewer/AGENT.md +64 -0
- package/agents/i18n-reviewer/evals/triggers.json +16 -0
- package/agents/inbox-triager/AGENT.md +98 -0
- package/agents/inbox-triager/evals/triggers.json +16 -0
- package/agents/infra-reviewer/AGENT.md +93 -0
- package/agents/infra-reviewer/evals/triggers.json +15 -0
- package/agents/java-build-resolver/AGENT.md +82 -0
- package/agents/java-build-resolver/evals/triggers.json +16 -0
- package/agents/java-reviewer/AGENT.md +64 -0
- package/agents/java-reviewer/evals/triggers.json +16 -0
- package/agents/kotlin-build-resolver/AGENT.md +89 -0
- package/agents/kotlin-build-resolver/evals/triggers.json +16 -0
- package/agents/kotlin-reviewer/AGENT.md +75 -0
- package/agents/kotlin-reviewer/evals/triggers.json +16 -0
- package/agents/mle-reviewer/AGENT.md +68 -0
- package/agents/mle-reviewer/evals/triggers.json +16 -0
- package/agents/network-config-reviewer/AGENT.md +68 -0
- package/agents/network-config-reviewer/evals/triggers.json +17 -0
- package/agents/payments-reviewer/AGENT.md +64 -0
- package/agents/payments-reviewer/evals/triggers.json +16 -0
- package/agents/performance-optimizer/AGENT.md +86 -0
- package/agents/performance-optimizer/evals/triggers.json +16 -0
- package/agents/perl-build-resolver/AGENT.md +84 -0
- package/agents/perl-build-resolver/evals/triggers.json +15 -0
- package/agents/perl-reviewer/AGENT.md +77 -0
- package/agents/perl-reviewer/evals/triggers.json +15 -0
- package/agents/php-build-resolver/AGENT.md +88 -0
- package/agents/php-build-resolver/evals/triggers.json +16 -0
- package/agents/php-reviewer/AGENT.md +61 -0
- package/agents/php-reviewer/evals/triggers.json +15 -0
- package/agents/planner/AGENT.md +75 -0
- package/agents/planner/evals/triggers.json +17 -0
- package/agents/pr-test-analyzer/AGENT.md +82 -0
- package/agents/pr-test-analyzer/evals/triggers.json +16 -0
- package/agents/python-build-resolver/AGENT.md +87 -0
- package/agents/python-build-resolver/evals/triggers.json +16 -0
- package/agents/python-reviewer/AGENT.md +63 -0
- package/agents/python-reviewer/evals/triggers.json +15 -0
- package/agents/rag-reviewer/AGENT.md +71 -0
- package/agents/rag-reviewer/evals/triggers.json +16 -0
- package/agents/react-reviewer/AGENT.md +70 -0
- package/agents/react-reviewer/evals/triggers.json +16 -0
- package/agents/refactor-cleaner/AGENT.md +82 -0
- package/agents/refactor-cleaner/evals/triggers.json +16 -0
- package/agents/ruby-build-resolver/AGENT.md +93 -0
- package/agents/ruby-build-resolver/evals/triggers.json +16 -0
- package/agents/ruby-reviewer/AGENT.md +62 -0
- package/agents/ruby-reviewer/evals/triggers.json +16 -0
- package/agents/rust-build-resolver/AGENT.md +98 -0
- package/agents/rust-build-resolver/evals/triggers.json +16 -0
- package/agents/rust-reviewer/AGENT.md +78 -0
- package/agents/rust-reviewer/evals/triggers.json +15 -0
- package/agents/security-reviewer/AGENT.md +84 -0
- package/agents/security-reviewer/evals/triggers.json +16 -0
- package/agents/silent-failure-hunter/AGENT.md +66 -0
- package/agents/silent-failure-hunter/evals/triggers.json +16 -0
- package/agents/solidity-reviewer/AGENT.md +70 -0
- package/agents/solidity-reviewer/evals/triggers.json +16 -0
- package/agents/spec-reviewer/AGENT.md +95 -0
- package/agents/spec-reviewer/evals/behavior.json +57 -0
- package/agents/spec-reviewer/evals/triggers.json +16 -0
- package/agents/swift-build-resolver/AGENT.md +85 -0
- package/agents/swift-build-resolver/evals/triggers.json +15 -0
- package/agents/swift-reviewer/AGENT.md +75 -0
- package/agents/swift-reviewer/evals/triggers.json +15 -0
- package/agents/task-implementer/AGENT.md +89 -0
- package/agents/task-implementer/evals/behavior.json +47 -0
- package/agents/task-implementer/evals/triggers.json +16 -0
- package/agents/typescript-build-resolver/AGENT.md +76 -0
- package/agents/typescript-build-resolver/evals/triggers.json +15 -0
- package/agents/typescript-reviewer/AGENT.md +76 -0
- package/agents/typescript-reviewer/evals/triggers.json +15 -0
- package/agents/vue-reviewer/AGENT.md +75 -0
- package/agents/vue-reviewer/evals/triggers.json +15 -0
- package/bin/kete-loom.js +723 -0
- package/commands/aside.md +19 -0
- package/commands/brainstorm.md +25 -0
- package/commands/build-fix.md +26 -0
- package/commands/campaign.md +19 -0
- package/commands/changelog.md +36 -0
- package/commands/checkpoint.md +26 -0
- package/commands/codemap.md +25 -0
- package/commands/commit.md +26 -0
- package/commands/debug.md +27 -0
- package/commands/deps-audit.md +32 -0
- package/commands/dual-review.md +34 -0
- package/commands/epic-decompose.md +21 -0
- package/commands/explain.md +37 -0
- package/commands/feature-dev.md +23 -0
- package/commands/finish-branch.md +26 -0
- package/commands/fix-bug.md +38 -0
- package/commands/hookify.md +23 -0
- package/commands/i18n-check.md +39 -0
- package/commands/issue-sync.md +22 -0
- package/commands/jira.md +19 -0
- package/commands/learn.md +23 -0
- package/commands/loom.md +21 -0
- package/commands/loop.md +20 -0
- package/commands/model-route.md +27 -0
- package/commands/onboard.md +35 -0
- package/commands/orchestrate.md +21 -0
- package/commands/plan-feature.md +36 -0
- package/commands/postmortem.md +42 -0
- package/commands/pr-describe.md +39 -0
- package/commands/pr.md +22 -0
- package/commands/prd.md +41 -0
- package/commands/production-readiness.md +45 -0
- package/commands/project-init.md +21 -0
- package/commands/refactor-clean.md +24 -0
- package/commands/resume-session.md +22 -0
- package/commands/review.md +35 -0
- package/commands/save-session.md +37 -0
- package/commands/security-scan.md +32 -0
- package/commands/sessions.md +21 -0
- package/commands/skill-create.md +21 -0
- package/commands/tdd.md +36 -0
- package/commands/test-coverage.md +24 -0
- package/commands/threat-model.md +36 -0
- package/commands/update-docs.md +25 -0
- package/commands/usage-report.md +43 -0
- package/commands/verify.md +21 -0
- package/hooks/block-dangerous-commands/HOOK.md +30 -0
- package/hooks/block-dangerous-commands/cases.json +50 -0
- package/hooks/block-dangerous-commands/hook.js +75 -0
- package/hooks/block-foreground-servers/HOOK.md +34 -0
- package/hooks/block-foreground-servers/cases.json +31 -0
- package/hooks/block-foreground-servers/hook.js +41 -0
- package/hooks/block-no-verify/HOOK.md +25 -0
- package/hooks/block-no-verify/cases.json +30 -0
- package/hooks/block-no-verify/hook.js +43 -0
- package/hooks/capture-lessons/HOOK.md +24 -0
- package/hooks/capture-lessons/hook.js +48 -0
- package/hooks/format-on-edit/HOOK.md +24 -0
- package/hooks/format-on-edit/hook.js +89 -0
- package/hooks/guard-secrets/HOOK.md +19 -0
- package/hooks/guard-secrets/cases.json +110 -0
- package/hooks/guard-secrets/hook.js +44 -0
- package/hooks/load-session-context/HOOK.md +20 -0
- package/hooks/load-session-context/hook.js +56 -0
- package/hooks/notify-on-stop/HOOK.md +25 -0
- package/hooks/notify-on-stop/hook.js +27 -0
- package/hooks/protect-files/HOOK.md +24 -0
- package/hooks/protect-files/cases.json +27 -0
- package/hooks/protect-files/hook.js +39 -0
- package/hooks/protect-lint-config/HOOK.md +29 -0
- package/hooks/protect-lint-config/cases.json +18 -0
- package/hooks/protect-lint-config/fixtures/.eslintrc.json +1 -0
- package/hooks/protect-lint-config/fixtures/.golangci.yml +1 -0
- package/hooks/protect-lint-config/fixtures/.prettierrc +1 -0
- package/hooks/protect-lint-config/fixtures/.rubocop.yml +1 -0
- package/hooks/protect-lint-config/fixtures/biome.json +1 -0
- package/hooks/protect-lint-config/fixtures/eslint.config.mjs +1 -0
- package/hooks/protect-lint-config/fixtures/ruff.toml +1 -0
- package/hooks/protect-lint-config/hook.js +25 -0
- package/hooks/read-before-edit/HOOK.md +26 -0
- package/hooks/read-before-edit/cases.json +15 -0
- package/hooks/read-before-edit/hook.js +50 -0
- package/hooks/run.js +148 -0
- package/hooks/verify-before-stop/HOOK.md +32 -0
- package/hooks/verify-before-stop/hook.js +70 -0
- package/mcp/atlassian.json +11 -0
- package/mcp/chrome-devtools.json +18 -0
- package/mcp/clickhouse.json +11 -0
- package/mcp/cloudflare.json +11 -0
- package/mcp/context7.json +11 -0
- package/mcp/exa.json +11 -0
- package/mcp/fetch.json +17 -0
- package/mcp/figma.json +11 -0
- package/mcp/firecrawl.json +11 -0
- package/mcp/git.json +17 -0
- package/mcp/github.json +11 -0
- package/mcp/linear.json +11 -0
- package/mcp/memory.json +18 -0
- package/mcp/notion.json +11 -0
- package/mcp/playwright.json +18 -0
- package/mcp/sentry.json +11 -0
- package/mcp/stripe.json +11 -0
- package/mcp/supabase.json +11 -0
- package/mcp/time.json +17 -0
- package/mcp/vercel.json +11 -0
- package/package.json +61 -4
- package/profiles.json +214 -0
- package/rules/common.md +21 -0
- package/rules/cpp.md +29 -0
- package/rules/csharp.md +25 -0
- package/rules/dart.md +29 -0
- package/rules/fsharp.md +28 -0
- package/rules/git.md +26 -0
- package/rules/go.md +29 -0
- package/rules/java.md +29 -0
- package/rules/kotlin.md +27 -0
- package/rules/perl.md +26 -0
- package/rules/php.md +28 -0
- package/rules/python.md +30 -0
- package/rules/ruby.md +27 -0
- package/rules/rust.md +26 -0
- package/rules/security.md +29 -0
- package/rules/swift.md +28 -0
- package/rules/testing.md +25 -0
- package/rules/typescript.md +29 -0
- package/rules/use-skills.md +23 -0
- package/schemas/skill-frontmatter.schema.json +52 -0
- package/scripts/lib/audit.js +96 -0
- package/scripts/lib/behavior.js +52 -0
- package/scripts/lib/frontmatter.js +65 -0
- package/scripts/lib/hooks-install.js +294 -0
- package/scripts/lib/i18n.js +51 -0
- package/scripts/lib/inventory.js +85 -0
- package/scripts/lib/lint.js +180 -0
- package/scripts/lib/mcp-install.js +288 -0
- package/scripts/lib/profiles.js +128 -0
- package/scripts/lib/render.js +92 -0
- package/scripts/lib/rules-install.js +118 -0
- package/scripts/lib/skills.js +87 -0
- package/scripts/lib/targets.js +123 -0
- package/skills/accounting-api-integration/SKILL.md +81 -0
- package/skills/accounting-api-integration/evals/triggers.json +17 -0
- package/skills/accounting-api-integration/references/quickbooks.md +48 -0
- package/skills/accounting-api-integration/references/xero.md +45 -0
- package/skills/agent-failure-debugging/SKILL.md +92 -0
- package/skills/agent-failure-debugging/evals/triggers.json +16 -0
- package/skills/agent-harness-design/SKILL.md +125 -0
- package/skills/agent-harness-design/evals/triggers.json +21 -0
- package/skills/agent-outbound-messaging/SKILL.md +92 -0
- package/skills/agent-outbound-messaging/evals/triggers.json +16 -0
- package/skills/agent-security/SKILL.md +117 -0
- package/skills/agent-security/evals/triggers.json +16 -0
- package/skills/agent-security/references/host-configs.md +37 -0
- package/skills/ai-media-generation/SKILL.md +89 -0
- package/skills/ai-media-generation/evals/triggers.json +16 -0
- package/skills/ai-media-generation/references/job-pipeline.md +76 -0
- package/skills/angular-patterns/SKILL.md +122 -0
- package/skills/angular-patterns/evals/triggers.json +16 -0
- package/skills/api-client-integration/SKILL.md +86 -0
- package/skills/api-client-integration/evals/triggers.json +16 -0
- package/skills/api-client-integration/references/resilience.md +57 -0
- package/skills/api-design/SKILL.md +96 -0
- package/skills/api-design/evals/triggers.json +18 -0
- package/skills/api-design/references/conventions.md +133 -0
- package/skills/architecture-decision-records/SKILL.md +98 -0
- package/skills/architecture-decision-records/evals/triggers.json +17 -0
- package/skills/article-writing/SKILL.md +108 -0
- package/skills/article-writing/evals/triggers.json +16 -0
- package/skills/aspnet-core-patterns/SKILL.md +149 -0
- package/skills/aspnet-core-patterns/evals/triggers.json +16 -0
- package/skills/auth-patterns/SKILL.md +104 -0
- package/skills/auth-patterns/evals/triggers.json +17 -0
- package/skills/auth-patterns/references/oauth-oidc.md +64 -0
- package/skills/autonomous-loops/SKILL.md +99 -0
- package/skills/autonomous-loops/evals/triggers.json +14 -0
- package/skills/aws-patterns/SKILL.md +91 -0
- package/skills/aws-patterns/evals/triggers.json +16 -0
- package/skills/azure-patterns/SKILL.md +86 -0
- package/skills/azure-patterns/evals/triggers.json +16 -0
- package/skills/benchmark-methodology/SKILL.md +88 -0
- package/skills/benchmark-methodology/evals/triggers.json +16 -0
- package/skills/benchmark-methodology/references/language-harnesses.md +130 -0
- package/skills/bgp-diagnostics/SKILL.md +84 -0
- package/skills/bgp-diagnostics/evals/triggers.json +18 -0
- package/skills/bgp-diagnostics/references/bgp-reference.md +81 -0
- package/skills/bioinformatics-workflows/SKILL.md +108 -0
- package/skills/bioinformatics-workflows/evals/triggers.json +16 -0
- package/skills/bioinformatics-workflows/references/commands.md +71 -0
- package/skills/bioinformatics-workflows/references/formats.md +24 -0
- package/skills/bioinformatics-workflows/references/workflow-managers.md +107 -0
- package/skills/blender-automation/SKILL.md +100 -0
- package/skills/blender-automation/evals/triggers.json +16 -0
- package/skills/blender-automation/references/batch-and-render.md +77 -0
- package/skills/blender-automation/references/bpy-inspection.md +91 -0
- package/skills/blender-automation/references/rig-and-retarget-checks.md +23 -0
- package/skills/brand-strategy/SKILL.md +83 -0
- package/skills/brand-strategy/evals/triggers.json +16 -0
- package/skills/brand-voice/SKILL.md +112 -0
- package/skills/brand-voice/evals/triggers.json +16 -0
- package/skills/browser-qa/SKILL.md +99 -0
- package/skills/browser-qa/evals/triggers.json +16 -0
- package/skills/bun-runtime/SKILL.md +93 -0
- package/skills/bun-runtime/evals/triggers.json +16 -0
- package/skills/change-impact-analysis/SKILL.md +89 -0
- package/skills/change-impact-analysis/evals/triggers.json +16 -0
- package/skills/change-impact-analysis/references/graph-commands.md +28 -0
- package/skills/cisco-ios-config/SKILL.md +101 -0
- package/skills/cisco-ios-config/evals/triggers.json +18 -0
- package/skills/cisco-ios-config/references/verification.md +63 -0
- package/skills/clickhouse-patterns/SKILL.md +101 -0
- package/skills/clickhouse-patterns/evals/triggers.json +18 -0
- package/skills/clickhouse-patterns/references/engines-and-views.md +138 -0
- package/skills/clinical-decision-support/SKILL.md +90 -0
- package/skills/clinical-decision-support/evals/triggers.json +16 -0
- package/skills/clinical-decision-support/references/cds-hooks.md +76 -0
- package/skills/clinical-decision-support/references/regulatory-boundaries.md +37 -0
- package/skills/code-tour/SKILL.md +97 -0
- package/skills/code-tour/evals/triggers.json +14 -0
- package/skills/codebase-onboarding/SKILL.md +112 -0
- package/skills/codebase-onboarding/evals/triggers.json +14 -0
- package/skills/cold-outreach-sequences/SKILL.md +90 -0
- package/skills/cold-outreach-sequences/evals/triggers.json +16 -0
- package/skills/content-repurposing/SKILL.md +82 -0
- package/skills/content-repurposing/evals/triggers.json +16 -0
- package/skills/context-budget/SKILL.md +84 -0
- package/skills/context-budget/evals/triggers.json +14 -0
- package/skills/contract-drafting/SKILL.md +96 -0
- package/skills/contract-drafting/evals/triggers.json +16 -0
- package/skills/contract-drafting/references/term-sheets.md +68 -0
- package/skills/contract-first-development/SKILL.md +86 -0
- package/skills/contract-first-development/evals/triggers.json +16 -0
- package/skills/contract-first-development/references/tooling.md +46 -0
- package/skills/conventional-commits/SKILL.md +144 -0
- package/skills/conventional-commits/evals/triggers.json +16 -0
- package/skills/cpp-patterns/SKILL.md +129 -0
- package/skills/cpp-patterns/evals/triggers.json +16 -0
- package/skills/cpp-patterns/references/cmake-and-tooling.md +88 -0
- package/skills/cpp-patterns/references/undefined-behaviour.md +75 -0
- package/skills/cpp-testing/SKILL.md +131 -0
- package/skills/cpp-testing/evals/triggers.json +16 -0
- package/skills/csharp-patterns/SKILL.md +110 -0
- package/skills/csharp-patterns/evals/triggers.json +17 -0
- package/skills/csharp-patterns/references/analyzers.md +59 -0
- package/skills/csharp-testing/SKILL.md +85 -0
- package/skills/csharp-testing/evals/triggers.json +17 -0
- package/skills/csharp-testing/references/integration-tests.md +77 -0
- package/skills/css-architecture/SKILL.md +143 -0
- package/skills/css-architecture/evals/triggers.json +16 -0
- package/skills/customs-trade-compliance/SKILL.md +95 -0
- package/skills/customs-trade-compliance/evals/triggers.json +16 -0
- package/skills/customs-trade-compliance/references/incoterms-2020.md +42 -0
- package/skills/dart-patterns/SKILL.md +157 -0
- package/skills/dart-patterns/evals/triggers.json +18 -0
- package/skills/dart-testing/SKILL.md +164 -0
- package/skills/dart-testing/evals/triggers.json +18 -0
- package/skills/data-analysis-notebooks/SKILL.md +113 -0
- package/skills/data-analysis-notebooks/evals/triggers.json +16 -0
- package/skills/data-analysis-notebooks/references/dataframe-pitfalls.md +49 -0
- package/skills/data-analysis-notebooks/references/statistics-pitfalls.md +24 -0
- package/skills/data-pipelines/SKILL.md +90 -0
- package/skills/data-pipelines/evals/triggers.json +16 -0
- package/skills/data-pipelines/references/orchestrators.md +64 -0
- package/skills/database-migrations/SKILL.md +102 -0
- package/skills/database-migrations/evals/triggers.json +16 -0
- package/skills/database-migrations/references/recipes.md +98 -0
- package/skills/database-migrations/references/tools.md +21 -0
- package/skills/dbt-patterns/SKILL.md +96 -0
- package/skills/dbt-patterns/evals/triggers.json +16 -0
- package/skills/dbt-patterns/references/yaml-examples.md +114 -0
- package/skills/decision-council/SKILL.md +98 -0
- package/skills/decision-council/evals/triggers.json +16 -0
- package/skills/deep-research/SKILL.md +107 -0
- package/skills/deep-research/evals/triggers.json +14 -0
- package/skills/dependency-audit/SKILL.md +103 -0
- package/skills/dependency-audit/evals/triggers.json +16 -0
- package/skills/dependency-audit/references/tools.md +124 -0
- package/skills/deployment-strategies/SKILL.md +108 -0
- package/skills/deployment-strategies/evals/triggers.json +16 -0
- package/skills/design-brainstorming/SKILL.md +132 -0
- package/skills/design-brainstorming/evals/behavior.json +55 -0
- package/skills/design-brainstorming/evals/triggers.json +16 -0
- package/skills/design-brainstorming/references/visual-mockups.md +34 -0
- package/skills/desktop-app-testing/SKILL.md +104 -0
- package/skills/desktop-app-testing/evals/triggers.json +16 -0
- package/skills/desktop-app-testing/references/drivers.md +81 -0
- package/skills/django-patterns/SKILL.md +123 -0
- package/skills/django-patterns/evals/triggers.json +16 -0
- package/skills/docker-patterns/SKILL.md +132 -0
- package/skills/docker-patterns/evals/triggers.json +16 -0
- package/skills/docker-patterns/references/dockerfiles.md +105 -0
- package/skills/document-processing/SKILL.md +100 -0
- package/skills/document-processing/evals/triggers.json +17 -0
- package/skills/document-processing/references/extraction-and-ocr.md +71 -0
- package/skills/document-processing/references/forms-and-conversion.md +69 -0
- package/skills/document-processing/references/redaction.md +61 -0
- package/skills/e2e-testing-playwright/SKILL.md +94 -0
- package/skills/e2e-testing-playwright/evals/triggers.json +16 -0
- package/skills/e2e-testing-playwright/references/config-and-ci.md +129 -0
- package/skills/ef-core-patterns/SKILL.md +117 -0
- package/skills/ef-core-patterns/evals/triggers.json +16 -0
- package/skills/email-deliverability/SKILL.md +99 -0
- package/skills/email-deliverability/evals/triggers.json +17 -0
- package/skills/email-deliverability/references/dns-records.md +85 -0
- package/skills/energy-procurement/SKILL.md +106 -0
- package/skills/energy-procurement/evals/triggers.json +16 -0
- package/skills/error-handling-patterns/SKILL.md +112 -0
- package/skills/error-handling-patterns/evals/triggers.json +18 -0
- package/skills/error-handling-patterns/references/language-idioms.md +49 -0
- package/skills/estimation-and-scoping/SKILL.md +97 -0
- package/skills/estimation-and-scoping/evals/triggers.json +14 -0
- package/skills/evm-dapp-integration/SKILL.md +73 -0
- package/skills/evm-dapp-integration/evals/triggers.json +16 -0
- package/skills/fastapi-patterns/SKILL.md +127 -0
- package/skills/fastapi-patterns/evals/triggers.json +16 -0
- package/skills/ffmpeg-media-processing/SKILL.md +94 -0
- package/skills/ffmpeg-media-processing/evals/triggers.json +16 -0
- package/skills/ffmpeg-media-processing/references/recipes.md +112 -0
- package/skills/fhir-integration/SKILL.md +81 -0
- package/skills/fhir-integration/evals/triggers.json +16 -0
- package/skills/fhir-integration/references/search-and-bundles.md +73 -0
- package/skills/fhir-integration/references/smart-on-fhir.md +50 -0
- package/skills/finishing-a-branch/SKILL.md +127 -0
- package/skills/finishing-a-branch/evals/behavior.json +49 -0
- package/skills/finishing-a-branch/evals/triggers.json +16 -0
- package/skills/flask-patterns/SKILL.md +132 -0
- package/skills/flask-patterns/evals/triggers.json +16 -0
- package/skills/flutter-patterns/SKILL.md +99 -0
- package/skills/flutter-patterns/evals/triggers.json +16 -0
- package/skills/flutterwave-integration/SKILL.md +75 -0
- package/skills/flutterwave-integration/evals/triggers.json +16 -0
- package/skills/flutterwave-integration/references/api.md +73 -0
- package/skills/flutterwave-integration/references/webhooks.md +49 -0
- package/skills/freight-carrier-management/SKILL.md +107 -0
- package/skills/freight-carrier-management/evals/triggers.json +16 -0
- package/skills/fsharp-patterns/SKILL.md +133 -0
- package/skills/fsharp-patterns/evals/triggers.json +16 -0
- package/skills/fsharp-testing/SKILL.md +136 -0
- package/skills/fsharp-testing/evals/triggers.json +16 -0
- package/skills/gcp-patterns/SKILL.md +86 -0
- package/skills/gcp-patterns/evals/triggers.json +16 -0
- package/skills/git-workflow/SKILL.md +114 -0
- package/skills/git-workflow/evals/triggers.json +16 -0
- package/skills/git-worktrees/SKILL.md +130 -0
- package/skills/git-worktrees/evals/behavior.json +56 -0
- package/skills/git-worktrees/evals/triggers.json +16 -0
- package/skills/github-actions-ci/SKILL.md +117 -0
- package/skills/github-actions-ci/evals/triggers.json +16 -0
- package/skills/github-api-automation/SKILL.md +101 -0
- package/skills/github-api-automation/evals/triggers.json +17 -0
- package/skills/go-patterns/SKILL.md +118 -0
- package/skills/go-patterns/evals/triggers.json +17 -0
- package/skills/go-patterns/references/concurrency.md +162 -0
- package/skills/go-testing/SKILL.md +154 -0
- package/skills/go-testing/evals/triggers.json +17 -0
- package/skills/google-workspace-integration/SKILL.md +65 -0
- package/skills/google-workspace-integration/evals/triggers.json +17 -0
- package/skills/google-workspace-integration/references/api.md +121 -0
- package/skills/harmonyos-arkts/SKILL.md +117 -0
- package/skills/harmonyos-arkts/evals/triggers.json +16 -0
- package/skills/harmonyos-arkts/references/build-errors.md +42 -0
- package/skills/hexagonal-architecture/SKILL.md +89 -0
- package/skills/hexagonal-architecture/evals/triggers.json +17 -0
- package/skills/hipaa-compliance/SKILL.md +91 -0
- package/skills/hipaa-compliance/evals/triggers.json +18 -0
- package/skills/hipaa-compliance/references/safeguards.md +68 -0
- package/skills/hl7v2-integration/SKILL.md +69 -0
- package/skills/hl7v2-integration/evals/triggers.json +16 -0
- package/skills/hl7v2-integration/references/messages-and-ack.md +78 -0
- package/skills/homelab-network-setup/SKILL.md +125 -0
- package/skills/homelab-network-setup/evals/triggers.json +18 -0
- package/skills/homelab-network-setup/references/firewall-and-dns.md +45 -0
- package/skills/homelab-network-setup/references/wireguard.md +72 -0
- package/skills/hubtel-integration/SKILL.md +77 -0
- package/skills/hubtel-integration/evals/triggers.json +16 -0
- package/skills/hubtel-integration/references/api.md +92 -0
- package/skills/i18n-localization/SKILL.md +114 -0
- package/skills/i18n-localization/evals/triggers.json +16 -0
- package/skills/i18n-localization/references/libraries.md +52 -0
- package/skills/implementation-plans/SKILL.md +117 -0
- package/skills/implementation-plans/evals/behavior.json +54 -0
- package/skills/implementation-plans/evals/triggers.json +16 -0
- package/skills/incident-postmortem/SKILL.md +118 -0
- package/skills/incident-postmortem/evals/triggers.json +14 -0
- package/skills/inventory-demand-planning/SKILL.md +89 -0
- package/skills/inventory-demand-planning/evals/triggers.json +16 -0
- package/skills/inventory-demand-planning/references/formulas.md +62 -0
- package/skills/investor-materials/SKILL.md +127 -0
- package/skills/investor-materials/evals/triggers.json +16 -0
- package/skills/investor-materials/references/templates.md +74 -0
- package/skills/invoicing-and-tax/SKILL.md +84 -0
- package/skills/invoicing-and-tax/evals/triggers.json +17 -0
- package/skills/invoicing-and-tax/references/e-invoicing.md +24 -0
- package/skills/invoicing-and-tax/references/invoice-fields.md +38 -0
- package/skills/invoicing-and-tax/references/rounding.md +26 -0
- package/skills/ios-platform-features/SKILL.md +99 -0
- package/skills/ios-platform-features/evals/triggers.json +16 -0
- package/skills/ios-platform-features/references/foundation-models.md +90 -0
- package/skills/java-patterns/SKILL.md +141 -0
- package/skills/java-patterns/evals/triggers.json +17 -0
- package/skills/java-testing/SKILL.md +142 -0
- package/skills/java-testing/evals/triggers.json +16 -0
- package/skills/jetpack-compose-patterns/SKILL.md +88 -0
- package/skills/jetpack-compose-patterns/evals/triggers.json +16 -0
- package/skills/jira-integration/SKILL.md +92 -0
- package/skills/jira-integration/evals/triggers.json +17 -0
- package/skills/jpa-hibernate/SKILL.md +92 -0
- package/skills/jpa-hibernate/evals/triggers.json +18 -0
- package/skills/jpa-hibernate/references/mapping.md +99 -0
- package/skills/jvm-sql-mappers/SKILL.md +98 -0
- package/skills/jvm-sql-mappers/evals/triggers.json +16 -0
- package/skills/jvm-sql-mappers/references/examples.md +129 -0
- package/skills/kotlin-multiplatform/SKILL.md +97 -0
- package/skills/kotlin-multiplatform/evals/triggers.json +16 -0
- package/skills/kotlin-patterns/SKILL.md +128 -0
- package/skills/kotlin-patterns/evals/triggers.json +16 -0
- package/skills/kotlin-testing/SKILL.md +117 -0
- package/skills/kotlin-testing/evals/triggers.json +16 -0
- package/skills/ktor-patterns/SKILL.md +135 -0
- package/skills/ktor-patterns/evals/triggers.json +18 -0
- package/skills/kubernetes-patterns/SKILL.md +106 -0
- package/skills/kubernetes-patterns/evals/triggers.json +16 -0
- package/skills/kubernetes-patterns/references/manifests.md +115 -0
- package/skills/laravel-patterns/SKILL.md +136 -0
- package/skills/laravel-patterns/evals/triggers.json +16 -0
- package/skills/linear-integration/SKILL.md +98 -0
- package/skills/linear-integration/evals/triggers.json +17 -0
- package/skills/literature-review/SKILL.md +109 -0
- package/skills/literature-review/evals/triggers.json +16 -0
- package/skills/literature-review/references/appraisal.md +41 -0
- package/skills/literature-review/references/search-sources.md +39 -0
- package/skills/llm-app-patterns/SKILL.md +97 -0
- package/skills/llm-app-patterns/evals/triggers.json +17 -0
- package/skills/llm-evals/SKILL.md +98 -0
- package/skills/llm-evals/evals/triggers.json +16 -0
- package/skills/llm-evals/references/graders.md +66 -0
- package/skills/logistics-exception-management/SKILL.md +90 -0
- package/skills/logistics-exception-management/evals/triggers.json +16 -0
- package/skills/manim-animations/SKILL.md +106 -0
- package/skills/manim-animations/evals/triggers.json +16 -0
- package/skills/market-research/SKILL.md +117 -0
- package/skills/market-research/evals/triggers.json +16 -0
- package/skills/marketing-campaign/SKILL.md +111 -0
- package/skills/marketing-campaign/evals/triggers.json +16 -0
- package/skills/mcp-server-patterns/SKILL.md +127 -0
- package/skills/mcp-server-patterns/evals/triggers.json +18 -0
- package/skills/mcp-server-patterns/references/protocol-notes.md +68 -0
- package/skills/metrics-dashboards/SKILL.md +113 -0
- package/skills/metrics-dashboards/evals/triggers.json +16 -0
- package/skills/ml-experiment-workflow/SKILL.md +125 -0
- package/skills/ml-experiment-workflow/evals/triggers.json +16 -0
- package/skills/mobile-accessibility/SKILL.md +94 -0
- package/skills/mobile-accessibility/evals/triggers.json +16 -0
- package/skills/mongodb-patterns/SKILL.md +115 -0
- package/skills/mongodb-patterns/evals/triggers.json +18 -0
- package/skills/mongodb-patterns/references/indexes-and-aggregation.md +94 -0
- package/skills/mpesa-daraja-integration/SKILL.md +70 -0
- package/skills/mpesa-daraja-integration/evals/triggers.json +16 -0
- package/skills/mpesa-daraja-integration/references/api.md +103 -0
- package/skills/mpesa-daraja-integration/references/callbacks.md +74 -0
- package/skills/mtn-momo-integration/SKILL.md +66 -0
- package/skills/mtn-momo-integration/evals/triggers.json +16 -0
- package/skills/mtn-momo-integration/references/api.md +153 -0
- package/skills/mtn-momo-integration/references/callbacks.md +92 -0
- package/skills/mtn-momo-integration/references/sandbox-and-go-live.md +51 -0
- package/skills/mtn-momo-integration/scripts/sandbox-setup.js +79 -0
- package/skills/mysql-patterns/SKILL.md +96 -0
- package/skills/mysql-patterns/evals/triggers.json +16 -0
- package/skills/mysql-patterns/references/explain.md +34 -0
- package/skills/mysql-patterns/references/online-ddl.md +41 -0
- package/skills/nestjs-patterns/SKILL.md +114 -0
- package/skills/nestjs-patterns/evals/triggers.json +16 -0
- package/skills/nestjs-patterns/references/testing.md +68 -0
- package/skills/network-automation/SKILL.md +107 -0
- package/skills/network-automation/evals/triggers.json +18 -0
- package/skills/network-automation/references/tool-snippets.md +153 -0
- package/skills/network-design/SKILL.md +98 -0
- package/skills/network-design/evals/triggers.json +16 -0
- package/skills/network-troubleshooting/SKILL.md +152 -0
- package/skills/network-troubleshooting/evals/triggers.json +18 -0
- package/skills/network-troubleshooting/references/commands.md +33 -0
- package/skills/nextjs-patterns/SKILL.md +150 -0
- package/skills/nextjs-patterns/evals/triggers.json +18 -0
- package/skills/nextjs-patterns/references/caching.md +87 -0
- package/skills/node-backend-patterns/SKILL.md +103 -0
- package/skills/node-backend-patterns/evals/triggers.json +16 -0
- package/skills/node-backend-patterns/references/templates.md +122 -0
- package/skills/nuxt-patterns/SKILL.md +103 -0
- package/skills/nuxt-patterns/evals/triggers.json +16 -0
- package/skills/observability/SKILL.md +125 -0
- package/skills/observability/evals/triggers.json +17 -0
- package/skills/observability/references/otel-setup.md +87 -0
- package/skills/observability/references/slo-alerts.md +70 -0
- package/skills/open-source-release/SKILL.md +107 -0
- package/skills/open-source-release/evals/triggers.json +15 -0
- package/skills/open-source-release/references/history-scrub.md +65 -0
- package/skills/parallel-agent-orchestration/SKILL.md +106 -0
- package/skills/parallel-agent-orchestration/evals/triggers.json +14 -0
- package/skills/patent-research/SKILL.md +94 -0
- package/skills/patent-research/evals/triggers.json +16 -0
- package/skills/patent-research/references/databases-and-queries.md +52 -0
- package/skills/paystack-integration/SKILL.md +59 -0
- package/skills/paystack-integration/evals/triggers.json +14 -0
- package/skills/paystack-integration/references/api.md +73 -0
- package/skills/paystack-integration/references/mobile-money.md +50 -0
- package/skills/paystack-integration/references/webhooks.md +80 -0
- package/skills/pci-dss-scope/SKILL.md +103 -0
- package/skills/pci-dss-scope/evals/triggers.json +18 -0
- package/skills/pci-dss-scope/references/saq-and-data.md +36 -0
- package/skills/perl-patterns/SKILL.md +135 -0
- package/skills/perl-patterns/evals/triggers.json +18 -0
- package/skills/perl-testing/SKILL.md +126 -0
- package/skills/perl-testing/evals/triggers.json +17 -0
- package/skills/php-patterns/SKILL.md +116 -0
- package/skills/php-patterns/evals/triggers.json +16 -0
- package/skills/php-testing/SKILL.md +123 -0
- package/skills/php-testing/evals/triggers.json +16 -0
- package/skills/postgres-patterns/SKILL.md +103 -0
- package/skills/postgres-patterns/evals/triggers.json +17 -0
- package/skills/postgres-patterns/references/explain.md +59 -0
- package/skills/postgres-patterns/references/locks.md +53 -0
- package/skills/prd-writing/SKILL.md +124 -0
- package/skills/prd-writing/evals/triggers.json +15 -0
- package/skills/prisma-patterns/SKILL.md +83 -0
- package/skills/prisma-patterns/evals/triggers.json +18 -0
- package/skills/prisma-patterns/references/prisma-8.md +46 -0
- package/skills/prisma-patterns/references/workflow.md +50 -0
- package/skills/privacy-compliance/SKILL.md +121 -0
- package/skills/privacy-compliance/evals/triggers.json +18 -0
- package/skills/privacy-compliance/references/jurisdictions.md +51 -0
- package/skills/production-scheduling/SKILL.md +98 -0
- package/skills/production-scheduling/evals/triggers.json +16 -0
- package/skills/prompt-engineering/SKILL.md +92 -0
- package/skills/prompt-engineering/evals/triggers.json +16 -0
- package/skills/prospect-research/SKILL.md +87 -0
- package/skills/prospect-research/evals/triggers.json +16 -0
- package/skills/python-app-distribution/SKILL.md +107 -0
- package/skills/python-app-distribution/evals/triggers.json +16 -0
- package/skills/python-app-distribution/references/pypi-trusted-publishing.md +55 -0
- package/skills/python-app-distribution/references/windows-macos-signing.md +70 -0
- package/skills/python-patterns/SKILL.md +107 -0
- package/skills/python-patterns/evals/triggers.json +16 -0
- package/skills/python-patterns/references/tooling.md +101 -0
- package/skills/python-testing/SKILL.md +126 -0
- package/skills/python-testing/evals/triggers.json +16 -0
- package/skills/python-testing/references/mocking.md +71 -0
- package/skills/pytorch-patterns/SKILL.md +139 -0
- package/skills/pytorch-patterns/evals/triggers.json +16 -0
- package/skills/pytorch-patterns/references/debugging.md +39 -0
- package/skills/quality-nonconformance/SKILL.md +107 -0
- package/skills/quality-nonconformance/evals/triggers.json +16 -0
- package/skills/quality-nonconformance/references/8d-and-capa.md +46 -0
- package/skills/quarkus-patterns/SKILL.md +93 -0
- package/skills/quarkus-patterns/evals/triggers.json +18 -0
- package/skills/rag-pipeline-patterns/SKILL.md +117 -0
- package/skills/rag-pipeline-patterns/evals/triggers.json +18 -0
- package/skills/rag-pipeline-patterns/references/evaluation.md +37 -0
- package/skills/rag-pipeline-patterns/references/retrieval-recipes.md +78 -0
- package/skills/rails-patterns/SKILL.md +132 -0
- package/skills/rails-patterns/evals/triggers.json +16 -0
- package/skills/react-native-patterns/SKILL.md +101 -0
- package/skills/react-native-patterns/evals/triggers.json +16 -0
- package/skills/react-patterns/SKILL.md +140 -0
- package/skills/react-patterns/evals/triggers.json +18 -0
- package/skills/react-performance/SKILL.md +107 -0
- package/skills/react-performance/evals/triggers.json +18 -0
- package/skills/react-testing/SKILL.md +121 -0
- package/skills/react-testing/evals/triggers.json +18 -0
- package/skills/react-testing/references/msw.md +64 -0
- package/skills/react-testing/references/queries.md +41 -0
- package/skills/react-testing/references/setup.md +74 -0
- package/skills/recommender-systems/SKILL.md +119 -0
- package/skills/recommender-systems/evals/triggers.json +16 -0
- package/skills/recommender-systems/references/evaluation.md +39 -0
- package/skills/redis-patterns/SKILL.md +109 -0
- package/skills/redis-patterns/evals/triggers.json +18 -0
- package/skills/redis-patterns/references/operations.md +61 -0
- package/skills/refactoring-safely/SKILL.md +107 -0
- package/skills/refactoring-safely/evals/behavior.json +57 -0
- package/skills/refactoring-safely/evals/triggers.json +17 -0
- package/skills/release-management/SKILL.md +141 -0
- package/skills/release-management/evals/triggers.json +16 -0
- package/skills/remotion-video/SKILL.md +91 -0
- package/skills/remotion-video/evals/triggers.json +16 -0
- package/skills/remotion-video/references/lambda.md +66 -0
- package/skills/reproducible-dev-environments/SKILL.md +132 -0
- package/skills/reproducible-dev-environments/evals/triggers.json +16 -0
- package/skills/responding-to-code-review/SKILL.md +124 -0
- package/skills/responding-to-code-review/evals/behavior.json +54 -0
- package/skills/responding-to-code-review/evals/triggers.json +16 -0
- package/skills/returns-reverse-logistics/SKILL.md +97 -0
- package/skills/returns-reverse-logistics/evals/triggers.json +16 -0
- package/skills/ruby-patterns/SKILL.md +127 -0
- package/skills/ruby-patterns/evals/triggers.json +18 -0
- package/skills/ruby-testing/SKILL.md +113 -0
- package/skills/ruby-testing/evals/triggers.json +18 -0
- package/skills/runbook-writing/SKILL.md +101 -0
- package/skills/runbook-writing/evals/triggers.json +14 -0
- package/skills/rust-patterns/SKILL.md +118 -0
- package/skills/rust-patterns/evals/triggers.json +16 -0
- package/skills/rust-patterns/references/cargo-and-clippy.md +105 -0
- package/skills/rust-patterns/references/errors-and-traits.md +97 -0
- package/skills/rust-testing/SKILL.md +148 -0
- package/skills/rust-testing/evals/triggers.json +16 -0
- package/skills/rust-testing/references/fakes-proptest-async.md +113 -0
- package/skills/search-first/SKILL.md +73 -0
- package/skills/search-first/evals/triggers.json +14 -0
- package/skills/security-review/SKILL.md +58 -0
- package/skills/security-review/evals/behavior.json +56 -0
- package/skills/security-review/evals/triggers.json +14 -0
- package/skills/security-review/references/checklist.md +54 -0
- package/skills/security-review/scripts/scan-secrets.js +79 -0
- package/skills/seo-audit/SKILL.md +111 -0
- package/skills/seo-audit/evals/triggers.json +16 -0
- package/skills/seo-audit/references/checks.md +65 -0
- package/skills/session-handoff/SKILL.md +101 -0
- package/skills/session-handoff/evals/behavior.json +55 -0
- package/skills/session-handoff/evals/triggers.json +14 -0
- package/skills/skill-authoring/SKILL.md +98 -0
- package/skills/skill-authoring/evals/triggers.json +15 -0
- package/skills/skill-authoring/references/frontmatter.md +40 -0
- package/skills/skill-authoring/references/pressure-testing.md +87 -0
- package/skills/slack-app-integration/SKILL.md +108 -0
- package/skills/slack-app-integration/evals/triggers.json +17 -0
- package/skills/slide-decks/SKILL.md +107 -0
- package/skills/slide-decks/evals/triggers.json +18 -0
- package/skills/slide-decks/references/html-decks.md +86 -0
- package/skills/slide-decks/references/layouts.md +45 -0
- package/skills/slide-decks/references/pptx.md +87 -0
- package/skills/smart-contract-security/SKILL.md +110 -0
- package/skills/smart-contract-security/evals/triggers.json +16 -0
- package/skills/smart-contract-security/references/vulnerability-checklist.md +79 -0
- package/skills/social-media-publishing/SKILL.md +84 -0
- package/skills/social-media-publishing/evals/triggers.json +17 -0
- package/skills/social-media-publishing/references/platform-apis.md +116 -0
- package/skills/solidity-patterns/SKILL.md +95 -0
- package/skills/solidity-patterns/evals/triggers.json +16 -0
- package/skills/spring-boot-patterns/SKILL.md +128 -0
- package/skills/spring-boot-patterns/evals/triggers.json +18 -0
- package/skills/spring-boot-patterns/references/testing.md +72 -0
- package/skills/stripe-integration/SKILL.md +69 -0
- package/skills/stripe-integration/evals/triggers.json +16 -0
- package/skills/stripe-integration/references/api.md +71 -0
- package/skills/stripe-integration/references/billing.md +58 -0
- package/skills/stripe-integration/references/webhooks.md +76 -0
- package/skills/subagent-driven-development/SKILL.md +109 -0
- package/skills/subagent-driven-development/evals/behavior.json +53 -0
- package/skills/subagent-driven-development/evals/triggers.json +15 -0
- package/skills/subagent-driven-development/references/implementer-brief.md +60 -0
- package/skills/subagent-driven-development/references/reviewer-briefs.md +52 -0
- package/skills/subscription-billing-ops/SKILL.md +118 -0
- package/skills/subscription-billing-ops/evals/triggers.json +17 -0
- package/skills/subscription-billing-ops/references/proration.md +47 -0
- package/skills/subscription-billing-ops/references/revenue-metrics.md +38 -0
- package/skills/svelte-patterns/SKILL.md +122 -0
- package/skills/svelte-patterns/evals/triggers.json +16 -0
- package/skills/swift-patterns/SKILL.md +113 -0
- package/skills/swift-patterns/evals/triggers.json +16 -0
- package/skills/swift-patterns/references/concurrency-migration.md +40 -0
- package/skills/swift-testing/SKILL.md +121 -0
- package/skills/swift-testing/evals/triggers.json +16 -0
- package/skills/swift-testing/references/swift-testing-cheatsheet.md +81 -0
- package/skills/swiftui-patterns/SKILL.md +102 -0
- package/skills/swiftui-patterns/evals/triggers.json +16 -0
- package/skills/systematic-debugging/SKILL.md +92 -0
- package/skills/systematic-debugging/evals/behavior.json +59 -0
- package/skills/systematic-debugging/evals/triggers.json +16 -0
- package/skills/systematic-debugging/references/condition-waiting.md +52 -0
- package/skills/systematic-debugging/references/root-cause-tracing.md +49 -0
- package/skills/systematic-debugging/references/test-pollution.md +46 -0
- package/skills/tdd-workflow/SKILL.md +69 -0
- package/skills/tdd-workflow/evals/behavior.json +55 -0
- package/skills/tdd-workflow/evals/triggers.json +15 -0
- package/skills/tdd-workflow/references/testing-anti-patterns.md +87 -0
- package/skills/technical-writing/SKILL.md +95 -0
- package/skills/technical-writing/evals/triggers.json +14 -0
- package/skills/terraform-patterns/SKILL.md +122 -0
- package/skills/terraform-patterns/evals/triggers.json +16 -0
- package/skills/terraform-patterns/references/backends.md +67 -0
- package/skills/test-coverage-improvement/SKILL.md +107 -0
- package/skills/test-coverage-improvement/evals/triggers.json +16 -0
- package/skills/threat-modeling/SKILL.md +113 -0
- package/skills/threat-modeling/evals/triggers.json +16 -0
- package/skills/transactional-email/SKILL.md +68 -0
- package/skills/transactional-email/evals/triggers.json +17 -0
- package/skills/transactional-email/references/providers.md +63 -0
- package/skills/typescript-patterns/SKILL.md +122 -0
- package/skills/typescript-patterns/evals/triggers.json +16 -0
- package/skills/typescript-testing/SKILL.md +101 -0
- package/skills/typescript-testing/evals/triggers.json +16 -0
- package/skills/ui-demo-recording/SKILL.md +93 -0
- package/skills/ui-demo-recording/evals/triggers.json +16 -0
- package/skills/ui-demo-recording/references/cursor-and-captions.md +48 -0
- package/skills/ui-demo-recording/references/playwright-recording.md +63 -0
- package/skills/ui-demo-recording/references/post-processing.md +57 -0
- package/skills/ui-design-polish/SKILL.md +113 -0
- package/skills/ui-design-polish/evals/triggers.json +18 -0
- package/skills/ui-design-polish/references/detail-checklist.md +45 -0
- package/skills/ui-design-polish/references/tokens.md +68 -0
- package/skills/ui-flow-audit/SKILL.md +112 -0
- package/skills/ui-flow-audit/evals/triggers.json +17 -0
- package/skills/ui-motion/SKILL.md +103 -0
- package/skills/ui-motion/evals/triggers.json +18 -0
- package/skills/ui-motion/references/patterns.md +138 -0
- package/skills/ui-motion/references/tokens.md +52 -0
- package/skills/unicode-text-processing/SKILL.md +103 -0
- package/skills/unicode-text-processing/evals/triggers.json +17 -0
- package/skills/unicode-text-processing/references/apis.md +89 -0
- package/skills/unicode-text-processing/references/script-notes.md +50 -0
- package/skills/verification-loop/SKILL.md +70 -0
- package/skills/verification-loop/evals/behavior.json +52 -0
- package/skills/verification-loop/evals/triggers.json +14 -0
- package/skills/verification-loop/scripts/detect-checks.js +102 -0
- package/skills/video-editing/SKILL.md +111 -0
- package/skills/video-editing/evals/triggers.json +16 -0
- package/skills/video-editing/references/edl-and-logging.md +44 -0
- package/skills/video-editing/references/ffmpeg-edit-recipes.md +92 -0
- package/skills/video-editing/references/resolve-scripting.md +53 -0
- package/skills/vite-patterns/SKILL.md +117 -0
- package/skills/vite-patterns/evals/triggers.json +16 -0
- package/skills/vue-patterns/SKILL.md +104 -0
- package/skills/vue-patterns/evals/triggers.json +16 -0
- package/skills/web-accessibility/SKILL.md +119 -0
- package/skills/web-accessibility/evals/triggers.json +16 -0
- package/skills/web-performance/SKILL.md +107 -0
- package/skills/web-performance/evals/triggers.json +16 -0
- package/skills/web-scraping/SKILL.md +80 -0
- package/skills/web-scraping/evals/triggers.json +16 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dart-testing
|
|
3
|
+
description: Writes deterministic Dart and Flutter tests with package:test and flutter_test, fakes collaborators with mocktail, asserts on Futures and Streams with expectLater and stream matchers, controls time with fake_async, and sets up basic golden image tests. Use when adding or fixing unit, widget or golden tests in a Dart or Flutter project, mocking a repository or HTTP client with mocktail, or chasing a flaky async test that hangs, times out or passes only sometimes.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Needs the Dart SDK (dart test) or Flutter (flutter test). mocktail and fake_async are pub packages added as dev dependencies.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: testing
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/requires: "dart"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Dart testing
|
|
15
|
+
|
|
16
|
+
Tests that run fast, never touch the network, and fail for one reason. Use `dart test` for pure Dart packages and `flutter test` for anything importing Flutter. Integration tests on a device (`integration_test`) and browser E2E are out of scope here.
|
|
17
|
+
|
|
18
|
+
## 0. Before you write
|
|
19
|
+
|
|
20
|
+
1. Check `dev_dependencies` in `pubspec.yaml`: `test` (pure Dart) or `flutter_test` (Flutter, from the SDK), plus `mocktail` if present. If the project uses `mockito` instead, follow it; don't add a second mocking library.
|
|
21
|
+
2. Run the existing suite once (`dart test` or `flutter test`) and note failures that were already there.
|
|
22
|
+
3. Mirror the source layout: `lib/src/cart.dart` is tested in `test/src/cart_test.dart`. Files must end in `_test.dart` to be picked up.
|
|
23
|
+
|
|
24
|
+
## 1. Test shape
|
|
25
|
+
|
|
26
|
+
```dart
|
|
27
|
+
import 'package:test/test.dart'; // Flutter: package:flutter_test/flutter_test.dart
|
|
28
|
+
|
|
29
|
+
void main() {
|
|
30
|
+
group('Cart.total', () {
|
|
31
|
+
late Cart cart;
|
|
32
|
+
setUp(() => cart = Cart());
|
|
33
|
+
|
|
34
|
+
test('is zero when empty', () {
|
|
35
|
+
expect(cart.total, Money.zero);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('throws on negative quantity', () {
|
|
39
|
+
expect(() => cart.add(item, quantity: -1), throwsA(isA<ArgumentError>()));
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- One behaviour per `test`; name it as a sentence a reader understands in the failure log.
|
|
46
|
+
- Build fresh state in `setUp`; register cleanup with `addTearDown(...)` right where the resource is created.
|
|
47
|
+
- Prefer specific matchers (`equals`, `isA<T>().having((e) => e.code, 'code', 404)`, `containsAll`, `closeTo`) over `isTrue` on a hand-built boolean, so failures print useful values.
|
|
48
|
+
- Run one test while iterating: `dart test test/src/cart_test.dart --name "is zero"`.
|
|
49
|
+
|
|
50
|
+
## 2. Mocking with mocktail
|
|
51
|
+
|
|
52
|
+
```dart
|
|
53
|
+
class MockUserApi extends Mock implements UserApi {}
|
|
54
|
+
class FakeUri extends Fake implements Uri {}
|
|
55
|
+
|
|
56
|
+
setUpAll(() => registerFallbackValue(FakeUri()));
|
|
57
|
+
|
|
58
|
+
test('maps 404 to UserNotFound', () async {
|
|
59
|
+
final api = MockUserApi();
|
|
60
|
+
when(() => api.fetch(any())).thenThrow(const HttpFailure(404));
|
|
61
|
+
final repo = UserRepository(api);
|
|
62
|
+
|
|
63
|
+
await expectLater(repo.load('42'), throwsA(isA<UserNotFound>()));
|
|
64
|
+
verify(() => api.fetch(any())).called(1);
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- Stub Future- and Stream-returning methods with `thenAnswer((_) async => value)` / `thenAnswer((_) => Stream.value(x))`, not `thenReturn`.
|
|
69
|
+
- An unstubbed method that returns a non-nullable type throws at call time; stub every call the code under test makes.
|
|
70
|
+
- `any()` with a custom type needs `registerFallbackValue` once, usually in `setUpAll`. Named arguments use `any(named: 'id')`.
|
|
71
|
+
- `verifyNever(...)` for calls that must not happen; `captureAny()` with `verify(...).captured` to inspect arguments.
|
|
72
|
+
- Mock only boundaries (HTTP, database, platform channels, clock). Never mock the class under test or simple value types; use real instances or a hand-written `Fake`.
|
|
73
|
+
|
|
74
|
+
## 3. Async code
|
|
75
|
+
|
|
76
|
+
- Make the test body `async` and `await` the call. A test that returns before its future completes passes without checking anything.
|
|
77
|
+
- Assert on a future with `await expectLater(future, completion(equals(x)))` or `throwsA(...)`. Use `expectLater`, not `expect`, when the matcher is asynchronous.
|
|
78
|
+
- Never use real `Future.delayed` or sleeps to wait for something. Inject the delay or use `fake_async` (section 5).
|
|
79
|
+
- The default per-test timeout is 30 seconds; a hang usually means an un-completed `Completer`, an un-closed stream, or a missing stub. Fix the cause instead of raising `timeout:`.
|
|
80
|
+
|
|
81
|
+
## 4. Streams
|
|
82
|
+
|
|
83
|
+
```dart
|
|
84
|
+
test('emits loading then data then closes', () async {
|
|
85
|
+
final states = bloc.states; // the Stream under test
|
|
86
|
+
final check = expectLater(states, emitsInOrder([isA<Loading>(), isA<Loaded>(), emitsDone]));
|
|
87
|
+
bloc.load();
|
|
88
|
+
await check;
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- Start `expectLater` before triggering the events, then await it, so no event is missed on a broadcast stream.
|
|
93
|
+
- Matchers: `emits(x)`, `emitsInOrder([...])`, `emitsThrough(x)`, `emitsError(isA<E>())`, `mayEmit(x)`, `neverEmits(x)`, `emitsDone`.
|
|
94
|
+
- Collect a finite stream with `await stream.toList()` when order and count are all that matter.
|
|
95
|
+
- Close controllers in `addTearDown(controller.close)` so a failing test does not leak listeners into the next one.
|
|
96
|
+
|
|
97
|
+
## 5. Time with fake_async
|
|
98
|
+
|
|
99
|
+
Add `fake_async` as a dev dependency. It controls `dart:async` time: `Timer`, `Future.delayed`, `Stream.periodic` and microtasks. It cannot control `DateTime.now()` or `Stopwatch`, because they are not part of `dart:async`.
|
|
100
|
+
|
|
101
|
+
```dart
|
|
102
|
+
test('retries after 2 seconds', () {
|
|
103
|
+
fakeAsync((async) {
|
|
104
|
+
final client = RetryingClient(api);
|
|
105
|
+
client.send(request);
|
|
106
|
+
async.elapse(const Duration(seconds: 2));
|
|
107
|
+
verify(() => api.post(any())).called(2);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- The callback is synchronous; don't `await` inside it. Use `async.flushMicrotasks()` to run pending futures and `async.elapse(d)` to advance timers.
|
|
113
|
+
- When logic reads the current time, have it use `clock.now()` / `clock.stopwatch()` from `package:clock`; `fakeAsync` overrides those automatically, so they follow `elapse`.
|
|
114
|
+
- In widget tests, time is already fake: use `tester.pump(duration)` instead of `fakeAsync`.
|
|
115
|
+
|
|
116
|
+
## 6. Widget tests (flutter_test)
|
|
117
|
+
|
|
118
|
+
```dart
|
|
119
|
+
testWidgets('shows error text when login fails', (tester) async {
|
|
120
|
+
when(() => auth.login(any(), any())).thenThrow(const AuthFailure());
|
|
121
|
+
await tester.pumpWidget(MaterialApp(home: LoginPage(auth: auth)));
|
|
122
|
+
|
|
123
|
+
await tester.enterText(find.byKey(const Key('email')), 'a@b.co');
|
|
124
|
+
await tester.tap(find.text('Sign in'));
|
|
125
|
+
await tester.pumpAndSettle();
|
|
126
|
+
|
|
127
|
+
expect(find.text('Invalid credentials'), findsOneWidget);
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- Wrap the widget in the minimum ancestors it needs (`MaterialApp`, providers, `MediaQuery`) and inject fakes through constructors or the project's DI.
|
|
132
|
+
- `pump()` renders one frame; `pumpAndSettle()` runs until no frames are scheduled and times out on endless animations (spinners). Use `pump(duration)` for those.
|
|
133
|
+
- Real I/O (files, sockets) does not complete inside the fake zone; wrap it in `await tester.runAsync(() async {...})` or, better, fake it.
|
|
134
|
+
- Find by `Key`, text or semantics label; avoid finding by widget index.
|
|
135
|
+
|
|
136
|
+
## 7. Golden tests (basics)
|
|
137
|
+
|
|
138
|
+
```dart
|
|
139
|
+
testWidgets('price tag golden', (tester) async {
|
|
140
|
+
await tester.pumpWidget(const MaterialApp(home: PriceTag(amount: 1250)));
|
|
141
|
+
await expectLater(find.byType(PriceTag), matchesGoldenFile('goldens/price_tag.png'));
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- Create or update reference images with `flutter test --update-goldens`, look at the PNGs, and commit them. Never update goldens just to make a red test green without checking the diff images written to a `failures/` folder next to the test file (the failure message prints the path).
|
|
146
|
+
- Goldens differ across operating systems and font setups. Generate and compare them on one platform (usually CI's), and tag them (`@Tags(['golden'])`) so they can run separately.
|
|
147
|
+
- Set a fixed surface size (`tester.view.physicalSize` and `devicePixelRatio`, reset in `addTearDown`) so output does not depend on the host.
|
|
148
|
+
- If the project uses a golden helper package, follow it; don't add one unasked.
|
|
149
|
+
|
|
150
|
+
## Stop and ask the user
|
|
151
|
+
|
|
152
|
+
- The code under test reads globals, singletons or `DateTime.now()` directly and can't be tested without refactoring production code.
|
|
153
|
+
- Fixing a failing test would mean changing the expected behaviour rather than the code.
|
|
154
|
+
- Goldens would need regenerating across many files.
|
|
155
|
+
|
|
156
|
+
## Never do
|
|
157
|
+
|
|
158
|
+
- Hit the real network, real databases or real platform channels in unit or widget tests.
|
|
159
|
+
- Skip (`skip:`) or delete a failing test to get green, or raise timeouts to hide a hang.
|
|
160
|
+
- Use `sleep` or real delays to wait for async work.
|
|
161
|
+
|
|
162
|
+
## Report back
|
|
163
|
+
|
|
164
|
+
Tests added or changed (file and test names), the command run (`dart test ...` / `flutter test ...`) with pass/fail counts, and any behaviour left untested and why.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Write mocktail tests for my Dart UserRepository that wraps an http client",
|
|
4
|
+
"How do I test that this Dart stream emits loading, then data, then closes?",
|
|
5
|
+
"My flutter widget test times out on pumpAndSettle, how do I fix it?",
|
|
6
|
+
"Add a golden test for the PriceTag widget in our Flutter app",
|
|
7
|
+
"Test this retry logic with a 2 second delay in Dart without actually waiting",
|
|
8
|
+
"mocktail says I need registerFallbackValue for my custom type, what does that mean"
|
|
9
|
+
],
|
|
10
|
+
"should_not_trigger": [
|
|
11
|
+
"Convert this Dart enum and switch into a sealed class hierarchy",
|
|
12
|
+
"Review my Flutter screen for stream subscription leaks and unawaited futures",
|
|
13
|
+
"dart run build_runner build fails with conflicting outputs, fix it",
|
|
14
|
+
"Write pytest fixtures for my FastAPI service",
|
|
15
|
+
"Set up Playwright end-to-end tests for our web checkout",
|
|
16
|
+
"Write Swift Testing tests with #expect for my iOS view model"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: data-analysis-notebooks
|
|
3
|
+
description: Keeps Jupyter and other notebook analyses reproducible from a clean kernel, with a set project layout, a pinned environment, raw data treated as read-only, pandas and polars code free of chained assignment and silent dtype or join errors, honest plots, and statistics that avoid p-hacking, multiple-comparison and leakage traps, then moves code that has settled into tested modules. Use when starting or cleaning up an exploratory analysis notebook, when a notebook gives different results on rerun, when reviewing the statistics or charts in an analysis, or when turning notebook code into a script or package others can run.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Examples use Python with Jupyter, pandas or polars, and matplotlib; the rules carry over to R Markdown, Quarto and other notebook tools.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: data
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Data analysis notebooks
|
|
14
|
+
|
|
15
|
+
A notebook is finished when someone else can run it top to bottom on a fresh kernel and get the same numbers and figures.
|
|
16
|
+
|
|
17
|
+
## 0. Assess first
|
|
18
|
+
|
|
19
|
+
1. Restart the kernel and run all cells (`jupyter nbconvert --to notebook --execute analysis.ipynb --output /tmp/check.ipynb`). Record which cell fails or which numbers change. This is the baseline.
|
|
20
|
+
2. Find the environment file (`pyproject.toml` with a lock file, `requirements.txt`, `environment.yml`). If none exists, create one before changing code.
|
|
21
|
+
3. Find where the data comes from. If it is a file only on someone's laptop or a query with no saved text, stop and ask the user how to get it reproducibly.
|
|
22
|
+
|
|
23
|
+
## 1. Project layout
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
project/
|
|
27
|
+
├── data/raw/ # read-only originals, never edited, usually git-ignored
|
|
28
|
+
├── data/processed/ # produced by code, safe to delete and regenerate
|
|
29
|
+
├── notebooks/ # numbered: 01-explore.ipynb, 02-model.ipynb
|
|
30
|
+
├── src/<package>/ # functions that notebooks import
|
|
31
|
+
├── tests/
|
|
32
|
+
├── reports/figures/
|
|
33
|
+
└── pyproject.toml + lock file (or environment.yml)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- Paths are relative to the project root (`pathlib.Path`), never `/Users/me/Downloads/...`.
|
|
37
|
+
- Secrets and connection strings come from environment variables, never cells.
|
|
38
|
+
- Commit notebooks with outputs stripped (`nbstripout --install`) or pair each with a text copy (`jupytext --set-formats ipynb,py:percent`) so diffs are reviewable.
|
|
39
|
+
|
|
40
|
+
## 2. Pin the environment
|
|
41
|
+
|
|
42
|
+
- Use one tool consistently: `uv` (`uv add pandas`, commit `uv.lock`), `pip-tools`, `poetry`, or `conda` with an exported `environment.yml`.
|
|
43
|
+
- Pin exact versions of the analysis libraries. pandas 3.0 changed defaults (Copy-on-Write always on, a new `str` dtype for text columns, microsecond datetime resolution), so results can differ between pandas 2.x and 3.x.
|
|
44
|
+
- Register the kernel from that environment (`python -m ipykernel install --user --name <project>`), and record the Python version.
|
|
45
|
+
|
|
46
|
+
## 3. Notebook hygiene
|
|
47
|
+
|
|
48
|
+
1. First cell: imports, settings, seeds (`rng = np.random.default_rng(42)`), and paths. No imports further down.
|
|
49
|
+
2. Run cells in order only. No cell may depend on a variable created by a cell below it or by a deleted cell.
|
|
50
|
+
3. Parameters (dates, thresholds, file names) in one cell near the top, tagged `parameters` if the notebook will be run with papermill.
|
|
51
|
+
4. One question per notebook. Over roughly 50 cells or several unrelated questions, split it.
|
|
52
|
+
5. Every result cell that a conclusion relies on prints the number it relies on, not just a chart.
|
|
53
|
+
6. Never mutate raw data in place; write derived data to `data/processed/` with code.
|
|
54
|
+
|
|
55
|
+
## 4. pandas and polars correctness
|
|
56
|
+
|
|
57
|
+
Full checklist in `references/dataframe-pitfalls.md`. The core rules:
|
|
58
|
+
|
|
59
|
+
- **Assignment:** use `df.loc[mask, "col"] = value`. Chained assignment (`df[mask]["col"] = value`) never updates `df` under pandas 3.0 Copy-on-Write; it only raises a `ChainedAssignmentError` warning, which is easy to miss.
|
|
60
|
+
- **Joins:** always pass `validate="one_to_one"` / `"many_to_one"` in pandas `merge` (polars: `validate="1:1"` / `"m:1"`), and check row counts before and after. A silent many-to-many join is the commonest wrong-answer bug.
|
|
61
|
+
- **Types:** declare dtypes when reading (`dtype=`, `parse_dates=`, polars `schema_overrides=`). Check `df.dtypes` and `df.isna().sum()` after loading. IDs with leading zeros are strings.
|
|
62
|
+
- **Missing values:** decide per column (drop, impute, keep as category) and write the decision down; `mean()` skips NaN silently.
|
|
63
|
+
- **Polars:** prefer lazy queries (`pl.scan_parquet(...)...collect()`) on large files; expressions inside `with_columns`, not Python loops or `map_elements` when a built-in expression exists.
|
|
64
|
+
- **Assert as you go:** `assert df["id"].is_unique`, `assert len(out) == len(left)`, value ranges. Cheap asserts catch the errors plots hide.
|
|
65
|
+
|
|
66
|
+
## 5. Plotting
|
|
67
|
+
|
|
68
|
+
- Label axes with units, title the question the chart answers, and state n.
|
|
69
|
+
- Start bar charts at zero. Use the same axis scales when panels are compared.
|
|
70
|
+
- Show uncertainty (confidence intervals, error bars, or raw points) whenever you show an estimate.
|
|
71
|
+
- Prefer colour-blind-safe palettes (matplotlib `viridis`, `cividis`) and never rely on colour alone.
|
|
72
|
+
- Save figures from code (`fig.savefig("reports/figures/fig1.png", dpi=200, bbox_inches="tight")`), not screenshots.
|
|
73
|
+
|
|
74
|
+
## 6. Statistics pitfalls (stop and flag)
|
|
75
|
+
|
|
76
|
+
Detail and fixes in `references/statistics-pitfalls.md`. Flag to the user, do not silently "fix":
|
|
77
|
+
|
|
78
|
+
- Many tests, one reported: correct for multiple comparisons (Holm, Benjamini-Hochberg) or report all tests run.
|
|
79
|
+
- Deciding the analysis after seeing the data (choosing subgroups, outlier rules or covariates by which gives p < 0.05).
|
|
80
|
+
- Train/test leakage: scaling, imputation or feature selection fitted on all data before splitting; time-series split at random.
|
|
81
|
+
- Non-independent observations (repeated measures, clustered data) analysed as independent.
|
|
82
|
+
- Correlation reported as causation.
|
|
83
|
+
- p-values without effect sizes and confidence intervals; "not significant" read as "no effect".
|
|
84
|
+
- Simpson's paradox: a trend that reverses within groups. Check the main result by key subgroups.
|
|
85
|
+
|
|
86
|
+
If the analysis supports a regulated, clinical or financial decision, say a qualified statistician should review it.
|
|
87
|
+
|
|
88
|
+
## 7. Move code out of the notebook
|
|
89
|
+
|
|
90
|
+
When a cell is reused, longer than about 20 lines, or the analysis is going into production:
|
|
91
|
+
|
|
92
|
+
1. Move the function into `src/<package>/`, with a docstring and type hints, and import it back (`%load_ext autoreload` and `%autoreload 2` while developing).
|
|
93
|
+
2. Add a test in `tests/` with a small fixed DataFrame that covers the edge cases you found (empty, missing values, duplicates).
|
|
94
|
+
3. Leave narrative, charts and parameter choices in the notebook. Leave logic in modules.
|
|
95
|
+
4. For scheduled or repeated runs, convert to a script (`jupyter nbconvert --to script`) and clean it up, or run the notebook with `papermill` and parameters. Production pipelines belong in a pipeline tool, not a notebook.
|
|
96
|
+
5. Re-run the notebook from a clean kernel and confirm the numbers match the baseline from step 0.
|
|
97
|
+
|
|
98
|
+
## Never
|
|
99
|
+
|
|
100
|
+
- Delete or edit files in `data/raw/`.
|
|
101
|
+
- Report a number that only appears after running cells out of order.
|
|
102
|
+
- Drop rows or outliers without printing how many and why.
|
|
103
|
+
- Commit large data files, credentials or notebooks full of personal data outputs.
|
|
104
|
+
|
|
105
|
+
## Report back
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Reruns clean: <yes/no, which cell failed before>
|
|
109
|
+
Environment: <tool, lock file, Python and key library versions>
|
|
110
|
+
Changes: <layout, hygiene, dataframe fixes, code moved to src/ with tests>
|
|
111
|
+
Statistics flags: <each issue, where, suggested fix>
|
|
112
|
+
Numbers changed vs baseline: <none, or which and why>
|
|
113
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"My Jupyter notebook gives a different churn rate every time I restart the kernel and run it, help me find out why",
|
|
4
|
+
"Clean up this exploratory pandas notebook: pin the environment, fix the merge that duplicates rows and move the helpers into a module",
|
|
5
|
+
"Check the statistics in my A/B test analysis notebook, I ran a t-test on twenty metrics and reported the two that were significant",
|
|
6
|
+
"Turn the cleaning cells in 02-explore.ipynb into a tested Python package the rest of the team can import",
|
|
7
|
+
"Set up a project structure for a new research analysis in notebooks so the results are reproducible"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Build an Airflow pipeline that refreshes the warehouse tables every hour",
|
|
11
|
+
"Create a Grafana dashboard for our API latency metrics",
|
|
12
|
+
"Fix the shape mismatch error in my PyTorch training loop",
|
|
13
|
+
"Search PubMed for studies on statin use and dementia risk and summarise them",
|
|
14
|
+
"Write a Snakemake rule that calls variants with bcftools"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# DataFrame pitfalls (pandas and polars)
|
|
2
|
+
|
|
3
|
+
## Loading
|
|
4
|
+
|
|
5
|
+
- pandas: `pd.read_csv(path, dtype={"zip": "string", "id": "string"}, parse_dates=["created_at"])`. Prefer Parquet over CSV for intermediates; it keeps types.
|
|
6
|
+
- polars: `pl.read_csv(path, schema_overrides={"zip": pl.String})`, `pl.scan_csv` / `pl.scan_parquet` for lazy reading.
|
|
7
|
+
- Check straight after loading: shape, `dtypes`, null counts, duplicate keys, min/max of numeric and date columns.
|
|
8
|
+
|
|
9
|
+
## Assignment and copies (pandas)
|
|
10
|
+
|
|
11
|
+
- pandas 3.0 makes Copy-on-Write the only mode: any indexing result behaves as a copy. `df[df.a > 0]["b"] = 1` never updates `df` (only a `ChainedAssignmentError` warning). Use `df.loc[df.a > 0, "b"] = 1`.
|
|
12
|
+
- `SettingWithCopyWarning` is gone in 3.0; do not rely on warnings to catch mistakes, assert on the result.
|
|
13
|
+
- Avoid `inplace=True`; reassign instead (`df = df.dropna(subset=["x"])`).
|
|
14
|
+
|
|
15
|
+
## Strings and dates (pandas 3.0)
|
|
16
|
+
|
|
17
|
+
- Text columns infer to the `str` dtype (backed by PyArrow when installed), not `object`. Code that checks `dtype == object` for strings will break.
|
|
18
|
+
- Default datetime resolution is microseconds when inferred from strings. Compare timestamps with matching time zones; localise with `tz_localize`, convert with `tz_convert`.
|
|
19
|
+
|
|
20
|
+
## Joins
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
before = len(left)
|
|
24
|
+
out = left.merge(right, on="customer_id", how="left", validate="many_to_one", indicator=True)
|
|
25
|
+
assert len(out) == before
|
|
26
|
+
print(out["_merge"].value_counts())
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
polars: `left.join(right, on="customer_id", how="left", validate="m:1")`.
|
|
30
|
+
|
|
31
|
+
- Check key dtypes and formats match on both sides. pandas raises on int vs string keys, but `"007"` vs `"7"` (an ID read as a number on one side) silently matches nothing.
|
|
32
|
+
- Strip whitespace and normalise case on string keys before joining.
|
|
33
|
+
|
|
34
|
+
## Grouping and aggregation
|
|
35
|
+
|
|
36
|
+
- `groupby(..., dropna=False)` if missing keys are a real group; pandas drops them by default.
|
|
37
|
+
- Use named aggregation (`df.groupby("g").agg(n=("id", "size"), mean_x=("x", "mean"))`) so columns say what they are.
|
|
38
|
+
- `size` counts rows including nulls; `count` excludes nulls.
|
|
39
|
+
- polars: `df.group_by("g").agg(pl.len().alias("n"), pl.col("x").mean())`; order is not guaranteed unless `maintain_order=True`.
|
|
40
|
+
|
|
41
|
+
## Floats and money
|
|
42
|
+
|
|
43
|
+
- Compare floats with tolerance (`np.isclose`). Money: integer minor units or `decimal`, not float sums.
|
|
44
|
+
|
|
45
|
+
## Performance without changing results
|
|
46
|
+
|
|
47
|
+
- Vectorise; avoid `iterrows` and `apply(axis=1)` for arithmetic.
|
|
48
|
+
- `category` dtype for low-cardinality strings in pandas.
|
|
49
|
+
- polars lazy queries: build the whole query, then `.collect()` once; `explain()` shows the plan.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Statistics pitfalls in exploratory analysis
|
|
2
|
+
|
|
3
|
+
For each, the sign to look for and what to do. Report the issue to the user; changing a conclusion is their call.
|
|
4
|
+
|
|
5
|
+
| Pitfall | Sign in the notebook | What to do |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| Multiple comparisons | Loops over many columns, groups or metrics with a p-value each; only the significant ones reported | Report every test run; adjust with Holm (`statsmodels.stats.multitest.multipletests(p, method="holm")`) or Benjamini-Hochberg (`method="fdr_bh"`) |
|
|
8
|
+
| Garden of forking paths / p-hacking | Outlier rules, subgroups or covariates changed between runs; cells commented out after a non-significant result | Write the analysis plan first; label later analyses "exploratory" |
|
|
9
|
+
| Optional stopping | Collecting more data until p < 0.05 | Fix sample size in advance, or use a sequential design built for it |
|
|
10
|
+
| Leakage | `fit` on the full dataset before `train_test_split`; target-derived features; random split of time series | Fit preprocessing inside a pipeline (`sklearn.pipeline.Pipeline`) on train only; split by time or group (`TimeSeriesSplit`, `GroupKFold`) |
|
|
11
|
+
| Non-independence | Several rows per person, site or day treated as independent samples | Aggregate to the unit of analysis, or use mixed models / cluster-robust errors |
|
|
12
|
+
| Wrong test assumptions | t-test on heavily skewed small samples; chi-square with expected counts below 5 | Check assumptions; use a rank-based test, exact test, or bootstrap |
|
|
13
|
+
| Significance without size | Only p-values reported | Report effect size with a confidence interval |
|
|
14
|
+
| Absence of evidence | "p = 0.2 so no effect" | Say the data cannot distinguish; show the interval |
|
|
15
|
+
| Simpson's paradox | Overall trend differs from within-group trends | Stratify by the likely confounder and show both |
|
|
16
|
+
| Survivorship and selection | Analysing only customers who stayed, only completed records | State who is missing and why; compare with the full population if possible |
|
|
17
|
+
| Regression to the mean | Extreme groups "improve" on remeasurement | Compare against a control group |
|
|
18
|
+
| Base rates | Accuracy reported on imbalanced classes | Report precision, recall, and the base rate; use a confusion matrix |
|
|
19
|
+
| Correlation as causation | Causal wording ("drives", "causes") from observational data | Use associational wording unless the design supports causal claims |
|
|
20
|
+
|
|
21
|
+
## Randomness
|
|
22
|
+
|
|
23
|
+
- Seed every random step (`np.random.default_rng(seed)`, `random_state=` in scikit-learn). Report results across several seeds when they vary.
|
|
24
|
+
- Bootstrap intervals: state the number of resamples and the seed.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: data-pipelines
|
|
3
|
+
description: Batch data pipeline engineering for extract-load-transform jobs run by an orchestrator such as Airflow, Dagster or Prefect, built so every task is idempotent and safe to rerun for any past interval, partitioned by logical date, guarded by row-count, freshness and schema checks before data is published, tolerant of late-arriving records, and traceable through lineage. Use when building or fixing a scheduled ingestion or ETL/ELT job, writing an Airflow DAG, Dagster asset or Prefect flow, planning a backfill, or chasing duplicate or missing rows after a rerun.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Needs the project's orchestrator CLI (airflow, dagster or prefect) and warehouse client to run anything; the design rules apply to any batch pipeline.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: data
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Batch data pipelines
|
|
14
|
+
|
|
15
|
+
Build pipelines where running any task twice for the same interval gives the same result, any past day can be rebuilt on demand, and bad data stops before anyone reads it.
|
|
16
|
+
|
|
17
|
+
## Ground rules
|
|
18
|
+
|
|
19
|
+
1. **One run = one interval.** Every task processes a bounded window given by the orchestrator (`data_interval_start`/`data_interval_end` in Airflow, a partition key in Dagster, a parameter in Prefect). Never use `now()` or "since last run" inside task logic; it makes reruns and backfills give different answers.
|
|
20
|
+
2. **Idempotent writes.** A task replaces its output for its window: `DELETE ... WHERE partition = :d` then `INSERT` in one transaction, `MERGE` on a natural key, `INSERT OVERWRITE` of a partition, or write to a staging table and swap. Plain `INSERT`/append is only safe with a dedup step downstream on a unique key.
|
|
21
|
+
3. **Land raw first.** Extract to an immutable raw zone (object storage or a raw schema) keyed by source and interval, exactly as received. Transform from raw, so a logic bug is fixed by rerunning transforms, not by re-hitting the source.
|
|
22
|
+
4. **Check, then publish.** Data quality checks run between build and publish. A failed blocking check stops downstream tasks; consumers never see half-built or failed output.
|
|
23
|
+
5. **Small, single-purpose tasks.** Extract, load, transform, check, publish are separate tasks so one can be retried alone. Pass references (table names, paths) between tasks, not data.
|
|
24
|
+
6. **Secrets from the orchestrator's connection or secret store**, never in DAG code or the repo.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
1. **Inventory.** Search the codebase for the orchestrator and its version (`airflow version`, `dagster --version`, `prefect version`), existing pipelines, the warehouse, and how tests run. Follow the existing patterns.
|
|
29
|
+
2. **Define the contract** for each output: grain (one row per what), primary key, partition column, freshness target ("yesterday's data by 06:00 UTC"), and who consumes it. If the grain or key is unclear, **stop and ask the user**.
|
|
30
|
+
3. **Pick the interval and schedule** from the freshness target and how the source exposes changes (full snapshot, `updated_at` watermark, change data capture, append-only events).
|
|
31
|
+
4. **Write extract** for one interval: paginate, retry transient errors with backoff, set timeouts, and save to the raw zone at a deterministic path such as `raw/<source>/<table>/dt=YYYY-MM-DD/`.
|
|
32
|
+
5. **Write load and transform** with one of the idempotent patterns from rule 2. If transforms live in dbt, the orchestrator calls dbt; model design is the `dbt-patterns` skill.
|
|
33
|
+
6. **Add checks** (next section) as their own tasks or asset checks.
|
|
34
|
+
7. **Handle late data** (below).
|
|
35
|
+
8. **Wire retries and alerts**: retries with delay on extract and load, no blind retries on checks, an alert on failure and on a missed freshness target.
|
|
36
|
+
9. **Test**: unit-test transform logic on small fixtures, then run one interval end to end, then run the same interval again and confirm row counts and checksums do not change.
|
|
37
|
+
|
|
38
|
+
Orchestrator-specific code (Airflow TaskFlow and backfills, Dagster partitioned assets and asset checks, Prefect flows and retries) is in `references/orchestrators.md`. Read it before writing or changing pipeline code.
|
|
39
|
+
|
|
40
|
+
## Data quality checks
|
|
41
|
+
|
|
42
|
+
Run at least these on every published table:
|
|
43
|
+
|
|
44
|
+
| Check | Example rule | Blocking? |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| Row count | not zero; within ±X% of the trailing 7-interval median | yes for zero, warn for drift |
|
|
47
|
+
| Primary key | unique and not null | yes |
|
|
48
|
+
| Freshness | `max(loaded_at)` within target | yes |
|
|
49
|
+
| Schema | expected columns and types present | yes |
|
|
50
|
+
| Referential | foreign keys exist in the parent table | warn, unless the user says block |
|
|
51
|
+
| Accepted values | status in the known set | warn |
|
|
52
|
+
| Reconciliation | totals match the source (count or sum per interval) | yes for money and counts reported outward |
|
|
53
|
+
|
|
54
|
+
Decide thresholds with the user; do not invent business tolerances.
|
|
55
|
+
|
|
56
|
+
## Late-arriving data
|
|
57
|
+
|
|
58
|
+
- Ask the user how late data can arrive, then pick one:
|
|
59
|
+
- **Lookback window**: each run also rebuilds the previous N intervals. Simple; costs N times the compute.
|
|
60
|
+
- **Partition by event time, reprocess on arrival**: detect which past partitions received new raw rows and rerun those.
|
|
61
|
+
- **Partition by load time**: never late by definition; consumers filter by event time and accept that history changes.
|
|
62
|
+
- Keep both `event_time` and `loaded_at` on every row.
|
|
63
|
+
- Document the cut-off after which late rows are dropped or routed to a quarantine table, and count them.
|
|
64
|
+
|
|
65
|
+
## Backfills
|
|
66
|
+
|
|
67
|
+
1. Confirm the task is idempotent (ground rule 2) and that the source still holds the history.
|
|
68
|
+
2. **Stop and ask the user** before backfilling more than a few intervals against a production source or warehouse: confirm the date range, cost, source rate limits, and whether consumers will see changing numbers.
|
|
69
|
+
3. Run oldest first with capped concurrency, then re-run checks for the whole range.
|
|
70
|
+
|
|
71
|
+
## Lineage
|
|
72
|
+
|
|
73
|
+
- Name inputs and outputs explicitly (Airflow assets, Dagster asset dependencies, dbt `ref`/`source`) so the orchestrator draws the graph.
|
|
74
|
+
- If the project uses OpenLineage, emit through the orchestrator's OpenLineage integration instead of hand-written events.
|
|
75
|
+
- Record in each output table or its docs: source system, pipeline name, and the code version that built it.
|
|
76
|
+
|
|
77
|
+
## Never
|
|
78
|
+
|
|
79
|
+
- Never delete or overwrite the raw zone to "fix" a run.
|
|
80
|
+
- Never mark a failed check as passed, or downgrade it to a warning, to get a run green without the user agreeing.
|
|
81
|
+
- Never run a backfill or `--full-refresh` against production without confirmation.
|
|
82
|
+
- Never use the wall clock to decide which data a task reads.
|
|
83
|
+
|
|
84
|
+
## Report back
|
|
85
|
+
|
|
86
|
+
- Pipelines and tasks added or changed, with the output table, grain, key and partition.
|
|
87
|
+
- The idempotency pattern used for each write.
|
|
88
|
+
- Checks added and which ones block.
|
|
89
|
+
- Late-data policy and backfill instructions.
|
|
90
|
+
- Commands run and their results, including the rerun-same-interval test.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Write an Airflow DAG that pulls yesterday's orders from the Shopify API into S3 and loads them into Snowflake",
|
|
4
|
+
"Our nightly ETL job inserts duplicate rows every time we rerun a failed day, make it idempotent",
|
|
5
|
+
"Convert this cron-driven Python ingestion script into Dagster partitioned assets with checks",
|
|
6
|
+
"We need to backfill six months of event data after fixing a bug in the transform step, how do we do it safely?",
|
|
7
|
+
"Events keep arriving up to three days late and our daily aggregates are wrong, how should the pipeline handle that?"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Restructure our dbt project into staging, intermediate and marts folders",
|
|
11
|
+
"Build a scraper that collects product prices from a retailer's listing pages",
|
|
12
|
+
"Decide which KPIs and charts should go on the weekly sales dashboard",
|
|
13
|
+
"Design ClickHouse tables for ingesting clickstream events with a materialised view rollup",
|
|
14
|
+
"Explore this CSV in a Jupyter notebook and plot the monthly churn rate"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Orchestrator notes
|
|
2
|
+
|
|
3
|
+
Check the installed version first; APIs differ between major versions. The official docs for the installed version are the final word.
|
|
4
|
+
|
|
5
|
+
## Airflow (3.x)
|
|
6
|
+
|
|
7
|
+
- Write DAGs with the TaskFlow API (`@dag`, `@task`) and pass `schedule=` (the old `schedule_interval` is gone in Airflow 3).
|
|
8
|
+
- `catchup` defaults to `False` in Airflow 3 (`[scheduler] catchup_by_default`). Set it explicitly on every DAG so behaviour does not depend on config.
|
|
9
|
+
- Read the window from the task context: `data_interval_start`, `data_interval_end`, `logical_date`. With the default `CronTriggerTimetable` in Airflow 3 the data interval can be zero-length; if the task needs a real window, use `CronDataIntervalTimetable` or compute the window from `logical_date` explicitly, and test it.
|
|
10
|
+
- Datasets were renamed **assets** in Airflow 3 (`from airflow.sdk import Asset`). Declare `outlets=[Asset(...)]` on producers and `schedule=[Asset(...)]` on consumers for data-aware scheduling and lineage.
|
|
11
|
+
- Retries: `default_args={"retries": 3, "retry_delay": timedelta(minutes=5), "retry_exponential_backoff": 2.0}`. Current Airflow 3 docs type `retry_exponential_backoff` as a float multiplier (0 = constant delay, 2.0 = doubling); Airflow 2 took a bool, so check the installed version. Set `execution_timeout` on every task.
|
|
12
|
+
- Limit parallel runs with `max_active_runs` on the DAG and pools for shared sources.
|
|
13
|
+
- Keep top-level DAG code cheap: no network or database calls at import time; the parser runs it constantly.
|
|
14
|
+
- Backfill (Airflow 3): `airflow backfill create --dag-id <id> --from-date 2025-01-01 --to-date 2025-01-31 --reprocess-behavior failed --max-active-runs 2`. `--reprocess-behavior` is `none`, `failed` or `completed`.
|
|
15
|
+
- Test one run locally with `airflow dags test <dag_id> <date>`.
|
|
16
|
+
- Secrets come from Connections and Variables backed by a secrets backend, read inside the task, not at parse time.
|
|
17
|
+
|
|
18
|
+
## Dagster
|
|
19
|
+
|
|
20
|
+
- Model outputs as **software-defined assets** (`@dg.asset`); dependencies come from function parameters or `deps=`.
|
|
21
|
+
- Partition by time with `DailyPartitionsDefinition(start_date="2025-01-01")`; read `context.partition_key` (or `context.partition_time_window`) inside the asset and write only that partition.
|
|
22
|
+
- Quality checks: `@dg.asset_check(asset=my_asset)` returning `AssetCheckResult(passed=..., severity=...)`, or `blocking=True` so downstream assets don't materialize on failure.
|
|
23
|
+
- Freshness and schedules: build a job from an asset selection and attach a schedule, or use declarative automation (`automation_condition=`).
|
|
24
|
+
- Backfill partitions from the UI or `dagster asset materialize --select <asset> --partition-range <start>...<end>` (the `--partition-range` flag appears in recent `dagster asset materialize --help` output but not in the CLI reference page; Dagster now recommends the `dg` CLI, so check `--help` for the installed version).
|
|
25
|
+
- Resources (`ConfigurableResource`) hold connections; secrets come from environment variables via `dg.EnvVar("NAME")`.
|
|
26
|
+
|
|
27
|
+
## Prefect (3.x)
|
|
28
|
+
|
|
29
|
+
- `@flow` for the pipeline, `@task` for steps. Pass the interval as flow parameters (`start: date, end: date`) so a backfill is just a run with old parameters.
|
|
30
|
+
- Retries: `@task(retries=3, retry_delay_seconds=[10, 60, 300])`; set `timeout_seconds`.
|
|
31
|
+
- Task caching: the default `cache_policy` keys on inputs, task source and the flow run ID, so a new run recomputes. A custom policy such as `INPUTS` can skip work across runs; make sure the key includes the interval, or use `NO_CACHE` for writes, otherwise a rerun silently does nothing.
|
|
32
|
+
- Deploy with `prefect deploy` / `flow.serve()` and a cron schedule; secrets come from Prefect `Secret` blocks or environment variables.
|
|
33
|
+
- Concurrency limits for shared sources: global concurrency limits or tags.
|
|
34
|
+
|
|
35
|
+
## Idempotent write snippets
|
|
36
|
+
|
|
37
|
+
Delete-insert one partition (Postgres, Snowflake, Redshift style):
|
|
38
|
+
|
|
39
|
+
```sql
|
|
40
|
+
BEGIN;
|
|
41
|
+
DELETE FROM analytics.orders_daily WHERE order_date = :ds;
|
|
42
|
+
INSERT INTO analytics.orders_daily SELECT ... FROM raw.orders WHERE order_date = :ds;
|
|
43
|
+
COMMIT;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Merge on a natural key:
|
|
47
|
+
|
|
48
|
+
```sql
|
|
49
|
+
MERGE INTO analytics.customers t
|
|
50
|
+
USING staging.customers_batch s ON t.customer_id = s.customer_id
|
|
51
|
+
WHEN MATCHED THEN UPDATE SET ...
|
|
52
|
+
WHEN NOT MATCHED THEN INSERT (...) VALUES (...);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
BigQuery or Spark/Hive partition overwrite: write the interval's rows with `INSERT OVERWRITE` (Spark, with dynamic partition overwrite mode) or a `WRITE_TRUNCATE` load job targeting the partition decorator (`table$20250131`) in BigQuery (with `bq load`, pass `--replace=true` to overwrite the partition instead of appending).
|
|
56
|
+
|
|
57
|
+
## Sources
|
|
58
|
+
|
|
59
|
+
- Airflow 3 upgrade notes (catchup default, `CronTriggerTimetable`, `airflow.sdk.Asset`): https://airflow.apache.org/docs/apache-airflow/stable/installation/upgrading_to_airflow3.html
|
|
60
|
+
- Airflow CLI (`backfill create`, `dags test`): https://airflow.apache.org/docs/apache-airflow/stable/cli-and-env-variables-ref.html
|
|
61
|
+
- Airflow Task SDK `BaseOperator` (`retry_exponential_backoff`): https://airflow.apache.org/docs/task-sdk/stable/api.html
|
|
62
|
+
- Dagster asset checks: https://dagster.io/docs/guides/test/asset-checks and https://dagster.io/docs/api/dagster/asset-checks
|
|
63
|
+
- Prefect caching and retries: https://docs.prefect.io/v3/concepts/caching and https://docs.prefect.io/v3/how-to-guides/workflows/retries
|
|
64
|
+
- BigQuery partition loads: https://docs.cloud.google.com/bigquery/docs/load-data-partitioned-tables
|