claude-code-kit 0.20.0__tar.gz → 0.21.0__tar.gz
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.
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/.claude-plugin/marketplace.json +1 -1
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/.claude-plugin/plugin.json +1 -1
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/CHANGELOG.md +53 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/PKG-INFO +1 -1
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/stack-skills/README.md +6 -2
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/hooks.json +2 -1
- claude_code_kit-0.21.0/hooks/scripts/guard-kubectl-delete.sh +37 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/pyproject.toml +1 -1
- claude_code_kit-0.21.0/skills/cron-and-scheduled-jobs/README.md +45 -0
- claude_code_kit-0.21.0/skills/cron-and-scheduled-jobs/SKILL.md +238 -0
- claude_code_kit-0.21.0/skills/cron-and-scheduled-jobs/references/choosing-and-operations.md +86 -0
- claude_code_kit-0.21.0/skills/cron-and-scheduled-jobs/references/kubernetes-cronjob.md +184 -0
- claude_code_kit-0.21.0/skills/cron-and-scheduled-jobs/references/repo-evidence.md +51 -0
- claude_code_kit-0.21.0/skills/cron-and-scheduled-jobs/references/temporal-schedules.md +112 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/README.md +43 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/SKILL.md +226 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/references/command-reference.md +137 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/references/context-namespace-rbac.md +91 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/references/debugging-playbooks.md +122 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/references/output-formats-and-selectors.md +125 -0
- claude_code_kit-0.21.0/skills/kubectl-operations/references/repo-evidence.md +59 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/__init__.py +1 -1
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/.gitignore +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/CLAUDE.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/CONTRIBUTING.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/LICENSE +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/acceptance-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/auditor.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/dependency-scanner.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/developer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/devils-advocate.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/devops-engineer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/e2e-tester.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/em-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/incident-responder.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/merge-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/observability-engineer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/orchestrator.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/owasp-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/policy-validator.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/pr-raiser.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/risk-classifier.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/sdlc-code-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/secret-scanner.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/security-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/senior-backend-dev.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/senior-frontend-dev.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/senior-tester.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/spec-doc-writer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/story-planner.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/technical-architect.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/tester.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/ui-designer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/agents/unit-tester.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/catalog/capture.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/catalog/mcp.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/catalog/org.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/catalog/profiles.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/catalog/stacks.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/commands/abort.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/commands/init.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/commands/sdlc.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/commands/status.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/agentic-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/agents.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/architecture.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/coverage-audit.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/eval-harness.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/org-capabilities.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/stack-skills/GAP-ANALYSIS.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/docs/stack-skills/REPO-INVENTORY.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/audit-log.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/capture-learnings.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/guard-destructive-git.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/guard-secrets.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/lint-fix.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/load-autonomy.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/load-continuity.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/load-learnings.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/type-check.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/validate-frontmatter.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/validate-settings.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/warn-large-edits.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/warn-llm-io.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/warn-missing-tests.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/warn-sensitive-files.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/hooks/scripts/warn-shared-modules.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/agent-guardrails.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/agent-memory.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/agent-resilience.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/autonomy-levels.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/code-organization.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/continuity.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/design-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/devops-observability.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/documentation.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/evals.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/frontend-best-practices.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/goal-setting-and-monitoring.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/human-in-the-loop.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/linting-and-formatting.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/mandatory-workflow.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/model-tiers.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/quality-gates.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/rarv-cycle.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/reasoning-techniques.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/responsive-and-accessibility.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/risk-classification.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/testing.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/rules/tool-design.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/scripts/init.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/_references/accessibility-checklist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/_references/orchestration-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/_references/performance-checklist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/_references/security-checklist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/_references/testing-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/accessibility-review/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/references/alembic-setup-and-env.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/references/async-and-multitenant-migrations.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/references/troubleshooting-and-debugging.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/alembic-migrations/references/writing-migrations.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/anthropic-vertex-integration/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/anthropic-vertex-integration/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/anthropic-vertex-integration/references/generate-helpers-and-retry.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/anthropic-vertex-integration/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/anthropic-vertex-integration/references/vertex-client-and-auth.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-and-interface-design/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-integration/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-pagination-filtering-sorting/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-pagination-filtering-sorting/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-pagination-filtering-sorting/references/query-params-conventions.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-pagination-filtering-sorting/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/api-pagination-filtering-sorting/references/response-metadata.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/archive-sprint/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/async-python-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/async-python-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/async-python-patterns/references/async-boundaries.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/async-python-patterns/references/lifecycle-and-gather.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/async-python-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/references/auth-dependencies.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/references/rbac-and-permissions.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/references/security-hardening.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/auth-and-rbac/references/tokens-and-hashing.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/references/deployment-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/references/entrypoint-and-config.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/references/structure-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backend-repo-architecture/references/troubleshooting.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backlog/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/backlog/item-template.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/browser-testing-with-devtools/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/bug-hunt/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/ci-cd-and-automation/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/code-review-and-quality/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/code-simplification/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/component-design/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/configargparse-yaml-env-layering/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/configargparse-yaml-env-layering/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/configargparse-yaml-env-layering/references/config-layering-anatomy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/configargparse-yaml-env-layering/references/mode-dispatch-and-precedence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/configargparse-yaml-env-layering/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/consolidate-learnings/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/references/deployment-and-secrets.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/references/dockerfile-and-compose.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/references/entrypoint-and-modes.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/references/kerberos-kinit-bootstrap.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/references/makefile-dev-workflow.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/containerization-and-deployment/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/context-engineering/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/references/bigquery-advanced-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/references/bigquery-gcs-io.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/references/medallion-architecture.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/data-engineering-bigquery-gcs/references/temp-table-merge-pattern.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/debugging-and-error-recovery/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/decision/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/decision/adr-template.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/deprecation-and-migration/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/references/anti-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/references/naming-and-layout.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/references/patterns-catalog.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/references/testing-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/design-patterns-and-conventions/references/troubleshooting.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-compose/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-compose/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-compose/references/compose-services-and-healthchecks.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-compose/references/dev-vs-prod-variants.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-compose/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-shared/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-shared/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-shared/references/dockerignore-and-build-secrets.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-shared/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-shared/references/shared-base-images.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/docker-shared/references/shared-compose-fragments.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-backend/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-backend/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-backend/references/backend-dockerfile-anatomy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-backend/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-backend/references/system-deps-and-caching.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-frontend/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-frontend/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-frontend/references/build-args-and-nginx.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-frontend/references/frontend-dockerfile-anatomy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/dockerfile-frontend/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/documentation-and-adrs/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/doubt-driven-development/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/edge-to-service-trust-boundary/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/edge-to-service-trust-boundary/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/edge-to-service-trust-boundary/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/edge-to-service-trust-boundary/references/trust-contract.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/execute/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/references/api-versioning.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/references/app-factory-and-lifespan.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/references/custom-route-and-middleware.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/references/dependency-injection.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/references/model-and-serialization-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/fastapi-service-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/file-export-and-reporting/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/file-export-and-reporting/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/file-export-and-reporting/references/excel-generation.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/file-export-and-reporting/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/file-export-and-reporting/references/streaming-and-downloads.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/references/api-layer-and-types.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/references/divergences.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/references/structure-and-state.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-repo-architecture/references/testing-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/frontend-ui-engineering/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcp-cloud-run-github-actions/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcp-cloud-run-github-actions/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcp-cloud-run-github-actions/references/cloud-run-deploy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcp-cloud-run-github-actions/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcp-cloud-run-github-actions/references/workflow-structure.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcs-file-storage-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcs-file-storage-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcs-file-storage-patterns/references/client-and-uploads.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcs-file-storage-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/gcs-file-storage-patterns/references/signed-urls-and-reads.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/git-workflow-and-versioning/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/references/dashboard-json-and-templating.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/references/provisioning-and-organization.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/references/red-metrics-queries.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/grafana-dashboards-and-alerts/references/unified-alerting.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/references/apollo-client-frontend.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/references/apollo-client-setup.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/references/strawberry-backend.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/graphql-patterns/references/when-to-use-graphql.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/idea-refine/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/idea-refine/examples.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/idea-refine/frameworks.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/idea-refine/refinement-criteria.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/idea-refine/scripts/idea-refine.sh +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/incident-postmortem/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/incremental-implementation/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/interview-me/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kafka-config-driven/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kafka-config-driven/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kafka-config-driven/references/config-and-sasl-kerberos.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kafka-config-driven/references/consumer-producer-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kafka-config-driven/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kafka-config-driven/references/troubleshooting-and-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kubernetes-workload-hardening/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kubernetes-workload-hardening/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kubernetes-workload-hardening/references/networkpolicy-and-rbac.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kubernetes-workload-hardening/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/kubernetes-workload-hardening/references/securitycontext-and-podsecurity.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/langfuse-llm-tracing/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/langfuse-llm-tracing/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/langfuse-llm-tracing/references/langfuse-client-and-tracing.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/langfuse-llm-tracing/references/python-and-typescript.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/langfuse-llm-tracing/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/load-testing/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/manual-test/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/references/migration-best-practices.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/references/pydantic-v1-to-v2.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/references/shared-internal-library.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/modernization-and-migration/references/sqlalchemy-14-to-20.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/multi-tenancy-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/multi-tenancy-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/multi-tenancy-patterns/references/caching-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/multi-tenancy-patterns/references/isolation-strategies.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/multi-tenancy-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/multi-tenancy-patterns/references/tenant-resolution.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-express-service/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-express-service/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-express-service/references/app-factory-and-mode-dispatch.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-express-service/references/config-and-module-alias.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-express-service/references/middleware-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-express-service/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-objection-knex/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-objection-knex/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-objection-knex/references/migrations-and-validation.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-objection-knex/references/objection-model-and-knex.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/node-objection-knex/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/notifications-and-messaging/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/notifications-and-messaging/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/notifications-and-messaging/references/provider-abstraction.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/notifications-and-messaging/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/notifications-and-messaging/references/templates-and-fallback.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/references/health-and-readiness.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/references/logging-and-structlog.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/references/outbound-metrics-and-multi-mode.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/references/pii-redaction.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/observability-and-logging/references/tracing-and-metrics.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/over-engineering-review/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/performance-optimization/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/planning-and-task-breakdown/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/playwright-verification/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/pydantic-schema-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/pydantic-schema-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/pydantic-schema-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/pydantic-schema-patterns/references/settings-and-validation.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/pydantic-schema-patterns/references/troubleshooting-and-common-errors.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/pydantic-schema-patterns/references/v1-vs-v2.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/references/advanced-query-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/references/basedao-and-sessions.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/references/mongodb-advanced.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/references/other-db-mongodb.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/python-dao-and-database/references/sqlalchemy-1x-vs-2x.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/radix-tailwind-component-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/radix-tailwind-component-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/radix-tailwind-component-patterns/references/radix-primitives-and-variants.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/radix-tailwind-component-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/radix-tailwind-component-patterns/references/tailwind-theme-and-cn.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/react-hook-form-zod-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/react-hook-form-zod-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/react-hook-form-zod-patterns/references/form-setup-and-zod.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/react-hook-form-zod-patterns/references/multi-step-and-modes.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/react-hook-form-zod-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/redis-caching-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/redis-caching-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/redis-caching-patterns/references/cache-manager-and-fallback.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/redis-caching-patterns/references/namespacing-and-invalidation.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/redis-caching-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/refresh-docs/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/remember/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/scope/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/scope/scope-template.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/sdlc/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/security-and-hardening/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/security-verification/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/shannon-ai-pentest/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/shannon-ai-pentest/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/shannon-ai-pentest/references/operating-guide.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/shipping-and-launch/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/simplification-debt/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/smoke-test/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/source-driven-development/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/spec-driven-development/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/sprint/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/sprint/sprint-template.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/tanstack-react-query-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/tanstack-react-query-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/tanstack-react-query-patterns/references/mutations-and-cache.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/tanstack-react-query-patterns/references/query-keys-and-hooks.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/tanstack-react-query-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/task-tracker-sync/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/references/config-and-retry-idempotency.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/references/dag-dsl-interpreter.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/references/schedule-registration.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/references/schedules-and-cron.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/temporal-config-driven/references/worker-workflow-activity-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/test-driven-development/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/test-plan-review/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/async-and-mocking.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/coverage-gap-and-recommendations.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/github-actions-test-orchestration.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/pytest-and-fixtures.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/pytest-asyncio-modes.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/security-regression-tests.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/testing-conventions/references/vitest-frontend-testing.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/threat-model/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/triage/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/ui-ux-design/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/unit-test/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/using-agent-skills/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/vitest-rtl-msw-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/vitest-rtl-msw-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/vitest-rtl-msw-patterns/references/msw-and-contract-tests.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/vitest-rtl-msw-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/vitest-rtl-msw-patterns/references/vitest-rtl-setup.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zap-vapt-scanning/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zap-vapt-scanning/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zap-vapt-scanning/references/operating-guide.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zap-vapt-scanning/scripts/endpoints.example.txt +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zap-vapt-scanning/scripts/requirements.txt +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zap-vapt-scanning/scripts/zap_vapt.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zustand-state-patterns/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zustand-state-patterns/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zustand-state-patterns/references/async-polling-and-persistence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zustand-state-patterns/references/repo-evidence.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/skills/zustand-state-patterns/references/store-structure-and-selectors.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/__main__.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/catalog.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/cli.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/hooks.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/models.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/prompts.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/render.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/scaffold.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/upgrader.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/src/claude_kit/validator.py +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/CLAUDE.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/CLAUDE.stack.md.tmpl +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/CONTINUITY.template.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/README.claude-sdlc.md.tmpl +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/MEMORY.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/api/.gitkeep +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/architecture/.gitkeep +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/debugging/.gitkeep +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/gotchas/.gitkeep +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/patterns/.gitkeep +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/agent-memory/performance/.gitkeep +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/adr.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/api-change-report.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/feature-spec.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/release-plan.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/runbook.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/security-review.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/artifacts/test-plan.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/agents/data-workflow-agent.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/agents/founder-prototype-agent.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/agents/internal-tools-builder.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/agents/pm-copilot.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/agents/staff-pm-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/agents/support-ticket-engineer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/devops-and-release/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/devops-and-release/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/engineering-core/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/engineering-core/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/non-engineer-builder/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/non-engineer-builder/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/onboarding-and-docs/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/onboarding-and-docs/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/product-to-code/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/product-to-code/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/quality-and-review/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/quality-and-review/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/security-and-compliance/README.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/packs/security-and-compliance/pack.yaml +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/ai-working-agreement.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/ambiguity-resolution.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/branch-and-pr-policy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/compliance-policy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/non-engineer-safe-coding.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/pii-policy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/production-data-policy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/prompt-to-task-conversion.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/prototype-boundaries.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/rules/secrets-policy.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/customer-issue-to-fix/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/feature-from-idea/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/prompt-to-safe-task/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/prototype-to-production/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/repo-onboarding/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/review-scope/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/review-sprint/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/review-sprint-plan/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/org/skills/review-ux-flow/SKILL.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/settings.json +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/backend/go/net-http/rules/go-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/backend/python/fastapi/rules/fastapi-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/mongodb/agents/migration-specialist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/mongodb/agents/mongodb-specialist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/mongodb/rules/mongodb-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/postgres/agents/db-performance-reviewer.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/postgres/agents/migration-specialist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/postgres/agents/postgres-specialist.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/postgres/rules/database-performance.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/db/postgres/rules/postgres-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/frontend/react/rules/design-system-compliance.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/frontend/react/rules/mobile-design-guidelines.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/frontend/react/rules/react-patterns.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/frontend/react/rules/ui-design-system.md +0 -0
- {claude_code_kit-0.20.0 → claude_code_kit-0.21.0}/templates/stacks/frontend/react/rules/ux-patterns.md +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "claude-kit",
|
|
11
11
|
"source": "./",
|
|
12
12
|
"description": "Cookiecutter-style scaffolder for an autonomous Claude Code SDLC config (no app code, no Docker): install CLAUDE.md + .claude/ (rules, the profile's agents/skills, hooks, artifact templates) + optional .mcp.json, then run /sdlc to drive spec → review → build → test → security → ship through profile-aware quality gates, working memory, and a self-improving learnings loop.",
|
|
13
|
-
"version": "0.
|
|
13
|
+
"version": "0.21.0",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"keywords": ["sdlc", "agents", "orchestration", "quality-gates", "workflow", "scaffold", "cookiecutter"]
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Cookiecutter-style scaffolder for an autonomous Claude Code SDLC config (no app code, no Docker). `claude-kit init` asks ordered questions and installs CLAUDE.md + .claude/ (rules, the profile's agents/skills, hooks, artifact templates) + optional .mcp.json; run /sdlc to drive spec → review → build → test → security → ship through profile-aware quality gates with working memory and a self-improving learnings loop.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Arjunsingh Yadav",
|
|
@@ -4,6 +4,59 @@ All notable changes to claude-kit are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/), and the project uses
|
|
5
5
|
[semantic versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.21.0] — 2026-06-22
|
|
8
|
+
|
|
9
|
+
**Add two stack-collection skills — `cron-and-scheduled-jobs` (scheduled/recurring jobs across Kubernetes
|
|
10
|
+
CronJobs and Temporal Schedules) and `kubectl-operations` (the full kubectl command surface for operating
|
|
11
|
+
those workloads) — now 45 skills.**
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`cron-and-scheduled-jobs`** — a stack-derived skill documenting how scheduled/recurring jobs are
|
|
16
|
+
configured in system config and invoked, across the two mechanisms this stack uses:
|
|
17
|
+
- **Kubernetes CronJob route** — the schedule is declared in Helm `values.yaml` under a `Crons.<job>`
|
|
18
|
+
block (`Schedule`, `Envs: {MODE: cron, CRON_JOB: <name>}`, `ConcurrencyPolicy: Forbid`, `Suspend`,
|
|
19
|
+
`TtlSecondsAfterFinished`); the chart renders one `batch/v1` CronJob per entry (`restartPolicy:
|
|
20
|
+
Never`, history limits 3/1). The shared image boots one-shot in `MODE=cron` and dispatches a single
|
|
21
|
+
named job from a Python cron registry (simple `name→callable` or rich `name→{task, description,
|
|
22
|
+
schedule}`), instrumented via `record_cron_job_executed`. Documents the chart's missing
|
|
23
|
+
`timeZone`/`startingDeadlineSeconds` and how to compensate.
|
|
24
|
+
- **Temporal Schedule route** — `cron_expressions` vs `ScheduleIntervalSpec` (interval+offset to dodge
|
|
25
|
+
the UTC-cron timezone foot-gun), `ScheduleOverlapPolicy.SKIP` + `pause_on_failure`, and the one-shot
|
|
26
|
+
k8s `Job` (not a CronJob) that registers the schedule. Cross-links `temporal-config-driven` (which
|
|
27
|
+
owns workflow/activity/worker mechanics and the create-or-update registration loop) rather than
|
|
28
|
+
duplicating it.
|
|
29
|
+
- Plus a decision matrix for choosing k8s CronJob vs Temporal Schedule, and the cross-cutting concerns
|
|
30
|
+
(concurrency, timezone, history, missed runs, suspend vs pause, observability, idempotency).
|
|
31
|
+
- Fully genericized; **not** wired into the catalog/scaffold (`claude-kit init` output is unchanged).
|
|
32
|
+
|
|
33
|
+
- **`kubectl-operations`** — a stack-derived, operations-first skill for running `kubectl` against this
|
|
34
|
+
stack's workloads:
|
|
35
|
+
- **Full command surface**, grouped by task — `get`/`describe`/`explain`/`api-resources`;
|
|
36
|
+
`apply`/`create`/`edit`/`patch`/`set`/`replace`; `logs`/`exec`/`port-forward`/`cp`/`debug`/
|
|
37
|
+
`attach`/`proxy`; `rollout`/`scale`/`autoscale`; `events`/`top`; `label`/`annotate`; `config`
|
|
38
|
+
(contexts & namespaces); `auth can-i`; `wait`/`diff`/`kustomize`; node `cordon`/`drain`/`taint`.
|
|
39
|
+
(`kubectl delete` is intentionally omitted — see the guardrail below — in favour of reversible
|
|
40
|
+
alternatives: `scale --replicas=0`, `rollout undo`, or removing the object from the Git/Helm source.)
|
|
41
|
+
- **Output formatting & selectors** — `-o wide/yaml/json/name/jsonpath/custom-columns/go-template`,
|
|
42
|
+
`--sort-by`, label (`-l`) and field selectors, `--watch`, with copy-ready JSONPath recipes.
|
|
43
|
+
- **Context/namespace/RBAC safety** (the #1 footgun) and **day-2 debugging playbooks** —
|
|
44
|
+
CrashLoopBackOff, ImagePullBackOff, Pending/unschedulable, OOMKilled, a cron that didn't fire, a
|
|
45
|
+
Service with no endpoints.
|
|
46
|
+
- Cross-links `cron-and-scheduled-jobs`, `kubernetes-workload-hardening`,
|
|
47
|
+
`containerization-and-deployment`, `temporal-config-driven`, and `observability-and-logging`. Fully
|
|
48
|
+
genericized; **not** wired into the catalog/scaffold. The collection index is updated (45 skills).
|
|
49
|
+
|
|
50
|
+
- **Plugin guardrail `guard-kubectl-delete`** — a `PreToolUse(Bash)` hook that blocks `kubectl delete`
|
|
51
|
+
from the agent's Bash tool (exit 2), joining the `rm -rf` / `push main` / `guard-destructive-git` /
|
|
52
|
+
`guard-secrets` destructive-command family. It matches the `delete` **subcommand** as a whole word —
|
|
53
|
+
sparing the safe look-alikes `config delete-context`, `drain --delete-emptydir-data`,
|
|
54
|
+
`wait --for=delete`, and the read-only `auth can-i delete …` — and splits compound commands on
|
|
55
|
+
`;`/`|`/`&` so a chained `… | xargs kubectl delete` can't slip past. It refuses with the reversible
|
|
56
|
+
alternatives (`scale --replicas=0`, `rollout undo`, GitOps reconcile) and degrades to a no-op without
|
|
57
|
+
`jq`. Wired into the **plugin** (`hooks/hooks.json`) only; intentionally **not** added to the pip-CLI
|
|
58
|
+
scaffold registry, so `claude-kit init` output is unchanged.
|
|
59
|
+
|
|
7
60
|
## [0.20.0] — 2026-06-20
|
|
8
61
|
|
|
9
62
|
**Expand the stack-specific skill collection: 21 new skills + 7 fold-in enhancements + a security pass,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.0
|
|
4
4
|
Summary: Cookiecutter-style scaffolder for an autonomous Claude Code SDLC configuration (no app code, no Docker). Asks ordered questions and installs CLAUDE.md + .claude/ (rules, the chosen profile's agents/skills, hooks, artifact templates) + optional .mcp.json; run /sdlc to drive spec → review → build → test → security → ship through profile-aware quality gates, working memory, and a self-improving learnings loop.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ajyadav013/claude-kit
|
|
6
6
|
Project-URL: Repository, https://github.com/ajyadav013/claude-kit
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Production Engineering Skills Collection
|
|
2
2
|
|
|
3
|
-
These forty-
|
|
3
|
+
These forty-five Claude Code skills encode production-proven engineering conventions derived from real-world Python/FastAPI, Node/Express, and React services. Each skill was extracted from analyzing patterns across multiple production backend and frontend services, capturing canonical patterns for FastAPI microservices, async Python, Kafka/Temporal integration, multi-tenancy, database access, layered configuration, Redis caching, GCS file handling, LLM integration (Vertex AI / Langfuse), Node/Express services, React frontends (state, data-fetching, forms, design systems, testing), observability (including Grafana dashboards & unified alerting), authentication, containerization (with granular Dockerfile/compose deep-dives), testing, data pipelines, security scanning (OWASP ZAP VAPT/DAST and autonomous AI pentesting), security architecture (edge-to-service signed-identity trust boundary, Kubernetes workload hardening), scheduled & recurring jobs (Kubernetes CronJob + Temporal Schedule), kubectl day-2 operations, and modernization strategies. Use them to align new projects with established patterns, audit existing services, or onboard engineers to modern Python, Node, and React development practices.
|
|
4
4
|
|
|
5
5
|
> **Where these live in this repo:** the skill folders are under [`skills/`](../../skills/) (auto-discovered by the claude-kit plugin). The links below point there.
|
|
6
6
|
|
|
@@ -51,6 +51,8 @@ These forty-three Claude Code skills encode production-proven engineering conven
|
|
|
51
51
|
| **shannon-ai-pentest** | Drive Shannon (by Keygraph) — an autonomous **white-box** AI pentest that reads an app's source, plans attacks, runs **real proof-of-concept exploits** against the live app, and reports only proven findings. Documents the external **AGPL-3.0** `npx @keygraph/shannon` CLI (setup/start/status/logs/stop/workspaces + flags), AI-provider & model-tier config (Anthropic/Bedrock/Vertex/proxy), the YAML engagement config (auth + login-flows + TOTP, scope avoid/focus rules, report filters), output layout, and safety. Not bundled — installed separately (complements `zap-vapt-scanning`) | [SKILL.md](../../skills/shannon-ai-pentest/SKILL.md) |
|
|
52
52
|
| **edge-to-service-trust-boundary** | The cryptographic trust contract between an API gateway/edge and the services behind it — edge **HMAC-signs** forwarded identity/tenant headers (signature + timestamp), downstream services **verify with constant-time compare and fail closed**, reject replayed/skewed requests, **detect conflicts** across resolution sources, and still enforce their own authz. Anti-patterns: `verify_signature=False`-then-trust, naked-header trust, fail-open. Complements `auth-and-rbac` + `multi-tenancy-patterns` | [SKILL.md](../../skills/edge-to-service-trust-boundary/SKILL.md) |
|
|
53
53
|
| **kubernetes-workload-hardening** | Runtime/manifest-layer Kubernetes hardening — pod/container `securityContext` (runAsNonRoot, drop-ALL caps, `readOnlyRootFilesystem`, seccomp `RuntimeDefault`), **default-deny NetworkPolicy** + explicit allows, **digest-pinned** images, resource requests/limits, **restricted PodSecurity** admission, least-privilege ServiceAccount/RBAC, and secrets via `secretRef`. The runtime layer atop the `dockerfile-*`/`docker-shared` image-build skills | [SKILL.md](../../skills/kubernetes-workload-hardening/SKILL.md) |
|
|
54
|
+
| **cron-and-scheduled-jobs** | Scheduled/recurring jobs two ways — **Kubernetes CronJob** declared in Helm values (`Crons` block) firing a one-shot `MODE=cron` pod that dispatches a named job from a Python registry, and **Temporal Schedules** (cron vs interval specs, `ScheduleOverlapPolicy.SKIP`, pause-on-failure, idempotent create-or-update registration run as a one-shot k8s `Job`) — how each is configured + invoked, concurrency/timezone/history, and choosing between them | [SKILL.md](../../skills/cron-and-scheduled-jobs/SKILL.md) |
|
|
55
|
+
| **kubectl-operations** | Operating Kubernetes workloads with `kubectl` — the full command surface (get/describe/explain, apply/create/edit/patch/delete, logs/exec/port-forward/cp/debug, rollout/scale/autoscale, config contexts/namespaces, auth can-i, jobs/cronjobs, node cordon/drain) + output formatting (`-o jsonpath/custom-columns/go-template`), label/field selectors, dry-run+diff, and day-2 debugging playbooks (CrashLoopBackOff, ImagePullBackOff, Pending, OOMKilled, cron didn't fire, Service has no endpoints). Context/namespace safety first | [SKILL.md](../../skills/kubectl-operations/SKILL.md) |
|
|
54
56
|
|
|
55
57
|
> **Existing skills extended (this release):** `fastapi-service-patterns` (API versioning + conditional routes), `python-dao-and-database` (MongoDB advanced — aggregation/bulk-upsert/indexes), `temporal-config-driven` (schedule registration), `graphql-patterns` (advanced Apollo Client setup), `containerization-and-deployment` (Makefile dev workflow + Kerberos kinit bootstrap), and `testing-conventions` (GitHub Actions test orchestration) each gained a new section + reference file. A follow-on **security pass** further extended `observability-and-logging` (PII/secret redaction processor + `references/pii-redaction.md`), `testing-conventions` (security-regression tests — negative authz, cross-tenant/RLS, IDOR, lockout, signed-header trust — + `references/security-regression-tests.md`), `graphql-patterns` (a CSRF-token clarification on the Apollo preflight note), and the **core** `security-and-hardening` skill (a CSRF synchronizer-token pattern + an outbound-TLS-verification ban).
|
|
56
58
|
|
|
@@ -101,11 +103,13 @@ These forty-three Claude Code skills encode production-proven engineering conven
|
|
|
101
103
|
- "run Shannon / autonomous or white-box AI pentest / exploit-test an app from its source / set up @keygraph/shannon / proof-by-exploitation report" → **shannon-ai-pentest**
|
|
102
104
|
- "sign forwarded identity headers / verify a gateway HMAC signature / trust x-user-data behind a gateway / fail closed on forwarded identity / prevent header spoofing or direct-to-service bypass" → **edge-to-service-trust-boundary**
|
|
103
105
|
- "harden a Kubernetes Deployment / add securityContext / write a NetworkPolicy / enforce PodSecurity restricted / pin an image digest / least-privilege ServiceAccount + RBAC" → **kubernetes-workload-hardening**
|
|
106
|
+
- "add a cron job / scheduled job / recurring job / declare a CronJob in Helm values / wire a MODE=cron entrypoint / register a Temporal schedule / choose k8s CronJob vs Temporal schedule" → **cron-and-scheduled-jobs**
|
|
107
|
+
- "run kubectl / inspect a Deployment or pod / tail logs / exec into a container / port-forward / roll out or roll back / kubectl -o jsonpath / debug CrashLoopBackOff or ImagePullBackOff / switch kube context or namespace / auth can-i" → **kubectl-operations**
|
|
104
108
|
|
|
105
109
|
4. **References:** Each skill includes a `references/` subdirectory with detailed evidence files showing the exact file paths, snippets, and patterns from source repositories.
|
|
106
110
|
|
|
107
111
|
## Scope and Limitations
|
|
108
112
|
|
|
109
113
|
- **Source:** These skills are derived from real-world production Python/FastAPI and React services as of June 2026. They reflect real-world conventions, including some anti-patterns that are documented for awareness.
|
|
110
|
-
- **Stack coverage:** Python FastAPI + SQLAlchemy (1.4 and 2.0) + Kafka + Temporal + Redis (caching); layered configuration (configargparse + YAML + Pydantic); GCS file ops + Excel/CSV reporting; LLM integration (Claude on Vertex AI via AnthropicVertex + Langfuse tracing); Node/Express + Objection/Knex + Joi; React + Vite + TypeScript (Zustand, TanStack Query, react-hook-form + Zod, Radix + Tailwind, Vitest + RTL + MSW); limited MongoDB (sync pymongo + aggregation/bulk/index patterns); BigQuery/GCS data pipelines; Strawberry GraphQL (backend) + Apollo Client (frontend); Docker + docker-compose + k8s; Cloud Run + GitHub Actions CI/CD; pytest + pytest-asyncio + Playwright; OpenTelemetry + Sentry + Prometheus + NewRelic; Grafana dashboards + unified alerting (Prometheus/Tempo/Pyroscope/managed-cloud datasources); argon2 + JWT + pyotp; Alembic migrations; multi-provider email/SMS notifications; OWASP ZAP VAPT/DAST scanning with automated PDF reporting; Shannon autonomous white-box AI pentesting (an external AGPL-3.0 CLI — documented, not bundled); edge-to-service HMAC-signed forwarded-identity trust boundary; Kubernetes runtime/manifest hardening (securityContext, NetworkPolicy, PodSecurity, RBAC, digest-pinned images).
|
|
114
|
+
- **Stack coverage:** Python FastAPI + SQLAlchemy (1.4 and 2.0) + Kafka + Temporal + Redis (caching); layered configuration (configargparse + YAML + Pydantic); GCS file ops + Excel/CSV reporting; LLM integration (Claude on Vertex AI via AnthropicVertex + Langfuse tracing); Node/Express + Objection/Knex + Joi; React + Vite + TypeScript (Zustand, TanStack Query, react-hook-form + Zod, Radix + Tailwind, Vitest + RTL + MSW); limited MongoDB (sync pymongo + aggregation/bulk/index patterns); BigQuery/GCS data pipelines; Strawberry GraphQL (backend) + Apollo Client (frontend); Docker + docker-compose + k8s; Cloud Run + GitHub Actions CI/CD; pytest + pytest-asyncio + Playwright; OpenTelemetry + Sentry + Prometheus + NewRelic; Grafana dashboards + unified alerting (Prometheus/Tempo/Pyroscope/managed-cloud datasources); argon2 + JWT + pyotp; Alembic migrations; multi-provider email/SMS notifications; OWASP ZAP VAPT/DAST scanning with automated PDF reporting; Shannon autonomous white-box AI pentesting (an external AGPL-3.0 CLI — documented, not bundled); edge-to-service HMAC-signed forwarded-identity trust boundary; Kubernetes runtime/manifest hardening (securityContext, NetworkPolicy, PodSecurity, RBAC, digest-pinned images); scheduled/recurring jobs (Kubernetes CronJob declared in Helm values + Temporal Schedules); kubectl day-2 operations (full command surface, output formatting/JSONPath, contexts/RBAC, debugging playbooks).
|
|
111
115
|
- **What's NOT covered:** SQLModel, Tortoise ORM, beanie/motor (async MongoDB), Django, Flask, and non-Express Node frameworks (NestJS, Fastify). These were absent (or single-repo only) in the analyzed codebases and were deliberately not created.
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
{ "type": "command", "command": "CMD=$(jq -r '.tool_input.command'); if echo \"$CMD\" | grep -qE 'rm[[:space:]]+-[^[:space:]]*r[^[:space:]]*f'; then echo 'BLOCKED: rm -rf is disabled by claude-kit. Move to trash or delete specific paths explicitly.' >&2; exit 2; fi" },
|
|
19
19
|
{ "type": "command", "command": "CMD=$(jq -r '.tool_input.command'); if echo \"$CMD\" | grep -qE 'git[[:space:]]+push.*[[:space:]:](main|master)([[:space:]]|$)'; then echo 'BLOCKED: refusing to push to main/master — use a feature branch and a PR.' >&2; exit 2; fi" },
|
|
20
20
|
{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/guard-destructive-git.sh\"" },
|
|
21
|
-
{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/guard-secrets.sh\"" }
|
|
21
|
+
{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/guard-secrets.sh\"" },
|
|
22
|
+
{ "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/guard-kubectl-delete.sh\"" }
|
|
22
23
|
]
|
|
23
24
|
},
|
|
24
25
|
{
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse(Bash): BLOCK `kubectl delete` — destructive deletes must not run from an agent session.
|
|
3
|
+
#
|
|
4
|
+
# Why a guard (block, exit 2) and not a warn: a delete is irreversible and trivially misfires against
|
|
5
|
+
# the wrong namespace or cluster. A PreToolUse advisory would be theatre — the resource would already
|
|
6
|
+
# be gone. So this refuses and points at the reversible alternatives (scale to 0, rollout undo, or
|
|
7
|
+
# removing the object from the Git/Helm source and letting the pipeline reconcile). It joins the
|
|
8
|
+
# guard-rm-rf / guard-push-main / guard-destructive-git destructive-command family.
|
|
9
|
+
#
|
|
10
|
+
# Scope is deliberately the `delete` SUBCOMMAND only, matched as a whole word, so it spares the safe
|
|
11
|
+
# look-alikes that merely contain the string "delete":
|
|
12
|
+
# - `kubectl config delete-context|delete-cluster|delete-user` (local kubeconfig edits, hyphenated)
|
|
13
|
+
# - `kubectl drain ... --delete-emptydir-data` (a drain flag, hyphenated)
|
|
14
|
+
# - `kubectl wait --for=delete ...` (a wait condition, after '=')
|
|
15
|
+
# - `kubectl auth can-i delete <res>` (a READ-ONLY RBAC query)
|
|
16
|
+
# Compound commands are split on ; | & first, so a chained delete (e.g. `get -o name | xargs kubectl
|
|
17
|
+
# delete`) is caught per-segment. Threat model: this prevents accidental agent deletes, not a determined
|
|
18
|
+
# operator who deliberately crafts a bypass string (they own the machine and can disable the hook).
|
|
19
|
+
#
|
|
20
|
+
# Degrades to a no-op (fail-open) without jq — consistent with the other script-backed guards.
|
|
21
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
22
|
+
CMD="$(jq -r '.tool_input.command // empty' 2>/dev/null || true)"
|
|
23
|
+
[ -z "$CMD" ] && exit 0
|
|
24
|
+
|
|
25
|
+
# Split on shell separators → one segment per line; drop read-only `auth can-i` queries; keep only
|
|
26
|
+
# kubectl segments; then look for a bare `delete` verb (not delete-context, --delete-*, or --for=delete).
|
|
27
|
+
if printf '%s' "$CMD" | tr ';|&' '\n\n\n' \
|
|
28
|
+
| grep -vE 'auth[[:space:]]+can-i' \
|
|
29
|
+
| grep -E '(^|[[:space:]])kubectl(\.exe)?[[:space:]]' \
|
|
30
|
+
| grep -qE '(^|[[:space:]])delete([[:space:]]|$)'; then
|
|
31
|
+
echo "BLOCKED: 'kubectl delete' is disabled by claude-kit — destructive deletes must not run from an agent session." >&2
|
|
32
|
+
echo " Use a reversible alternative: 'kubectl scale --replicas=0' to stop a workload, 'kubectl rollout undo' to roll back," >&2
|
|
33
|
+
echo " or remove the resource from the Git/Helm source and let the pipeline reconcile." >&2
|
|
34
|
+
echo " Read-only checks still work ('kubectl auth can-i delete <res>', 'kubectl get/describe'). (guard-kubectl-delete.sh)" >&2
|
|
35
|
+
exit 2
|
|
36
|
+
fi
|
|
37
|
+
exit 0
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "claude-code-kit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.21.0"
|
|
8
8
|
description = "Cookiecutter-style scaffolder for an autonomous Claude Code SDLC configuration (no app code, no Docker). Asks ordered questions and installs CLAUDE.md + .claude/ (rules, the chosen profile's agents/skills, hooks, artifact templates) + optional .mcp.json; run /sdlc to drive spec → review → build → test → security → ship through profile-aware quality gates, working memory, and a self-improving learnings loop."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Cron & Scheduled Jobs
|
|
2
|
+
|
|
3
|
+
A stack-derived skill for **scheduled / recurring jobs** as this stack actually runs them — across the
|
|
4
|
+
two mechanisms it uses and where each one keeps the schedule.
|
|
5
|
+
|
|
6
|
+
The same business need ("run this every night") is implemented two opposite ways here, and the
|
|
7
|
+
confusing part is *where the schedule lives*:
|
|
8
|
+
|
|
9
|
+
- **Kubernetes CronJob** — the schedule is **Helm config** (`Crons.<name>.Schedule`); the cluster fires
|
|
10
|
+
a one-shot pod that runs the shared image in `MODE=cron` and dispatches a single named job from a
|
|
11
|
+
Python registry, then exits. There is no in-app scheduler.
|
|
12
|
+
- **Temporal Schedule** — the schedule is a **server-owned object** registered by a one-shot deploy step;
|
|
13
|
+
Temporal fires a workflow, with overlap policy, pause-on-failure, catch-up, and manual triggers.
|
|
14
|
+
|
|
15
|
+
## What this skill covers
|
|
16
|
+
|
|
17
|
+
- **k8s CronJob route**: the Helm `Crons` values block → the rendered `CronJob` and its defaults
|
|
18
|
+
(`concurrencyPolicy: Forbid`, history limits, `restartPolicy: Never`, `ttlSecondsAfterFinished`); the
|
|
19
|
+
`MODE=cron` + `CRON_JOB` entrypoint dispatch; the one-shot runner; simple vs rich cron registries;
|
|
20
|
+
the execution metric and retry; and the chart's missing `timeZone`/`startingDeadlineSeconds`.
|
|
21
|
+
- **Temporal Schedule route**: `cron_expressions` vs `ScheduleIntervalSpec` (and why intervals dodge the
|
|
22
|
+
UTC-cron foot-gun); `ScheduleOverlapPolicy.SKIP` + `pause_on_failure`; idempotent create-or-update
|
|
23
|
+
registration; the one-shot k8s `Job` that registers a schedule; manual trigger and lifecycle helpers.
|
|
24
|
+
- **Choosing between them** and the cross-cutting operational concerns (concurrency, timezone, history,
|
|
25
|
+
missed runs, suspend vs pause, observability).
|
|
26
|
+
|
|
27
|
+
## Relationship to other skills
|
|
28
|
+
|
|
29
|
+
- `temporal-config-driven` — the **workflow/activity/worker** mechanics (retries, idempotency, worker
|
|
30
|
+
bootstrap) and the deeper schedule-registration reference. This skill owns the **scheduling /
|
|
31
|
+
recurrence dimension** and the **CronJob-vs-Temporal decision**, and cross-links rather than repeats.
|
|
32
|
+
- `containerization-and-deployment` — the multi-`MODE` entrypoint and Helm packaging that the CronJob
|
|
33
|
+
route builds on.
|
|
34
|
+
- `kubernetes-workload-hardening` — securityContext / NetworkPolicy / resources for the CronJob pod.
|
|
35
|
+
- `observability-and-logging` — the `record_cron_job_executed` metric and alerting on missing runs.
|
|
36
|
+
|
|
37
|
+
## How to use
|
|
38
|
+
|
|
39
|
+
Read `SKILL.md` for the conventions, the two-mechanism decision table, and both copy-ready skeletons.
|
|
40
|
+
See `references/` for the field-by-field Helm/CronJob detail, the Temporal schedule patterns, and the
|
|
41
|
+
operational decision matrix.
|
|
42
|
+
|
|
43
|
+
> Stack-derived: encodes a real Python/FastAPI + Kubernetes + Temporal deployment topology. **Not**
|
|
44
|
+
> wired into `claude-kit init`; install it deliberately. All names (service, registry, namespace, job
|
|
45
|
+
> names, hosts) are generic placeholders — no internal services, hosts, project IDs, or cluster names.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cron-and-scheduled-jobs
|
|
3
|
+
description: Scheduled / recurring jobs across the two mechanisms this stack uses — Kubernetes CronJobs (the schedule is declared in Helm values under a Crons block, and the app is invoked one-shot via MODE=cron + CRON_JOB into a Python cron registry) and Temporal Schedules (recurrence owned by the Temporal server via cron_expressions or interval specs, with overlap policy, pause-on-failure, and idempotent create-or-update registration run as a one-shot k8s Job). Covers how each is configured, how the schedule maps to the code that runs, concurrency/timezone/history, observability, and choosing between them. Use when adding a periodic or scheduled job, wiring a MODE=cron entrypoint and cron registry, declaring a CronJob in Helm values, registering or updating a Temporal schedule, or deciding between a Kubernetes CronJob and a Temporal Schedule.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cron & Scheduled Jobs
|
|
7
|
+
|
|
8
|
+
Two mechanisms run recurring work in this stack, and they put the *schedule* in two very different
|
|
9
|
+
places. Knowing which one you're in tells you where the schedule lives and what owns the recurrence:
|
|
10
|
+
|
|
11
|
+
1. **Kubernetes CronJob** — the cluster's `CronJob` controller is the scheduler. It fires a fresh pod
|
|
12
|
+
on the schedule; the pod runs the **same service image** booted in a one-shot `MODE=cron` that
|
|
13
|
+
executes a single named job from a Python registry and exits. The schedule lives in **Helm values**,
|
|
14
|
+
never in the app.
|
|
15
|
+
2. **Temporal Schedule** — the **Temporal server** is the durable scheduler. A `Schedule` object fires
|
|
16
|
+
a workflow on a cron expression or interval; a missed window, catch-up, pause, and backfill are all
|
|
17
|
+
first-class. The schedule lives in **a registration step** (run once / idempotently on deploy).
|
|
18
|
+
|
|
19
|
+
> Companion skills: `temporal-config-driven` (workflow/activity/worker mechanics, retries, idempotency,
|
|
20
|
+
> and the deeper schedule-registration reference — this skill cross-links it rather than repeating it),
|
|
21
|
+
> `containerization-and-deployment` (the `MODE`-dispatch entrypoint and Helm packaging),
|
|
22
|
+
> `kubernetes-workload-hardening` (securityContext/NetworkPolicy for the CronJob pod), and
|
|
23
|
+
> `observability-and-logging` (the cron execution metric).
|
|
24
|
+
|
|
25
|
+
## When to use
|
|
26
|
+
|
|
27
|
+
- Adding a **periodic / scheduled job** to a service and deciding where the schedule belongs
|
|
28
|
+
- Wiring a **`MODE=cron` entrypoint** and registering a job in the **Python cron registry**
|
|
29
|
+
- Declaring a **CronJob in Helm values** (`Crons` block) and understanding the rendered manifest
|
|
30
|
+
- **Registering or updating a Temporal Schedule** (cron vs interval, overlap, pause-on-failure)
|
|
31
|
+
- Deploying schedule registration as a **one-shot k8s `Job`**
|
|
32
|
+
- Choosing between a **Kubernetes CronJob** and a **Temporal Schedule**
|
|
33
|
+
- Debugging "the job didn't run", overlapping runs, timezone drift, or piled-up executions
|
|
34
|
+
|
|
35
|
+
## Two mechanisms at a glance
|
|
36
|
+
|
|
37
|
+
| | **Kubernetes CronJob + `MODE=cron`** | **Temporal Schedule** |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| Scheduler | k8s `CronJob` controller | Temporal server |
|
|
40
|
+
| Where the schedule lives | Helm `values.yaml` → `Crons.<name>.Schedule` | a registration step (`create_schedule`) |
|
|
41
|
+
| What runs | one-shot pod: `MODE=cron CRON_JOB=<name>` → registry handler → exit | a Temporal workflow |
|
|
42
|
+
| Recurrence units | 5-field cron only | cron **or** interval (`every=` + `offset=`) |
|
|
43
|
+
| Overlap control | `concurrencyPolicy: Forbid` (coarse) | `ScheduleOverlapPolicy.SKIP/BUFFER_ONE/...` (rich) |
|
|
44
|
+
| Missed-run visibility | none (the pod just didn't run) | first-class (server tracks it) |
|
|
45
|
+
| Pause / backfill / manual fire | suspend the CronJob (no backfill) | `pause`/`unpause`/`backfill`/`trigger` |
|
|
46
|
+
| Retry across fires | none (pod exits; next fire is fresh) | per-fire `pause_on_failure` + workflow RetryPolicy |
|
|
47
|
+
| Best for | simple, self-contained periodic app tasks | durable/long jobs needing overlap, catch-up, visibility |
|
|
48
|
+
|
|
49
|
+
## Core conventions
|
|
50
|
+
|
|
51
|
+
### Kubernetes CronJob + `MODE=cron`
|
|
52
|
+
|
|
53
|
+
**The schedule is config, not code.** You declare a cron under the service's `Crons` block in Helm
|
|
54
|
+
values; the chart renders one `kind: CronJob` per entry. The job's *only* app-side coupling is two env
|
|
55
|
+
vars — `MODE=cron` and `CRON_JOB=<name>` — that tell the shared image which single job to run.
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
# Helm values — Projects.<service>.Crons.<job-name>
|
|
59
|
+
Crons:
|
|
60
|
+
nightly-report:
|
|
61
|
+
Schedule: "0 2 * * *" # 5-field cron (the authoritative schedule)
|
|
62
|
+
Envs:
|
|
63
|
+
MODE: cron # boot the image in one-shot cron mode
|
|
64
|
+
CRON_JOB: nightly-report # which registry entry to run
|
|
65
|
+
ConcurrencyPolicy: Forbid # default; don't start a fire if the last is still running
|
|
66
|
+
Suspend: false # set true to pause without deleting
|
|
67
|
+
TtlSecondsAfterFinished: 300 # GC the finished Job pod
|
|
68
|
+
# Parallelism, Resources, NodeSelector, Tolerations also supported
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The rendered CronJob carries sensible defaults from the chart: `concurrencyPolicy: Forbid`,
|
|
72
|
+
`failedJobsHistoryLimit: 3`, `successfulJobsHistoryLimit: 1`, `restartPolicy: Never`,
|
|
73
|
+
`ttlSecondsAfterFinished: 300`. **The chart has no `timeZone` and no `startingDeadlineSeconds`** — so
|
|
74
|
+
the schedule evaluates in the cluster's timezone (usually UTC) and a controller that's down past a fire
|
|
75
|
+
window silently skips it. Plan around both (see `references/choosing-and-operations.md`).
|
|
76
|
+
|
|
77
|
+
**The app side is a one-shot dispatcher, not a daemon.** A multi-mode `entrypoint.py` reads `MODE`; the
|
|
78
|
+
`cron` branch runs a single job from a registry and the process exits. There is no in-process scheduler
|
|
79
|
+
or loop — k8s owns the cadence.
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
# entrypoint.py — the cron branch of the MODE dispatch
|
|
83
|
+
if MODE == "cron": # (server / consumer / worker / temporal_worker handled above)
|
|
84
|
+
from crons.run import main as cron_main
|
|
85
|
+
asyncio.run(cron_main()) # runs ONE job named by CRON_JOB, then exits
|
|
86
|
+
|
|
87
|
+
# crons/run.py — look up CRON_JOB, run it once, record the outcome
|
|
88
|
+
async def main():
|
|
89
|
+
name = loaded_config.CRON_JOB
|
|
90
|
+
entry = CRON_TASKS.get(name)
|
|
91
|
+
if not entry:
|
|
92
|
+
raise ValueError(f"No cron job found for name: {name}")
|
|
93
|
+
start = asyncio.get_event_loop().time()
|
|
94
|
+
try:
|
|
95
|
+
result = await entry["task"]() # one-shot
|
|
96
|
+
record_cron_job_executed(name, "success", asyncio.get_event_loop().time() - start)
|
|
97
|
+
return result
|
|
98
|
+
except Exception:
|
|
99
|
+
record_cron_job_executed(name, "error", asyncio.get_event_loop().time() - start)
|
|
100
|
+
raise
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**The registry maps a name to a handler.** Two shapes are common — a plain `name → async callable`, or a
|
|
104
|
+
richer `name → {task, description, schedule}`. In the rich shape the `schedule` field is
|
|
105
|
+
**documentation only**; the authoritative schedule is the Helm `Crons` entry. Keep them in sync by
|
|
106
|
+
convention (the registry comment should point at the Helm values).
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
# crons/registry.py — rich shape (schedule is a doc hint, NOT the real schedule)
|
|
110
|
+
CRON_TASKS = {
|
|
111
|
+
"nightly-report": {
|
|
112
|
+
"task": generate_nightly_report,
|
|
113
|
+
"description": "Aggregate yesterday's events into the report table",
|
|
114
|
+
"schedule": "0 2 * * *", # for reference; defined for real in Helm values
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
# simple shape: CRON_TASKS = {"nightly-report": generate_nightly_report}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Conventions that matter for CronJobs:
|
|
121
|
+
- **Idempotency is the job's responsibility.** `concurrencyPolicy: Forbid` prevents *overlap*, not
|
|
122
|
+
*re-runs* — a retried/late fire may reprocess the same window. Make the handler safe to run twice
|
|
123
|
+
(upsert, watermark/cursor, or a dedupe key).
|
|
124
|
+
- **Exit non-zero on failure.** `restartPolicy: Never` + a raised exception marks the Job failed and
|
|
125
|
+
surfaces in `failedJobsHistoryLimit`. Don't swallow the exception.
|
|
126
|
+
- **Handle SIGTERM** for a graceful stop on pod eviction/rollout.
|
|
127
|
+
- **Emit the execution metric** (`record_cron_job_executed(name, status, duration)`) so cron health is
|
|
128
|
+
observable — see `observability-and-logging`.
|
|
129
|
+
|
|
130
|
+
### Temporal Schedule
|
|
131
|
+
|
|
132
|
+
When the work is already a Temporal workflow, or needs durability / overlap control / catch-up /
|
|
133
|
+
visibility, let the Temporal **server** own the recurrence with a `Schedule`. The workflow/activity
|
|
134
|
+
mechanics live in `temporal-config-driven`; this skill covers the **scheduling dimension**.
|
|
135
|
+
|
|
136
|
+
**Prefer an interval spec over a cron expression for daily-ish cadences.** Temporal evaluates
|
|
137
|
+
`cron_expressions` in **UTC** by default (the chart/clients here don't set `time_zone`), so
|
|
138
|
+
`["0 9 * * *"]` fires at 09:00 *UTC*, not local. An interval with an offset is timezone-explicit and
|
|
139
|
+
avoids the foot-gun:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from datetime import timedelta
|
|
143
|
+
from temporalio.client import (
|
|
144
|
+
Schedule, ScheduleActionStartWorkflow, ScheduleIntervalSpec,
|
|
145
|
+
ScheduleOverlapPolicy, SchedulePolicy, ScheduleSpec,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Two fires/day, offset so they land at ~09:00 / 21:00 local (UTC+5:30 here):
|
|
149
|
+
spec = ScheduleSpec(
|
|
150
|
+
intervals=[ScheduleIntervalSpec(every=timedelta(hours=12), offset=timedelta(hours=3, minutes=30))]
|
|
151
|
+
)
|
|
152
|
+
# (cron form, if you must: ScheduleSpec(cron_expressions=["0 2 * * *"]) — remember it's UTC)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Register idempotently, and run it as a one-shot Job.** Build the schedule from the `spec` above plus
|
|
156
|
+
an `action` and `policy`, then register it safely:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
schedule = Schedule(
|
|
160
|
+
action=ScheduleActionStartWorkflow(ReportWorkflow.run, {"mode": "daily"},
|
|
161
|
+
id="nightly-report-run", task_queue="report-queue"),
|
|
162
|
+
spec=spec,
|
|
163
|
+
policy=SchedulePolicy(overlap=ScheduleOverlapPolicy.SKIP, pause_on_failure=True),
|
|
164
|
+
)
|
|
165
|
+
# create-or-update: try client.create_schedule(...) / except "already exists" -> handle.update(...)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Registration is a deploy step, not worker startup** — a separate one-shot k8s `kind: Job` (not a
|
|
169
|
+
CronJob) runs `python -m <pkg>.schedules ensure` after the worker Deployment is up, writing the schedule
|
|
170
|
+
into Temporal, which then fires it. The full create-or-update loop, the CLI, and the lifecycle helpers
|
|
171
|
+
(`pause`/`unpause`/`delete`/`update`) are owned by the **`temporal-config-driven`** skill; the Job
|
|
172
|
+
manifest, the interval/overlap details, and the manual-trigger snippet are in
|
|
173
|
+
`references/temporal-schedules.md`.
|
|
174
|
+
|
|
175
|
+
### Choosing between them
|
|
176
|
+
|
|
177
|
+
- **Kubernetes CronJob** when the task is a simple, self-contained periodic job, runs to completion in
|
|
178
|
+
one shot, and `Forbid` overlap is enough. Lowest moving parts; the schedule is plain Helm config.
|
|
179
|
+
- **Temporal Schedule** when the job is long or durable, needs **overlap policy** finer than Forbid,
|
|
180
|
+
**catch-up / backfill**, **per-fire pause-on-failure**, **missed-run visibility**, or is already a
|
|
181
|
+
Temporal workflow. The server gives you scheduling observability a CronJob can't.
|
|
182
|
+
|
|
183
|
+
Don't run both for the same job (double fires). See `references/choosing-and-operations.md` for the
|
|
184
|
+
full decision matrix and the timezone/overlap/history details.
|
|
185
|
+
|
|
186
|
+
## Skeleton / example
|
|
187
|
+
|
|
188
|
+
A "nightly report" job, shown both ways. **Pick one** — they're alternatives, not layers.
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
Kubernetes CronJob route Temporal Schedule route
|
|
192
|
+
──────────────────────── ───────────────────────
|
|
193
|
+
Helm values: Crons.nightly-report schedules.py: ensure() create-or-update
|
|
194
|
+
Schedule "0 2 * * *" ScheduleSpec(intervals=[every=24h, offset=...])
|
|
195
|
+
Envs MODE=cron CRON_JOB=nightly-report overlap=SKIP, pause_on_failure=True
|
|
196
|
+
│ k8s CronJob controller fires a pod deploy: one-shot Job runs `... schedules ensure`
|
|
197
|
+
▼ │ Temporal server fires the workflow
|
|
198
|
+
entrypoint MODE=cron → crons/run.main() ▼
|
|
199
|
+
CRON_TASKS["nightly-report"]["task"]() ReportWorkflow.run (worker consumes it)
|
|
200
|
+
record_cron_job_executed(...) → exit
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
See `references/kubernetes-cronjob.md` and `references/temporal-schedules.md` for the complete,
|
|
204
|
+
copy-ready versions of each.
|
|
205
|
+
|
|
206
|
+
## Anti-patterns to avoid
|
|
207
|
+
|
|
208
|
+
- **Putting the real schedule in app config.** For the k8s route the registry's `schedule` field is a
|
|
209
|
+
doc hint only — the cluster reads the Helm `Crons.Schedule`. Editing the Python value changes nothing.
|
|
210
|
+
- **Assuming local time.** Both k8s CronJob (no `timeZone` in this chart) and Temporal `cron_expressions`
|
|
211
|
+
evaluate in **UTC** here. Use interval+offset (Temporal) or compute the UTC cron, and write the
|
|
212
|
+
intended local time in a comment.
|
|
213
|
+
- **Relying on `concurrencyPolicy` for correctness.** `Forbid` stops overlap, not duplicate processing.
|
|
214
|
+
Non-idempotent handlers corrupt data on a late/retried fire.
|
|
215
|
+
- **Swallowing the exception** so the pod exits 0 — the failure never shows in
|
|
216
|
+
`failedJobsHistoryLimit` and the job looks healthy while doing nothing.
|
|
217
|
+
- **Registering a Temporal schedule at worker startup**, or with a bare `create_schedule` that crashes
|
|
218
|
+
the second deploy on "already exists." Use a one-shot Job + create-or-update.
|
|
219
|
+
- **Confusing a registration `Job` with a `CronJob`.** The schedule-registration manifest is a `Job`
|
|
220
|
+
(runs once); the recurrence is owned by Temporal, not by re-running the Job.
|
|
221
|
+
- **Running the same job as both a k8s CronJob and a Temporal schedule** — it fires twice.
|
|
222
|
+
- **No execution metric / no alert** — a cron that silently stops is invisible until something
|
|
223
|
+
downstream is missing. Emit `record_cron_job_executed` and alert on missing successes.
|
|
224
|
+
- **Unbounded history / no TTL** — leftover Job pods pile up; keep `ttlSecondsAfterFinished` and the
|
|
225
|
+
history limits.
|
|
226
|
+
|
|
227
|
+
## References
|
|
228
|
+
|
|
229
|
+
- [kubernetes-cronjob.md](./references/kubernetes-cronjob.md) — The Helm `Crons` values schema, the
|
|
230
|
+
rendered CronJob and its defaults, the `MODE=cron` entrypoint + one-shot runner, registry shapes,
|
|
231
|
+
instrumentation/retry, and the `timeZone`/`startingDeadlineSeconds` gaps.
|
|
232
|
+
- [temporal-schedules.md](./references/temporal-schedules.md) — Cron vs interval specs, overlap and
|
|
233
|
+
pause-on-failure policy, idempotent create-or-update registration, the one-shot registration Job,
|
|
234
|
+
manual trigger, and lifecycle helpers (cross-links `temporal-config-driven`).
|
|
235
|
+
- [choosing-and-operations.md](./references/choosing-and-operations.md) — Decision matrix and the
|
|
236
|
+
cross-cutting operational concerns: concurrency, timezone, history limits, missed runs/catch-up,
|
|
237
|
+
suspend vs pause, and observability.
|
|
238
|
+
- [repo-evidence.md](./references/repo-evidence.md) — Representative patterns described generically.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Choosing a mechanism + operational concerns (reference)
|
|
2
|
+
|
|
3
|
+
## Decision matrix
|
|
4
|
+
|
|
5
|
+
Start from the job's needs, not the tooling. Walk these in order — the first "yes" usually decides it.
|
|
6
|
+
|
|
7
|
+
| Question | If yes → |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Is the work already a Temporal workflow? | **Temporal Schedule** (don't fork it into a CronJob) |
|
|
10
|
+
| Must a *missed* fire be visible / caught up later? | **Temporal Schedule** (server tracks missed windows; the CronJob chart has no `startingDeadlineSeconds`) |
|
|
11
|
+
| Do you need overlap handling finer than "skip if running"? | **Temporal Schedule** (`BUFFER_ONE`, `CANCEL_OTHER`, …) |
|
|
12
|
+
| Should a failing run pause the schedule (not fire-and-fail forever)? | **Temporal Schedule** (`pause_on_failure`) |
|
|
13
|
+
| Do you need backfill / replay of past windows? | **Temporal Schedule** |
|
|
14
|
+
| Is the run long-lived and must survive worker/pod restarts mid-run? | **Temporal Schedule** (durable workflow) |
|
|
15
|
+
| Is it a short, self-contained task where "skip if still running" is enough? | **Kubernetes CronJob** |
|
|
16
|
+
| Do you want the fewest moving parts and the schedule as plain Helm config? | **Kubernetes CronJob** |
|
|
17
|
+
|
|
18
|
+
Rules of thumb:
|
|
19
|
+
- **Default to the k8s CronJob** for simple periodic app tasks — it's the least machinery and the
|
|
20
|
+
schedule is one line of Helm config.
|
|
21
|
+
- **Reach for Temporal** the moment you need scheduling *observability or control* the CronJob can't
|
|
22
|
+
give you (missed-run tracking, overlap policy, pause-on-failure, backfill, durability).
|
|
23
|
+
- **Never run both** for the same logical job — it fires twice. Pick one home for the schedule.
|
|
24
|
+
|
|
25
|
+
## Concurrency / overlap
|
|
26
|
+
|
|
27
|
+
- **k8s CronJob:** `concurrencyPolicy` is coarse — `Forbid` (default here; skip if the last is still
|
|
28
|
+
running), `Allow`, or `Replace`. It prevents overlapping *pods*; it does **not** make a handler
|
|
29
|
+
exactly-once. A late or manually re-triggered fire can still reprocess a window — the handler must be
|
|
30
|
+
idempotent.
|
|
31
|
+
- **Temporal:** `ScheduleOverlapPolicy` is rich — `SKIP` (convention here), `BUFFER_ONE`, `BUFFER_ALL`,
|
|
32
|
+
`CANCEL_OTHER`, `TERMINATE_OTHER`, `ALLOW_ALL`. Choose based on whether a long run should skip,
|
|
33
|
+
queue, or pre-empt the next.
|
|
34
|
+
|
|
35
|
+
## Timezone
|
|
36
|
+
|
|
37
|
+
Both routes default to **UTC** here, and getting this wrong is the most common "it ran at the wrong
|
|
38
|
+
time" bug:
|
|
39
|
+
- **k8s CronJob:** the chart sets no `timeZone`, so `Schedule` evaluates in the cluster zone (UTC).
|
|
40
|
+
Compute the UTC time for your intended local hour, and comment the local intent
|
|
41
|
+
(`# 07:30 UTC = 13:00 IST`).
|
|
42
|
+
- **Temporal:** `cron_expressions` evaluate in UTC unless `time_zone` is set (it isn't here). Prefer a
|
|
43
|
+
`ScheduleIntervalSpec(every=..., offset=...)` — the offset places the fire at the local wall-clock
|
|
44
|
+
time explicitly and dodges DST/zone ambiguity for fixed-interval cadences.
|
|
45
|
+
|
|
46
|
+
## Missed runs / catch-up
|
|
47
|
+
|
|
48
|
+
- **k8s CronJob:** no `startingDeadlineSeconds` in this chart → if the controller is down across a fire
|
|
49
|
+
window, that fire is **silently skipped**, no catch-up. For jobs where a missed run matters, either
|
|
50
|
+
move to Temporal or add an external "did it run in the last N hours?" alert keyed on the execution
|
|
51
|
+
metric.
|
|
52
|
+
- **Temporal:** the server records missed windows; overlap/backfill policies decide whether to catch up.
|
|
53
|
+
|
|
54
|
+
## History / cleanup
|
|
55
|
+
|
|
56
|
+
- **k8s CronJob:** the chart fixes `failedJobsHistoryLimit: 3` and `successfulJobsHistoryLimit: 1`, and
|
|
57
|
+
`ttlSecondsAfterFinished` (default 300) GCs finished Job pods. Keep these bounded so pods don't pile
|
|
58
|
+
up; bump the failed-history limit temporarily when debugging a flaky job.
|
|
59
|
+
- **Temporal:** runs are workflow executions, retained per the namespace's retention policy and visible
|
|
60
|
+
in the Temporal UI.
|
|
61
|
+
|
|
62
|
+
## Suspend vs pause
|
|
63
|
+
|
|
64
|
+
- **k8s CronJob:** `Suspend: true` in Helm values (renders `suspend: true`) stops new fires without
|
|
65
|
+
deleting the CronJob. In-flight jobs continue. `Ignore: true` removes the CronJob from the render
|
|
66
|
+
entirely.
|
|
67
|
+
- **Temporal:** `pause()/unpause()` on the schedule handle (also auto-paused by `pause_on_failure`).
|
|
68
|
+
Paused schedules keep their definition and history; unpausing resumes future fires.
|
|
69
|
+
|
|
70
|
+
## Observability
|
|
71
|
+
|
|
72
|
+
- Emit `record_cron_job_executed(name, "success"|"error", duration_seconds)` from the cron runner so
|
|
73
|
+
every fire is a data point (see `observability-and-logging`). Build the alert on **absence of
|
|
74
|
+
success** (a cron that silently stops is invisible otherwise), not just on errors.
|
|
75
|
+
- For Temporal, the server UI shows recent/next fires, paused state, and per-run history — but still
|
|
76
|
+
alert on "no successful run in the expected window" so a paused-on-failure schedule is noticed.
|
|
77
|
+
- Log with the job name and a run/correlation id so a single fire is greppable end to end.
|
|
78
|
+
|
|
79
|
+
## Idempotency (both routes)
|
|
80
|
+
|
|
81
|
+
Neither route guarantees exactly-once delivery of *effects*. Design every scheduled handler to be safe
|
|
82
|
+
to run twice:
|
|
83
|
+
- upsert instead of insert; carry a watermark/cursor; or derive a deterministic dedupe/run key from the
|
|
84
|
+
window (e.g. the date) so re-processing the same window is a no-op.
|
|
85
|
+
- For Temporal, a deterministic workflow id per window makes a duplicate fire a no-op (the server
|
|
86
|
+
rejects a duplicate running id); see `temporal-config-driven` for `activity_id`-based idempotency.
|