GitHub Actions is the standard CI/CD platform. All pipelines use reusable workflows from the `Sea-Haven-Industries/.github` org repo (`.github/workflows/`).
## Workflow Structure
Every repo gets two thin workflow files in `.github/workflows/`:
- Inline policy allowing `sts:AssumeRole` on CDK/SAM bootstrap roles
2. A repo secret `AWS_DEPLOY_ROLE_ARN` containing the role ARN
## Node.js Version
Always pass `node-version: "24"` to reusable workflows. Local dev uses Node 24 / npm 11 which generates lockfileVersion 3. The workflow defaults match this, but be explicit to avoid drift.
Pull requests are auto-labeled org-wide by a reusable workflow in `.github`. The label rules live once, centrally, inside the reusable workflow itself (written to the runner at execution time), so each repo needs only a short caller and **no per-repo `labeler.yml`**:
```yaml
# .github/workflows/labeler.yml — the per-repo caller
- The trigger is plain `pull_request`, not `pull_request_target`: private repos take no fork PRs, so the lower-privilege event is sufficient and avoids the pwn-request surface. Because `pull_request` runs the workflow from the merge commit, the Labeler check appears on the PR that first adds the caller — an absent or failed check means a missing permission, not expected behaviour.
- The caller MUST grant all three permissions. Reusable-workflow permissions can only be downgraded from the caller, so omitting `issues: write` (needed to create labels that don't exist yet) or any other grant causes a silent `startup_failure`.
- Adding the caller is part of new-repo provisioning.