End-to-end GitHub Actions pipeline: build, test, scan, validate, security-scan, and tag-publish per branch/semver conventions. Five workflows under .github/workflows/, plus a CI/CD section in BUILDING.md and a CODEOWNERS file.
This PR is a draft for review. Workflows have not been executed in CI yet — the first push to this PR is the validation cycle. act was not run locally because most jobs require macOS runners that act can't simulate.
What lands
File
Purpose
.github/workflows/ci.yml
Main CI — boundary gates (17 of 18 on Linux), webview (pnpm), SPM matrix across all 14 packages on macos-15, app target (xcodebuild via scripts/check-app-builds.sh), optional self-hosted real-hardware lane, tag-publish on push to develop/rc/release/main
.github/workflows/codeql.yml
CodeQL static analysis for Swift + JS/TS, security-extended queries, weekly cron
.github/workflows/semgrep.yml
Semgrep with p/default, p/swift, p/typescript, p/secrets rule packs
.github/workflows/dependency-review.yml
Blocks high-severity vulnerable deps on PRs that touch npm/SPM manifests
.github/workflows/release.yml
Triggered by v* tag push; creates a GitHub Release with auto-generated changelog
Branch + tag strategy (defaults — override if your standards differ)
feature/*, fix/* — PR-only; full build/test/scan; no tag.
develop — every push: full CI + pre-release tag v0.X.Y-dev.<run_number>.
rc/* and release/* — every push: full CI + tag v0.X.Y-rc.N (N auto-increments).
main — every push: full CI + tag v0.X.Y + GitHub Release. Only ever updated via PR from rc/* or release/*.
Versioning source: Conventional Commits since the previous final tag.
feat: → minor bump
fix: → patch bump
feat!: or BREAKING CHANGE: footer → major bump
Seed version:v0.1.0 (current roadmap milestone target — see .planning/ROADMAP-2026-05-12.md). No tags currently exist in the repo, so the first push to develop after merge would publish v0.1.0-dev.<run_number>.
To override these conventions, edit the branches: lists in ci.yml and adjust the case statement in the publish-tag job.
Assumptions
Runner: macos-15. All Swift/Xcode jobs use macos-15 (currently the most recent GitHub-hosted macOS image with Xcode 16+). If you're on a Mac plan that limits macOS minutes, the SPM matrix (14 jobs) and CodeQL Swift job will dominate the budget — consider switching the matrix to a single representative package or a quarterly cron.
xcodegen on PATH — installed via brew install xcodegen in the app-build job because scripts/check-app-builds.sh invokes it when Jarvis.xcodeproj is missing.
CodeQL Swift extraction covers only Bus, AgentCore, MCP packages — a representative subset to keep the security lane cheap. Expand if needed.
Codesign — verify-entitlements.sh --pre-codesign/--post-codesign only run during a real signed build (they expect Xcode env vars); CI invokes only verify-codesign-settings.sh, which has no env deps.
Real-hardware tests
JARVIS_REAL_MODELS=1 and JARVIS_REAL_CAMERA=1 suites are gated on a [self-hosted, macOS] runner. To run them:
Register a self-hosted macOS runner with Ollama + the required models + camera TCC grants.
Actions tab → CI → "Run workflow" → set run_real_hardware to true.
The job is skipped entirely otherwise; no GitHub-hosted runner will ever try to execute these.
Morning actions for the user
Optional: set SEMGREP_APP_TOKEN at Settings → Secrets and variables → Actions if you want Semgrep findings posted to Semgrep Cloud. Without it, scans still run with public rules; findings only appear in the workflow log + SARIF upload to the Security tab.
Verify secret scanning is enabled at Settings → Code security and analysis. This is a repo-level setting; no workflow needed.
Verify Dependabot alerts + security updates are enabled in the same panel (they already are based on the existing dependabot.yml).
Branch protection on main (recommended): require status checks Boundary gates, Webview (pnpm test + build), SPM <pkg> matrix, App target (xcodebuild) to pass before merge; restrict pushes to PRs from rc/* / release/*.
CircleCI: this PR does NOT touch .circleci/. To stop CircleCI's red checkmarks, either un-wire the integration at Settings → Integrations or re-add a .circleci/config.yml. GitHub Actions is now the canonical CI surface — recommend removing CircleCI.
Optional: tighten dependency-review.yml by adding deny-licenses: GPL-2.0, GPL-3.0, AGPL-3.0 after auditing the existing SPM + npm graph for compatibility.
Verification
All five workflow YAML files parse cleanly (python3 -c "import yaml; yaml.safe_load(...)")
18 boundary gate scripts confirmed present; 17 wired into the Linux gate job
First push to this PR exercises boundary-gates, webview, swift-packages (matrix of 14), app-build, codeql, semgrep, dependency-review
After merging to develop, first push triggers publish-tag and creates v0.1.0-dev.<run_number>
Risks / open questions
Cost. Across boundary gates + 14 SPM jobs + app build + CodeQL Swift, expect ~30–60 macOS minutes per PR cycle. If this is too expensive, the SPM matrix can be collapsed to a single representative package or sharded across cron runs.
macos-15 availability. If GitHub deprecates this image before Xcode 17 lands, swap to macos-latest.
Tag-publish from develop runs on every push. If develop lands several commits per day this produces a lot of pre-release tags. Easy to throttle: change the trigger to workflow_dispatch or restrict via paths-ignore.
No code signing in CI. Releases are GitHub Releases only (per project scope — personal, not distributed). The verify-entitlements.sh codesign-verification flow only runs during a real signed build.
Dogfooding
After merge, watch the Actions tab for the first run on develop. Expected timeline: boundary gates (~1 min) → webview (~2-3 min) → SPM matrix (~10-15 min) → app build (~5 min) → publish-tag (~30 s).
## Summary
End-to-end GitHub Actions pipeline: build, test, scan, validate, security-scan, and tag-publish per branch/semver conventions. Five workflows under `.github/workflows/`, plus a CI/CD section in `BUILDING.md` and a `CODEOWNERS` file.
**This PR is a draft for review.** Workflows have not been executed in CI yet — the first push to this PR is the validation cycle. `act` was not run locally because most jobs require macOS runners that `act` can't simulate.
## What lands
| File | Purpose |
|------|---------|
| `.github/workflows/ci.yml` | Main CI — boundary gates (17 of 18 on Linux), webview (pnpm), SPM matrix across all 14 packages on `macos-15`, app target (`xcodebuild` via `scripts/check-app-builds.sh`), optional self-hosted real-hardware lane, tag-publish on push to `develop`/`rc`/`release`/`main` |
| `.github/workflows/codeql.yml` | CodeQL static analysis for Swift + JS/TS, `security-extended` queries, weekly cron |
| `.github/workflows/semgrep.yml` | Semgrep with `p/default`, `p/swift`, `p/typescript`, `p/secrets` rule packs |
| `.github/workflows/dependency-review.yml` | Blocks high-severity vulnerable deps on PRs that touch npm/SPM manifests |
| `.github/workflows/release.yml` | Triggered by `v*` tag push; creates a GitHub Release with auto-generated changelog |
| `.github/CODEOWNERS` | Catch-all owner `@KofTwentyTwo` |
| `BUILDING.md` | New CI/CD section: workflow map, branch/tag conventions, opt-in real-hardware tests, required secrets |
## Branch + tag strategy (defaults — override if your standards differ)
- **`feature/*`, `fix/*`** — PR-only; full build/test/scan; no tag.
- **`develop`** — every push: full CI + pre-release tag `v0.X.Y-dev.<run_number>`.
- **`rc/*` and `release/*`** — every push: full CI + tag `v0.X.Y-rc.N` (N auto-increments).
- **`main`** — every push: full CI + tag `v0.X.Y` + GitHub Release. Only ever updated via PR from `rc/*` or `release/*`.
**Versioning source:** Conventional Commits since the previous final tag.
- `feat:` → minor bump
- `fix:` → patch bump
- `feat!:` or `BREAKING CHANGE:` footer → major bump
**Seed version:** `v0.1.0` (current roadmap milestone target — see `.planning/ROADMAP-2026-05-12.md`). No tags currently exist in the repo, so the first push to `develop` after merge would publish `v0.1.0-dev.<run_number>`.
To override these conventions, edit the `branches:` lists in `ci.yml` and adjust the case statement in the `publish-tag` job.
## Assumptions
1. **Runner: `macos-15`.** All Swift/Xcode jobs use `macos-15` (currently the most recent GitHub-hosted macOS image with Xcode 16+). If you're on a Mac plan that limits macOS minutes, the SPM matrix (14 jobs) and CodeQL Swift job will dominate the budget — consider switching the matrix to a single representative package or a quarterly cron.
2. **pnpm 10.30.2** (matches `webview/package.json` `packageManager` field).
3. **Node 20** (matches `webview/package.json` `engines` field).
4. **`xcodegen` on PATH** — installed via `brew install xcodegen` in the app-build job because `scripts/check-app-builds.sh` invokes it when `Jarvis.xcodeproj` is missing.
5. **CodeQL Swift extraction** covers only `Bus`, `AgentCore`, `MCP` packages — a representative subset to keep the security lane cheap. Expand if needed.
6. **Codesign** — `verify-entitlements.sh --pre-codesign`/`--post-codesign` only run during a real signed build (they expect Xcode env vars); CI invokes only `verify-codesign-settings.sh`, which has no env deps.
## Real-hardware tests
`JARVIS_REAL_MODELS=1` and `JARVIS_REAL_CAMERA=1` suites are gated on a `[self-hosted, macOS]` runner. To run them:
1. Register a self-hosted macOS runner with Ollama + the required models + camera TCC grants.
2. Actions tab → CI → "Run workflow" → set `run_real_hardware` to `true`.
The job is skipped entirely otherwise; no GitHub-hosted runner will ever try to execute these.
## Morning actions for the user
- [ ] **Optional: set `SEMGREP_APP_TOKEN`** at Settings → Secrets and variables → Actions if you want Semgrep findings posted to Semgrep Cloud. Without it, scans still run with public rules; findings only appear in the workflow log + SARIF upload to the Security tab.
- [ ] **Verify secret scanning is enabled** at Settings → Code security and analysis. This is a repo-level setting; no workflow needed.
- [ ] **Verify Dependabot alerts + security updates** are enabled in the same panel (they already are based on the existing `dependabot.yml`).
- [ ] **Branch protection on `main`** (recommended): require status checks `Boundary gates`, `Webview (pnpm test + build)`, `SPM <pkg>` matrix, `App target (xcodebuild)` to pass before merge; restrict pushes to PRs from `rc/*` / `release/*`.
- [ ] **CircleCI**: this PR does NOT touch `.circleci/`. To stop CircleCI's red checkmarks, either un-wire the integration at Settings → Integrations or re-add a `.circleci/config.yml`. GitHub Actions is now the canonical CI surface — recommend removing CircleCI.
- [ ] **Optional: tighten `dependency-review.yml`** by adding `deny-licenses: GPL-2.0, GPL-3.0, AGPL-3.0` after auditing the existing SPM + npm graph for compatibility.
## Verification
- [x] All five workflow YAML files parse cleanly (`python3 -c "import yaml; yaml.safe_load(...)"`)
- [x] 18 boundary gate scripts confirmed present; 17 wired into the Linux gate job
- [ ] First push to this PR exercises `boundary-gates`, `webview`, `swift-packages` (matrix of 14), `app-build`, `codeql`, `semgrep`, `dependency-review`
- [ ] After merging to `develop`, first push triggers `publish-tag` and creates `v0.1.0-dev.<run_number>`
## Risks / open questions
- **Cost.** Across boundary gates + 14 SPM jobs + app build + CodeQL Swift, expect ~30–60 macOS minutes per PR cycle. If this is too expensive, the SPM matrix can be collapsed to a single representative package or sharded across cron runs.
- **`macos-15` availability.** If GitHub deprecates this image before Xcode 17 lands, swap to `macos-latest`.
- **Tag-publish from develop runs on every push.** If `develop` lands several commits per day this produces a lot of pre-release tags. Easy to throttle: change the trigger to `workflow_dispatch` or restrict via `paths-ignore`.
- **No code signing in CI.** Releases are GitHub Releases only (per project scope — personal, not distributed). The `verify-entitlements.sh` codesign-verification flow only runs during a real signed build.
## Dogfooding
After merge, watch the Actions tab for the first run on `develop`. Expected timeline: boundary gates (~1 min) → webview (~2-3 min) → SPM matrix (~10-15 min) → app build (~5 min) → publish-tag (~30 s).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
End-to-end GitHub Actions pipeline: build, test, scan, validate, security-scan, and tag-publish per branch/semver conventions. Five workflows under
.github/workflows/, plus a CI/CD section inBUILDING.mdand aCODEOWNERSfile.This PR is a draft for review. Workflows have not been executed in CI yet — the first push to this PR is the validation cycle.
actwas not run locally because most jobs require macOS runners thatactcan't simulate.What lands
.github/workflows/ci.ymlmacos-15, app target (xcodebuildviascripts/check-app-builds.sh), optional self-hosted real-hardware lane, tag-publish on push todevelop/rc/release/main.github/workflows/codeql.ymlsecurity-extendedqueries, weekly cron.github/workflows/semgrep.ymlp/default,p/swift,p/typescript,p/secretsrule packs.github/workflows/dependency-review.yml.github/workflows/release.ymlv*tag push; creates a GitHub Release with auto-generated changelog.github/CODEOWNERS@KofTwentyTwoBUILDING.mdBranch + tag strategy (defaults — override if your standards differ)
feature/*,fix/*— PR-only; full build/test/scan; no tag.develop— every push: full CI + pre-release tagv0.X.Y-dev.<run_number>.rc/*andrelease/*— every push: full CI + tagv0.X.Y-rc.N(N auto-increments).main— every push: full CI + tagv0.X.Y+ GitHub Release. Only ever updated via PR fromrc/*orrelease/*.Versioning source: Conventional Commits since the previous final tag.
feat:→ minor bumpfix:→ patch bumpfeat!:orBREAKING CHANGE:footer → major bumpSeed version:
v0.1.0(current roadmap milestone target — see.planning/ROADMAP-2026-05-12.md). No tags currently exist in the repo, so the first push todevelopafter merge would publishv0.1.0-dev.<run_number>.To override these conventions, edit the
branches:lists inci.ymland adjust the case statement in thepublish-tagjob.Assumptions
macos-15. All Swift/Xcode jobs usemacos-15(currently the most recent GitHub-hosted macOS image with Xcode 16+). If you're on a Mac plan that limits macOS minutes, the SPM matrix (14 jobs) and CodeQL Swift job will dominate the budget — consider switching the matrix to a single representative package or a quarterly cron.webview/package.jsonpackageManagerfield).webview/package.jsonenginesfield).xcodegenon PATH — installed viabrew install xcodegenin the app-build job becausescripts/check-app-builds.shinvokes it whenJarvis.xcodeprojis missing.Bus,AgentCore,MCPpackages — a representative subset to keep the security lane cheap. Expand if needed.verify-entitlements.sh --pre-codesign/--post-codesignonly run during a real signed build (they expect Xcode env vars); CI invokes onlyverify-codesign-settings.sh, which has no env deps.Real-hardware tests
JARVIS_REAL_MODELS=1andJARVIS_REAL_CAMERA=1suites are gated on a[self-hosted, macOS]runner. To run them:run_real_hardwaretotrue.The job is skipped entirely otherwise; no GitHub-hosted runner will ever try to execute these.
Morning actions for the user
SEMGREP_APP_TOKENat Settings → Secrets and variables → Actions if you want Semgrep findings posted to Semgrep Cloud. Without it, scans still run with public rules; findings only appear in the workflow log + SARIF upload to the Security tab.dependabot.yml).main(recommended): require status checksBoundary gates,Webview (pnpm test + build),SPM <pkg>matrix,App target (xcodebuild)to pass before merge; restrict pushes to PRs fromrc/*/release/*..circleci/. To stop CircleCI's red checkmarks, either un-wire the integration at Settings → Integrations or re-add a.circleci/config.yml. GitHub Actions is now the canonical CI surface — recommend removing CircleCI.dependency-review.ymlby addingdeny-licenses: GPL-2.0, GPL-3.0, AGPL-3.0after auditing the existing SPM + npm graph for compatibility.Verification
python3 -c "import yaml; yaml.safe_load(...)")boundary-gates,webview,swift-packages(matrix of 14),app-build,codeql,semgrep,dependency-reviewdevelop, first push triggerspublish-tagand createsv0.1.0-dev.<run_number>Risks / open questions
macos-15availability. If GitHub deprecates this image before Xcode 17 lands, swap tomacos-latest.developlands several commits per day this produces a lot of pre-release tags. Easy to throttle: change the trigger toworkflow_dispatchor restrict viapaths-ignore.verify-entitlements.shcodesign-verification flow only runs during a real signed build.Dogfooding
After merge, watch the Actions tab for the first run on
develop. Expected timeline: boundary gates (~1 min) → webview (~2-3 min) → SPM matrix (~10-15 min) → app build (~5 min) → publish-tag (~30 s).🤖 Generated with Claude Code