From deabf1705f13c356b3fcf18e8fad4d38f435cdfb Mon Sep 17 00:00:00 2001 From: Lars Weiser Date: Fri, 24 Apr 2026 09:17:12 +0200 Subject: [PATCH 01/13] Document repo visibility and branch protection in TECH_STACK.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds §8.4 covering: - Repository visibility: public as of 2026-04-23, post secret scan - Pre-flip secret scan procedure (gitleaks) - Branch protection rulesets: protect-main and protect-dev - Rationale for deferring the required-status-checks toggle to Pass 2 Also trims §2.1's visibility bullet to cross-reference §8.4 instead of duplicating the pre-flip scan procedure. Also adds Pass 2 backlog item #5 for adding a PR-triggered CI workflow that can serve as the required status check once in place (backlog file itself is under plans/ and gitignored — this commit is docs-only). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/TECH_STACK.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/TECH_STACK.md b/docs/TECH_STACK.md index dfb512d..904ca46 100644 --- a/docs/TECH_STACK.md +++ b/docs/TECH_STACK.md @@ -79,7 +79,7 @@ Blackbrowed Labs builds tools for classroom management. Two areas are in active - **GitHub organisation:** `blackbrowed-labs` *(note the hyphen — the org name differs from the domain/brand, which have no hyphen: `blackbrowedlabs`)* - **Website repo:** `blackbrowed-labs/blackbrowedlabs.com` -- **Visibility:** Public (signal of craftsmanship and openness; content is not commercially sensitive). **Before making the repo public** — if any private history exists — run a secret scan such as `gitleaks detect --source . -v`. For a fresh repo with no history, skip this step. +- **Visibility:** Public (signal of craftsmanship and openness; content is not commercially sensitive). Full pre-flip secret-scan procedure and branch-protection ruleset details in §8.4. --- @@ -472,6 +472,32 @@ The repo's `.gitignore` is at the root and covers three categories of files: - **Source maps** (`.map` files) ship in production builds to aid debugging; no reason to ignore. - **Handoff documentation** in `docs/` and the Claude Design bundle in `design/handoff-bundle/` are committed — see §8.1 and §8.2 for the rationale. +### 8.4 Repository visibility and branch protection + +- **Visibility:** The repository is **public**. Flipped to public on 2026-04-23, after Pass 1 foundation was complete and a secret scan confirmed no sensitive values had been committed. The repo is `blackbrowed-labs/blackbrowedlabs.com`. + +- **Rationale for public:** The repo contains only brand-facing documentation (`docs/`), design-system handoff material (`design/handoff-bundle/`), and the Astro source. No secrets (all in `.env`, gitignored per §8.3). Public visibility signals craftsmanship and aligns with the studio's open posture. Also unlocks free branch protection rulesets on the GitHub free plan, which private repos on Team plans don't get. + +- **Pre-flip secret scan:** Before flipping, run `gitleaks detect --source . --verbose --redact` from the repo root. Expected output: `no leaks found`. If any leaks are reported: do not flip public until they're resolved (rotate exposed secrets, rewrite history with `git filter-repo` or equivalent, rerun scan). + +- **Branch protection rulesets** (GitHub → Settings → Rules): + - **`protect-main`** (Active): + - Target: `main` + - Restrict deletions: enabled + - Block force pushes: enabled + - Require pull request before merging: enabled (0 required approvals — solo founder; raise if collaborators join) + - Require linear history: enabled + - Allow bypass: empty (no one bypasses) + - **`protect-dev`** (Active): + - Target: `dev` + - Restrict deletions: enabled + - Block force pushes: enabled + - Other toggles intentionally off — `dev` is an integration branch and direct commits are expected + +- **Status checks deliberately not required:** "Require status checks to pass" is off on `protect-main` because GitHub requires at least one specific check to be named, and we don't yet have a PR-triggered CI workflow (the deploy workflows are push-triggered, not PR-triggered). Pass 2 backlog item #5: add a PR-triggered CI workflow (`npm ci && npm run build` at minimum) and add it as a required status check on `protect-main`. + +- **Default branch:** `main`. Changed from `dev` to `main` at the same time as ruleset configuration. Workflow is now: feature work on `dev` → auto-deploy to staging (`dev.blackbrowedlabs.com`) → PR `dev` → `main` → auto-deploy to production (`blackbrowedlabs.com`). + --- ## 9. Deployment & DNS From da5cef7c24048489804bc02026de9ea2245e706f Mon Sep 17 00:00:00 2001 From: Lars Weiser Date: Fri, 24 Apr 2026 09:37:29 +0200 Subject: [PATCH 02/13] Make SiteHeader sticky + set scroll-padding for skip-link target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SiteHeader.astro: change .site-header from position: relative to position: sticky; top: 0; z-index: 50. Keeps the hairline bottom border. Background is already opaque (var(--color-bg)) — header will not show through to scrolled content. - global.css: add scroll-padding-top: 5rem to html so the "Skip to main content" link's target (#main) lands below the sticky header instead of behind it. Also covers any future anchor jumps. No JS, no scroll-driven effects, no frosted/translucent surface — plain position: sticky per CLAUDE_DESIGN_BRIEF §8 (paper before screen, no ornament). No animation, so prefers-reduced-motion is unaffected. Z-index 50 sits above the in-header mobile-nav panel (10) and ThemeToggle menu (20), well below the SkipLink (1000) so the skip link stays visible on focus. sticky also qualifies as a "positioned" value, so the mobile nav panel's `position: absolute; top: 100%` still anchors to the header correctly. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/SiteHeader.astro | 4 +++- src/styles/global.css | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/SiteHeader.astro b/src/components/SiteHeader.astro index ea8ac62..9e0b18a 100644 --- a/src/components/SiteHeader.astro +++ b/src/components/SiteHeader.astro @@ -89,7 +89,9 @@ const aboutActive = path === aboutHref || path === aboutHref + '/';