@ccoalm/ccl-skills 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +49 -0
- package/dist/assets/marketplace/.agents/plugins/marketplace.json +12 -0
- package/dist/assets/marketplace/.claude-plugin/marketplace.json +13 -0
- package/dist/assets/marketplace/marketplace-manifest.json +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.claude-plugin/marketplace.json +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.claude-plugin/plugin.json +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.codex-plugin/plugin.json +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.worktree-only +3 -0
- package/dist/assets/marketplace/plugins/ccl-skills/agent-context/session-start.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/agent-context/subagent-start.md +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/AGENTS.md +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-delegation-owner.sh +125 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-edit-isolation.sh +102 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-merge-authorization.sh +1156 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/merge-authorization-prompt.sh +142 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/owner-dispatch-guard.sh +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/owner-dispatch-stop.sh +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-post-merge-cleanup.sh +144 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/session-context.sh +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/session-start.sh +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/skill-extraction-gate-stop.sh +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/subagent-start.sh +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_delegation_owner.sh +329 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_edit_isolation.sh +322 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_merge_authorization.sh +902 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_merge_authorization_prompt.sh +178 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_post_merge_cleanup.sh +121 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_session_start.sh +170 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/AGENTS.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +564 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-install-skills.md +14 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-update-skills.md +44 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-verify-skills.md +109 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-worktree-check.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/AGENTS.md +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/README.md +276 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.example.json +10 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.sh +1307 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/test.sh +941 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/agents-file-coverage-gate/SKILL.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/agents-file-coverage-gate/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/SKILL.md +188 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/android-dev.md +92 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/flutter-dev.md +80 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/ios-dev.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/kotlin-multiplatform.md +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-platform-boundaries.md +77 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-quality-release.md +77 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/source-evidence-map.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/SKILL.md +353 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/client-routing.md +419 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/manual-invocation-and-prompts.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +197 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/timeout-auth-and-capabilities.md +179 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/AGENTS.md +98 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_envelope.py +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_timeout_exit.sh +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/claude_review.sh +1438 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/codex_review.sh +324 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/concern_excerpt.py +295 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/egress_schema.py +214 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/init_policy_matrix.py +642 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_packet_mcp.py +181 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_review.sh +1165 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/opencode_review.sh +1190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_cli_review.py +946 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_opencode_review.py +474 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_probe_result.py +1899 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_review_json.py +200 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +2845 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.sh +6 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/run_claude_capture.py +71 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/runtime-surface-verification-design.md +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_classify_envelope.sh +68 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_claude_review_probe.sh +2311 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_cli_review_wrappers.sh +1832 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_code_review_identity.sh +73 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_concern_excerpt.sh +245 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_egress_schema.sh +177 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_init_policy_matrix.sh +272 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_kimi_packet_mcp.py +195 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_opencode_review_concurrency.sh +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_opencode_review_retry.sh +1005 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_opencode_review.sh +258 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_probe_result.sh +574 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_review_json.sh +349 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +434 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_order.sh +264 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +2412 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/verify_native_skill_binding.py +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/SKILL.md +153 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/references/diagnosis-playbook.md +54 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/references/prevention-routing.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/SKILL.md +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/references/security-review-gate.md +41 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/SKILL.md +165 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/api-security-boundaries.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/architecture-playbook.md +160 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/artifact-generation-architecture.md +37 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/audit-history-architecture.md +29 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/bulk-workflow-architecture.md +33 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/config-rule-routing-architecture.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/cross-cutting-concerns.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-modeling-and-migrations.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-platform-architecture.md +210 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/dependency-platform.md +105 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/developer-tooling-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/error-contract-architecture.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/event-driven-architecture.md +260 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/http-gateway-architecture.md +74 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/mq-consumer-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/multi-tenant-isolation.md +275 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/notification-architecture.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/ops-checklist.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/performance-capacity-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/protobuf-contract-architecture.md +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/redis-cache-coordination.md +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/release-runtime-readiness.md +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/replay-comparison-architecture.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/runtime-observability.md +94 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/service-scaffold.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/source-evidence-map.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/workflow-state-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/SKILL.md +159 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/artifact-generation-patterns.md +37 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/audit-history-patterns.md +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/bulk-import-export-patterns.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/config-rule-routing-patterns.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/data-access-patterns.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/db-schema-and-dal-patterns.md +109 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/dependency-client-patterns.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/developer-tooling-patterns.md +70 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/domain-feature-patterns.md +78 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/engineering-patterns.md +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/error-contract-patterns.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/feature-playbook.md +61 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/http-gateway-client-patterns.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/mq-consumer-patterns.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/notification-patterns.md +42 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/observability-implementation-patterns.md +101 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/performance-capacity-patterns.md +44 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/protobuf-contract-patterns.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/public-api-integration-patterns.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/quality-and-testing-patterns.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/redis-cache-lock-patterns.md +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/release-ops-patterns.md +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/reliability-patterns.md +83 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/replay-comparison-patterns.md +32 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/scaffold-and-codegen.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/source-evidence-map.md +54 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/state-machine-task-patterns.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/grill-me/SKILL.md +80 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/grill-me/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/SKILL.md +117 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-approval-auto-reviewer.md +106 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-command-sandbox.md +441 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-context-freshness.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-credentials-auth.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-extensions-skills.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-file-edit-protocol.md +129 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-ide-integration.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-input-ingestion.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-instruction-composition.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-lifecycle-hooks.md +92 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-messaging.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-runtime-bootstrap.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-session-persistence.md +448 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-task-orchestration.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-tool-dispatch.md +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-turn-lifecycle.md +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/inference-capacity-operations.md +162 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/llm-client-gateway.md +156 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/model-prompt-evaluation.md +146 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/retrieval-agent-safety.md +273 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/SKILL.md +202 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/contracts-and-state.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/cross-stack-alignment.md +94 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/framework-choice.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/online-practice-uptake.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/platform-capabilities.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/product-page-checklist.md +40 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/qa-release.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/source-evidence-map.md +82 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/SKILL.md +103 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/agents/openai.yaml +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md +100 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/SKILL.md +70 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-data-acquisition.md +549 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-disclosure-channels.md +97 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/research-prompts.md +66 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/scripts/AGENTS.md +32 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/scripts/test-public-data-acquisition-recipes.sh +379 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +244 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/alerting-and-on-call.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/framework-middleware-checklist.md +142 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/infra-component-deployment.md +268 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/log-correlation-recipe.md +124 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/log-schema-canonical.md +208 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/metrics-conventions.md +105 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/obs-stack-architecture.md +107 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/sli-slo-design.md +95 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/source-register.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/SKILL.md +303 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/canary-and-rollout-strategy.md +163 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/config-center-via-etcd.md +245 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/custom-control-plane-boundary.md +298 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/deploy-cli-concrete-recipe.md +312 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/deploy-pipeline.md +165 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/env-and-lane-matrix.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/lane-orchestration-control-plane.md +383 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/multi-region-and-cluster.md +135 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/promotion-gate-and-review.md +149 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/python-package-registry-release.md +462 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/rollback-playbook.md +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/secret-and-config-management.md +231 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/version-authority-and-deprecation.md +21 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/SKILL.md +276 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/dual-sidecar-and-traffic-config-center.md +127 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/framework-middleware.md +143 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/grpc-authority-workaround.md +90 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/http-response-envelope-contract.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/mesh-architecture.md +127 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/multi-env-routing.md +192 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/protobuf-http-contract-signals.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md +124 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/rpc-framework-recipe.md +494 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-choice.md +113 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-migration-playbook.md +231 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-recipe.md +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +235 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/adr-convention.md +146 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-checklist.md +30 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-evaluation-report-template.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-execution-spec.md +108 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-sop.md +457 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-templates.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/artifact-egress-confidentiality.md +58 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/code-review-checklist.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/cross-repo-coordination.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/delivery-lifecycle.md +192 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-review-gate-mechanics.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-routing-and-readiness.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/diagnostic-spec-match-gate.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/dispatch-owner-skills.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/dormant-code-activation.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/existing-project-assessment-report.md +223 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/external-skill-augmentation.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/feature-deprecation-cascade.md +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/high-risk-resilience-gates.md +73 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/implementation-completeness-and-minimality.md +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/implementation-entry-reentry-gate.md +122 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/modular-monolith-heuristic.md +105 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/pre-final-continuation-gate.md +115 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/problem-resolution-and-learning.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/quality-attributes.md +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/quality-remediation-program.md +88 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/rd-standards-doc-family-checklist.md +27 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/refactoring-discipline.md +52 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/review-reception.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/shared-gate-artifact-classification.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/source-evidence-map.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/status-tracker-sync.md +77 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/sync-spec-repo-contract.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/verify-developer-experience.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/worktree-mechanics.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/scripts/AGENTS.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/scripts/check-agent-contract-coverage.sh +213 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/SKILL.md +136 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/agents/openai.yaml +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/analytics-visualization-interactions.md +206 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/behavioral-aesthetic-logic.md +108 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/complex-creation-interactions.md +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-execution-checklist.md +214 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-impl-naming-and-versioning.md +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-intake-and-acceptance.md +129 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-system-source-of-truth.md +97 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/external-ui-ux-quality-benchmarks.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/frontend-code-evidence-map.md +63 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/interaction-design-patterns.md +146 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/layout-recipes-and-screenshot-acceptance.md +250 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-project-token-consistency.md +237 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-stack-strategy.md +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/operational-processing-workflows.md +237 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-mobile-patterns.md +324 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-web-desktop-patterns.md +456 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-lifecycle-acceptance-and-iteration.md +114 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-surface-patterns.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/resource-management-interactions.md +113 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/scenario-community-patterns.md +133 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/source-map.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/tokens-and-components.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/trust-sensitive-ai-and-data-patterns.md +96 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-audit.md +106 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-design-development.md +176 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/visual-craft.md +111 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/SKILL.md +157 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/ai-service-integration-boundaries.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/api-contract-and-schema.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/api-security-boundaries.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/architecture-playbook.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/async-execution-model.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/background-jobs-and-scheduling.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/batch-and-pipeline-architecture.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/config-secrets-runtime.md +22 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-modeling-and-migrations.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-platform-architecture.md +211 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/event-driven-architecture.md +263 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/multi-tenant-isolation.md +281 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/observability-and-ops.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/packaging-runtime-readiness.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/redis-cache-coordination.md +41 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/reliability-and-error-contract.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/source-evidence-map.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/web-framework-boundaries.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/SKILL.md +143 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/ai-service-wiring-patterns.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/async-and-worker-patterns.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/background-job-patterns.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/batch-and-artifact-patterns.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/dependency-client-patterns.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/error-handling-patterns.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/feature-playbook.md +43 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/observability-implementation-patterns.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/project-structure-and-tooling.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/public-api-security-patterns.md +52 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/redis-cache-lock-patterns.md +78 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/schema-and-validation-patterns.md +23 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/source-evidence-map.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/sqlalchemy-and-migrations-patterns.md +99 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/testing-and-quality-patterns.md +61 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/web-framework-patterns.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/SKILL.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/config-runtime-readback.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/mr-merge-authorization.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/post-release-env-reset.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/release-closeout-evidence.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/release-scope-confirmation.md +21 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/tag-and-prod-pipeline-gate.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/test-scope-prompt.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/watcher-discipline.md +14 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/SKILL.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/comment-safe-release-doc.md +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/release-evidence-workflow.md +23 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/release-testing-scope-section.md +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-baseline/SKILL.md +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-baseline/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/SKILL.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/prd-composition-contract.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/requirement-closure-contract.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/security-four-questions.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-intent/SKILL.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-intent/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/SKILL.md +88 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +337 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/analysis-parse-fix-test-challenge-replay.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/attribution-verification.md +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/bootstrap-slim-c3-obligation-table.md +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/coverage-exhaustion-traps.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/description-authoring.md +162 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +507 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/eval-routing.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/evidence-card-template.md +51 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/example-domain-preselect.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/harness-patterns-and-eval.md +286 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/incident-postmortem-extraction.md +190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/l0-l1-l2-routing.md +114 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/online-skill-review.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/parallel-stack-references-pattern.md +164 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/r0-leakage-audit.md +90 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/recurring-anti-patterns-checklist.md +320 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/resume-paused-delivery.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-feedback-mining.md +33 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-finding-standards.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-rubric.md +40 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/rule-consolidation.md +118 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/skill-listing-budget.md +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +254 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +658 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/two-source-extraction-pattern.md +167 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-judgment-extraction.md +179 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-routing-map.md +51 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +180 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/AGENTS.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +1452 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-evidence-card-leak.sh +491 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-mr-target-freshness.sh +173 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-size-budget.sh +488 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-sync-pointers.sh +419 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-golden-trace.rb +197 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-health.rb +327 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-routing-bank.rb +401 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-routing.rb +248 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/generic-r0-leak-scan.sh +282 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/governing-chain-diff.py +321 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +964 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +708 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/skill-behavior-eval.py +540 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/source-register-lifecycle.rb +51 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/source-register-pending-status.rb +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ai_coding_implementation_gates.sh +829 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh +1203 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_r0_status.sh +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_register_pending_exclusion.sh +137 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +173 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_route_drift.sh +377 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_size_budget.sh +833 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_skill_catalog.sh +491 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_source_register_lifecycle.sh +114 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_mr_target_freshness.sh +261 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_sync_pointers.sh +538 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_controlled_escalation_pins.sh +154 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_bank_grader_diagnostics.sh +190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_bank_surface_binding.sh +178 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_prose_target.sh +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_generic_r0_leak_scan.sh +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_git_identity_predicate_gate.sh +243 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_governing_chain_diff.sh +419 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_gate_dateless_host.sh +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_resolution.sh +724 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +414 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_regression_runner_registration.sh +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_bank_integrity.sh +205 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_pointer_integrity.sh +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_credential_cwd.sh +61 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_cross_refs.sh +111 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_root_depth.sh +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate-skill.sh +257 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/SKILL.md +98 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/input-state-machines.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/streaming-rich-output.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/terminal-side-channels.md +96 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/SKILL.md +408 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/AGENTS.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/bitable-setup.md +573 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/README.md +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/github-actions.yml +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/gitlab-ci.yml +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/jenkins.Jenkinsfile +106 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/classical-test-design-techniques.md +279 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/gen_report.py +2807 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/makefile-template.md +200 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/report-config-schema.md +272 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/run_pytestless.py +475 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/source-to-case-workflows.md +258 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-marker-conventions.md +316 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-review-and-prioritization.md +145 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/AGENTS.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.dart +129 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.go +197 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.py +135 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.ts +285 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/test_gen_report.py +2144 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/update-lifecycle.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/SKILL.md +212 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/ci-fixtures-and-flake-control.md +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/client-runtime-test-matrices.md +50 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/data-and-workflow-testing.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/design-closed-contract-oracles.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/e2e-real-flow-testing.md +71 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/fitness-functions.md +240 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/integration-contract-testing.md +235 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/non-functional-specialized-scenarios.md +296 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/rd-testing-standard-template.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/run-killing-mutation-walk.md +43 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/scenario-testing.md +136 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/source-evidence-map.md +59 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/structured-tc-input-translation.md +67 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-code-authoring-patterns.md +392 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-data-and-determinism.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-topology-and-commands.md +92 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/unit-testing.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/vendored-contract-drift-checklist.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/verify-enforcement-mechanisms.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/AGENTS.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/client-terminal-ansi-check.py +140 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/client-terminal-ansi-check.test.sh +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-ast-check.py +170 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-ast-check.test.sh +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-go-check.go +198 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-go-check.test.sh +109 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/test_mutation_backup_recipe.sh +237 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +184 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/comment-safe-feishu.md +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/cross-model-co-review.md +3 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/delivery-face-closeout.md +60 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/doc-charter-first.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/session-vantage-leakage.md +58 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/SKILL.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/complex-workspace-patterns.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/embedded-h5-in-host.md +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/react-architecture.md +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/source-evidence-map.md +60 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-quality-release.md +190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-ui-quality.md +83 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/SKILL.md +179 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/references/shared-branch-rebase.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/AGENTS.md +23 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_status.sh +207 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_sweep.sh +481 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/worktree-status.sh +325 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/worktree-sweep.sh +245 -0
- package/dist/assets/release.json +2797 -0
- package/dist/claude-adapter.d.ts +9 -0
- package/dist/claude-adapter.js +240 -0
- package/dist/cli-worker.d.ts +1 -0
- package/dist/cli-worker.js +32 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.js +214 -0
- package/dist/codex-host.d.ts +30 -0
- package/dist/codex-host.js +162 -0
- package/dist/fs-safe.d.ts +21 -0
- package/dist/fs-safe.js +241 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/manifest.d.ts +8 -0
- package/dist/manifest.js +135 -0
- package/dist/opencode-adapter.d.ts +10 -0
- package/dist/opencode-adapter.js +416 -0
- package/dist/operations.d.ts +3 -0
- package/dist/operations.js +956 -0
- package/dist/paths.d.ts +20 -0
- package/dist/paths.js +4 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +1 -0
- package/dist/unified.d.ts +4 -0
- package/dist/unified.js +64 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +5 -0
- package/package.json +35 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Multi-Tenant Isolation (Python)
|
|
2
|
+
|
|
3
|
+
Use when designing the tenant-isolation architecture of a SaaS service: how tenants are kept apart at the data, compute, network, identity, observability, lifecycle, and compliance layers; how queries, jobs, caches, and external calls carry tenant context safely; how a tenant's data can be exported or deleted on demand; and how shared services keep cross-tenant aggregation auditable.
|
|
4
|
+
|
|
5
|
+
> **Sibling sync.** A parallel `go-microservice-architecture/references/multi-tenant-isolation.md` mirrors **all non-stack-specific sections** of this file. Only the *Python-specific implementation patterns* section diverges by stack. Maintainers updating any mirrored section here must update the sibling in the same change. The mirrored sections stay free of three categories of stack-specific token: DB-engine-specific syntax, runtime/concurrency-mechanic names, and library / framework API names. The concrete token list and grep command live in the *Mirrored-section grep gate* subsection at the end of this file's stack-glue section. Before commit, run that grep against the file's mirrored sections; zero hits required. The same gate lives in the Go sibling. Routing-reference text (which sibling file each "route to" link points to) may differ between Go and Python because the sibling skill trees differ — this is the only mirrored-section divergence explicitly allowed.
|
|
6
|
+
|
|
7
|
+
> **Sanitization boundary.** Tenant identifiers, customer names, lane / region names, regulator labels, and quota numbers below are illustrative; concrete values live only in the private alias map. The list of audiences that require sanitization is **positive** (these audiences require it unless explicitly approved otherwise): external / client-facing materials, customer-specific deliverables, regulator or auditor evidence, SOC / compliance reports, procurement responses, internal compliance reviews, sales-engineering or security-questionnaire appendices, partner architecture drafts, and any document that could be forwarded to any of those. "Internal" by itself is not safety; internal documents are routinely forwarded.
|
|
8
|
+
|
|
9
|
+
## When this applies / does not apply
|
|
10
|
+
|
|
11
|
+
Apply when:
|
|
12
|
+
- the service has more than one tenant (customer, organization, workspace) sharing any layer (DB, compute, broker, cache, storage),
|
|
13
|
+
- a single tenant's data, behavior, or failure must not be visible to or affect another tenant,
|
|
14
|
+
- tenants have differing commitments (residency, deletion SLA, quota tier, isolation tier),
|
|
15
|
+
- regulatory or compliance scopes (PCI, HIPAA, SOC, residency requirements) require provable tenant separation.
|
|
16
|
+
|
|
17
|
+
Skip when:
|
|
18
|
+
- the service is single-tenant by deployment (per-customer dedicated stack with no shared layer); route to `platform-release-engineering/SKILL.md` and to this file's *Compliance, residency, sovereignty* section for residency commitments,
|
|
19
|
+
- the service is internal-only with a single owning team (employees of one org are not "tenants" for this purpose); identity/permission boundaries still apply but route to `web-framework-boundaries.md` or `api-contract-and-schema.md`,
|
|
20
|
+
- tenant-equivalent isolation is owned entirely by a platform layer above the service (e.g., per-tenant namespace owned by the platform); route to `platform-service-connectivity/SKILL.md` for the platform contract.
|
|
21
|
+
|
|
22
|
+
## Tenant isolation tiers (decision tree)
|
|
23
|
+
|
|
24
|
+
Treat isolation as **two orthogonal placement decisions**: data placement (where the tenant's bytes live) and compute placement (where the tenant's CPU/memory runs). Real systems combine the two — Azure's elastic-pool SaaS pattern, for example, gives each tenant a single-tenant database (high data isolation) while pooling compute (high density). Picking a "tier" globally without naming both placements leads to over- or under-isolating one of them.
|
|
25
|
+
|
|
26
|
+
**Data placement** — lowest to highest isolation:
|
|
27
|
+
- *Shared with row-level scope* — one DB, one schema, every row carries `tenant_id`, database-level Row-Level Security (RLS) policies enforce filtering at the engine. Cheapest, highest density.
|
|
28
|
+
- *Schema-per-tenant* — one DB instance, one schema per tenant; queries route through the tenant's selected schema namespace. Useful when per-tenant DDL diverges or per-tenant backup is required.
|
|
29
|
+
- *Single-tenant data container on pooled compute* — one database (or equivalent isolated container) per tenant inside a pooled engine. Data is physically separable for export / delete / encryption; compute remains shared.
|
|
30
|
+
- *Database-per-tenant on dedicated compute* — one DB instance per tenant (or per tenant group) on its own compute. Adds blast-radius isolation on the storage engine itself.
|
|
31
|
+
- *Region-per-tenant (or per-tenant-group)* — one full stack per region/cluster, with explicit routing. Required for residency, sovereignty, and the strongest blast-radius isolation.
|
|
32
|
+
|
|
33
|
+
**Compute placement** — lowest to highest isolation:
|
|
34
|
+
- *Quota-protected shared compute* — one pool of workers serves all tenants; per-tenant quotas (CPU, memory, concurrency, OS-level cgroups) prevent noisy-neighbor.
|
|
35
|
+
- *Pool-per-tenant-group* — bounded pools serve groups of tenants with similar profiles (free tier, pro tier, enterprise tier).
|
|
36
|
+
- *Pool-per-tenant* — a dedicated compute pool per tenant; the strongest noisy-neighbor isolation that still amortizes platform cost.
|
|
37
|
+
- *Dedicated cluster / region* — full stack isolation per tenant; pairs naturally with region-per-tenant data.
|
|
38
|
+
|
|
39
|
+
**Hybrid placements are first-class.** Real combinations: shared row-scoped data + pool-per-tenant compute (high compute isolation for noisy workloads while keeping data dense); single-tenant data container + pooled compute (high data isolation for compliance while keeping compute dense). The tenant directory records both placements per tenant; the data layer, compute layer, observability, and lifecycle layers each read the placement that applies to them.
|
|
40
|
+
|
|
41
|
+
**Compatibility constraints between placements (residency / sovereignty boundary).** When a tenant has region-pinned or sovereignty-pinned data, the compute that can read, decrypt, cache, log, index, export, transform, or administer that data **must be pinned to the same region / sovereignty boundary**. A shared global worker pool in `us-east` that pulls jobs for an `EU` residency tenant violates the residency commitment even when the bytes are at-rest in EU. The compatibility rule: for every (data_placement, compute_placement) pair the directory records, the compute placement's region/sovereignty must be a subset of (or equal to) the data placement's. Exceptions exist only for a documented *control-plane-only* path that touches no tenant data (a purely metadata refresh, a placement record write) and that has explicit compliance approval. Observability, logging, audit, and analytics pipelines are *not* control-plane-only; they touch tenant content and must follow the compatibility rule.
|
|
42
|
+
|
|
43
|
+
Pick each placement by:
|
|
44
|
+
- **Compliance/residency commitments** — the strictest commitment determines the floor (residency demands region-per-tenant data for that region's tenants).
|
|
45
|
+
- **Blast radius requirement** — what failure mode must one tenant be protected from? Compute blast radius is solved by compute placement; data blast radius is solved by data placement.
|
|
46
|
+
- **Per-tenant ops needs** — own backup window, own DDL, own version, own deletion SLA → higher data placement.
|
|
47
|
+
- **Density and cost** — lower placements serve more tenants per dollar; do not pick a higher placement than the commitment justifies.
|
|
48
|
+
- **Migration cost** — the placement must be reachable from where the service is now; designing for a placement the service cannot deliver is worse than picking a lower one with a documented promotion path.
|
|
49
|
+
|
|
50
|
+
Document each tenant's placement per layer in a tenant directory (a `tenants` table or a config source-of-truth); the directory is the contract that the data, compute, observability, and lifecycle layers all read.
|
|
51
|
+
|
|
52
|
+
## Tenant context as a first-class value
|
|
53
|
+
|
|
54
|
+
Tenant id is not derived, inferred from session, or recovered from a payload field consumed downstream. Treat it as a first-class request-scoped value with explicit propagation:
|
|
55
|
+
|
|
56
|
+
- **Entry-point extraction** — every request, message, job, or trigger names where its tenant id comes from (JWT claim, request header, message header, parent job context). The extraction is one function per entry point; never re-derived later.
|
|
57
|
+
- **Reject missing tenant** — if the tenant id is absent and the operation needs one (almost all of them do), fail at the boundary with an explicit `missing_tenant` error. Do not fall back to a default tenant, a `0` sentinel, or "the only tenant we know about." The rare *legitimately tenant-less* operations — health checks from a load balancer, scheduled cron jobs that operate across tenants, system bootstrap, platform background work, evaluation jobs — are explicitly enumerated by name; each carries an explicit `no_tenant` / `cross_tenant` marker so the default reject path stays default.
|
|
58
|
+
- **Propagation through every hop** — the tenant id rides on the request context, message headers, RPC metadata, log fields, trace baggage, and outbox rows. Concurrent work spawned from a request must carry the same propagation; see the stack-specific section for the work-spawning propagation rules, which differ by mechanism per stack.
|
|
59
|
+
- **No tenant in path params for high-trust operations** — for a privileged operation that names the tenant in the URL or payload, the tenant in the URL must match the tenant id derived from the authenticated principal; never trust the path alone. The mismatch is a security event, not a 400. *Legitimate exception:* a principal authorized to operate on a different tenant (parent-org admin acting on a child tenant, partner integration scoped to multiple tenants) — this is itself a cross-tenant capability and follows the cross-tenant rules below; never a silent allowance.
|
|
60
|
+
- **Cross-tenant operations are explicit** — when an operation legitimately spans tenants (admin queries, marketplace aggregation), it carries an explicit `cross_tenant` capability claim and an explicit list of tenants; the default deny path means no operation can quietly become cross-tenant by losing scope.
|
|
61
|
+
|
|
62
|
+
## Tenant-aware data access
|
|
63
|
+
|
|
64
|
+
Once the tenant context is reliable, data access enforces it at multiple layers (defense in depth — the application layer can be bypassed; the DB layer is the engine-level authority *for the application's normal role*, and the application's normal role is what serves end-user requests):
|
|
65
|
+
|
|
66
|
+
- **DB engine enforcement** — for shared data placements, the engine enforces tenant filtering on every row read or written by the application role. The engine policy is authoritative for that role; the ORM filter is a hot-path optimization. **Bypass paths exist and must be controlled.** A normal engine policy is bypassed by: privileged roles equivalent to superuser, roles holding the engine's bypass attribute, the table owner unless table-level forced enforcement is set, bulk truncate or schema-level operations, logical-replication streams, view-execution semantics where the policy belongs to the viewer vs the definer, and triggers running as a different role. The architecture must (a) enable forced policy enforcement on every tenant-scoped table, (b) use distinct DB roles for application / migration / admin / replication, none of which carry the bypass attribute for the production app role, (c) require explicit tenant filters or offline approval for any path that legitimately runs as a bypass role (data migration, regulator export, repair script), and (d) audit every connection that runs under a bypass role. The stack-glue section names the engine-specific syntax for each control.
|
|
67
|
+
- **Bypass-role audit independence — full control-plane scope, with degraded mode for small orgs.** "Audit every bypass connection" is meaningless if the bypass role (or the operator who can assume it) can read, modify, or *prevent delivery of* the audit. Independence has two parts: **data-plane** (the bypass role cannot `SELECT` / `UPDATE` / `DELETE` / `TRUNCATE` audit rows; ingestion uses a separate write-only role with `INSERT`-only privilege; reads of audit go through a distinct read-only auditor role the bypass roles cannot assume), and **control-plane** (the operator who can use the bypass role cannot modify network policy, security groups, firewall rules, DNS, service-account bindings, sidecars, queues, or routing between the bypass-role host and the audit sink). A bypass operator who can drop egress to the audit DB, run a migration under bypass, and restore egress has defeated the audit even though no audit row was visible. Verify both planes: attempted audit-table `SELECT` / `DELETE` with each bypass role is denied; attempted modification of the audit transport (firewall, DNS, service account, queue) from each bypass operating role is denied; and an alert exists on **audit delivery gaps** (the audit pipeline notices when expected events stop arriving from a bypass-host source) so that a successful tamper of the transport is detected even when no audit row appears.
|
|
68
|
+
**Degraded mode for small orgs where control-plane independence is impossible.** A small org with one root operator (or one ops team that owns both bypass-role access and infra controls) cannot mechanically separate the two planes. The architecture must not block forever on impossible separation; instead, classify bypass as **break-glass only** under the degraded mode, and replace mechanical independence with: (a) the audit sink delivers to an **external append-only audit store outside the operator's control** (a regulator-grade evidence service, a separate vendor's audit log, a tamper-evident ledger), (b) **two-person approval** is required before any bypass operation runs (one person initiates, a second approves; both identities recorded), (c) **delivery-gap alerting** runs from outside the operator's infrastructure so a tamper of local transport is still alerted by the external system, and (d) a **time-boxed remediation plan** is documented (when the org grows, the mechanical control-plane independence is restored). Record explicitly whether each environment runs in the strong-independence mode or the degraded mode; un-recorded environments default to strong-independence required.
|
|
69
|
+
- **Catalog-level coverage gate by classification of every relation, not just by column.** A representative cross-tenant-read denial test catches the obvious case but misses newly added tenant-scoped tables — especially join tables (e.g., `user_roles(user_id, role_id)`) whose tenancy is inferred via a parent table's `tenant_id`, denormalized projections, composite-key tables where tenant is implicit, **runtime-created tables** (worker-managed temp tables, queue inboxes), **extension-created child tables** (partition-management extensions that materialize child partitions, materialized view refreshes), and views. The schema source-of-truth must **classify every relation** (table, view, materialized view, partition child) as `tenant_scoped` / `global` / `cross_tenant_aggregate` / `system`; the schema-CI gate **fails any migration that adds or modifies a relation without a classification**, including extension-created relations classified by **owner/template rule** (every child partition of a tenant-scoped parent inherits `tenant_scoped`; every relation owned by a tenant-scoped extension inherits the extension's class; relations created by an unrecognized owner block merge). For tenant-scoped relations: if the relation has a `tenant_id` column, the gate verifies engine-policy enabled + forced enforcement + application-role policy + missing-tenant query returns zero / errors; if no `tenant_id` column (inferred-tenancy via parent), the classification names the parent / join path and the gate verifies the policy expression resolves tenant correctly via that join path (the stack-glue section gives the engine-specific syntax). The catalog of classifications is a checked-in source-of-truth artifact reviewed on every migration; unclassified relations block merge.
|
|
70
|
+
- **Tenant session state must survive the actual unit of work** — the session-level tenant variable that the engine filter reads must be set so that *every query in the request* sees it. Transaction-local settings vanish at statement end if no transaction is open; session-scoped settings leak across connection check-in unless reset. The stack-glue section names the safe pattern per stack: either wrap all tenant-scoped work in an explicit transaction with the tenant variable set inside it, or set the session variable on every connection checkout and reset it on every check-in with a default-deny engine policy when the variable is missing. Default-deny on missing tenant is the only correct fail mode at the engine layer.
|
|
71
|
+
- **Connection pool tenancy** — a connection cannot leak across tenants between two checkouts. Either issue an explicit reset on check-in, or use a connection-per-request pattern with explicit tenant set on checkout, paired with a default-deny engine policy. Reset hooks are *cleanup*, not *correctness*: the correctness comes from setup on checkout / transaction start plus default-deny, not from trusting every reset path (invalidation, async-connection GC, terminating connections may skip the reset). Alert on connections returned to the pool with a non-default tenant setting.
|
|
72
|
+
- **Cache classification, not "every key carries tenant"** — caches divide into classes; each class has its own keying and access rule:
|
|
73
|
+
- *Tenant-scoped cache* — every key includes the tenant id; cross-tenant read is a leak.
|
|
74
|
+
- *Global immutable or config cache* — values truly global to the product, immutable or refreshed centrally; no tenant key; intentionally cross-tenant.
|
|
75
|
+
- *Cross-tenant aggregate cache* — pre-computed aggregates (top-N, billing rollups); access is gated by the cross-tenant capability; keys do not carry tenant but reads are authorized.
|
|
76
|
+
- *Prewarm / system cache* — operational caches without specific tenant; access is system-only.
|
|
77
|
+
**Differential test before classifying a cache as global, with declared dependency domains covering external sources.** Before declaring a cache "global," answer: *if I served this exact key to tenant A and to tenant B from the same cache entry, could the value, the visibility, or the authorization differ?* Causes of divergence include tenant contracts, entitlements, feature-flag targeting (per-tenant rollout), AB-test assignment, residency/region, model entitlement, partner tier, jurisdiction-specific behavior, and tenant-overridden config. If any can differ, the cache is tenant-scoped, not global, even when the data is called "config." Pricing, entitlement, model-routing, flag-targeted config, and partner-product caches are almost always tenant-scoped despite looking like global config. **Future-proofing: the classification is not a one-time decision.** Each cache declares its **dependency domains** — the input domains whose schema changes can introduce tenant-varying divergence (entitlements, feature flags, contracts, pricing, model routing, residency, tenant config). Dependency declarations **must include external and runtime-config sources**, not only the team's own checked-in schemas: third-party feature-flag SaaS, runtime A/B-test config services, partner-managed entitlement APIs, vendor-side billing or pricing surfaces. For each external/runtime dependency, declare a change signal: a webhook-backed drift trigger that fires on the dependency's change events, a scheduled attestation job that re-verifies the differential test on a documented cadence, or — when no reliable change signal is available — **default downgrade to tenant-scoped**. A change to any declared dependency domain (internal schema or external/runtime config) triggers a CI gate that reviews and either re-runs the differential test or downgrades the cache. Without dependency declarations that cover external sources, a global cache silently becomes wrong the moment a remote schema/config change ships. Audit each cache for its class; raw cross-tenant reads on a tenant-scoped cache without tenant in the key are the most common cross-tenant data leak in practice.
|
|
78
|
+
- **Cross-tenant queries are exceptional, audited, and capability-gated** — operations that legitimately span tenants (search across customers for an admin, billing aggregation across tenants) bypass the per-tenant filter via a named capability. Every cross-tenant query writes an audit row (who, what, why, which tenants, what was returned in aggregate); the capability is rate-limited; the audit table is read by the privacy team. Do not let cross-tenant become a runtime hatch with no record. (See *Cross-tenant features* below for the modes that handle high-volume legitimate cases.)
|
|
79
|
+
- **Read replicas carry the same enforcement** — engine filtering, schema routing, and bypass-role controls all apply to replicas; a replica that bypasses enforcement is a leak. Verify on every replica including logical-replication downstreams.
|
|
80
|
+
- **Backup and analytics pipelines carry the same enforcement** — exporting data to a warehouse, a backup, or an analytics broker is still tenant-scoped; the export tool either preserves the tenant column or partitions by tenant. Where enforcement cannot happen at the source (a warehouse that loads via bulk insert), it must happen at the consumer (warehouse-side row policies, view filters). An analytics dashboard that loses tenant scope is a cross-tenant leak with a delayed timer.
|
|
81
|
+
|
|
82
|
+
## Quota and rate limit per tenant
|
|
83
|
+
|
|
84
|
+
A noisy or hostile tenant must not consume more than its share of any contended resource. Apply per-tenant budgets at every layer where contention is possible:
|
|
85
|
+
|
|
86
|
+
- **API gateway / ingress** — per-tenant requests/sec; surface a `429 Too Many Requests` with a `Retry-After` header; tag the rejection with the tenant for observability.
|
|
87
|
+
- **Background worker / job runner** — per-tenant concurrent job budget; per-tenant queue depth limit; per-tenant CPU/memory hint where the runtime supports it.
|
|
88
|
+
- **DB connections** — per-tenant connection share; a hostile tenant cannot starve the pool. Connection pool with per-tenant tag is the simplest; per-tenant DB user with role-level limits is stricter.
|
|
89
|
+
- **Broker / messaging** — per-tenant publish rate; per-tenant consumer lag budget (one tenant's slow consumer cannot block the rest).
|
|
90
|
+
- **Object storage / egress** — per-tenant request and byte budgets; egress cost attribution is a tenant attribute.
|
|
91
|
+
- **External provider quotas** — when calling a shared downstream (LLM vendor, payment provider), the per-provider budget (see `event-driven-architecture.md`) is partitioned per tenant; a single tenant cannot burn the shared quota.
|
|
92
|
+
- **Shared accelerator / GPU inference** — modern inference systems rely on continuous or dynamic batching for throughput; hard-partitioning the batcher per tenant destroys utilization economics without necessarily improving fairness. For shared accelerators, the default isolation is **fair scheduling + admission control + per-tenant spend / request budgets + abuse-isolation rate limits**, not per-tenant physical or batch partitioning. Document the fairness algorithm (token bucket per tenant feeding a fair scheduler; per-tenant fallback when over budget) and the abuse-isolation cutoff (a runaway tenant is degraded, not allowed to starve the batch). **Exception for SLO-contracted or large-prefill workloads:** named tenants with latency-SLO contracts, or workload classes with rare but very large requests (long prefill, big batches), starve under pure fair queuing when many small requests fill the batcher. For those, layer one of: reserved accelerator capacity for the named tenant, a priority lane with bounded share, max-wait admission control that preempts smaller jobs after a deadline, or a dedicated partition. Document which mechanism applies per tenant / workload class; fair scheduling is the default for shared long-tail traffic, not proof that partitioning is wrong.
|
|
93
|
+
- **Resources without quota** — file descriptors, ephemeral ports, in-memory buffer pools, broker per-topic quotas, OS-level limits. Per-tenant quota does not exist for these by default; the architecture protects them with global guardrails plus per-tenant attribution so that exhaustion is traceable to a tenant.
|
|
94
|
+
- **Quota tier alignment** — quotas align with the tenant's tier in the tenant directory; an enterprise tier carries higher budgets than a free tier. *Exception:* free-tier abuse protection sometimes requires *stricter* limits than enterprise baseline, and trial tenants may carry elevated quotas. Quotas are tenant-directory attributes, not hardcoded in code.
|
|
95
|
+
|
|
96
|
+
For each quota, define: the budget, the enforcement layer, the response when exceeded, the alert when the budget is approached, and the escalation path when a tenant legitimately needs more.
|
|
97
|
+
|
|
98
|
+
## Tenant-aware observability
|
|
99
|
+
|
|
100
|
+
Every telemetry record carries tenant scope. Metrics use `tenant_id` only for the bounded named cohorts and heavy-hitters defined below (full per-id labeling at long-tail scale is infeasible); logs and traces carry `tenant_id` on every record; all three carry an explicit `cross_tenant` / `platform` marker when the operation is not single-tenant. The compromise model below balances the operator's need for "which tenant is affected" against the cost of unbounded cardinality:
|
|
101
|
+
|
|
102
|
+
- **Headline metrics by tenant id** — RED / USE metrics on the most operationally critical paths (request rate, error rate, latency) carry `tenant_id` for **bounded, named cohorts**: paid tenants, high-risk tenants, internal tenants. Free-tier and long-tail tenants do not get individual labels.
|
|
103
|
+
- **Long-tail metrics by tenant tier** — for tenants outside the named cohorts, metrics carry `tenant_tier` (free / pro / enterprise) instead of `tenant_id`; the operator can detect tier-wide issues without per-tenant cardinality.
|
|
104
|
+
- **Heavy-hitter detection** — a separate fast path identifies the top-N tenants by traffic in a rolling window; a noisy tenant from the long tail is promoted to per-id observation when detected.
|
|
105
|
+
- **Exemplars / trace links / log joins** — for the long tail, traces and logs carry `tenant_id` even though metrics do not; the operator joins from a tier-level metric alert to traces / logs filtered by tenant id when investigating.
|
|
106
|
+
- **Cohort SLOs** — per-tenant SLO computation is infeasible at millions of tenants; define SLOs per cohort (per-tier, per-region, per-product-line) with the named-tenant exceptions for paid / high-risk getting their own SLO. The single-tenant SLO is reserved for tenants whose contract names one.
|
|
107
|
+
- **Log fields** — `tenant_id` as a structured field on every log line; the log aggregator filters by tenant. Logs without tenant scope are usable only for stack-trace forensics, not for incident triage.
|
|
108
|
+
- **Trace attributes** — `tenant.id` as a span attribute (OpenTelemetry semantic convention); trace baggage carries tenant id across service hops.
|
|
109
|
+
- **Audit log scope** — security-relevant events (cross-tenant query, admin god-mode, deletion, export, regulated transactions) write to an append-only audit stream with stricter retention and access control. For regulated domains (books-and-records under FINRA/SEC and similar regimes), specific structured app logs and ops logs may *also* be classified as audit records; the audit scope is set by the compliance mapping, not by a default "audit is a separate stream from logs." Cross-index ops logs into the audit retention plane where regulators require it.
|
|
110
|
+
|
|
111
|
+
## Per-tenant lifecycle
|
|
112
|
+
|
|
113
|
+
The lifecycle operations — provision, suspend, export, delete, retention, archive — are tenant-scoped and contractual.
|
|
114
|
+
|
|
115
|
+
- **Provision** — creating a tenant is an idempotent workflow: tenant directory row, isolation placement resources (schema / DB / region per placement), default quotas, seed data, identity provider linking. Each step must be retryable; partial-provision must be recoverable, not leave a half-tenant.
|
|
116
|
+
- **Suspend** — pause access without deleting data. Used for non-payment, security incidents, or compliance holds. Suspension is reversible; a suspended tenant's data is preserved according to the retention policy.
|
|
117
|
+
- **Export (right to portability)** — the tenant can request all of their data in a documented format. The export must include data across every store (DB, broker offsets if relevant, object storage, analytics warehouse extracts) and must not leak other tenants' data; the export job runs under the same tenant-scoped enforcement as normal queries. Track export SLA per tenant tier.
|
|
118
|
+
- **Serving suppression before physical delete (per-path inventory + propagation barrier)** — most deletes are async across stores; the production DB row may be deleted while a search index, CDN edge cache, hot in-memory cache, or downstream materialized view still serves the document for minutes or hours. Mark the tenant (or the specific object) in an **authoritative denylist** at the moment deletion starts; every serving path (API read, search query, CDN origin, cache layer, replica read, analytics dashboard) consults the denylist before serving. **The denylist write must be propagated to every serving path before any destructive source action runs** — fire-and-forget denylist replication is not enough; if any serving path receives the denylist update through an eventually consistent config channel whose lag can exceed source delete latency, stale tenant content keeps being served. Maintain a **serving-path inventory** that lists every path serving tenant data; for each path, one of these **suppression modes** is declared and tested before launch:
|
|
119
|
+
- *Ack barrier* — the path implements an ack endpoint; the deletion workflow blocks source destruction until the path acks the denylist version.
|
|
120
|
+
- *Central strong check* — every serving read calls a central consistent suppression store before serving until async replicas catch up.
|
|
121
|
+
- *Path disabled / removed from serving* — the path is removed from the serving topology before destructive action (acceptable when the path's content is rebuildable).
|
|
122
|
+
- *Vendor purge with verifiable completion* — for third-party CDN / hosted analytics / managed warehouse paths that cannot ack or call back, invoke the vendor's purge API and wait for its completion signal; the vendor's purge API itself must be auditable.
|
|
123
|
+
- *Wait-out max TTL* — block destructive action until the path's documented max-content-TTL has elapsed since the denylist write (acceptable only when TTL is bounded and short; record the max-TTL per path).
|
|
124
|
+
Denylist entries are removed only after the per-store physical-deletion modes below complete. The workflow refuses to advance past denylist write until each path's declared mode has been satisfied. A path with no declared mode blocks the workflow; un-ackable paths must explicitly pick vendor purge, disablement, or wait-out, not silently fall back to fire-and-forget.
|
|
125
|
+
- **Delete (right to erasure) with per-store modes** — define explicitly per store *which* deletion mode applies; "deletion complete" means the committed policy state for each store, not always physical absence:
|
|
126
|
+
- *Hard-delete verified* — rows are physically removed; verification queries confirm absence (production DB, hot indexes, hot caches).
|
|
127
|
+
- *Anonymized* — identifiers and PII are stripped; rows that must outlive the tenant for regulatory reasons (audit records, financial transaction history) become non-attributable.
|
|
128
|
+
- *Beyond-use / suppressed until purge* — the store cannot delete on demand (backups, WORM archives, snapshot-only warehouses); access is suppressed and the data is included in the next regularly scheduled purge (which has its own SLA per tier).
|
|
129
|
+
- *Retained under legal basis* — explicit hold for a legal or regulatory reason; the hold itself is documented and revisited.
|
|
130
|
+
- *Unverifiable immutable append* — write-only audit logs, blockchain-style ledgers; deletion is impossible by design; the tenant is informed.
|
|
131
|
+
Each per-store step records `pending` / `done` / `unknown`; an `unknown` triggers a reconciliation job and alert; per-store mode is encoded in the workflow so completion can be reasoned about.
|
|
132
|
+
- **Retention** — per-tenant or per-tier retention windows for production data, logs, audit, and backups. Retention drives storage cost and compliance; it is a tenant-directory attribute.
|
|
133
|
+
- **Archive** — moving cold tenants to cheaper storage; the archive path preserves tenant scope and supports re-hydration on request.
|
|
134
|
+
|
|
135
|
+
The export, delete, and archive workflows are the highest-stakes lifecycle paths — they are also the easiest to half-implement. The `unknown` / `reconcile` state pattern from `event-driven-architecture.md` applies; the per-store deletion modes above prevent the workflow from either falsely marking complete or blocking forever.
|
|
136
|
+
|
|
137
|
+
## Per-tenant rollout
|
|
138
|
+
|
|
139
|
+
Code changes that touch a tenant's data or behavior do not roll out everywhere at once.
|
|
140
|
+
|
|
141
|
+
- **Per-tenant feature flags** — a flag system that can target by tenant id, tenant tier, or tenant tag. Flag service is itself a tenant-aware service.
|
|
142
|
+
- **Per-tenant canary** — promote a tenant or tenant group to the new version first; observe per-tenant SLO (where it exists) or per-cohort SLO; promote next group only on green.
|
|
143
|
+
- **Per-tier promotion ordering** — typical order is internal/synthetic tenants → free tier → pro tier → enterprise tier; never test on enterprise first.
|
|
144
|
+
- **Per-tenant rollback** — when a change harms a single tenant, rolling back for that tenant must be possible without rolling back the whole fleet (config flip, route override, schema rollback). Document the rollback path per change class.
|
|
145
|
+
- **Per-tenant schema migration** — for schema-per-tenant or DB-per-tenant placements, migrations run per tenant; the runner tracks progress per tenant and isolates failures.
|
|
146
|
+
|
|
147
|
+
## Cross-tenant features (admin views, aggregations, investigations)
|
|
148
|
+
|
|
149
|
+
A small set of legitimate operations cross tenant boundaries. Each is an exception, not a default. Different volumes need different modes — a single rule cannot serve both an admin's single search and a security team's 24/7 fraud monitoring:
|
|
150
|
+
|
|
151
|
+
- **Normal-volume admin operations (per-call audit)** — admin search, individual support actions, single-tenant repair scripts. Each call: explicit capability claim, audit row per call (who, when, what, which tenants), short TTL access token, rate-limited, surface-limited (aggregates not raw rows where possible).
|
|
152
|
+
- **High-volume investigations (per-job / per-session audit)** — security forensics, fraud monitoring, regulator response, customer-requested cross-tenant joint debugging. Per-call audit would either flood the audit pipeline or be down-sampled to uselessness; audit operates at the **session** or **job** granularity (who started it, when, what tenants are in scope, what was the purpose, when it ended), with per-call records summarized at the session level. The session itself is short-TTL and renewable with approval.
|
|
153
|
+
- **Break-glass raw access** — incident response where an operator legitimately needs raw cross-tenant rows. Allowed under a named break-glass capability with after-the-fact review (the operation runs, the audit happens immediately, the review happens within a documented SLA), separate retention, and a post-incident report.
|
|
154
|
+
- **Audit capacity controls** — the audit emission rate itself is rate-limited per capability so that legitimate high-volume use cannot DoS the audit system; over-quota events page the security team.
|
|
155
|
+
|
|
156
|
+
"Admin god-mode" with no audit, no rate limit, no TTL, and no review SLA is the single most common path to a cross-tenant data leak. Never ship it.
|
|
157
|
+
|
|
158
|
+
## Compliance, residency, sovereignty
|
|
159
|
+
|
|
160
|
+
Tenant commitments around where data lives and who can see it shape the isolation placement directly.
|
|
161
|
+
|
|
162
|
+
- **Residency** — "tenant X's data stays in region Y" is a region-per-tenant or region-pinned commitment; the data plane (DB, object storage, backup, analytics) all honor it; the routing layer enforces it.
|
|
163
|
+
- **Sovereignty** — government / regulated tenants may require a separate stack with no cross-border access; this is a deployment-level isolation, not a runtime knob.
|
|
164
|
+
- **Encryption** — at-rest encryption per tenant (separate keys per tenant) is a stronger model than a shared key.
|
|
165
|
+
- **Crypto-deletion is conditional, not universal** — destroying the per-tenant key is acceptable proof of erasure **only when** the key hierarchy, key backups, envelope keys, restore paths, and the relevant regulator's interpretation all support it. NIST SP 800-88 treats cryptographic erase as a sanitization technique with conditions; some interpretations of GDPR distinguish anonymization (irreversible) from pseudonymization (key-linkable encrypted data may still be personal data). Where any condition fails, crypto-deletion is a *beyond-use / suppression* control (one of the per-store deletion modes above), not proof of erasure; the deletion workflow records the actual mode achieved per tenant per store, and the tenant is told what was achieved. **Required evidence before recording "erasure" via crypto-deletion**, per store and per tenant; each artifact must be authentic to *this* deletion, not theatrical paperwork:
|
|
166
|
+
- *(a) key hierarchy diagram* — scoped to this store and this tenant's key version, dated within a defined freshness window (e.g., last 30 days), showing every key that wraps or could reconstruct the data.
|
|
167
|
+
- *(b) key-backup inventory* — for this store, scoped to this tenant's keys, naming every backup location, rotation policy, and the holder of each backup; dated within the freshness window.
|
|
168
|
+
- *(c) restore-path test result* — run against *this* backup store with *this* tenant's key-version destroyed, confirming the restore fails because the key is gone. A restore test on a different store or a different key-version is not evidence.
|
|
169
|
+
- *(d) envelope-key destruction proof* — for every wrapping key in the hierarchy, signed or countersigned by a role that is **independent of the role executing the deletion** (no operator may self-attest their own destruction).
|
|
170
|
+
- *(e) backup-key purge SLA* — the crypto-erasure is not complete until backup-key purge completes; the SLA names the date by which all backups containing the key will be purged, and the workflow remains in `beyond-use` until that date.
|
|
171
|
+
- *(f) compliance / regulator acceptance* — explicit acceptance recorded for this store and this jurisdiction, dated, naming the regulatory regime; a generic "GDPR" acceptance from headquarters does not cover a regional regulator.
|
|
172
|
+
Each artifact's chain-of-custody must use **a non-forgeable workflow execution identifier**, not a bare run id: the workflow engine signs each execution record with a nonce or content-addressed event id (the hash of the execution's immutable input state), and each artifact references that signed/hashed identifier. Artifact hashes are themselves recorded in the append-only audit store at production time. A sequential or predictable run id alone — which a CI system could let any operator re-trigger with arbitrary metadata — is not chain-of-custody. Without all six artifacts at the required scope and freshness, and a non-forgeable execution-record link, the mode is *beyond-use* until they are produced.
|
|
173
|
+
- **Data subject rights** — GDPR-style erasure, portability, access requests are tenant lifecycle operations (see *Per-tenant lifecycle*). The compliance team owns the policy; this skill owns the executable workflows.
|
|
174
|
+
- **Audit retention vs data retention** — separate from data retention; audit logs typically have longer required retention (years) than operational data. *Conflict case:* when audit retention preserves data that the tenant has a deletion right over, the deletion workflow's `anonymized` mode is the typical resolution: audit records survive without tenant-attributable PII. Document the resolution per regulator.
|
|
175
|
+
|
|
176
|
+
Residency and sovereignty commitments are made at the customer-contract layer (product / legal); the architecture enforces what was promised. Do not make commitments the architecture cannot deliver, and do not under-deliver isolation that was promised. Silent migrations (an acquired tenant assigned to a placement the architecture cannot deliver) need an audit-and-remediation workflow before the commitment lapses.
|
|
177
|
+
|
|
178
|
+
## Migration between tiers
|
|
179
|
+
|
|
180
|
+
Tenants graduate between placements when their commitments, load, or risk profile changes. The migration path must be designed up front; retrofitting it is the painful case.
|
|
181
|
+
|
|
182
|
+
- **Promotion** — move one tenant from a lower placement to a higher one. Steps: provision new placement resources, copy data with tenant-scoped enforcement, cut over reads, drain writes from the old placement, cut over writes, decommission the old tenant's footprint.
|
|
183
|
+
- **Classify each step's reversibility before starting.** Two classes of irreversibility apply:
|
|
184
|
+
- *Structural irreversibility* — the step itself rewrites a primitive the system cannot un-do: ID-scheme reshape, shard-key rewrite, encryption-key envelope change, object-prefix change, warehouse re-partition.
|
|
185
|
+
- *Time-based irreversibility* — the step looks reversible at start, but a TTL, retention job, token-expiry, object-lifecycle rule, log-purge cadence, or backup-rotation window will delete the old state during the migration window. By the time rollback is attempted, the old state is gone even though no structural irreversible step ran.
|
|
186
|
+
For each irreversible step (either class), define the pre-step checkpoint or export snapshot, the reconciliation query that verifies post-state, and the **last safe rollback point** before that step. The last safe rollback point is the **earliest** of the structural-irreversible boundary and any time-based deadline (the soonest TTL, retention purge, or lifecycle expiry that touches state needed for rollback). Either freeze / extend those timers across the migration window, or compute the rollback point from them. Beyond the last safe rollback point, recovery is forward-fix, not rollback.
|
|
187
|
+
- **Live dual-write is itself a small process-manager workflow** — dual-write between placements diverges under load, partial failure, and ordering reordering. Prefer write-freeze windows or outbox-replay-from-checkpoint over ad-hoc dual-write; if dual-write is used, the divergence-detection and reconciliation job is part of the migration design, not the operations runbook.
|
|
188
|
+
- **Per-tenant migration windows** — a single tenant's migration does not require a fleet-wide window; the system supports per-tenant maintenance.
|
|
189
|
+
- **Audit and verification** — verify per-store that all data is in the new placement before decommissioning the old; "did we leave anything behind" is the most common defect.
|
|
190
|
+
- **Demotion is rare** — moving a tenant down a placement is usually for cost recovery on suspended tenants; the path is rarely automated and is usually a manual operation.
|
|
191
|
+
|
|
192
|
+
## Anti-patterns
|
|
193
|
+
|
|
194
|
+
Block these:
|
|
195
|
+
|
|
196
|
+
- **Tenant id derived at boundary, then trusted as a payload field downstream** — extracted from a JWT at the gateway, passed down as a payload field that downstream code treats as authoritative. Either re-verify at the data layer (engine-level filter), or document explicitly that a specific hot-path runs under a verified upstream filter and cannot be reached by an unverified path.
|
|
197
|
+
- **Tenant-scoped cache without tenant in the key** — the single most common cross-tenant data leak. Audit every cache against the cache classification above.
|
|
198
|
+
- **Engine-level tenant filter disabled "for performance"** — turning it off makes the application layer the only barrier. Tune indexes and queries first; never disable the engine filter as the fix.
|
|
199
|
+
- **Bypass-role connections without explicit tenant scoping** — migration runs, repair scripts, regulator exports, replication streams that run as a bypass role without an explicit per-row tenant filter. Treat any bypass-role connection as if there is no engine filter and add the application-layer filter, the audit, and the approval.
|
|
200
|
+
- **`tenant_id` as nullable / optional column** — every tenant-scoped table has `tenant_id NOT NULL`; nullable means a row that can be returned to any tenant.
|
|
201
|
+
- **Cross-tenant query as ad-hoc DB read in a debugging path** — the privacy boundary does not have a "debug mode" exception. Use the audited cross-tenant capability, or do not run the query.
|
|
202
|
+
- **Admin god-mode without audit, rate limit, or TTL** — a sustained admin session can see anything. Audit per call (or per session for high-volume); rate-limit; short-lived tokens; review SLA.
|
|
203
|
+
- **Logs and metrics without tenant scope** — incident response cannot answer "which tenant" without the label; aggregate dashboards quietly mix tenant impact.
|
|
204
|
+
- **Tenant-scoped data in shared object-store buckets without per-tenant prefix and policy** — a misrouted object can be visible cross-tenant. Per-tenant prefix + IAM policy; never rely on the application path alone.
|
|
205
|
+
- **Deletion that leaves data behind past the documented mode** — "we deleted from prod" is not deletion if a backup still has it past the backup-purge SLA. The deletion workflow names the mode per store and is honest about what was achieved.
|
|
206
|
+
- **Tier commitment in contracts that the architecture cannot deliver** — promising residency-in-region-X when the deployment does not have a stack in region X. Product / legal must consult the architecture before committing; silent migrations need a remediation workflow.
|
|
207
|
+
- **Cross-tenant feature added without capability gate, audit, or mode** — every cross-tenant code path needs an explicit capability claim and an audit mode appropriate to its volume (per-call / per-session / break-glass); no exceptions.
|
|
208
|
+
- **"Crypto-deletion" claimed without validating the conditions** — destroying a key is not erasure when key copies exist, when envelope keys would reconstruct, when backups still hold the key, or when the regulator does not accept it.
|
|
209
|
+
|
|
210
|
+
## Operations checklist (multi-tenant boundary launch)
|
|
211
|
+
|
|
212
|
+
Each item below is a verifiable action; "complete" requires the artifact named, not an acceptance statement.
|
|
213
|
+
|
|
214
|
+
- Data placement and compute placement declared per tenant in the tenant directory; the directory is queryable by the data, compute, observability, and lifecycle layers and one query returns the placement set for any tenant id.
|
|
215
|
+
- Tenant context extraction documented per entry point; a synthetic test request with no tenant id at each entry point produces a `missing_tenant` rejection; cross-tenant entry points require the explicit capability and the test without the capability is rejected.
|
|
216
|
+
- Engine-level enforcement verified by an end-to-end test that attempts a cross-tenant read with the application role and is denied; bypass roles enumerated; one connection per bypass role tested and an audit row confirmed.
|
|
217
|
+
- Schema-CI catalog gate runs on every migration: **every relation** (table, view, materialized view, partition child, runtime-created or extension-created relation) is classified `tenant_scoped` / `global` / `cross_tenant_aggregate` / `system` in the checked-in catalog; the build fails on any unclassified relation; extension-created relations follow the owner/template rule. For tenant-scoped relations, the gate verifies engine-policy enabled + forced + application-role policy covers the relation + missing-tenant query returns zero/errors; tenant-scoped relations without a `tenant_id` column declare the parent / join path and the gate verifies the policy resolves tenant via that path.
|
|
218
|
+
- Bypass-role audit independence verified at **both planes**: (a) data-plane — `SELECT` and `DELETE` against the audit sink with each bypass role denied; reads of audit routed through a distinct read-only auditor role; (b) control-plane — attempted modification of audit transport (firewall, security group, DNS, service-account binding, sidecar, queue, routing) from each bypass operating role denied; (c) audit-delivery-gap alert exercised by a synthetic transport tamper (audit pipeline notices when events stop arriving from a bypass source). Environments running the degraded mode for small orgs record: external append-only audit store, two-person approval, external-system delivery-gap alerting, time-boxed remediation plan.
|
|
219
|
+
- (Compatibility) every (data_placement, compute_placement) pair in the directory passes the residency / sovereignty compatibility rule: compute that can read / decrypt / cache / log / index / export / administer region-pinned data is itself region-pinned to the same boundary; control-plane-only exceptions have compliance approval recorded.
|
|
220
|
+
- Tenant session variable set inside an explicit transaction or on every checkout with reset on check-in; pool-reset hook in place; an alert exists on the pool-state metric for connections returned with non-default tenant.
|
|
221
|
+
- Cache classification documented per cache (tenant-scoped / global / cross-tenant aggregate / system); each cache declares its dependency domains (internal + external/runtime config sources, e.g., third-party feature-flag SaaS); a CI gate re-runs the differential test or downgrades the cache when any declared domain changes; for external dependencies without a reliable change signal, the cache defaults to tenant-scoped. A grep/lint gate records zero raw cache-read calls outside the keying helper for tenant-scoped caches; cross-tenant aggregates have an authorization gate that an end-to-end test exercises.
|
|
222
|
+
- Per-tenant quotas listed by layer (API, worker, DB connections, broker, storage, external providers, accelerators, OS-level resources without quota); each quota has a documented budget, enforcement layer, exceeded-response, alert threshold, and escalation owner; a synthetic over-quota test exercises each.
|
|
223
|
+
- Observability: a sampled request, message, and job each show `tenant_id` (for named cohorts) or `tenant_tier` (for long tail) on the headline metric, in the structured log, and in the trace; the per-tenant or per-cohort SLO dashboard URL is linked from the runbook; heavy-hitter detection produces a tenant id within N minutes of synthetic traffic.
|
|
224
|
+
- Cross-tenant capability gates verified: per-call audit for normal admin, per-session for high-volume, break-glass with post-hoc review; the audit emission rate-limit is configured; over-quota emission triggers a security page.
|
|
225
|
+
- Per-tenant lifecycle: provision is idempotent (a synthetic re-provision is a no-op); export job runs under tenant-scoped enforcement and a synthetic test confirms zero cross-tenant rows in the output; delete workflow maintains a **serving-path inventory** with one declared suppression mode per path (ack barrier / central strong check / disabled-from-serving / vendor purge / wait-out max TTL); the workflow blocks source destruction until each path's mode is satisfied (the test exercises a synthetic path failing to ack and confirms the workflow does not advance); per-store deletion modes (hard-delete-verified / anonymized / beyond-use / retained-under-legal-basis / unverifiable-append) each have a test; **crypto-deletion mode** requires the six evidence artifacts at per-store/per-tenant/per-key-version scope, within the freshness window, countersigned by an independent role, linked to the workflow's signed/content-addressed execution identifier (not a bare run id), with artifact hashes in the append-only audit store; archive and re-hydration tested.
|
|
226
|
+
- Per-tenant rollout: feature flags target by tenant / tier / tag; canary order documented; per-tenant rollback path tested for at least one representative change class.
|
|
227
|
+
- Compliance commitments per tenant in the directory; residency / sovereignty / encryption / data-subject-rights workflows in place where promised; crypto-deletion mode classified per store; audit retention vs data retention conflict resolution documented per regulator.
|
|
228
|
+
- Migration path between placements (promotion) designed; structural and time-based irreversible steps classified; TTL / retention / lifecycle deadlines that intersect the migration window are frozen or extended **only where legally permitted** (regulator-mandated retention maxima and data-subject deletion SLAs cannot be paused — in those cases the deadline is immutable and the last safe rollback point is computed from it); last safe rollback point computed as the earliest of structural and time-based boundaries, accepting that beyond it recovery is forward-fix; a migration dry-run on a synthetic tenant has run end-to-end.
|
|
229
|
+
|
|
230
|
+
## Python-specific implementation patterns
|
|
231
|
+
|
|
232
|
+
Stack-localized recipes; the sibling Go file localizes the same patterns differently.
|
|
233
|
+
|
|
234
|
+
- **Tenant context on `contextvars.ContextVar`** — define a module-level `tenant_id_var: ContextVar[UUID | None] = ContextVar("tenant_id", default=None)` and helpers `set_tenant(id) -> Token`, `get_tenant() -> UUID | None`, `require_tenant() -> UUID` (raises on missing). Every entry point (FastAPI dependency, Starlette middleware, message handler) sets the var once; downstream code reads via `get_tenant()` / `require_tenant()` and never accepts tenant as a separate argument.
|
|
235
|
+
- **Async task spawning** — in Python 3.11+, `asyncio.create_task(coro())` **copies the current context by default**; the tenant var propagates without explicit `copy_context()`. Pass an explicit context only when overriding (e.g., starting a long-lived worker with a different tenant scope). The dangerous propagation gaps are **not** `create_task`; they are:
|
|
236
|
+
- `loop.run_in_executor(executor, fn)` and raw `concurrent.futures.ThreadPoolExecutor.submit(fn)` — the executor thread does **not** see the caller's contextvars. Wrap the callable: `loop.run_in_executor(executor, contextvars.copy_context().run, fn, *args)`.
|
|
237
|
+
- `asyncio.to_thread(fn, *args)` — does propagate contextvars (it uses `copy_context().run` internally); the gap is `run_in_executor`, not `to_thread`.
|
|
238
|
+
- `ProcessPoolExecutor` — separate processes never share contextvars; pass the tenant id as an explicit argument to the submitted function.
|
|
239
|
+
- Long-lived background workers (Celery, arq, custom consumers) — establish per-message context inside the worker; do not rely on the parent process's contextvars.
|
|
240
|
+
- Callbacks from foreign threads (signal handlers, third-party callback APIs) — contextvars are per-thread; a foreign-thread callback enters with the foreign thread's contextvars, not the request's.
|
|
241
|
+
- **FastAPI dependency for tenant** — a single dependency `tenant: UUID = Depends(require_tenant_from_jwt)` validates the JWT, looks up the tenant in the directory, sets `tenant_id_var`, and returns the id. Endpoints declare the dependency explicitly; missing-tenant raises `HTTPException(status_code=401)` before the endpoint body runs. Cross-tenant endpoints use a distinct dependency `cross_tenant: CrossTenantCap = Depends(require_cross_tenant_cap)` that reads a different claim, writes an audit row before the handler runs, and tags the request with the audit mode (per-call / per-session / break-glass).
|
|
242
|
+
- **PostgreSQL tenant session variable with FORCE RLS** — schema setup: `ALTER TABLE <t> ENABLE ROW LEVEL SECURITY; ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` for every tenant-scoped table (FORCE makes the table owner subject to RLS too). Create distinct DB roles: `app_user` (no BYPASSRLS), `migration_user` (BYPASSRLS, used only by Alembic/SQLAlchemy migration sessions), `replication_user`, `admin_user` (used only via audited bastion). Application connects as `app_user`. Tenant variable: set inside an explicit transaction per request with `await session.execute(text("SELECT set_config('app.tenant_id', :tid, true)"), {"tid": str(tenant_id)})`. The `true` third argument is tx-local; **outside an explicit transaction the setting vanishes at statement end**. Wrap every tenant-scoped request in `async with session.begin():` (or use `async_session_factory()` with explicit `begin()`); SQLAlchemy 2.x's autobegin gives you that as long as you use the unit-of-work pattern, but a `session.execute` outside `begin()` is the failure mode to avoid. Default-deny policy: `CREATE POLICY tenant_isolation ON <t> USING (tenant_id = current_setting('app.tenant_id', true)::uuid)`; the `true` second arg to `current_setting` makes a missing setting return NULL, which fails the policy and rejects the row — default-deny without crash.
|
|
243
|
+
- **Connection pool reset** — `event.listens_for(pool, "reset")` issues `RESET app.tenant_id; RESET ROLE` on connection return. Treat reset as cleanup, not correctness; SQLAlchemy's reset event has paths (terminating connections, async-connection GC, invalidated connections) where the hook is not guaranteed to execute the SQL. Correctness comes from setup on every transaction (the `set_config` above) plus the default-deny policy that rejects rows when the setting is missing. A periodic sampler queries `pg_stat_activity` and alerts on sessions with `app.tenant_id` set outside an active query.
|
|
244
|
+
- **Cache key construction** — a single helper per cache class. `tenant_key(namespace, *parts)` for tenant-scoped caches (calls `require_tenant()`); `global_key(namespace, *parts)` for global immutable caches; `aggregate_key(namespace, *parts)` paired with a `require_cross_tenant()` check for cross-tenant aggregates. Lint enforcement via a ruff custom rule or a CI grep gate forbidding raw `await redis.get(key)` outside these helpers for tenant-scoped caches.
|
|
245
|
+
- **Starlette / FastAPI middleware** — a `TenantMiddleware` extracts tenant from the verified JWT/session, validates against the tenant directory, sets `tenant_id_var`, and yields to the next app. Missing tenant short-circuits with a typed error response before the route runs.
|
|
246
|
+
- **Async message consumer** — every message header carries `tenant_id`; the consumer's first action after decode is `tenant_id_var.set(msg.headers["tenant_id"])`. A message without a tenant id goes to DLQ with `missing_tenant` disposition unless the message type is explicitly cross-tenant.
|
|
247
|
+
- **Outbox rows carry tenant** — the `outbox` table has `tenant_id` (UUID, NOT NULL); the poller publishes with the tenant id in the broker header. Downstream consumers re-enter their own tenant context from the header. The claim-commit-publish-mark-sent loop (see `event-driven-architecture.md`) reads tenant from each row.
|
|
248
|
+
- **Quota enforcement** — per-tenant token bucket in Redis keyed by `tenant:<id>:bucket:<resource>`; an async helper `await acquire_token(tenant_id, resource) -> bool` is called at the entry of each rate-limited operation. For per-process limits use `asyncio.Semaphore` indexed by tenant; for cross-process use Redis-backed bucket via a `redis-py` Lua script. For shared accelerators (LLM inference, GPU), the per-tenant bucket feeds a fair scheduler that interleaves tenants without partitioning the batch.
|
|
249
|
+
- **Observability** — `structlog` processor that pulls `tenant_id_var.get()` and attaches `tenant_id` to every log record; OpenTelemetry baggage (`baggage.set_baggage("tenant.id", str(tenant_id))`) propagates across spans; emit Prometheus metrics with `tenant_id` only on headline RED metrics for named cohorts; tag tenant tier for long tail; heavy-hitter detection runs in a sidecar that promotes a long-tail tenant to per-id observation when its traffic crosses a threshold. Wire OTel startup in `observability-and-ops.md`.
|
|
250
|
+
- **Cross-tenant capability** — a typed `CrossTenantCap` Pydantic model attached to the request via a dependency, with a mode field (`per_call` / `per_session` / `break_glass`); a helper `audit_cross_tenant(tenants: list[UUID], operation: str, mode: AuditMode)` writes an audit row per call (per-call mode) or starts a session record (per-session mode); break-glass mode also queues a post-hoc review task.
|
|
251
|
+
- **Tenant directory client with revision-aware refresh + atomic-snapshot semantics** — `httpx.AsyncClient` over the tenant directory service. A monotonic `generation` alone is not enough when the directory's backing store is sharded or eventually consistent — a global revision can advance while one tenant's update has not yet reached the replica the directory serves from. The directory must expose either (a) a true atomic-snapshot read with a watermark covering all tenants, or (b) per-tenant / per-shard versions plus a checksum the client can use to detect partial snapshots. The client caches the last-known-good snapshot tagged with the generation + completeness proof; the background refresher polls and replaces the snapshot only when the new snapshot is provably complete (atomic watermark, or all shard versions ≥ the previous snapshot's). On a partial-snapshot signal, keep the old snapshot, alert, and retry; do not replace. Readiness fails if the snapshot is older than the configured staleness budget; the client returns `unknown_tenant` (fail-closed) when the directory itself is unreachable past readiness budget. Tier downgrades propagate within one refresh interval; alert when refresh duration exceeds the budget. `async-lru` is acceptable for the in-memory snapshot; the refresh task is the authoritative path, not the TTL eviction.
|
|
252
|
+
- **Test substitution** — define a `TenantDirectory` Protocol; provide an in-memory implementation for pytest with a few synthetic tenants; integration tests run against a real directory via `testcontainers-python` or a dev instance.
|
|
253
|
+
- **Graceful tenant offboarding** — the deletion workflow is a state machine (see `background-jobs-and-scheduling.md` or your workflow engine); each per-store step has an async handler that records `pending` / `done` / `unknown`; each step is tagged with one of the per-store deletion modes (hard-delete-verified / anonymized / beyond-use / retained-under-legal-basis / unverifiable-append); the workflow's `unknown` path triggers a reconciliation job and alerts. Schema-per-tenant or DB-per-tenant deletion paths drop the tenant's schema/DB after data export verification; the drop is itself audited.
|
|
254
|
+
|
|
255
|
+
### Mirrored-section grep gate
|
|
256
|
+
|
|
257
|
+
The sibling-sync header forbids three categories of stack-specific token in mirrored sections (everything from "When this applies" through "Operations checklist"; everything *before* the `## Python-specific implementation patterns` H2). Run this grep against the mirrored region before every commit; zero hits required (except inside fenced code blocks, which mirrored sections do not use).
|
|
258
|
+
|
|
259
|
+
Forbidden tokens for this Python file's mirrored sections:
|
|
260
|
+
|
|
261
|
+
- **DB-engine syntax** — `SET LOCAL`, `RESET ROLE`, `RESET app\.tenant_id`, `set_config\(`, `current_setting\(`, `pg_try_advisory`, `pg_stat_activity`, `BYPASSRLS`, `FORCE ROW LEVEL SECURITY`, `search_path`, `CREATE POLICY`, `ENABLE ROW LEVEL SECURITY`, `GET_LOCK\(`.
|
|
262
|
+
- **Runtime / concurrency mechanic names** — `context\.Context`, `\bgoroutine\b`, `\bgoroutines\b`, `ctx\.Done`, `ResetSession`, `database/sql`, `\bsqlx\b`, `contextvars`, `\basyncio\b`, `run_in_executor`, `to_thread`, `ThreadPoolExecutor`, `ProcessPoolExecutor`, `copy_context`, `async with`, `executor/thread-pool/process-pool`.
|
|
263
|
+
- **Library / framework API names** — `GORM`, `\bsqlx\b`, `Hertz`, `Kitex`, `golang\.org/x/time/rate`, `SQLAlchemy`, `FastAPI`, `Starlette`, `Pydantic`, `httpx`, `aiokafka`, `pika`, `aio-pika`, `redis-py`, `tenacity`, `structlog`, `testcontainers`, `Alembic`, `async-lru`, `asyncpg`, `psycopg`, `cache\.Get`.
|
|
264
|
+
|
|
265
|
+
Run the command below. The regex is **generated from** the token list above and must match it exactly — token list changes require regenerating the regex. Word boundaries (`\b…\b`) preserve the declared semantics (`asyncio` as a word, not as a substring of `asyncio.create_task` in a routing-reference text).
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
awk '/^## Python-specific implementation patterns/{exit} 1' multi-tenant-isolation.md \
|
|
269
|
+
| grep -nE '(SET LOCAL|RESET ROLE|RESET app\.tenant_id|set_config\(|current_setting\(|pg_try_advisory|pg_stat_activity|BYPASSRLS|FORCE ROW LEVEL SECURITY|search_path|CREATE POLICY|ENABLE ROW LEVEL SECURITY|GET_LOCK\(|context\.Context|\bgoroutine\b|\bgoroutines\b|ctx\.Done|ResetSession|database/sql|\bsqlx\b|contextvars|\basyncio\b|run_in_executor|to_thread|ThreadPoolExecutor|ProcessPoolExecutor|copy_context|async with|executor/thread-pool/process-pool|GORM|Hertz|Kitex|SQLAlchemy|FastAPI|Starlette|Pydantic|httpx|aiokafka|\bpika\b|aio-pika|redis-py|tenacity|structlog|testcontainers|Alembic|async-lru|asyncpg|psycopg|cache\.Get)'
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Allowed exception: the *Sibling sync* header itself names the three category classes (without tokens) and references this gate; the *Sanitization boundary* header does not contain any of these tokens. The sibling Go file maintains the matching gate for Go-side tokens (`context.Context`, `goroutine`, `GORM`, `database/sql`, etc.), so a token forbidden here may legitimately appear in the *Go-specific implementation patterns* section of the sibling, and vice versa.
|
|
273
|
+
|
|
274
|
+
## Topic-extension backlog
|
|
275
|
+
|
|
276
|
+
Two multi-tenant isolation areas are known to be wider than the current rules close. Extend each via **incident-driven evidence**, not a generic re-review pass — a generic round only surfaces them at wording level without resolving them. Each names the general rule already in place + the residual gap + the incident evidence that would unblock the next extension.
|
|
277
|
+
|
|
278
|
+
- **External / runtime cache dependency change-signal contracts.** Rule in place: each global cache declares its dependency domains including external / runtime sources; the gate uses webhook-backed drift triggers, scheduled attestation, or default-downgrade-to-tenant-scoped. Residual: the **specific change-signal contract** between this codebase and each external dependency is per-integration and cannot be generalized. Extend when: a real incident occurs where a remote dependency schema shifted and a global cache silently broke. Evidence to bring: the specific external provider, its change-event surface (or lack of one), the cache that broke, the drift detection that should have caught it.
|
|
279
|
+
- **Catalog gate coverage for non-relational tenant stores.** Rule in place: the schema-CI gate enumerates every relation (table, view, materialized view, partition child, runtime-created, extension-created) and fails on unclassified ones. Residual: the rule is DB-relation-only. Non-relational tenant stores — including but not limited to message-queue topics that fan out per-tenant, object-store paths with per-tenant prefixes, search indexes, vector embeddings stores, document DB collections (MongoDB, DocumentDB), graph DB labels/edges, time-series and metrics stores (Prometheus / Mimir / VictoriaMetrics tenant series), ML feature stores, primary key-value stores (Redis / DynamoDB used as system-of-record, not as cache), secrets and config stores (Vault, KMS, parameter stores), CDN origins, analytics-warehouse extracts, and cache namespaces — each have their own catalog-and-classification gap that the DB-CI gate does not see. Treat the list as open-ended; any per-tenant store class outside the DB-relations boundary needs its own enumeration mechanism. Extend when: a real incident occurs where a non-DB store accumulated unclassified tenant-scoped content (a search index with tenant rows that bypassed the deletion workflow, an object-store path with tenant data not in the deletion serving-suppression denylist). Evidence to bring: the non-DB store class, its enumeration mechanism (or lack of one), the tenant-classification gap, and the gate that should have caught it.
|
|
280
|
+
|
|
281
|
+
A related open concern: **workflow-execution-identifier forgery / replay** in crypto-deletion chain-of-custody — use a signed nonce or content-addressed event id rather than a bare run id; the specific signing primitive depends on the workflow engine in use, so extend when the engine surfaces a real replay or relabeling case.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Observability And Ops
|
|
2
|
+
|
|
3
|
+
Use this for logs, metrics, traces, health checks, readiness, and operational controls.
|
|
4
|
+
|
|
5
|
+
## Required Surfaces
|
|
6
|
+
|
|
7
|
+
- Structured logs with request ID, trace ID, user/tenant/resource scope where safe, route/job name, dependency target, and outcome.
|
|
8
|
+
- Metrics for request latency, error rate, dependency latency, queue depth, retry/drop counts, cache hit/miss, and job duration.
|
|
9
|
+
- Traces for inbound requests, outbound HTTP, DB calls, queue work, and inference calls where feasible.
|
|
10
|
+
- Health checks distinguish process liveness from dependency readiness.
|
|
11
|
+
- Debug endpoints and profilers must be disabled or protected in production.
|
|
12
|
+
|
|
13
|
+
## Python Notes
|
|
14
|
+
|
|
15
|
+
- Use OpenTelemetry or framework-supported instrumentation when available.
|
|
16
|
+
- Make logging configuration deterministic at startup; avoid libraries configuring global logging unexpectedly.
|
|
17
|
+
- Use JSON logs for service environments where log aggregation expects structured fields.
|
|
18
|
+
|
|
19
|
+
## Cross-Stack Conventions
|
|
20
|
+
|
|
21
|
+
When the portfolio contains Go services and Python services that share dashboards and alerts, the architecture layer fixes a common shape:
|
|
22
|
+
|
|
23
|
+
- Metric naming convention: `{category}_{operation}_{suffix}` snake_case, identical across stacks. Base label set for RPC/HTTP metrics is platform-fixed (`caller`, `caller_cluster`, `caller_env`, `caller_method`, `callee`, `callee_cluster`, `callee_env`, `method`, `err_code`); high-cardinality identifiers are forbidden as labels in either stack.
|
|
24
|
+
- Logger trace-linkage contract: every service-internal logger accepts `ctx` (Go) or carries `contextvars` (Python), automatically emits the same four trace-identity fields, and adds `span.AddEvent` / `span.add_event` on warn/error. The wire shape is identical; only the call site differs. A shared foundation framework may propagate this cross-cutting context, but it does not own the application's logger API surface or codegen output meant for wire consumers; keep that ownership boundary explicit.
|
|
25
|
+
- OTel resource attributes (`service.name`, `service.namespace`, `service.version`, `lane`, `pod.ip`, `pod.name`) are set once per process at startup in both stacks. Per-call attributes belong on spans, not on the provider.
|
|
26
|
+
- Context propagation tiers (global trace/log identity, post-auth API context, inbound header mappings) follow the same three-tier shape as the Go side. Typed accessors hide the bare-string assertion in both stacks.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Packaging Runtime Readiness
|
|
2
|
+
|
|
3
|
+
Use this for pyproject, uv/poetry/pip, lockfiles, tooling, containers, and deployment process.
|
|
4
|
+
|
|
5
|
+
## Packaging
|
|
6
|
+
|
|
7
|
+
- Prefer `pyproject.toml` as the canonical project metadata and tool config surface.
|
|
8
|
+
- Use lockfiles for deployable services.
|
|
9
|
+
- Separate runtime and dev dependency groups.
|
|
10
|
+
- In monorepos, make workspace packages explicit and avoid import success that depends on developer-local `PYTHONPATH` tricks.
|
|
11
|
+
- Generated clients and shared packages should be versioned or workspace-pinned deliberately.
|
|
12
|
+
- **For new Python service architectures, `uv` (Astral, Rust-based) is the current default packaging tool** — single static binary replacing pip + pip-tools + virtualenv + pipx + most of poetry + pyenv (per Astral docs). Architecture impact beyond "faster install": (a) Cargo-style workspaces map cleanly to monorepo subpackages so workspace pinning is first-class rather than ad-hoc; (b) built-in Python version management means CI / Docker base images no longer need separate `pyenv` / system-Python juggling; (c) `uv.lock` is cross-platform reproducible (single lockfile across macOS / Linux / Windows / arch variants), removing per-platform lockfile drift that plagued poetry; (d) pip-compatible interface (`uv pip`) makes migration low-risk because existing requirements.txt / setup.py / pyproject can be consumed without restructuring. For existing services on poetry / pip-tools / pdm / rye / hatch, plan the uv switch as a dedicated architecture migration (lockfile parity check, CI pipeline flip, Dockerfile rebuild, dev-onboarding doc update in one slice), not as drive-by during feature work.
|
|
13
|
+
|
|
14
|
+
## Runtime
|
|
15
|
+
|
|
16
|
+
- Define entrypoint: `uvicorn`/`gunicorn`, framework command, worker command, scheduler command, or CLI.
|
|
17
|
+
- Define process model: worker count, async event loop, thread/process workers, memory limits, graceful shutdown, and health probes.
|
|
18
|
+
- Release readiness includes migrations, startup validation, smoke tests, canary, rollback, and observability checks.
|
|
19
|
+
- **ASGI server choice has expanded beyond `uvicorn` / `gunicorn+uvicorn` / `hypercorn`** — `granian` (emmett-framework, Rust-based) is the current credible high-throughput alternative for ASGI services, supporting ASGI/3, RSGI, WSGI, HTTP/1, HTTP/2, TLS, WebSockets (HTTP/3 planned per the project README's "eventually 3" roadmap note — verified not shipped as of May 2026). Per the Granian project's own `benchmarks/vs.md` and third-party load-test repos (e.g., `piccolo-orm/asgi_server_performance`, `synodriver/asgi-server-benchmark`), ASGI echo on 10KB payload typically lands granian > uvicorn-httptools > hypercorn by roughly the ratios 58k / 51k / 8k RPS in April-2026-era runs; file-serving gap is wider (granian ~47k vs uvicorn ~18k via `pathsend`). Treat the absolute numbers as benchmark-snapshot-specific; re-run against your workload before basing a switch on them. Architecture impact: when serving throughput is the binding constraint, granian can buy headroom without rewriting the **plain ASGI path**. **"Without rewriting" caveats**: granian's worker / process model differs from `gunicorn+uvicorn` fork-based workers (Rust runtime + Python interpreters with different lifecycle hooks); ASGI lifespan events, contextvars propagation across worker boundaries, custom signal handlers, prometheus/metrics exporters tied to uvicorn internals, and ASGI middleware that depends on uvicorn-specific behavior all need smoke-testing on granian before a switch. If the team plans to adopt granian's bespoke RSGI protocol for max performance (rather than ASGI), application code that uses ASGI-specific middleware, ASGI scope manipulation, or third-party ASGI libraries WILL need rewriting — RSGI is a different protocol, not a faster ASGI. Trade-offs: smaller operational maturity, fewer community recipes, Rust-runtime-on-the-side observability differs from a pure-Python server. **Choose uvicorn** for ecosystem maturity, broad reference material, and known operational patterns; **choose granian** when (a) profiled benchmarks on your workload show uvicorn saturation, (b) the team has Rust-toolchain debugging capacity, (c) the deployment story can absorb a less-common runtime. Hypercorn remains the choice when HTTP/2 + ASGI under pure-Python ops matters more than peak throughput.
|
|
20
|
+
- **Python runtime version baseline (2025-2026)**: Python 3.13 (released October 2024) ships **experimental** free-threaded build per PEP 703 — GIL-disabled, ~40% single-threaded perf hit per python.org "What's New in 3.13" notes, used at the team's risk for parallel-CPU workloads. Python 3.14 (released 7 October 2025) advances free-threading to **supported (Phase II of PEP 703)** per PEP 779 — meaning the free-threaded build is a first-class supported configuration, NOT that it is the default Python build or the default production choice. Per the python.org free-threading howto, the single-threaded penalty narrowed to ~5-10% (specializing adaptive interpreter re-enabled thread-safely); PEP 803 defines the `abi3t` stable ABI for free-threaded C extensions. Architecture impact: for services where parallel CPU work matters (in-process ML inference fan-out, heavy parsing, parallel compression), 3.14 free-threading is the first version where adoption is **a defensible experiment for a selected service**, not yet a defensible default. Pre-flight burn-in required before any production switch: (a) C-extension readiness — all extensions in the service's dependency tree must declare free-threading support; many popular extensions (numpy, pandas, lxml, psycopg native bits, asyncpg native bits, pillow, cryptography) were still mid-migration at 2026-Q1, verify per-version; mixing GIL-only and free-threading-aware extensions in one process is unsupported; (b) GC and runtime behavior under sustained threading load differs from GIL build — measure tail latency, memory residency, and CPU efficiency on the actual workload; (c) debugger / profiler ergonomics (gdb, pdb, py-spy, scalene, prometheus exporters) may have rough edges on free-threaded builds; (d) library-level thread-safety: code paths that were "implicitly safe because of the GIL" can race in free-threaded mode (singletons built at import time, module-level mutable caches, third-party libraries that rely on GIL-protected dict mutation). For pure I/O-bound services, stay on stock GIL build — the 5-10% overhead is pure cost. For services on 3.13 or older, treat free-threading as opt-in research, not default.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Redis Cache Coordination
|
|
2
|
+
|
|
3
|
+
Use this for Redis cache, locks, rate limits, counters, idempotency windows, and ephemeral coordination.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- Redis is not durable source of truth for auditable state.
|
|
8
|
+
- Centralize key names, TTLs, namespaces, lock leases, and rate-limit windows.
|
|
9
|
+
- Use unique lock values and compare-and-delete unlock semantics.
|
|
10
|
+
- TTL policy is part of architecture, not an implementation afterthought.
|
|
11
|
+
- Cache invalidation must have an owner: write-through, event-driven invalidation, explicit delete, or time-bounded staleness.
|
|
12
|
+
- If Redis is used for idempotency, separate pending claim, completed marker, duplicate, and retryable-failure states. Pending claims need a lease/TTL and completed markers need a dedupe window that matches the external retry horizon.
|
|
13
|
+
- Redis Streams, Pub/Sub, lists, and sorted sets are not interchangeable. Name the delivery guarantee: fire-and-forget notification, replayable stream, deduplicated pending work, delayed scheduling, or durable queue backed by DB/MQ.
|
|
14
|
+
- Broad pattern deletion and stream cleanup need a bounded strategy. Architecture should state whether cleanup is batched, TTL-driven, event-driven, or an admin/backfill operation.
|
|
15
|
+
- Redis failure policy must be per responsibility: fail open for optional caches, fail closed for authorization/risk controls, return duplicate/pending states for idempotency, and expose repair/retry for workflow coordination.
|
|
16
|
+
|
|
17
|
+
## Python Notes
|
|
18
|
+
|
|
19
|
+
- Choose sync or async Redis clients according to the service stack.
|
|
20
|
+
- Do not use a sync Redis client directly in async endpoints unless isolated.
|
|
21
|
+
- Connection pools, timeouts, and retries should be configured once through dependency assembly.
|
|
22
|
+
|
|
23
|
+
## Cache Stampede Architecture
|
|
24
|
+
|
|
25
|
+
- For any cache fronting an expensive source of truth, architecture names the stampede defense: single-flight (one fetcher per key), negative caching with shorter TTL for misses, and randomized TTL jitter. Architecture also names the staleness budget so the team can pick the right combination.
|
|
26
|
+
- Multi-tier caches (process-local in front of Redis in front of DB) need a coherent invalidation contract: Pub/Sub fan-out, `CLIENT TRACKING` (RESP3) for short-staleness reads, or explicit delete-on-write. Architecture names the chosen mechanism per cache tier.
|
|
27
|
+
|
|
28
|
+
## Cluster Topology Boundary
|
|
29
|
+
|
|
30
|
+
- If Redis is deployed as Cluster (or Cluster-compatible managed service), architecture declares the hash-tag convention and the keys that must share a slot. Cross-slot Lua, `MULTI/EXEC`, and pipeline-with-dependencies are architectural decisions, not coincidence; the key schema is the contract.
|
|
31
|
+
- Cluster failover, slot migration, and topology refresh behavior is owned at the platform layer; this skill names the client's expected behavior (refresh on `MOVED`/`ASK`, retry on topology change, idempotency on the retry path).
|
|
32
|
+
|
|
33
|
+
## Authentication And Encryption Responsibility
|
|
34
|
+
|
|
35
|
+
- Production Redis must be authenticated and encrypted. TLS is required for any non-loopback traffic; the auth model is whichever the chosen Redis provider supports — ACL user + password, mTLS client certificates, or short-lived IAM/AAD tokens. Architecture names the trust anchor (managed CA, internal PKI) and the credential lifetime, and treats the provider's strongest supported option as the default.
|
|
36
|
+
- Redis ACL users follow least-privilege: per-service users with explicit command lists. Cluster-wide admin commands (`FLUSHDB`, `CONFIG`, `DEBUG`) are not part of application user grants.
|
|
37
|
+
|
|
38
|
+
## Retry And Circuit Breaker Ownership
|
|
39
|
+
|
|
40
|
+
- Retry policy and circuit breaker for Redis access live at the dependency-assembly layer, not scattered through call sites. Architecture names the transient-error catalog (timeout, connection reset, `LOADING`, `BUSY`) and the breaker scope (per-endpoint, per-shard).
|
|
41
|
+
- Breaker-open behavior is a product contract: cache-miss path may return stale-OK, authz path must fail closed, idempotency path returns "duplicate uncertain". Architecture names the per-responsibility breaker semantics; do not let the resilience layer pick silently.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Reliability And Error Contract
|
|
2
|
+
|
|
3
|
+
Use this for timeout, retry, fallback, exception mapping, and canonical errors.
|
|
4
|
+
|
|
5
|
+
## Error Contract
|
|
6
|
+
|
|
7
|
+
- Define canonical error shape once.
|
|
8
|
+
- Map Pydantic validation, framework HTTP exceptions, ORM errors, Redis errors, queue errors, HTTP client errors, and inference-client errors into that shape. A pluggable or runtime error classifier's output is untrusted input at the boundary: validate/normalize it and fail closed to a safe generic code; never index the code→status mapping with an unvalidated classifier or external value.
|
|
9
|
+
- Keep public error details safe: no secrets, stack traces, raw provider payloads, or internal IDs unless explicitly allowed. Gate every code through an allow-list separating client-safe from internal-only codes before writing it to a client-facing response body.
|
|
10
|
+
|
|
11
|
+
## Reliability
|
|
12
|
+
|
|
13
|
+
- Every external call needs timeout, retry/fallback policy, and observability.
|
|
14
|
+
- Retries require idempotency or a clear reason the operation is safe.
|
|
15
|
+
- Circuit breakers, rate limits, and backpressure belong to architecture when a dependency can overload.
|
|
16
|
+
- Fail closed for auth, permissions, money, irreversible actions, and data-integrity checks.
|
|
17
|
+
- Use graceful degradation only for non-critical cache, analytics, recommendations, or telemetry paths.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Python Architecture Source Evidence Map (Methodology Template)
|
|
2
|
+
|
|
3
|
+
This file describes the **shape** of source-evidence tracking for Python architecture extraction. Project-specific provenance (real repo names, branch state, dates, module counts, extraction logs) lives in the maintainer's private alias file at `~/.<host>/.private-aliases/<project>.yaml`, never in this shared skill tree — see `skill-extraction-workflow` Core Rule "Extraction lifecycle handoff".
|
|
4
|
+
|
|
5
|
+
## Scope boundary
|
|
6
|
+
|
|
7
|
+
This shared template contains reusable methodology only. Do not add concrete repository names, branch state, module counts, package descriptors, or extraction logs.
|
|
8
|
+
|
|
9
|
+
## Source coverage dimensions (architecture-level)
|
|
10
|
+
|
|
11
|
+
When extracting Python architecture guidance from a new source set, organize evidence by these dimensions:
|
|
12
|
+
|
|
13
|
+
| Dimension | What to collect | What to extract at architecture layer |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Service boundary inventory | How services are split (by domain / by traffic class / by data ownership); inter-service contract count | Boundary criteria, when to split vs merge, ownership rules |
|
|
16
|
+
| API contract shape | Pydantic / OpenAPI / framework schemas in use, public-vs-internal API split, contract evolution practice | Contract-first discipline, additive evolution rule, public/internal split when stability needs differ |
|
|
17
|
+
| Data ownership | Per-service write model, cross-service read patterns, migration discipline (Alembic / framework migrations) | Each service owns its write model; cross-service reads through API; relational source-of-truth |
|
|
18
|
+
| Runtime platform | Service discovery integration, framework choice (FastAPI / Flask / Django / equivalent), dynamic config, secret management, observability, mesh integration | Workload identity, registry-based vs DNS-based SD, mesh ownership boundary, dependency client contracts |
|
|
19
|
+
| Async / sync model | asyncio call-chain hygiene, blocking work isolation (thread pool / `asyncio.to_thread` / process pool), framework async support | Async only when call chain and libraries are truly non-blocking; isolate blocking I/O / CPU / GPU explicitly |
|
|
20
|
+
| Worker / job design | Celery / RQ / arq / framework workers, schedule, retry, idempotency, backfill | Worker design as first-class architecture; idempotency key, lease, max execution |
|
|
21
|
+
| Error / context contract | Error code enum, exception → code map, ctx propagation through async paths | Stable enum, framework exception mapping, contextvars-as-source-of-truth for correlation |
|
|
22
|
+
| Reliability surfaces | Rate limit, backpressure, circuit breaker, idempotency, durable status | Reliability is architecture, not bolt-on |
|
|
23
|
+
| AI / LLM service hosting | Inference adapter shape, streaming protocol, replay, token cost, fallback | Service-side boundary only; inference design routes to `llm-inference-integration` |
|
|
24
|
+
| Generated code ownership | OpenAPI client gen, protobuf gen, ORM autogenerate, ownership boundary | Generated code is output; generation commands documented and portable |
|
|
25
|
+
| Packaging | Dependency manager (uv / poetry / pip), lockfile, container image, process model | Reproducible builds, pinned dependencies, documented process model |
|
|
26
|
+
| Release runtime | Deployment unit, mesh routing, canary, approval, rollback | Architecture surface, not afterthought |
|
|
27
|
+
|
|
28
|
+
## Sibling-generalization mini-map (template)
|
|
29
|
+
|
|
30
|
+
For each Python architecture extraction, record decisions across sibling skills:
|
|
31
|
+
|
|
32
|
+
- `python-service-dev` — does the architectural rule have an implementation pattern? note in dev reference.
|
|
33
|
+
- `go-microservice-architecture` — cross-language counterpart? mirror at architecture level.
|
|
34
|
+
- `go-microservice-dev` — implementation counterpart?
|
|
35
|
+
- `llm-inference-integration` — does the AI/inference-adjacent rule belong there instead?
|
|
36
|
+
- `testing-strategy` — what test layer proves the architectural property?
|
|
37
|
+
- `platform-observability` / `platform-service-connectivity` / `platform-release-engineering` — does the rule belong at platform layer?
|
|
38
|
+
|
|
39
|
+
Decisions go in the private alias map alongside the per-batch extraction log.
|
|
40
|
+
|
|
41
|
+
## Coverage discipline rules
|
|
42
|
+
|
|
43
|
+
- Architecture extractions describe **decision criteria, invariants, ownership boundaries, and acceptance checks**. Implementation patterns go to `python-service-dev`.
|
|
44
|
+
- Mark each dimension `pending` / `read` / `deep-read` / `excluded` / `unavailable` / `routed` with the actual artifacts inspected, in the private alias map.
|
|
45
|
+
- Re-read source artifacts when changing rules; use `wording cleanup` / `no new source read` labels honestly.
|
|
46
|
+
|
|
47
|
+
## Where the live provenance lives
|
|
48
|
+
|
|
49
|
+
For the maintainer's current Python extraction project, see:
|
|
50
|
+
- Private alias map: `~/.<host>/.private-aliases/<project>.yaml`
|
|
51
|
+
- Per-batch extraction logs: `~/.<host>/skills/.extraction-work/<batch>-completion.md`
|
|
52
|
+
|
|
53
|
+
## Audit gate
|
|
54
|
+
|
|
55
|
+
Before committing a change to this skill, run the private alias map's `audit_cmd` against the changed shared-skill files. Any hit on real repo names, branch states, dates, file counts, or business-domain nouns is either fixed or recorded as `known_debt` (pre-existing hits only — new/modified content must stay zero-hit per the R0 rule).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Web Framework Boundaries
|
|
2
|
+
|
|
3
|
+
Use this when choosing or reviewing FastAPI, Flask, Django, Starlette, ASGI, or WSGI boundaries.
|
|
4
|
+
|
|
5
|
+
## Framework Choice
|
|
6
|
+
|
|
7
|
+
- Prefer FastAPI for typed HTTP APIs, OpenAPI-first contracts, async-compatible endpoints, dependency injection, and service-style applications.
|
|
8
|
+
- Prefer Django when the product needs admin, ORM conventions, forms, templating, user/session features, and a cohesive framework.
|
|
9
|
+
- Prefer Flask for small synchronous tools, simple internal UIs, or minimal APIs where explicit wiring is more valuable than framework breadth.
|
|
10
|
+
- Use Starlette-level primitives only when the service needs lower-level ASGI control.
|
|
11
|
+
- **Consider Litestar (formerly Starlite) as a structured alternative to FastAPI** when the architecture wants framework-owned ORM integration, server-side sessions, caching, plugin system, and OpenTelemetry built in rather than assembled per-project; per Litestar docs the framework does more work at bootstrap (precomputed per-route requirements) so runtime cost is lower, and dependency injection is a dict-based `Provide(...)` model that allows transparent override at app/router/controller/route level. The architecture-level trade-off is: more framework convention vs more ecosystem maturity. Choose Litestar when the team wants framework opinions to outpace ad-hoc choices; stay on FastAPI when ecosystem maturity (third-party integrations, hiring pool, community examples) outweighs the structural delta. **Validate production-adoption risks before committing**: Litestar's plugin / middleware ecosystem is smaller than FastAPI's (which inherits much of Starlette's middleware library); the most common production-critical pieces — observability/OTel exporter (Litestar has first-party support, but the specific exporter version + auth-header forwarding behavior may differ), auth middleware (Litestar plugins exist but parity with FastAPI-specific extensions is per-feature), deployment-runtime quirks (lifespan event ordering, ASGI middleware chaining, custom serializer hooks) — should each be smoke-tested on a real Litestar app before the team commits. Litestar does NOT extend Starlette, so third-party "Starlette middleware" packages may need a Litestar-native equivalent or wrapper. Either choice is a long-term commitment — framework switches mid-product are expensive and rarely worth it. Implementation-level Litestar specifics live in `python-service-dev/references/web-framework-patterns.md`.
|
|
12
|
+
|
|
13
|
+
## Boundaries
|
|
14
|
+
|
|
15
|
+
- Keep routers/views thin. They should bind request data, authenticate/authorize, call application services, and map responses/errors.
|
|
16
|
+
- Put business decisions and data transactions outside route handlers.
|
|
17
|
+
- Use app factories or explicit `create_app()` functions when middleware, clients, settings, and test substitution matter.
|
|
18
|
+
- Use framework dependency mechanisms, but do not bury heavy construction, network I/O, or mutable global state inside dependency functions.
|
|
19
|
+
- Treat ASGI/WSGI choice as runtime architecture: worker count, event loop, sync adapters, lifespan hooks, and shutdown cleanup all matter.
|
|
20
|
+
|
|
21
|
+
## Anti-Patterns
|
|
22
|
+
|
|
23
|
+
- Mixing sync ORM calls inside async endpoints without isolation.
|
|
24
|
+
- Starting clients, schedulers, or background loops at import time.
|
|
25
|
+
- Returning raw ORM objects or unvalidated dictionaries as public API contracts.
|
|
26
|
+
- Letting framework folder conventions define domain ownership without an explicit boundary.
|