@thebassclef/lite 0.0.1 → 0.1.2
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 +202 -0
- package/README.md +85 -4
- package/dist/cli.cjs +1612 -0
- package/dist/cli.js +1589 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/package.json +51 -3
- package/substrate/.bassclef/lite-manifest.json +2701 -0
- package/substrate/.claude/agents/architect.md +70 -0
- package/substrate/.claude/agents/builder.md +114 -0
- package/substrate/.claude/agents/designer.md +156 -0
- package/substrate/.claude/agents/reviewer.md +88 -0
- package/substrate/.claude/hooks/artifact-ingestion-gate.sh +357 -0
- package/substrate/.claude/hooks/assert-verify-steering.sh +77 -0
- package/substrate/.claude/hooks/bassclef-source-config-validate.sh +215 -0
- package/substrate/.claude/hooks/bassclef-sync.sh +634 -0
- package/substrate/.claude/hooks/compound-noun-scrub.sh +292 -0
- package/substrate/.claude/hooks/kiss-expansion-inject.sh +69 -0
- package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +492 -0
- package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +492 -0
- package/substrate/.claude/hooks/plain-english-steering.sh +156 -0
- package/substrate/.claude/hooks/post-skill-friction-check.sh +177 -0
- package/substrate/.claude/hooks/post-skill-telemetry.sh +62 -0
- package/substrate/.claude/hooks/pre-build-gate.sh +511 -0
- package/substrate/.claude/hooks/pre-commit-gate.sh +451 -0
- package/substrate/.claude/hooks/session-end.sh +433 -0
- package/substrate/.claude/hooks/session-reflection.sh +303 -0
- package/substrate/.claude/hooks/skill-body-grade-gate.sh +219 -0
- package/substrate/.claude/hooks/skill-body-intent-drift.sh +107 -0
- package/substrate/.claude/hooks/skill-step-list-check.sh +171 -0
- package/substrate/.claude/hooks/state-validate.sh +271 -0
- package/substrate/.claude/hooks/substrate-clarity-gate.sh +1110 -0
- package/substrate/.claude/hooks/temperance-gate.sh +147 -0
- package/substrate/.claude/hooks/testing-tier-enforce.sh +233 -0
- package/substrate/.claude/hooks/turn-prose-grade-measure.sh +219 -0
- package/substrate/.claude/hooks/turn-prose-kiss-check.sh +463 -0
- package/substrate/.claude/hooks/vocabulary-migration-check.sh +171 -0
- package/substrate/.claude/hooks/whereami-utc-gate.sh +142 -0
- package/substrate/.claude/luminaries/alan-cooper.md +170 -0
- package/substrate/.claude/luminaries/alistair-cockburn.md +140 -0
- package/substrate/.claude/luminaries/amazon-pr-faq.md +34 -0
- package/substrate/.claude/luminaries/ash-maurya.md +121 -0
- package/substrate/.claude/luminaries/bill-buxton.md +210 -0
- package/substrate/.claude/luminaries/charles-sanders-peirce.md +150 -0
- package/substrate/.claude/luminaries/david-ogilvy.md +192 -0
- package/substrate/.claude/luminaries/don-norman.md +173 -0
- package/substrate/.claude/luminaries/edward-tufte.md +179 -0
- package/substrate/.claude/luminaries/eric-evans.md +160 -0
- package/substrate/.claude/luminaries/frederick-brooks.md +50 -0
- package/substrate/.claude/luminaries/gang-of-four.md +157 -0
- package/substrate/.claude/luminaries/glenford-myers.md +230 -0
- package/substrate/.claude/luminaries/hunt-thomas.md +115 -0
- package/substrate/.claude/luminaries/hyrum-wright.md +94 -0
- package/substrate/.claude/luminaries/jason-fried-dhh.md +46 -0
- package/substrate/.claude/luminaries/jesse-james-garrett.md +154 -0
- package/substrate/.claude/luminaries/john-ousterhout.md +94 -0
- package/substrate/.claude/luminaries/karl-popper.md +132 -0
- package/substrate/.claude/luminaries/kent-beck.md +168 -0
- package/substrate/.claude/luminaries/linus-torvalds.md +218 -0
- package/substrate/.claude/luminaries/martin-fowler.md +164 -0
- package/substrate/.claude/luminaries/michael-feathers.md +125 -0
- package/substrate/.claude/luminaries/michael-nygard.md +118 -0
- package/substrate/.claude/luminaries/robert-c-martin.md +164 -0
- package/substrate/.claude/luminaries/saltzer-schroeder.md +194 -0
- package/substrate/.claude/luminaries/sophia-prater.md +193 -0
- package/substrate/.claude/luminaries/stephen-toulmin.md +131 -0
- package/substrate/.claude/luminaries/tony-hoare.md +170 -0
- package/substrate/.claude/luminaries/vaughn-vernon.md +50 -0
- package/substrate/.claude/luminaries/w-edwards-deming.md +158 -0
- package/substrate/.claude/rules/accessor-library-discipline.md +138 -0
- package/substrate/.claude/rules/adr-discipline.md +120 -0
- package/substrate/.claude/rules/api-conventions.md +125 -0
- package/substrate/.claude/rules/artifact-ingestion.md +179 -0
- package/substrate/.claude/rules/assert-only-after-verify.md +137 -0
- package/substrate/.claude/rules/blocked-items.md +146 -0
- package/substrate/.claude/rules/bootstrap-pair-discipline.md +141 -0
- package/substrate/.claude/rules/branching.md +28 -0
- package/substrate/.claude/rules/cold-adopter-harness-discipline.md +129 -0
- package/substrate/.claude/rules/commit-conventions.md +22 -0
- package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +188 -0
- package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +188 -0
- package/substrate/.claude/rules/context-engineering.md +202 -0
- package/substrate/.claude/rules/context-management.md +85 -0
- package/substrate/.claude/rules/defensive-bash.md +68 -0
- package/substrate/.claude/rules/deferred-actions.md +233 -0
- package/substrate/.claude/rules/destructive-operations.md +69 -0
- package/substrate/.claude/rules/diagnosis.md +38 -0
- package/substrate/.claude/rules/github-issue-flash-tweet.md +156 -0
- package/substrate/.claude/rules/guardrails.md +73 -0
- package/substrate/.claude/rules/hook-wire-on-author.md +103 -0
- package/substrate/.claude/rules/identifier-leak-prevention.md +104 -0
- package/substrate/.claude/rules/iteration-bet-brief-completeness.md +54 -0
- package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +98 -0
- package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +89 -0
- package/substrate/.claude/rules/loop-discipline.md +81 -0
- package/substrate/.claude/rules/manual-prod-approval.md +100 -0
- package/substrate/.claude/rules/marker-enrichment-discipline.md +99 -0
- package/substrate/.claude/rules/mobile-ephemeral-session.md +109 -0
- package/substrate/.claude/rules/new-dependency-check.md +51 -0
- package/substrate/.claude/rules/oo-ad-entry-point.md +117 -0
- package/substrate/.claude/rules/operator-facing-prose.md +196 -0
- package/substrate/.claude/rules/option-label-discipline.md +108 -0
- package/substrate/.claude/rules/pattern-annotation.md +100 -0
- package/substrate/.claude/rules/plain-english-discipline.md +156 -0
- package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +211 -0
- package/substrate/.claude/rules/pr-body-shape.md +317 -0
- package/substrate/.claude/rules/pr-strategy.md +167 -0
- package/substrate/.claude/rules/pr-title-shape.md +161 -0
- package/substrate/.claude/rules/prototype-workflow.md +65 -0
- package/substrate/.claude/rules/reserved-skill-names.md +123 -0
- package/substrate/.claude/rules/schema-management.md +49 -0
- package/substrate/.claude/rules/sdlc-gates.md +149 -0
- package/substrate/.claude/rules/security.md +37 -0
- package/substrate/.claude/rules/session-artifacts.md +236 -0
- package/substrate/.claude/rules/skill-composition-declarations.md +124 -0
- package/substrate/.claude/rules/skill-description-clarity.md +247 -0
- package/substrate/.claude/rules/skill-procedure-step-list.md +137 -0
- package/substrate/.claude/rules/state-schema-validation.md +162 -0
- package/substrate/.claude/rules/stuck-signal-diagnostic.md +140 -0
- package/substrate/.claude/rules/substrate-config-schema.md +98 -0
- package/substrate/.claude/rules/test-list-discipline.md +175 -0
- package/substrate/.claude/rules/test-sufficiency.md +210 -0
- package/substrate/.claude/rules/testing-tier-config.md +145 -0
- package/substrate/.claude/rules/testing.md +38 -0
- package/substrate/.claude/rules/turn-estimate-grounding.md +134 -0
- package/substrate/.claude/rules/visual-hierarchy.md +437 -0
- package/substrate/.claude/rules/we-dont-break-adopters.md +126 -0
- package/substrate/.claude/rules/whereami-load-bearing.md +202 -0
- package/substrate/.claude/rules/writing-craft-discipline.md +92 -0
- package/substrate/.claude/rules/wu-sequencing-compounds.md +145 -0
- package/substrate/.claude/skills/build/SKILL.md +640 -0
- package/substrate/.claude/skills/chronicle/SKILL.md +55 -0
- package/substrate/.claude/skills/clean-artifacts/SKILL.md +249 -0
- package/substrate/.claude/skills/decompose/SKILL.md +280 -0
- package/substrate/.claude/skills/diagnose/SKILL.md +297 -0
- package/substrate/.claude/skills/feynman/SKILL.md +90 -0
- package/substrate/.claude/skills/howdoi/SKILL.md +105 -0
- package/substrate/.claude/skills/ia-model/SKILL.md +108 -0
- package/substrate/.claude/skills/interaction-design/SKILL.md +112 -0
- package/substrate/.claude/skills/interpret-input/SKILL.md +180 -0
- package/substrate/.claude/skills/journal/SKILL.md +209 -0
- package/substrate/.claude/skills/kiss/SKILL.md +449 -0
- package/substrate/.claude/skills/launch/SKILL.md +915 -0
- package/substrate/.claude/skills/lean-canvas/SKILL.md +332 -0
- package/substrate/.claude/skills/longrun/SKILL.md +463 -0
- package/substrate/.claude/skills/luminary/SKILL.md +481 -0
- package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +177 -0
- package/substrate/.claude/skills/onboard-repo/SKILL.md +1624 -0
- package/substrate/.claude/skills/pattern-review/SKILL.md +99 -0
- package/substrate/.claude/skills/personas/SKILL.md +207 -0
- package/substrate/.claude/skills/promote/SKILL.md +283 -0
- package/substrate/.claude/skills/requirement/SKILL.md +98 -0
- package/substrate/.claude/skills/retro/SKILL.md +117 -0
- package/substrate/.claude/skills/riff/SKILL.md +114 -0
- package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +163 -0
- package/substrate/.claude/skills/session-end/SKILL.md +309 -0
- package/substrate/.claude/skills/session-log/SKILL.md +299 -0
- package/substrate/.claude/skills/skills/SKILL.md +228 -0
- package/substrate/.claude/skills/spec/SKILL.md +105 -0
- package/substrate/.claude/skills/sprint/SKILL.md +392 -0
- package/substrate/.claude/skills/stage/SKILL.md +384 -0
- package/substrate/.claude/skills/state-a-problem/SKILL.md +185 -0
- package/substrate/.claude/skills/temperance/SKILL.md +108 -0
- package/substrate/.claude/skills/use-case/SKILL.md +417 -0
- package/substrate/.claude/skills/user-stories/SKILL.md +268 -0
- package/substrate/.claude/skills/value-prop/SKILL.md +251 -0
- package/substrate/.claude/skills/verify/SKILL.md +160 -0
- package/substrate/.claude/skills/visual-review/SKILL.md +503 -0
- package/substrate/.claude/skills/whats-the-plan/SKILL.md +202 -0
- package/substrate/.claude/skills/whereami/SKILL.md +307 -0
- package/substrate/AGENTS.md +79 -0
- package/substrate/CLAUDE-lite.md +85 -0
- package/substrate/CODE_OF_CONDUCT.md +28 -0
- package/substrate/CONTRIBUTING.md +177 -0
- package/substrate/README.md +173 -0
- package/substrate/SECURITY.md +19 -0
- package/substrate/architecture/decisions/ADR-029-release-pipeline.md +79 -0
- package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +139 -0
- package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +192 -0
- package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +145 -0
- package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +155 -0
- package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +162 -0
- package/substrate/lib/clean-artifacts-sweep.sh +112 -0
- package/substrate/lib/code-comment-discipline.sh +144 -0
- package/substrate/lib/composer-preflight.sh +459 -0
- package/substrate/lib/hook-inject.sh +255 -0
- package/substrate/lib/luminary-pick.sh +96 -0
- package/substrate/lib/output-discipline.sh +143 -0
- package/substrate/lib/prose-scan-boundary.sh +171 -0
- package/substrate/lib/rewrite-check.sh +214 -0
- package/substrate/lib/state.sh +1372 -0
- package/substrate/lib/telemetry.sh +205 -0
- package/substrate/lib/tier-check.sh +187 -0
- package/substrate/lib/tier-dependency-audit.sh +1088 -0
- package/substrate/presence/install/bassclef-hook-connect.sh +178 -0
- package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +841 -0
- package/substrate/presence/install/bassclef-sync.template.sh +2076 -0
- package/substrate/presence/install/schedule-auto-save.cron.sh +88 -0
- package/substrate/presence/install/schedule-auto-save.taskscheduler.md +122 -0
- package/substrate/scripts/aggregate-telemetry.sh +217 -0
- package/substrate/scripts/analyze-tier-dependencies.sh +239 -0
- package/substrate/scripts/generate-lite-manifest.sh +505 -0
- package/substrate/scripts/generate-tier-manifest.sh +28 -0
- package/substrate/scripts/intent-drift-check.sh +456 -0
- package/substrate/scripts/lite-manifest-drift-check.sh +146 -0
- package/substrate/scripts/render-lite-manifest-doc.sh +150 -0
- package/substrate/standards/adr-template.md +86 -0
- package/substrate/standards/api-conventions/nextjs.md +84 -0
- package/substrate/standards/artifact-composition.md +209 -0
- package/substrate/standards/bash-hook-safety.md +246 -0
- package/substrate/standards/bassclef-configs-schema.md +232 -0
- package/substrate/standards/bassclef-evolution.md +143 -0
- package/substrate/standards/bassclef-internal-jargon.md +244 -0
- package/substrate/standards/bassclef-managed-sentinel.md +96 -0
- package/substrate/standards/bassclef-source-config.md +228 -0
- package/substrate/standards/branch-stacking.md +408 -0
- package/substrate/standards/code-safety-principles.md +176 -0
- package/substrate/standards/composer-prerequisites.md +155 -0
- package/substrate/standards/deferred-actions-schema.md +204 -0
- package/substrate/standards/dependency-discipline/cargo.md +39 -0
- package/substrate/standards/dependency-discipline/gem.md +43 -0
- package/substrate/standards/dependency-discipline/go-mod.md +41 -0
- package/substrate/standards/dependency-discipline/npm.md +42 -0
- package/substrate/standards/dependency-discipline/pip.md +42 -0
- package/substrate/standards/deployment-topology/ec2-tailscale.md +225 -0
- package/substrate/standards/deployment-topology.md +69 -0
- package/substrate/standards/docs-sync-allowlist.md +76 -0
- package/substrate/standards/domain-and-dns.md +145 -0
- package/substrate/standards/frontend-stack.md +67 -0
- package/substrate/standards/frontmatter-schema.md +154 -0
- package/substrate/standards/graceful-exit.md +227 -0
- package/substrate/standards/hook-idempotency.md +102 -0
- package/substrate/standards/hook-injection-discipline.md +202 -0
- package/substrate/standards/hook-install-class.md +215 -0
- package/substrate/standards/input-handler-interface.md +152 -0
- package/substrate/standards/lite-manifest-schema-changes.md +135 -0
- package/substrate/standards/luminary-matching.md +105 -0
- package/substrate/standards/luminary-problem-patterns.md +481 -0
- package/substrate/standards/migration-discipline/active-record.md +50 -0
- package/substrate/standards/migration-discipline/alembic.md +43 -0
- package/substrate/standards/migration-discipline/gorm.md +50 -0
- package/substrate/standards/migration-discipline/prisma.md +53 -0
- package/substrate/standards/migration-discipline/sqlalchemy.md +51 -0
- package/substrate/standards/mobile-ephemeral-session.md +167 -0
- package/substrate/standards/model-routing-discipline.md +160 -0
- package/substrate/standards/ogilvy-writing-rules.md +225 -0
- package/substrate/standards/opener-discipline.md +96 -0
- package/substrate/standards/operator-facing-prose-discipline.md +201 -0
- package/substrate/standards/persona-schema.md +229 -0
- package/substrate/standards/pluggable-luminaries.md +323 -0
- package/substrate/standards/pr-body-discipline.md +115 -0
- package/substrate/standards/preview-state-schema.md +189 -0
- package/substrate/standards/project-directory-layout.md +276 -0
- package/substrate/standards/release-tagging.md +137 -0
- package/substrate/standards/reserved-skill-names.md +120 -0
- package/substrate/standards/scannable-multi-option-output.md +261 -0
- package/substrate/standards/sdlc-compliance.md +286 -0
- package/substrate/standards/sdlc-gates/typescript.md +57 -0
- package/substrate/standards/secrets-lifecycle.md +210 -0
- package/substrate/standards/security-scanner-adapter.md +145 -0
- package/substrate/standards/session-board.md +256 -0
- package/substrate/standards/skill-output-discipline.md +90 -0
- package/substrate/standards/state-spine-contract.md +255 -0
- package/substrate/standards/state-spine.md +511 -0
- package/substrate/standards/steering-hints/kiss-words.md +11 -0
- package/substrate/standards/substrate-config-schema.md +267 -0
- package/substrate/standards/tech-stack-config.md +109 -0
- package/substrate/standards/tier-dependency-analysis.md +167 -0
- package/substrate/standards/tier-runtime-deps/lite.md +57 -0
- package/substrate/standards/tier-tag-schema.md +155 -0
- package/substrate/standards/two-layer-config.md +99 -0
- package/substrate/standards/use-case-format.md +292 -0
- package/substrate/standards/user-story-invest.md +268 -0
- package/substrate/standards/velocity-and-appetite.md +229 -0
- package/substrate/standards/voice-input-pattern.md +119 -0
- package/substrate/standards/whereami-schema.md +301 -0
- package/substrate/standards/worktree-management.md +211 -0
- package/substrate/standards/writing-guide.md +213 -0
- package/substrate/templates/chronicle-template.md +75 -0
- package/substrate/templates/deferred-action-template.md +45 -0
- package/substrate/templates/memory-proposal-template.md +77 -0
- package/substrate/templates/persona-template.md +200 -0
- package/substrate/templates/pr-faq.md +45 -0
- package/substrate/templates/secret-rotation-template.md +162 -0
- package/substrate/templates/spec-template.md +131 -0
- package/substrate/templates/use-case-template.md +194 -0
- package/substrate/templates/user-story-template.md +107 -0
- package/substrate/templates/whereami-template.md +101 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: "The operator's reference deployment. Stack-specific instantiation of standards/deployment-topology.md for adopters who pick the same target."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deployment Topology — EC2 + Docker Compose + Tailscale + GHA-SSH
|
|
7
|
+
|
|
8
|
+
The operator's reference deployment. Stack-specific instantiation of `standards/deployment-topology.md` for adopters who pick the same target.
|
|
9
|
+
|
|
10
|
+
## When this sibling fires
|
|
11
|
+
|
|
12
|
+
When adopter's `.claude/bassclef-configs.jsonc` has `tech_stack.deploy: ec2-tailscale`. The loader (future ticket) reads this sibling and applies the platform-specific guidance below in addition to the universal principles in the parent standard.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
**Single EC2 instance + Docker Compose + Tailscale mesh + GHA-SSH deploy.**
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌────────────────────────────────────────────────────────┐
|
|
21
|
+
│ EC2 Instance (on Tailscale) │
|
|
22
|
+
│ ┌──────────────────────────────────────────────────┐ │
|
|
23
|
+
│ │ docker-compose.prod.yml │ │
|
|
24
|
+
│ │ • app (Next.js / API) │ │
|
|
25
|
+
│ │ • worker (queue processor) │ │
|
|
26
|
+
│ │ • postgres (local volume) │ │
|
|
27
|
+
│ │ • redis (local volume) │ │
|
|
28
|
+
│ └──────────────────────────────────────────────────┘ │
|
|
29
|
+
│ ┌──────────────────────────────────────────────────┐ │
|
|
30
|
+
│ │ docker-compose.staging.yml (optional, same box)│ │
|
|
31
|
+
│ │ • app on different port │ │
|
|
32
|
+
│ │ • worker │ │
|
|
33
|
+
│ │ • SHARES postgres (different DB) │ │
|
|
34
|
+
│ │ • SHARES redis (different namespace) │ │
|
|
35
|
+
│ └──────────────────────────────────────────────────┘ │
|
|
36
|
+
│ /opt/backups/ (pg_dump on every deploy) │
|
|
37
|
+
│ .env.production, .env.staging (on-box, gitignored) │
|
|
38
|
+
└────────────────────────────────────────────────────────┘
|
|
39
|
+
↑ ↑
|
|
40
|
+
│ Tailscale SSH │ Tailscale HTTPS
|
|
41
|
+
GitHub Actions (CI) Users + operator phone
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## When this pattern fits
|
|
45
|
+
|
|
46
|
+
- Small team (≤10 users)
|
|
47
|
+
- Trusted user set (all known, on Tailscale)
|
|
48
|
+
- Cost-sensitive (~$15-30/mo infra per environment)
|
|
49
|
+
- Low-to-moderate traffic (< ~50 concurrent users)
|
|
50
|
+
- Solo or small-team ops (no dedicated SRE)
|
|
51
|
+
- Private / internal tool (not public-facing)
|
|
52
|
+
|
|
53
|
+
## When to graduate beyond
|
|
54
|
+
|
|
55
|
+
| Signal | Graduate to |
|
|
56
|
+
|--------|-------------|
|
|
57
|
+
| Public-facing with >100 concurrent users | ALB + auto-scaling group, or managed Platform-as-Service |
|
|
58
|
+
| Multi-region / geo-redundancy required | Terraform-defined multi-region; managed DB |
|
|
59
|
+
| Compliance requires isolation (SOC2, HIPAA) | Dedicated network / VPC + managed services |
|
|
60
|
+
| >1 developer pushing concurrently | Per-PR preview environments |
|
|
61
|
+
| Data loss intolerant (RPO < 1 hour) | Managed DB with PITR (RDS, Aurora) + offsite backups |
|
|
62
|
+
|
|
63
|
+
**Graduation is a conscious choice, not default.** Most products never
|
|
64
|
+
need it. Starting simple and graduating under pressure is cheaper than
|
|
65
|
+
over-architecting up front.
|
|
66
|
+
|
|
67
|
+
## Environment separation rules
|
|
68
|
+
|
|
69
|
+
### Topology choices
|
|
70
|
+
|
|
71
|
+
**Option A — Same box, multiple Compose stacks** (cheapest, default)
|
|
72
|
+
|
|
73
|
+
- Prod stack on `docker-compose.prod.yml` at port 3001
|
|
74
|
+
- Staging stack on `docker-compose.staging.yml` at port 3002
|
|
75
|
+
- Shared Postgres, different DBs (`{app}_prod`, `{app}_staging`)
|
|
76
|
+
- Shared Redis, different namespaces (`prod:*`, `staging:*`)
|
|
77
|
+
- Shared box = resource contention risk; monitor
|
|
78
|
+
|
|
79
|
+
**Option B — Separate boxes, same pattern** (isolation, ~$15-20/mo more)
|
|
80
|
+
|
|
81
|
+
- Prod box + staging box, both on Tailscale mesh
|
|
82
|
+
- Separate Postgres + Redis per box
|
|
83
|
+
- Clean isolation at cost of second instance
|
|
84
|
+
|
|
85
|
+
Default is Option A. Upgrade to B if contention manifests.
|
|
86
|
+
|
|
87
|
+
### Required separation
|
|
88
|
+
|
|
89
|
+
Regardless of topology choice:
|
|
90
|
+
- **Separate `.env.{environment}` files** — never share credentials
|
|
91
|
+
- **Separate DBs / namespaces** — never share data
|
|
92
|
+
- **Separate backup paths** — `/opt/backups/prod/`, `/opt/backups/staging/`
|
|
93
|
+
- **Separate API keys** — staging uses test-tier keys where providers
|
|
94
|
+
support (Anthropic, Resend, etc.)
|
|
95
|
+
- **No PII in staging** — synthetic fixtures or anonymized seed,
|
|
96
|
+
never a raw prod copy
|
|
97
|
+
|
|
98
|
+
## Deploy workflow shape (bassclef)
|
|
99
|
+
|
|
100
|
+
Every deploy workflow (`.github/workflows/deploy.yml`) follows this sequence:
|
|
101
|
+
|
|
102
|
+
1. **Test** — unit + integration tests must pass
|
|
103
|
+
2. **Build** — Docker image → push to GHCR with SHA tag
|
|
104
|
+
3. **Pre-deploy backup** — SSH to box, `pg_dump` current DB to
|
|
105
|
+
`/opt/backups/{env}/`
|
|
106
|
+
4. **Deploy** — pull image, run migrations in temporary container,
|
|
107
|
+
`docker compose up -d` with maintenance-mode flag during restart
|
|
108
|
+
5. **Smoke test** — curl health endpoint + one critical path; fail
|
|
109
|
+
the job if anything breaks
|
|
110
|
+
6. **Alert on failure** — auto-create GitHub issue labeled priority:high
|
|
111
|
+
|
|
112
|
+
Staging runs this sequence on PR open/push. Prod runs on merge to main
|
|
113
|
+
**with manual approval gate** (see Manual approval rule below).
|
|
114
|
+
|
|
115
|
+
## Manual approval gate (MUST)
|
|
116
|
+
|
|
117
|
+
Prod deploys always require manual human approval. Mechanism: GitHub
|
|
118
|
+
Environments with `required_reviewers`.
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
# In deploy.yml
|
|
122
|
+
jobs:
|
|
123
|
+
deploy-prod:
|
|
124
|
+
environment:
|
|
125
|
+
name: prod # configured with required_reviewers in repo settings
|
|
126
|
+
...
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
No app repo may skip this gate. Per `.claude/rules/manual-prod-approval.md`,
|
|
130
|
+
absence of this configuration is a rule violation.
|
|
131
|
+
|
|
132
|
+
## Backup protocol
|
|
133
|
+
|
|
134
|
+
- `pg_dump` before every deploy, compressed, timestamped
|
|
135
|
+
- Stored locally on the box at `/opt/backups/{env}/`
|
|
136
|
+
- Retention: 30 days on-box, longer offsite if compliance requires
|
|
137
|
+
- Weekly rotation to offsite (S3, separate account) if data is
|
|
138
|
+
business-critical
|
|
139
|
+
|
|
140
|
+
## Rollback
|
|
141
|
+
|
|
142
|
+
- Docker image tagged by SHA at every push to GHCR
|
|
143
|
+
- Rollback = redeploy previous SHA: `docker compose -f docker-compose.prod.yml`
|
|
144
|
+
with image tag swapped
|
|
145
|
+
- Database rollback via `pg_restore` from pre-deploy backup (last resort;
|
|
146
|
+
most migrations should be expand-and-contract so rollback ≠ restore)
|
|
147
|
+
- Runbook lives at `docs/runbooks/rollback.md` per app repo
|
|
148
|
+
|
|
149
|
+
## Maintenance mode
|
|
150
|
+
|
|
151
|
+
During restart, users should see a holding page, not a broken UI.
|
|
152
|
+
Implementation: env flag `MAINTENANCE_MODE=1` set in `.env.{env}`
|
|
153
|
+
during the deploy window, read by the app's request handler, renders
|
|
154
|
+
a simple HTML holding page for all paths.
|
|
155
|
+
|
|
156
|
+
Deploy sequence:
|
|
157
|
+
1. Set `MAINTENANCE_MODE=1` in env
|
|
158
|
+
2. Run migrations (in temporary container)
|
|
159
|
+
3. Restart app + worker containers
|
|
160
|
+
4. Health-check loop: up to N retries
|
|
161
|
+
5. Unset `MAINTENANCE_MODE`, restart to pick up env change
|
|
162
|
+
|
|
163
|
+
## Mobile / ephemeral safety
|
|
164
|
+
|
|
165
|
+
Deploy flows NEVER run from an ephemeral session (mobile, CI-nested
|
|
166
|
+
agent, etc.). Ephemeral sessions open PRs; CI handles the deploy on
|
|
167
|
+
merge after approval gate. See `standards/mobile-ephemeral-session.md`.
|
|
168
|
+
|
|
169
|
+
## Templates
|
|
170
|
+
|
|
171
|
+
Working templates for instantiation into new app repos:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
presence/install/deployment/
|
|
175
|
+
docker-compose.prod.template.yml
|
|
176
|
+
docker-compose.staging.template.yml
|
|
177
|
+
env.prod.template
|
|
178
|
+
env.staging.template
|
|
179
|
+
github-workflows-deploy.template.yml
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Parameterized on: `{{APP_NAME}}`, `{{APP_PORT_PROD}}`, `{{APP_PORT_STAGING}}`,
|
|
183
|
+
`{{DB_NAME_PROD}}`, `{{DB_NAME_STAGING}}`, `{{GHCR_IMAGE}}`,
|
|
184
|
+
`{{DEPLOY_HOST}}`, `{{DEPLOY_USER}}`, `{{DEPLOY_PATH}}`, `{{TAILSCALE_TAG}}`.
|
|
185
|
+
|
|
186
|
+
Values come from `substrate.config.md` fields (per
|
|
187
|
+
`standards/substrate-config-schema.md`).
|
|
188
|
+
|
|
189
|
+
## Substrate config fields required for deployment
|
|
190
|
+
|
|
191
|
+
```yaml
|
|
192
|
+
deploy_host: [Tailscale hostname]
|
|
193
|
+
deploy_user: [SSH user]
|
|
194
|
+
deploy_path: [absolute path on box]
|
|
195
|
+
staging_deploy_host: [optional; same or different]
|
|
196
|
+
staging_deploy_path: [optional]
|
|
197
|
+
tailscale_tag: [e.g., tag:ci]
|
|
198
|
+
backup_path: [absolute path]
|
|
199
|
+
prod_approval_reviewers: [comma-separated GitHub usernames]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Anti-patterns
|
|
203
|
+
|
|
204
|
+
- **Hardcoded host/user/path in deploy.yml** — always pull from
|
|
205
|
+
`substrate.config.md` via GHA secrets or variables
|
|
206
|
+
- **Same `.env.production` on staging** — never. Separate files,
|
|
207
|
+
always.
|
|
208
|
+
- **Prod data copied to staging** — PII leak + violates substrate
|
|
209
|
+
separation rule
|
|
210
|
+
- **Auto-deploy to prod without approval gate** — violates guardrails
|
|
211
|
+
- **Deploy from ephemeral session** — violates mobile-ephemeral rules
|
|
212
|
+
- **Skipping pre-deploy backup** — no recovery path if deploy breaks
|
|
213
|
+
|
|
214
|
+
## Related
|
|
215
|
+
|
|
216
|
+
- `standards/mobile-ephemeral-session.md` — ephemeral constraints
|
|
217
|
+
- `standards/substrate-config-schema.md` — resource reference schema
|
|
218
|
+
- `.claude/rules/manual-prod-approval.md` — prod gate enforcement
|
|
219
|
+
- `.claude/rules/guardrails.md` — prod deploy always human-approved
|
|
220
|
+
|
|
221
|
+
## Refs
|
|
222
|
+
|
|
223
|
+
- Parent standard: `standards/deployment-topology.md`
|
|
224
|
+
- ARCH-T0 #1133 — operator-stack-leakage audit + remediation
|
|
225
|
+
- bassclef#1315 — this sibling (deployment-topology Path A WU-9 of bet 2026-06-20e)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: Document the deployment target your project actually uses, so substrate-side hooks + rules + skills load the right per-platform siblings via the loader (future ticket) reading tech_stack.deploy from .claude/bassclef-configs.jsonc.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deployment Topology Standard
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Document the deployment target your project actually uses, so substrate-side hooks + rules + skills load the right per-platform siblings via the loader (future ticket) reading `tech_stack.deploy` from `.claude/bassclef-configs.jsonc`.
|
|
11
|
+
|
|
12
|
+
This standard is universal — it instructs you to declare your deployment target, not which platform to adopt. The operator's deployment (single EC2 + Docker Compose + Tailscale + GHA-SSH) is documented as one example under `standards/deployment-topology/ec2-tailscale.md`; adopters on Vercel, Netlify, Fly, Render, Cloud Run, Amplify add their own siblings.
|
|
13
|
+
|
|
14
|
+
## Why declare your deployment
|
|
15
|
+
|
|
16
|
+
Bassclef's deploy-side discipline (prod approval gates, environment isolation, secret handling, observability hooks, rollback procedures) ships as universal principles with per-platform siblings. The loader matches your declared deploy target to the relevant sibling; without one, the universal principles still apply but platform-specific specifics are skipped.
|
|
17
|
+
|
|
18
|
+
Declare your deployment in `.claude/bassclef-configs.jsonc` `tech_stack.deploy`:
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
"tech_stack": {
|
|
22
|
+
"deploy": "ec2-tailscale" | "vercel" | "netlify" | "fly" | "render" | "gcp-cloud-run" | "amplify" | "none"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Per-platform siblings
|
|
27
|
+
|
|
28
|
+
| Adopter's `tech_stack.deploy` | Sibling location |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `ec2-tailscale` (operator's deployment) | `standards/deployment-topology/ec2-tailscale.md` |
|
|
31
|
+
| `vercel` | `standards/deployment-topology/vercel.md` *(future — file `/promote` to author)* |
|
|
32
|
+
| `netlify` | `standards/deployment-topology/netlify.md` *(future)* |
|
|
33
|
+
| `fly` | `standards/deployment-topology/fly.md` *(future)* |
|
|
34
|
+
| `render` | `standards/deployment-topology/render.md` *(future)* |
|
|
35
|
+
| `gcp-cloud-run` | `standards/deployment-topology/gcp-cloud-run.md` *(future)* |
|
|
36
|
+
| `amplify` | `standards/deployment-topology/amplify.md` *(future)* |
|
|
37
|
+
| `none` or unset | universal principles only; no platform-specific guidance |
|
|
38
|
+
|
|
39
|
+
## Universal principles
|
|
40
|
+
|
|
41
|
+
Whichever deployment target you pick:
|
|
42
|
+
|
|
43
|
+
- **Production deploys require human approval** — never auto-deploy to prod without explicit gate per `.claude/rules/manual-prod-approval.md`. Hard ceiling regardless of platform.
|
|
44
|
+
- **Environment isolation** — local / staging / prod are distinct; secrets, data, and config never cross boundaries
|
|
45
|
+
- **ENV vars and secrets** — never committed; live in your platform's secret-management mechanism (GitHub Actions Secrets, Vercel env vars, AWS Secrets Manager, 1Password, etc.). Reference by name in code; never inline values.
|
|
46
|
+
- **Backups before destructive operations** — DB backup before any migration that drops columns / changes types / renames tables. Backup retention policy declared in your sibling.
|
|
47
|
+
- **Rollback procedure** — documented per platform. Know your N-1 deployable artifact at all times.
|
|
48
|
+
- **Observability** — health endpoint + error reporting + log aggregation. Platform-specific tooling varies; the obligation is universal.
|
|
49
|
+
- **Secret rotation** — declared cadence per secret type. Per `standards/secrets-lifecycle.md`.
|
|
50
|
+
|
|
51
|
+
## Operator's deployment reference
|
|
52
|
+
|
|
53
|
+
The operator's reference deployment is single EC2 + Docker Compose + Tailscale mesh + GHA-SSH deploy. Full architecture diagram + capacity bounds + when to graduate + setup walkthrough + key commands live in `standards/deployment-topology/ec2-tailscale.md`.
|
|
54
|
+
|
|
55
|
+
This is one example among many valid patterns. Adopters on cloud-platform deployments (Vercel, Netlify, Fly, Render, Cloud Run, Amplify) read their own sibling once it exists; until then, the universal principles above apply.
|
|
56
|
+
|
|
57
|
+
## When to graduate from your declared deployment
|
|
58
|
+
|
|
59
|
+
Each platform sibling documents capacity bounds + graduation triggers (when single-instance bottlenecks force migration to multi-region / managed services / Kubernetes / etc.). The operator's EC2-Tailscale sibling carries the original graduation triggers for that pattern; adopters on cloud platforms document their own.
|
|
60
|
+
|
|
61
|
+
## Refs
|
|
62
|
+
|
|
63
|
+
- ARCH-T0 #1133 — operator-stack-leakage audit + remediation (parent)
|
|
64
|
+
- bassclef#1315 — this Path A WU-9 of bet 2026-06-20e
|
|
65
|
+
- bassclef#1309 + bassclef#1311 + bassclef#1313 — sister Path A passes
|
|
66
|
+
- bassclef#1127 — tech_stack vocabulary
|
|
67
|
+
- `.claude/rules/manual-prod-approval.md` — prod approval gate (universal)
|
|
68
|
+
- `standards/secrets-lifecycle.md` — secret rotation discipline
|
|
69
|
+
- `standards/deployment-topology/ec2-tailscale.md` — operator's deployment reference
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: Files whose change triggers bassclef-docs-sync.yml.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Docs Sync Allowlist
|
|
7
|
+
|
|
8
|
+
Files whose change triggers `bassclef-docs-sync.yml`. The workflow syncs bassclef's adopter-facing docs into a discoverable surface (GitHub Wiki + cross-reference verification) so substrate-vs-docs drift can't accumulate silently between sessions.
|
|
9
|
+
|
|
10
|
+
Tracked under c-package iteration goal 2026-05-13. Closes the discipline gap surfaced when `.bassclef-source.json` was described as pointing at S3 (it points at GitHub) one turn after the description shipped.
|
|
11
|
+
|
|
12
|
+
## Files
|
|
13
|
+
|
|
14
|
+
When any of these paths change in a push to `main`, the docs-sync workflow fires:
|
|
15
|
+
|
|
16
|
+
- `standards/project-directory-layout.md`
|
|
17
|
+
- `docs/bassclef-mental-model.md`
|
|
18
|
+
- `docs/bassclef-overview.md`
|
|
19
|
+
- `docs/getting-started.md` (added 2026-05-14 — dedicated Getting Started walkthrough)
|
|
20
|
+
- `docs/first-use-sequence.md` (added 2026-06-13 — bassclef#965 first-use sequence diagram)
|
|
21
|
+
- `docs/how-skills-work.md` (added 2026-06-13 — adopter guidance on discovery + composition + autonomy modes)
|
|
22
|
+
- `README.md`
|
|
23
|
+
- `docs/hooks-index.md`
|
|
24
|
+
- `docs/glossary.md` (added 2026-05-14 — exhaustive-docs stack)
|
|
25
|
+
- `docs/philosophy.md` (added 2026-05-14)
|
|
26
|
+
- `docs/skills-catalog.md` (added 2026-05-14)
|
|
27
|
+
- `docs/hooks-catalog.md` (added 2026-05-14)
|
|
28
|
+
- `docs/rules-catalog.md` (added 2026-05-14)
|
|
29
|
+
- `architecture/decisions/ADR-*.md` (any new file matching this glob)
|
|
30
|
+
- `.claude/skills/*/SKILL.md` (any new file OR `deprecated: true` flip in frontmatter)
|
|
31
|
+
- `.claude/rules/*.md` (any new file)
|
|
32
|
+
- `standards/bassclef-source-config.md`
|
|
33
|
+
- `standards/vendor-bindings.md` (standard tier — substrate reference)
|
|
34
|
+
- `standards/bassclef-configs-schema.md` (added 2026-06-20 — bassclef#1284 closeout; covers the schema doc updated when new bassclef-configs blocks ship)
|
|
35
|
+
- `standards/sibling-validation-checklist.md` (standard tier; added 2026-06-20 — bassclef#1284 closeout; operator-runnable end-to-end validation procedure for adopter inheritance)
|
|
36
|
+
- `standards/bassclef-internal-jargon.md` → `Bassclef-Internal-Jargon.md` (added 2026-06-20 — bassclef#1298 / WU-13 of bet 2026-06-20e; the BLOCK / ADVISE / ALLOW wordlist read by turn-prose-kiss-check.sh + pr-body-scrub-check.sh; amended frequently — every wordlist addition should sync to wiki so adopters see current catalog)
|
|
37
|
+
- `standards/adr-template.md` → `ADR-Template.md` (added 2026-06-20 — bassclef#1208 / WU-14 of bet 2026-06-20e; 14-day wiki-as-we-go sweep — ADR template for adopter architecture-record discipline)
|
|
38
|
+
- `standards/bash-hook-safety.md` → `Bash-Hook-Safety.md` (added 2026-06-20 — same; 7 defensive-bash disciplines)
|
|
39
|
+
- `standards/code-safety-principles.md` → `Code-Safety-Principles.md` (added 2026-06-20 — same; language-agnostic safety principles)
|
|
40
|
+
- `standards/frontmatter-schema.md` → `Frontmatter-Schema.md` (added 2026-06-20 — same; required/optional fields for rules + skills)
|
|
41
|
+
- `standards/model-routing-discipline.md` → `Model-Routing-Discipline.md` (added 2026-06-20 — same; per-agent model_tier discipline)
|
|
42
|
+
- `standards/pseudonym-key-schema.md` → `Pseudonym-Key-Schema.md` (standard tier; added 2026-06-20 — same; operator-private pseudonym registry schema)
|
|
43
|
+
- `standards/security-scanner-adapter.md` → `Security-Scanner-Adapter.md` (added 2026-06-20 — same; per-stack security scanner integration)
|
|
44
|
+
- `standards/tech-stack-config.md` → `Tech-Stack-Config.md` (added 2026-06-20 — same; tech_stack vocabulary bassclef#1127 drives)
|
|
45
|
+
|
|
46
|
+
## What the workflow does
|
|
47
|
+
|
|
48
|
+
For each changed allowlisted path:
|
|
49
|
+
|
|
50
|
+
1. **Identify the artifact class.** Standard / mental-model / overview / README / ADR / skill / rule / hooks-index.
|
|
51
|
+
2. **If a wiki page exists for this artifact**, update it with the new content (light header transform — strip frontmatter, add wiki-style title).
|
|
52
|
+
3. **If no wiki page exists yet**, create one + add to `_Sidebar.md`.
|
|
53
|
+
4. **Cross-reference check.** Grep bassclef-overview + README + mental-model for stale links to the changed file. Surface mismatches as warnings on the PR.
|
|
54
|
+
5. **Step summary.** GitHub Actions step summary names what was synced.
|
|
55
|
+
|
|
56
|
+
## What does NOT trigger sync
|
|
57
|
+
|
|
58
|
+
Changes to files NOT on the allowlist. The allowlist is intentionally narrow — internal-decomposition docs, chronicles, iteration goals, LinkedIn drafts, sibling-validations, and audits all stay non-synced. Wiki is for adopter-facing reference, not operator-internal records.
|
|
59
|
+
|
|
60
|
+
## Adding a new path
|
|
61
|
+
|
|
62
|
+
When a new file should be synced, edit this allowlist + the workflow's `paths:` filter in the same PR. Per `standards/project-directory-layout.md` anti-drift rule: substrate change + standard update in same change.
|
|
63
|
+
|
|
64
|
+
## Override
|
|
65
|
+
|
|
66
|
+
`SKIP_DOCS_SYNC=1` in a commit body skips the workflow for that commit. Logged via trace-helper. Use rarely; prefer narrowing the allowlist if a path shouldn't be synced.
|
|
67
|
+
|
|
68
|
+
## Sources read
|
|
69
|
+
|
|
70
|
+
- `docs/iteration-bets/2026-05-13-s3-retirement-docs-sync-hooks-index.md` — parent bet
|
|
71
|
+
- `docs/roadmaps/2026-05-07-7-phase-staircase.md` — current `last_event` = `phase_v_mvd_substrate_shipped` at `2026-05-12T01:30:00Z`
|
|
72
|
+
- `.claude/rules/bassclef-workflow-parity.md` (standard tier) — sibling-grep discipline when adding workflows
|
|
73
|
+
|
|
74
|
+
## Closes
|
|
75
|
+
|
|
76
|
+
WU-4 of c-package bet — the standard half. WU-5 ships the `/docs-sync` skill that runs the same logic locally. The workflow YAML itself ships in this same WU.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: - .claude/skills/bind-subdomain/SKILL.md — operationalizes this standard - scripts/bind-subdomain.sh + scripts/adapters/* — the implementation - standards/substrate-config-schema.md — field conventions used by the script -…
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Sources read
|
|
7
|
+
|
|
8
|
+
- `.claude/skills/bind-subdomain/SKILL.md` — operationalizes this standard
|
|
9
|
+
- `scripts/bind-subdomain.sh` + `scripts/adapters/*` — the implementation
|
|
10
|
+
- `standards/substrate-config-schema.md` — field conventions used by the script
|
|
11
|
+
- bassclef #254 — shaping ticket this standard closes
|
|
12
|
+
- `docs/learnings/2026-04-19-mobile-to-preview.md` — source of the manual pattern now automated
|
|
13
|
+
|
|
14
|
+
## What I'm NOT reading (with reason)
|
|
15
|
+
|
|
16
|
+
- `standards/deployment-topology.md` — orthogonal (that's EC2 + Docker Compose; this is DNS/TLS for any managed platform)
|
|
17
|
+
- Route 53-specific DNS management — out of scope v1; Phase 2 of automation path
|
|
18
|
+
|
|
19
|
+
# Domain + DNS Standard
|
|
20
|
+
|
|
21
|
+
Bassclef decision for how sunj-labs apps get friendly URLs:
|
|
22
|
+
subdomain convention, TLS ownership, and DNS automation.
|
|
23
|
+
|
|
24
|
+
## The four coupled decisions
|
|
25
|
+
|
|
26
|
+
### 1. Subdomain convention: `<app>.apps.fivepandas.com`
|
|
27
|
+
|
|
28
|
+
- **Apex (`fivepandas.com`)** — reserved for marketing/brand
|
|
29
|
+
- **`apps.fivepandas.com`** — bassclef subtree for sunj-labs apps
|
|
30
|
+
- **`<app>.apps.fivepandas.com`** — one per app
|
|
31
|
+
|
|
32
|
+
Per-environment subdomains (e.g., `quorum.preview.apps.fivepandas.com`) are **deferred**. Single binding per app until multi-environment needs emerge. When they do, the pattern extends to `<app>.<env>.apps.fivepandas.com`.
|
|
33
|
+
|
|
34
|
+
**Why `apps.` bucket:** leaves apex + first-level untouched for brand; centralizes app surfaces under one predictable subtree; matches the bassclef-as-operating-system frame.
|
|
35
|
+
|
|
36
|
+
### 2. TLS / cert ownership: Amplify-managed (Phase 1) → Route 53 delegation (Phase 2)
|
|
37
|
+
|
|
38
|
+
| Phase | Approach | Trigger |
|
|
39
|
+
|-------|----------|---------|
|
|
40
|
+
| **Phase 1 (current)** | Amplify-managed cert (ACM); validation records live in Cloudflare | First 1-2 apps; before IaC lands |
|
|
41
|
+
| **Phase 2 (future)** | Route 53 delegation — delegate `apps.fivepandas.com` NS to Route 53; Amplify manages DNS + cert end-to-end | Triggered by #250 (IaC: CDK vs Gen 2) |
|
|
42
|
+
|
|
43
|
+
Phase 2 is the target because only Route 53 composes cleanly with AWS-native IaC. But Phase 1 is correct today — the cost of Route 53 delegation isn't justified for 1-2 apps.
|
|
44
|
+
|
|
45
|
+
### 3. DNS automation: `/bind-subdomain` skill
|
|
46
|
+
|
|
47
|
+
All DNS binding goes through `/bind-subdomain` — no manual clickops. The skill:
|
|
48
|
+
|
|
49
|
+
- Reads `substrate.config.md` for the consumer repo
|
|
50
|
+
- Dispatches to deploy-host adapter (Amplify v1; Netlify/Vercel/CF-Pages future)
|
|
51
|
+
- Dispatches to DNS-provider adapter (Cloudflare v1; Route 53 future)
|
|
52
|
+
- Creates domain association + validation records idempotently
|
|
53
|
+
- Polls cert validation (up to 20 min)
|
|
54
|
+
- Enables auto-build on the bound branch
|
|
55
|
+
|
|
56
|
+
**Idempotency** is mandatory. Re-running the skill against an already-bound app returns the current binding without modification. Script failure mid-way is recoverable by re-run.
|
|
57
|
+
|
|
58
|
+
### 4. Prototype gallery URL pattern: path-based, under the app subdomain
|
|
59
|
+
|
|
60
|
+
Per ADR-016 (bassclef#441 resolution): `/preview-build` and `/prototype-variants` dispatches expose variants under the app's existing subdomain at:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
https://<app>.apps.fivepandas.com/prototypes/<dispatch-slug>/<variant-slug>/
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Examples (live):
|
|
67
|
+
|
|
68
|
+
- `https://quorum.apps.fivepandas.com/prototypes/<historical-example-bet>/variant-tufte/` — Quorum's 22-variant gallery
|
|
69
|
+
- `https://twodo.apps.fivepandas.com/prototypes/2026-05-02-twodo/variant-a-tufte/` — TwoDo PR #269 (pending bind)
|
|
70
|
+
|
|
71
|
+
**Per-variant routing is the consumer app's responsibility**, not bassclef's `/bind-subdomain` skill. Static folder under `public/prototypes/` works on every supported deploy host (Amplify, Vercel, Netlify); Next.js App Router with `app/prototypes/[...slug]/page.tsx` works for dynamic galleries.
|
|
72
|
+
|
|
73
|
+
**One subdomain per app, regardless of variant count.** A 22-variant gallery binds the same way a single page does — one cert validation cycle, one DNS record. The path-based pattern preserves §1's "one subdomain per app" rule without amendment.
|
|
74
|
+
|
|
75
|
+
**`/launch-preview` (bassclef#448) operationalizes this convention.** The composer provisions exactly one subdomain per app via `/bind-subdomain`; variants ride along under `/prototypes/`.
|
|
76
|
+
|
|
77
|
+
**Production exclusion is the consumer's responsibility.** `/prototypes/*` routes should be gated behind a build-time flag (`NODE_ENV === 'development'`, `PREVIEW_TIER === '1'`, etc.) so production builds strip them. `standards/prototype-gallery.md` codifies the exclusion expectation.
|
|
78
|
+
|
|
79
|
+
Alternatives considered + rejected (subdomain-prefix, sub-subdomain) and full rationale: see ADR-016.
|
|
80
|
+
|
|
81
|
+
## Required config fields
|
|
82
|
+
|
|
83
|
+
Consumer repo's `substrate.config.md` declares:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
hosting_platform: amplify # amplify (bassclef default) | ec2-tailscale | vercel | netlify | cloudflare-pages | none
|
|
87
|
+
amplify_app_id: d154l5usyc80nk
|
|
88
|
+
amplify_region: eu-north-1
|
|
89
|
+
amplify_branch: main # optional, defaults to main
|
|
90
|
+
subdomain: quorum.apps.fivepandas.com
|
|
91
|
+
dns_provider: cloudflare # cloudflare | route53
|
|
92
|
+
dns_zone: fivepandas.com
|
|
93
|
+
cloudflare_token_env: CLOUDFLARE_API_TOKEN
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Secret values NEVER live in `substrate.config.md`. The field
|
|
97
|
+
`cloudflare_token_env` names an environment variable; the value is
|
|
98
|
+
set in the operator's shell (`~/.zshrc`, `~/.bashrc`, 1Password CLI
|
|
99
|
+
integration, etc.).
|
|
100
|
+
|
|
101
|
+
## Zone ownership + account topology
|
|
102
|
+
|
|
103
|
+
- `fivepandas.com` zone lives in Cloudflare (operator-owned)
|
|
104
|
+
- AWS Amplify apps live in AWS account `515820372344` (sunj-labs)
|
|
105
|
+
- TLS cert issuance happens in AWS (ACM); validation happens in CF
|
|
106
|
+
- No AWS-side DNS today (Phase 2 changes this for the `apps.` subtree)
|
|
107
|
+
|
|
108
|
+
## Security posture
|
|
109
|
+
|
|
110
|
+
- Cloudflare API token: least-privilege — Zone:Read + DNS:Edit, scoped to `fivepandas.com` zone only
|
|
111
|
+
- TTL on CF token: 90-day rotation recommended (forces rotation discipline early)
|
|
112
|
+
- AWS CLI: existing operator creds; narrowing IAM to Amplify-only is future hardening
|
|
113
|
+
- No tokens in source control, ever
|
|
114
|
+
|
|
115
|
+
## When to graduate beyond this standard
|
|
116
|
+
|
|
117
|
+
- **Multi-environment per app** (preview/staging/prod) → extend subdomain pattern to `<app>.<env>.apps.fivepandas.com`; `/bind-subdomain` learns a new optional arg
|
|
118
|
+
- **Non-Amplify hosting target** → add adapter at `scripts/adapters/deploy/<host>.sh`; no changes to main script
|
|
119
|
+
- **Non-Cloudflare DNS** → add adapter at `scripts/adapters/dns/<provider>.sh`; migrate to Route 53 per Phase 2
|
|
120
|
+
- **Per-PR preview URLs** → couples to IaC work (#250); likely Amplify-native feature set + new subdomain pattern
|
|
121
|
+
|
|
122
|
+
## Relationship to adjacent standards
|
|
123
|
+
|
|
124
|
+
- `substrate-config-schema.md` — field definitions the script reads
|
|
125
|
+
- `deployment-topology.md` — orthogonal (that's the POA EC2 pattern; this is DNS/TLS for any managed platform)
|
|
126
|
+
- `bassclef-evolution.md` — this standard shipped as the resolution of #254
|
|
127
|
+
|
|
128
|
+
## Relationship to adjacent skills
|
|
129
|
+
|
|
130
|
+
| Skill | Role |
|
|
131
|
+
|-------|------|
|
|
132
|
+
| `/bind-subdomain` | Implements this standard |
|
|
133
|
+
| `/onboard-repo` | Peer — provisions bassclef substrate for a new repo; binding happens after deploy host exists |
|
|
134
|
+
| `/deploy-prod` | Peer — POA's EC2+Tailscale deploy pattern; doesn't use this skill |
|
|
135
|
+
| `/substrate-check` | Validates `substrate.config.md` schema coverage |
|
|
136
|
+
|
|
137
|
+
## Evolution
|
|
138
|
+
|
|
139
|
+
- **v1.0 (2026-04-23)** — initial standard + skill + scripts + adapter
|
|
140
|
+
pattern. Amplify + Cloudflare v1 only. First consumer: quorum.
|
|
141
|
+
|
|
142
|
+
## Closes
|
|
143
|
+
|
|
144
|
+
- bassclef #254 (shaping)
|
|
145
|
+
- bassclef iteration goal 2026-04-23a-bind-subdomain (this ship)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: Document the stack your project actually uses, so substrate-side hooks + rules + skills load the right per-stack siblings via the loader (future ticket) reading tech_stack from .claude/bassclef-configs.jsonc.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Application Stack Standard
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Document the stack your project actually uses, so substrate-side hooks + rules + skills load the right per-stack siblings via the loader (future ticket) reading `tech_stack` from `.claude/bassclef-configs.jsonc`.
|
|
11
|
+
|
|
12
|
+
This standard is universal — it instructs you to declare your stack, not which stack to adopt. The operator's stack is documented as one example under `standards/frontend-stack/nextjs-prisma.md`; adopters on other stacks add their own sibling.
|
|
13
|
+
|
|
14
|
+
## Why declare your stack
|
|
15
|
+
|
|
16
|
+
Bassclef's substrate carries cross-cutting discipline (testing tiers, SDLC gates, API conventions, schema management, dependency discipline, deployment topology). Each ships a universal rule with per-stack siblings. The loader matches your declared stack to the relevant siblings; without a declared stack, the universal principles still apply but the stack-specific specifics are skipped.
|
|
17
|
+
|
|
18
|
+
Declare your stack in `.claude/bassclef-configs.jsonc` `tech_stack` block:
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
"tech_stack": {
|
|
22
|
+
"frontend": "nextjs" | "react-vite" | "vue" | "svelte" | "fastapi" | "django" | "rails" | "none",
|
|
23
|
+
"backend": "nodejs" | "python" | "ruby" | "go" | "rust" | "deno",
|
|
24
|
+
"orm": "prisma" | "sqlalchemy" | "active-record" | "gorm" | "alembic" | "none",
|
|
25
|
+
"pkg_manager": "npm" | "pip" | "cargo" | "gem" | "go-mod",
|
|
26
|
+
"deploy": "ec2-tailscale" | "vercel" | "netlify" | "fly" | "render" | "gcp-cloud-run" | "amplify" | "none"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Per-stack siblings
|
|
31
|
+
|
|
32
|
+
| Adopter's stack | Sibling location |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Next.js + Prisma + Postgres + EC2-Tailscale (operator's stack) | `standards/frontend-stack/nextjs-prisma.md` |
|
|
35
|
+
| FastAPI + SQLAlchemy + Postgres | `standards/frontend-stack/fastapi-sqlalchemy.md` *(future — file `/promote` to author)* |
|
|
36
|
+
| Rails + ActiveRecord | `standards/frontend-stack/rails.md` *(future)* |
|
|
37
|
+
| Other | document yours under `standards/frontend-stack/<name>.md` |
|
|
38
|
+
|
|
39
|
+
When no sibling matches your declared stack, the universal principle below applies; sibling-specific guidance is skipped.
|
|
40
|
+
|
|
41
|
+
## Universal principle
|
|
42
|
+
|
|
43
|
+
Whichever stack you pick:
|
|
44
|
+
|
|
45
|
+
- One declared stack per project — mixing N stacks for parts of one app produces drift; pick one and document it
|
|
46
|
+
- Type safety from boundary to boundary where the language supports it (TypeScript strict, Python type hints + mypy, etc.)
|
|
47
|
+
- Single source of truth for DB schema (an ORM schema file, a migration history, or a generated artifact — your call, but ONE source)
|
|
48
|
+
- ENV vars never committed; live in `.env.local` (local) and your deployment platform's env mechanism (production)
|
|
49
|
+
- Testing tiers per `.claude/rules/testing-tier-config.md` (Tier 0 strict TDD for substrate; Tier 1/2/3 by blast radius)
|
|
50
|
+
- Migrations per `.claude/rules/schema-management.md` (never auto-apply; never use `db push`-style tools that bypass migration files)
|
|
51
|
+
|
|
52
|
+
## Operator's stack reference
|
|
53
|
+
|
|
54
|
+
The operator's reference stack is Next.js + TypeScript + Prisma + Postgres + EC2-Tailscale. Full details + project structure + conventions + key commands live in `standards/frontend-stack/nextjs-prisma.md`.
|
|
55
|
+
|
|
56
|
+
See [ADR-008](../architecture/decisions/ADR-008-full-typescript-stack.md) for the original operator-side rationale. ADR-008 is operator-specific by nature (it documents one project's architecture decision); adopters on other stacks make their own ADRs.
|
|
57
|
+
|
|
58
|
+
## Refs
|
|
59
|
+
|
|
60
|
+
- ARCH-T0 #1133 — operator-stack-leakage audit + remediation (parent)
|
|
61
|
+
- bassclef#1313 — this Path A WU-8 of bet 2026-06-20e
|
|
62
|
+
- bassclef#1309 + bassclef#1311 — sister Path A passes
|
|
63
|
+
- bassclef#1127 — tech_stack vocabulary
|
|
64
|
+
- `.claude/rules/testing-tier-config.md` — testing tier discipline
|
|
65
|
+
- `.claude/rules/schema-management.md` — migration discipline (Path A precedent)
|
|
66
|
+
- `.claude/rules/new-dependency-check.md` — dependency discipline (Path A precedent)
|
|
67
|
+
- `standards/frontend-stack/nextjs-prisma.md` — operator's stack reference
|