[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6N9HYVVR0FXGZACNVDP2N2F":3,"skill-same:01M6N9HYVVR0FXGZACNVDP2N2F":69},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":54,"install":55,"resources":68},"01M6N9HYVVR0FXGZACNVDP2N2F","bubbles-config-sst",null,"Enforce Configuration Single Source of Truth (SST) governance. Use when adding config values, creating services, modifying ports, reviewing env files, changing Docker Compose, or auditing config drift. Triggers include new service\u002Fport\u002Fendpoint, .env editing, hardcoded values in source, config generation pipeline changes, and environment variable additions.","pkirsanov\u002Fsmackerel","pkirsanov","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F138962?v=4","01M6N8NAPD2KXMVC17X6GJ0WZ5","01M6N8NATQ9SAZ00H9D61R0TPV",1,"MIT","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbubbles-config-sst\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"config","bubbles config sst","sst","drift","docker","changes","source","docker compose","port","env","triggers","enforce","pipeline","files","compose","use","environment","editing","ports","endpoint","2026-11-10 10:12:30",false,"---\nname: bubbles-config-sst\ndescription: Enforce Configuration Single Source of Truth (SST) governance. Use when adding config values, creating services, modifying ports, reviewing env files, changing Docker Compose, or auditing config drift. Triggers include new service\u002Fport\u002Fendpoint, .env editing, hardcoded values in source, config generation pipeline changes, and environment variable additions.\n---\n\n# Bubbles Configuration Single Source of Truth (SST)\n\n## Goal\n\nEnsure every configuration value has exactly ONE canonical location (the SST file) and all other consumers either reference SST-generated artifacts or are produced by the config generation pipeline. Zero hardcoded values, zero manual edits to generated files, zero silent defaults.\n\n## Use This Skill When\n\n- Adding a new service, port, endpoint, or config value\n- Modifying Docker Compose files or port mappings\n- Reviewing or editing `.env` files\n- Finding hardcoded ports, URLs, or credentials in source code\n- Changing the config generation pipeline\n- Adding environment variables to services\n- Auditing config consistency across environments\n- Setting up a new project with Bubbles\n- Reviewing PRs that touch config-adjacent files\n\n## SST Lifecycle\n\n### Phase 1: Define in SST\n\nEvery config value enters the system through the SST config file.\n\n```\nconfig\u002F\u003Cproject>.yaml    ← Human edits happen HERE and ONLY here\n```\n\nThe SST file is organized by concern:\n\n| Section | Contains |\n|---------|----------|\n| `project` | Name, namespace, version |\n| `ports` | Host and internal port mappings per service |\n| `services` | Service-specific config (resources, env, deps) |\n| `infrastructure` | Database, message bus, cache, observability |\n| `auth` | JWT, encryption, session config |\n| `environments` | Environment-specific overrides (dev, test, staging, prod) |\n\n### Phase 2: Generate Derived Files\n\nThe config generator reads the SST and writes all derived files.\n\n```bash\n.\u002F\u003Cproject>.sh config generate    # or: config compile\n```\n\nGenerated files MUST:\n- Contain a header comment marking them as auto-generated\n- Be listed in the project's \"DO NOT EDIT\" manifest (copilot-instructions.md)\n- Be reproducible (same SST input → same generated output)\n\n### Phase 3: Consume at Runtime\n\nRuntime code reads values from generated artifacts (env vars, config JSON), never from the SST file directly.\n\n```\nBackend  → reads env vars from .env or compiled JSON\nFrontend → reads build-time env vars from .env\nDocker   → reads Compose file + .env\nTests    → reads test-specific env from generated test config\n```\n\n## Config Bundle Artifact (Build-Once Deploy-Many)\n\nIn a build-once-deploy-many pipeline, the SST generator MUST also emit a **config bundle artifact** for each target environment. The bundle is the immutable, hash-identified package that pairs with an immutable application image at deploy time.\n\n### Bundle Generator Surface\n\n```\n.\u002F\u003Cproject>.sh config generate --env \u003Cenv> --bundle [--output-dir \u003Cdir>]\n```\n\n- `--bundle` flag instructs the generator to emit a tar.gz alongside loose env files\n- `--output-dir` defaults to `dist\u002Fconfig-bundles\u002F`\n- Output filename: `config-bundle-\u003Cenv>-\u003CsourceSha>.tar.gz`\n- Bundle MUST contain ALL generated config artifacts for that environment (`.env` files, generated YAML\u002FJSON configs, runtime Compose overlays)\n- Bundle MUST be deterministic: same SST + same env + same sourceSha → byte-identical bundle (sort entries, fix mtimes, fix uid\u002Fgid)\n\n### Bundle Hash Naming\n\n```\nbundle name:  config-bundle-\u003Cenv>-\u003CsourceSha>.tar.gz\nbundle hash:  \u003Cenv>-\u003CsourceSha>          # short identifier consumed by `apply`\nsha256 hash:  \u003Cfull sha256 digest>       # used for adapter-side verification\n```\n\nThe `\u003Cenv>-\u003CsourceSha>` identifier MUST appear in:\n- The build manifest CI publishes (`build-manifest-\u003CsourceSha>.yaml`)\n- The deployment manifest the adapter writes (`deploy\u002F\u003Ctarget>\u002Fmanifest.yaml`)\n- The CI workflow output (visible to operators)\n\n### CI Pipeline Step\n\n```yaml\n# Excerpt from .github\u002Fworkflows\u002Fbuild.yml\n- name: Generate config bundles for all environments\n  run: |\n    for env in dev staging prod; do\n      .\u002F\u003Cproject>.sh config generate --env \"$env\" --bundle\n    done\n\n- name: Verify bundle determinism\n  run: |\n    for env in dev staging prod; do\n      .\u002F\u003Cproject>.sh config generate --env \"$env\" --bundle --output-dir \u002Ftmp\u002Fverify\n      diff \u003C(sha256sum dist\u002Fconfig-bundles\u002Fconfig-bundle-$env-$GITHUB_SHA.tar.gz) \\\n           \u003C(sha256sum \u002Ftmp\u002Fverify\u002Fconfig-bundle-$env-$GITHUB_SHA.tar.gz)\n    done\n\n- name: Publish bundles to artifact registry\n  run: |\n    for env in dev staging prod; do\n      \u003Cpublish-tool> push dist\u002Fconfig-bundles\u002Fconfig-bundle-$env-$GITHUB_SHA.tar.gz\n    done\n```\n\n### Adapter-Side Consumption\n\nThe deployment adapter `apply.sh` MUST:\n1. Pull the bundle by hash from the artifact registry\n2. Verify the sha256 matches the build manifest entry\n3. Extract bundle to a target-local mount path (e.g. `\u002Fvar\u002Flib\u002F\u003Cproject>\u002F\u003Ctarget>\u002Fconfig\u002F\u003Cbundle-hash>\u002F`)\n4. Reference the extracted path from the runtime Compose file (read-only mount)\n5. Record the bundle hash in `deploy\u002F\u003Ctarget>\u002Fmanifest.yaml`\n\n### Bundle Drift Rules\n\n| Scenario | Required Behavior |\n|----------|-------------------|\n| Same `\u003CsourceSha>` rebuilt twice | Bundle hash MUST match (determinism) |\n| `\u003CsourceSha>` changes but no SST change | Bundle hash changes (sourceSha is part of identity) |\n| SST changes without `\u003CsourceSha>` change | Impossible by construction; sourceSha is git SHA at build |\n| Operator hand-edits a bundle on the target | Detected by hash mismatch on next `apply` or `verify`; treated as drift |\n\n### Anti-Patterns (Bundle-Specific)\n\n| Anti-Pattern | Fix |\n|--------------|-----|\n| Bundle generated on the deploy target | Bundle is a CI artifact; adapter consumes it as-is |\n| Bundle includes secrets in plaintext | Secrets are referenced (env var names, secret manager refs); never embedded |\n| Bundle is non-deterministic (timestamps, random ordering) | Sort entries; pin mtimes; pin uid\u002Fgid |\n| Bundle depends on host-side SST file | Bundle is self-contained; no runtime SST lookup on target |\n| Adapter regenerates bundle on rollback | Rollback re-points to the prior bundle hash; never regenerates |\n\n## Classification Rules\n\n### SST-Managed (MUST be in SST file)\n\n| Value Type | Examples |\n|------------|----------|\n| Ports | Host ports, internal ports, mapped ports |\n| URLs | Database URLs, service endpoints, external APIs |\n| Credentials | DB passwords, JWT secrets, API keys (or secret refs) |\n| Timeouts | Server timeouts, connection timeouts, rate limits |\n| Resource limits | Memory, CPU, pool sizes |\n| Feature flags | Enable\u002Fdisable toggles |\n| Service identity | Container names, image names, network names, volume names |\n\n### NOT SST-Managed (OK to define elsewhere)\n\n| Value Type | Where |\n|------------|-------|\n| Build-time constants | Source code constants module |\n| Compile-time feature flags | Build system (Cargo features, webpack defines) |\n| UI design tokens | Design token files (CSS vars, Tailwind config) |\n| Test fixture data | Test files |\n| Algorithm parameters | Domain config files (if not deployment-sensitive) |\n\n## Verification Checklist\n\nWhen reviewing config changes, verify ALL of these:\n\n```\n[ ] New value defined in SST file (config\u002F\u003Cproject>.yaml)\n[ ] Config generator updated to parse and emit the new value\n[ ] Generated files regenerated and committed (if checked in)\n[ ] Source code reads from env var or config JSON, not hardcoded\n[ ] No fallback\u002Fdefault pattern for the new value in source code\n[ ] copilot-instructions.md updated if new generated file added\n[ ] Port allocation follows project's assigned block (10k Rule)\n[ ] Dual-URL standard followed (internal DNS vs external 127.0.0.1)\n[ ] Secrets separated from non-secret config (not committed to git)\n```\n\n## Anti-Patterns (BLOCKING)\n\n| Anti-Pattern | Why It's Wrong | Fix |\n|--------------|---------------|-----|\n| Editing a generated `.env` file | Will be overwritten on next generate | Edit SST file, regenerate |\n| Hardcoded port `50001` in Go source | Bypasses SST pipeline | Read from `os.Getenv(\"PORT\")` |\n| `DB_HOST.unwrap_or(\"localhost\")` | Silent default masks missing config | `DB_HOST?` with error propagation |\n| Different port in YAML vs Compose | Config drift between SST and consumer | Regenerate, verify diff is clean |\n| Adding env var to Dockerfile but not SST | Value exists outside SST control | Add to SST YAML first |\n| Service URL hardcoded in frontend | Bypasses config pipeline | Use build-time env injection |\n| Config value in two YAML files | Dual source of truth | Single SST with generation |\n\n## Config Drift Detection\n\nRun these checks to detect SST drift:\n\n```bash\n# 1. Regenerate all config from SST\n.\u002F\u003Cproject>.sh config generate\n\n# 2. Check for uncommitted changes to generated files\ngit diff --name-only config\u002Fgenerated\u002F *.env docker-compose.yml\n\n# 3. Scan for hardcoded port literals in source\ngrep -rn '\u003Cport>' src\u002F backend\u002F frontend\u002F services\u002F \\\n    --include='*.ts' --include='*.go' --include='*.rs' --include='*.py' \\\n    | grep -v '.env' | grep -v 'test' | grep -v 'node_modules'\n\n# 4. Scan for default\u002Ffallback patterns\ngrep -rn ':-\\|unwrap_or\\|getOrElse\\||| .\\|?? .' src\u002F backend\u002F frontend\u002F services\u002F \\\n    --include='*.sh' --include='*.rs' --include='*.go' --include='*.ts' --include='*.py'\n\n# 5. Verify all SST-managed ports appear in generated files\n# (project-specific: compare SST ports section to generated .env)\n```\n\n## Secrets Handling\n\nSecrets follow the SST principle but with an additional security layer:\n\n| Approach | When to Use |\n|----------|-------------|\n| Separate `secrets.yaml` (gitignored) | Dev-only, no secret manager |\n| Secret manager refs in SST | Production (Infisical, Vault, AWS SSM) |\n| `.env.secrets` bootstrap | Local dev with secret manager backup |\n\n**Rules:**\n- Secrets MUST NOT be committed to git (even in dev)\n- SST file MAY contain secret placeholders\u002Frefs but not actual values\n- Config generator resolves secret refs at generation time\n- Generated files with resolved secrets MUST be gitignored\n\n## Environment Overlay Pattern\n\nFor multi-environment deployments:\n\n```\nconfig\u002F\n├── \u003Cproject>.yaml              ← Base SST (shared values)\n├── environments\u002F\n│   ├── dev.yaml                ← Dev overrides\n│   ├── staging.yaml            ← Staging overrides\n│   └── prod.yaml               ← Production overrides\n└── secrets.yaml                ← Gitignored secrets\n```\n\nThe config compiler merges: `base + environment overlay + secrets → generated config`.\n\nAlternatively, for simpler projects, embed `environments:` section inline in the SST file with per-environment port blocks and compose project names.\n\n## Integration with Bubbles Governance\n\n| Bubbles Gate | SST Relevance |\n|--------------|--------------|\n| Implementation Reality Scan (G028) | Detects hardcoded values that should come from SST |\n| Integration Completeness (G029) | New services must be wired into SST pipeline |\n| Docker Bundle Freshness (Gate 9\u002F10) | Config must be regenerated before freshness check |\n| Pre-Completion Self-Audit | `config generate` + `git diff` is a required step |\n| Vertical Slice (G035) | Config values must flow end-to-end (SST → backend → frontend) |\n\n## References\n\n- `.github\u002Finstructions\u002Fbubbles-config-sst.instructions.md`\n- `.github\u002Fagents\u002Fbubbles_shared\u002Fproject-config-contract.md`\n- `.github\u002Fskills\u002Fbubbles-docker-port-standards\u002FSKILL.md`\n- `.github\u002Finstructions\u002Fbubbles-docker-lifecycle-governance.instructions.md`\n","# Bubbles Configuration Single Source of Truth (SST)\n\n## Goal\n\nEnsure every configuration value has exactly ONE canonical location (the SST file) and all other consumers either reference SST-generated artifacts or are produced by the config generation pipeline. Zero hardcoded values, zero manual edits to generated files, zero silent defaults.\n\n## Use This Skill When\n\n- Adding a new service, port, endpoint, or config value\n- Modifying Docker Compose files or port mappings\n- Reviewing or editing `.env` files\n- Finding hardcoded ports, URLs, or credentials in source code\n- Changing the config generation pipeline\n- Adding environment variables to services\n- Auditing config consistency across environments\n- Setting up a new project with Bubbles\n- Reviewing PRs that touch config-adjacent files\n\n## SST Lifecycle\n\n### Phase 1: Define in SST\n\nEvery config value enters the system through the SST config file.\n\n```\nconfig\u002F\u003Cproject>.yaml    ← Human edits happen HERE and ONLY here\n```\n\nThe SST file is organized by concern:\n\n| Section | Contains |\n|---------|----------|\n| `project` | Name, namespace, version |\n| `ports` | Host and internal port mappings per service |\n| `services` | Service-specific config (resources, env, deps) |\n| `infrastructure` | Database, message bus, cache, observability |\n| `auth` | JWT, encryption, session config |\n| `environments` | Environment-specific overrides (dev, test, staging, prod) |\n\n### Phase 2: Generate Derived Files\n\nThe config generator reads the SST and writes all derived files.\n\n```bash\n.\u002F\u003Cproject>.sh config generate    # or: config compile\n```\n\nGenerated files MUST:\n- Contain a header comment marking them as auto-generated\n- Be listed in the project's \"DO NOT EDIT\" manifest (copilot-instructions.md)\n- Be reproducible (same SST input → same generated output)\n\n### Phase 3: Consume at Runtime\n\nRuntime code reads values from generated artifacts (env vars, config JSON), never from the SST file directly.\n\n```\nBackend  → reads env vars from .env or compiled JSON\nFrontend → reads build-time env vars from .env\nDocker   → reads Compose file + .env\nTests    → reads test-specific env from generated test config\n```\n\n## Config Bundle Artifact (Build-Once Deploy-Many)\n\nIn a build-once-deploy-many pipeline, the SST generator MUST also emit a **config bundle artifact** for each target environment. The bundle is the immutable, hash-identified package that pairs with an immutable application image at deploy time.\n\n### Bundle Generator Surface\n\n```\n.\u002F\u003Cproject>.sh config generate --env \u003Cenv> --bundle [--output-dir \u003Cdir>]\n```\n\n- `--bundle` flag instructs the generator to emit a tar.gz alongside loose env files\n- `--output-dir` defaults to `dist\u002Fconfig-bundles\u002F`\n- Output filename: `config-bundle-\u003Cenv>-\u003CsourceSha>.tar.gz`\n- Bundle MUST contain ALL generated config artifacts for that environment (`.env` files, generated YAML\u002FJSON configs, runtime Compose overlays)\n- Bundle MUST be deterministic: same SST + same env + same sourceSha → byte-identical bundle (sort entries, fix mtimes, fix uid\u002Fgid)\n\n### Bundle Hash Naming\n\n```\nbundle name:  config-bundle-\u003Cenv>-\u003CsourceSha>.tar.gz\nbundle hash:  \u003Cenv>-\u003CsourceSha>          # short identifier consumed by `apply`\nsha256 hash:  \u003Cfull sha256 digest>       # used for adapter-side verification\n```\n\nThe `\u003Cenv>-\u003CsourceSha>` identifier MUST appear in:\n- The build manifest CI publishes (`build-manifest-\u003CsourceSha>.yaml`)\n- The deployment manifest the adapter writes (`deploy\u002F\u003Ctarget>\u002Fmanifest.yaml`)\n- The CI workflow output (visible to operators)\n\n### CI Pipeline Step\n\n```yaml\n# Excerpt from .github\u002Fworkflows\u002Fbuild.yml\n- name: Generate config bundles for all environments\n  run: |\n    for env in dev staging prod; do\n      .\u002F\u003Cproject>.sh config generate --env \"$env\" --bundle\n    done\n\n- name: Verify bundle determinism\n  run: |\n    for env in dev staging prod; do\n      .\u002F\u003Cproject>.sh config generate --env \"$env\" --bundle --output-dir \u002Ftmp\u002Fverify\n      diff \u003C(sha256sum dist\u002Fconfig-bundles\u002Fconfig-bundle-$env-$GITHUB_SHA.tar.gz) \\\n           \u003C(sha256sum \u002Ftmp\u002Fverify\u002Fconfig-bundle-$env-$GITHUB_SHA.tar.gz)\n    done\n\n- name: Publish bundles to artifact registry\n  run: |\n    for env in dev staging prod; do\n      \u003Cpublish-tool> push dist\u002Fconfig-bundles\u002Fconfig-bundle-$env-$GITHUB_SHA.tar.gz\n    done\n```\n\n### Adapter-Side Consumption\n\nThe deployment adapter `apply.sh` MUST:\n1. Pull the bundle by hash from the artifact registry\n2. Verify the sha256 matches the build manifest entry\n3. Extract bundle to a target-local mount path (e.g. `\u002Fvar\u002Flib\u002F\u003Cproject>\u002F\u003Ctarget>\u002Fconfig\u002F\u003Cbundle-hash>\u002F`)\n4. Reference the extracted path from the runtime Compose file (read-only mount)\n5. Record the bundle hash in `deploy\u002F\u003Ctarget>\u002Fmanifest.yaml`\n\n### Bundle Drift Rules\n\n| Scenario | Required Behavior |\n|----------|-------------------|\n| Same `\u003CsourceSha>` rebuilt twice | Bundle hash MUST match (determinism) |\n| `\u003CsourceSha>` changes but no SST change | Bundle hash changes (sourceSha is part of identity) |\n| SST changes without `\u003CsourceSha>` change | Impossible by construction; sourceSha is git SHA at build |\n| Operator hand-edits a bundle on the target | Detected by hash mismatch on next `apply` or `verify`; treated as drift |\n\n### Anti-Patterns (Bundle-Specific)\n\n| Anti-Pattern | Fix |\n|--------------|-----|\n| Bundle generated on the deploy target | Bundle is a CI artifact; adapter consumes it as-is |\n| Bundle includes secrets in plaintext | Secrets are referenced (env var names, secret manager refs); never embedded |\n| Bundle is non-deterministic (timestamps, random ordering) | Sort entries; pin mtimes; pin uid\u002Fgid |\n| Bundle depends on host-side SST file | Bundle is self-contained; no runtime SST lookup on target |\n| Adapter regenerates bundle on rollback | Rollback re-points to the prior bundle hash; never regenerates |\n\n## Classification Rules\n\n### SST-Managed (MUST be in SST file)\n\n| Value Type | Examples |\n|------------|----------|\n| Ports | Host ports, internal ports, mapped ports |\n| URLs | Database URLs, service endpoints, external APIs |\n| Credentials | DB passwords, JWT secrets, API keys (or secret refs) |\n| Timeouts | Server timeouts, connection timeouts, rate limits |\n| Resource limits | Memory, CPU, pool sizes |\n| Feature flags | Enable\u002Fdisable toggles |\n| Service identity | Container names, image names, network names, volume names |\n\n### NOT SST-Managed (OK to define elsewhere)\n\n| Value Type | Where |\n|------------|-------|\n| Build-time constants | Source code constants module |\n| Compile-time feature flags | Build system (Cargo features, webpack defines) |\n| UI design tokens | Design token files (CSS vars, Tailwind config) |\n| Test fixture data | Test files |\n| Algorithm parameters | Domain config files (if not deployment-sensitive) |\n\n## Verification Checklist\n\nWhen reviewing config changes, verify ALL of these:\n\n```\n[ ] New value defined in SST file (config\u002F\u003Cproject>.yaml)\n[ ] Config generator updated to parse and emit the new value\n[ ] Generated files regenerated and committed (if checked in)\n[ ] Source code reads from env var or config JSON, not hardcoded\n[ ] No fallback\u002Fdefault pattern for the new value in source code\n[ ] copilot-instructions.md updated if new generated file added\n[ ] Port allocation follows project's assigned block (10k Rule)\n[ ] Dual-URL standard followed (internal DNS vs external 127.0.0.1)\n[ ] Secrets separated from non-secret config (not committed to git)\n```\n\n## Anti-Patterns (BLOCKING)\n\n| Anti-Pattern | Why It's Wrong | Fix |\n|--------------|---------------|-----|\n| Editing a generated `.env` file | Will be overwritten on next generate | Edit SST file, regenerate |\n| Hardcoded port `50001` in Go source | Bypasses SST pipeline | Read from `os.Getenv(\"PORT\")` |\n| `DB_HOST.unwrap_or(\"localhost\")` | Silent default masks missing config | `DB_HOST?` with error propagation |\n| Different port in YAML vs Compose | Config drift between SST and consumer | Regenerate, verify diff is clean |\n| Adding env var to Dockerfile but not SST | Value exists outside SST control | Add to SST YAML first |\n| Service URL hardcoded in frontend | Bypasses config pipeline | Use build-time env injection |\n| Config value in two YAML files | Dual source of truth | Single SST with generation |\n\n## Config Drift Detection\n\nRun these checks to detect SST drift:\n\n```bash\n# 1. Regenerate all config from SST\n.\u002F\u003Cproject>.sh config generate\n\n# 2. Check for uncommitted changes to generated files\ngit diff --name-only config\u002Fgenerated\u002F *.env docker-compose.yml\n\n# 3. Scan for hardcoded port literals in source\ngrep -rn '\u003Cport>' src\u002F backend\u002F frontend\u002F services\u002F \\\n    --include='*.ts' --include='*.go' --include='*.rs' --include='*.py' \\\n    | grep -v '.env' | grep -v 'test' | grep -v 'node_modules'\n\n# 4. Scan for default\u002Ffallback patterns\ngrep -rn ':-\\|unwrap_or\\|getOrElse\\||| .\\|?? .' src\u002F backend\u002F frontend\u002F services\u002F \\\n    --include='*.sh' --include='*.rs' --include='*.go' --include='*.ts' --include='*.py'\n\n# 5. Verify all SST-managed ports appear in generated files\n# (project-specific: compare SST ports section to generated .env)\n```\n\n## Secrets Handling\n\nSecrets follow the SST principle but with an additional security layer:\n\n| Approach | When to Use |\n|----------|-------------|\n| Separate `secrets.yaml` (gitignored) | Dev-only, no secret manager |\n| Secret manager refs in SST | Production (Infisical, Vault, AWS SSM) |\n| `.env.secrets` bootstrap | Local dev with secret manager backup |\n\n**Rules:**\n- Secrets MUST NOT be committed to git (even in dev)\n- SST file MAY contain secret placeholders\u002Frefs but not actual values\n- Config generator resolves secret refs at generation time\n- Generated files with resolved secrets MUST be gitignored\n\n## Environment Overlay Pattern\n\nFor multi-environment deployments:\n\n```\nconfig\u002F\n├── \u003Cproject>.yaml              ← Base SST (shared values)\n├── environments\u002F\n│   ├── dev.yaml                ← Dev overrides\n│   ├── staging.yaml            ← Staging overrides\n│   └── prod.yaml               ← Production overrides\n└── secrets.yaml                ← Gitignored secrets\n```\n\nThe config compiler merges: `base + environment overlay + secrets → generated config`.\n\nAlternatively, for simpler projects, embed `environments:` section inline in the SST file with per-environment port blocks and compose project names.\n\n## Integration with Bubbles Governance\n\n| Bubbles Gate | SST Relevance |\n|--------------|--------------|\n| Implementation Reality Scan (G028) | Detects hardcoded values that should come from SST |\n| Integration Completeness (G029) | New services must be wired into SST pipeline |\n| Docker Bundle Freshness (Gate 9\u002F10) | Config must be regenerated before freshness check |\n| Pre-Completion Self-Audit | `config generate` + `git diff` is a required step |\n| Vertical Slice (G035) | Config values must flow end-to-end (SST → backend → frontend) |\n\n## References\n\n- `.github\u002Finstructions\u002Fbubbles-config-sst.instructions.md`\n- `.github\u002Fagents\u002Fbubbles_shared\u002Fproject-config-contract.md`\n- `.github\u002Fskills\u002Fbubbles-docker-port-standards\u002FSKILL.md`\n- `.github\u002Finstructions\u002Fbubbles-docker-lifecycle-governance.instructions.md`\n",{"name":5,"description":7},"main","ed893cc338281a0bb9bb9ecf3415716cb242bb3f",".github\u002Fskills\u002Fbubbles-config-sst",0,"https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel","https:\u002F\u002Fgithub.com\u002Fpkirsanov","2026-11-07 02:54:37",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":67},[57,60,63],{"tool":58,"command":59},"npx","npx skills add pkirsanov\u002Fsmackerel --skill bubbles-config-sst",{"tool":61,"command":62},"bunx","bunx skills add pkirsanov\u002Fsmackerel --skill bubbles-config-sst",{"tool":64,"command":65},"pnpm","pnpm dlx skills add pkirsanov\u002Fsmackerel --skill bubbles-config-sst","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbubbles-config-sst\u002FSKILL.md",true,[],[70,99,117,145,166,194],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":79,"publishedAt":43},"01M6N9V5TBHQT20V5SCCJ1VRBC","smackerel-trace-capture","Wire Smackerel's concrete validate-plane stack into the framework trace-driven defect-discovery method. Use when running live-category tests (integration\u002Fe2e\u002Fe2e-ui\u002Fstress) against the ephemeral test stack; capturing SLO or trace evidence; hunting latency\u002Ferror\u002Fperf bugs from spans; querying the test-stack Jaeger or Prometheus; or touching `.specify\u002Fruntime\u002Fobservability`. Concrete smackerel endpoints + the exact `capture-slo.sh` command; do NOT duplicate `bubbles-observability-adapter` — this only adds the wiring.","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fsmackerel-trace-capture\u002FSKILL.md",[76],{"categoryNo":77,"categoryName":78,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量",[80,81,82,83,84,85,86,87,88,38,89,90,91,92,93,94,95,96,97,98],"trace","capture","smackerel trace capture","perf","observability","prometheus","specify","e2e","discovery","slo","only","evidence","do","latency","runtime","tests","adapter","error","bugs",{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":106,"publishedAt":43},"01M6N9TZDEV26RZ7W34HEFPQE9","smackerel-no-defaults","Enforce Smackerel's NO-DEFAULTS \u002F fail-loud SST policy. Use when editing config, Docker Compose, deploy adapters, docs, instructions, skills, env handling, host bind addresses, or any runtime value that could be hidden by fallback syntax.","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fsmackerel-no-defaults\u002FSKILL.md",[105],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[107,27,108,23,109,30,110,40,111,38,37,34,94,112,32,113,114,25,115,116],"smackerel no defaults","policy","deploy","syntax","instructions","bind","host","Adapters","addresses","value",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":126,"publishedAt":43},"01M6N9TJRS5PF83JH2W4614D4W","bubbles-workflow-mode-resolution","Resolve a Bubbles workflow mode against `bubbles\u002Fworkflows.yaml`, including template inheritance, status ceilings, gate wiring, and decision policy. Use when picking a mode for a request, when a guard reports a mode-related failure, or when extending workflows.yaml with a new mode or template. Covers natural-language intent routing and the workflow registry consistency rules.","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbubbles-workflow-mode-resolution\u002FSKILL.md",[123],{"categoryNo":124,"categoryName":125,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[127,128,129,130,108,131,132,133,134,135,136,38,137,138,139,140,141,142,143,144],"workflow","resolution","mode","bubbles workflow mode resolution","workflows","routing","guard","template","decision","Rules","reports","intent","inheritance","with","consistency","natural-language","for","wiring",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":152,"publishedAt":43},"01M6N9TC98D6DJR0D64SSN0SN3","bubbles-workflow-execution-loops","Run per-round synchronous workflow execution loops correctly. Use when orchestrating a multi-round workflow, dispatching specialist subagents, handling round-based remediation, or interpreting a workflow mode's execution policy. Covers authorized direct execution, dispatch-and-wait, batch-then-summarize prohibition, and mapped-mode execution.","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbubbles-workflow-execution-loops\u002FSKILL.md",[151],{"categoryNo":124,"categoryName":125,"taxonomyType":20,"taxonomyTypeDesc":21},[127,153,154,155,156,108,157,158,159,160,161,38,162,163,164,165,129],"execution","loops","bubbles workflow execution loops","summarize","run","batch","remediation","direct","subagents","dispatch","wait","multi","multi-round",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":176,"publishedAt":43},"01M6N9SYXQNJDQ1T1YT81JH2BG","bubbles-vscode-agent-constraints","Design agents that fit the VS Code Copilot Chat runtime instead of fighting it. Use when authoring or editing any `*.agent.md`; when adding `tools:`, `agents:`, `handoffs:`, `model:`, `user-invocable:`, or `disable-model-invocation:` frontmatter; when designing an orchestrator that dispatches specialists; when a design implies agent-calls-agent-calls-agent chaining; when a subagent dispatch silently no-ops or an agent cannot be selected in the dropdown; or when writing a governance rule about delegation that the runtime cannot actually enforce. Prevents multi-level-subagent designs, prose-only dispatch laws, and frontmatter\u002Fbody contradictions.","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbubbles-vscode-agent-constraints\u002FSKILL.md",[172,175],{"categoryNo":173,"categoryName":174,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":124,"categoryName":125,"taxonomyType":20,"taxonomyTypeDesc":21},[177,178,179,180,181,182,183,184,185,186,187,188,40,189,90,94,190,191,192,193],"vscode","constraints","bubbles vscode agent constraints","design","writing","copilot","code","delegation","Tools","subagent","model","chaining","orchestrator","authoring","fit","subagent dispatch","frontmatter",{"skillNo":195,"name":196,"nameZh":6,"description":197,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":198,"categories":199,"keywords":200,"publishedAt":43},"01M6N9SD78SK12PRT9KBRZ6TB3","bubbles-upkeep-cadence","How to schedule, dispatch, and record recurring operational upkeep tasks (backup, restore-drill, BCDR-drill, patch-cycle, secret-rotation, flag-cleanup, compliance-sweep). Use when authoring or modifying `config\u002Fupkeep-calendar.yaml`, when investigating a missed task, when reading the upkeep ledger, or when adding a new task type.","https:\u002F\u002Fgithub.com\u002Fpkirsanov\u002Fsmackerel\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fbubbles-upkeep-cadence\u002FSKILL.md",[],[201,202,203,204,205,206,207,208,38,209,210,211,212,213,214,215,216,217,218,219],"cadence","bubbles upkeep cadence","tasks","cleanup","backup","sweep","schedule","recurring","patch","restore","task","cycle","record","missed","type","drill","how to","new task","rotation"]