CI/CD
CareerVector uses normal CI/CD as the quality spine. The quality service and story taxonomy support CI; they do not replace it.
Ownership
| Surface | Owner | Reason |
|---|---|---|
| Fast gate (common case) | Crow CI (.crow/ci.yaml) |
Typecheck + unit tests on the corbet-devops Crow agent on push; replaces the CircleCI fast lane for the common case. |
| Default browser/e2e tests | CircleCI | Browser, perf, artifacts, and parallelism belong in the main CI runner. |
| Release promotion | CircleCI runner job | Release/build jobs run on the self-hosted runner and publish artifacts explicitly. |
| Jobcache scraping | sporewright orchestrator (alwaysdata) | The CircleCI jobcache_planner/jobcache_keepalive jobs were deleted; the orchestrator is the sole scraping driver — scraping is not CI work. |
| Off-fleet Rust compile gate | GitHub Actions (rust-check.yml) |
Dispatch-only escape hatch while the fleet cannot run cargo; see below. |
| Local/agent gate ledger | tools/quality |
Agents and humans need named gates and auditable local run records. |
Do not make tools/quality a second CI system. It should stay a thin
runner/ledger and may later read CircleCI job results.
CircleCI
.circleci/config.yml is the default test scaffold.
All runner jobs are CircleCI jobs on resource_class: corbet/unraid
(self-hosted k3s on Unraid). Push/default pipelines stay dark unless a QA/API,
MCP, or human dispatches a named only_job.
Jobs:
fast: install, typecheck, unit/contract tests, story-coverage audit, paid-forbidden sentinel, and flakiness budget through the root Bun workspace scripts.jobcache_fast: JobCache package checks and tests.rust_workspace: Rust workspace check + test gate.desktop_release_linux: Linux desktop release build (Tauri bundles) and GitHub Release publish ondesktop-v*tags.browser_qa: local app boot plustest:qa:core.browser_cutover: curated cutover browser contract gate, not the full historical Playwright tree.browser_stories/browser_contracts/browser_dashboard/browser_cvl/browser_realtime/browser_smoke: themed browser suites over curated spec lists.playwright_specs/vitest_specs: generic spec dispatch driven by thespecspipeline parameter.runner_smoke: tiny canary proving the CircleCI → corbet/unraid (k3s pod) runner path is alive.perf: local app boot plus enforced Playwright performance budgets.
Jobcache scraping (planner + keepalive) is NOT a CI job: the
jobcache_planner/jobcache_keepalive jobs were deleted, and the sporewright
orchestrator on alwaysdata is the sole scraping driver.
Each browser job uses its own port and .wrangler-e2e state id so concurrent
jobs do not share local D1 files.
Crow fast gate
.crow/ci.yaml runs the fast gate (install, bun run check, bun run test)
on the corbet-devops Crow agent (kubernetes backend, one pod per step) on
push/manual. It replaces the CircleCI fast lane for the common case; the
heavier browser/e2e lanes stay on CircleCI because they need a per-job
wrangler dev and are bound by the CF free-tier quota policy.
GitHub Actions
.github/workflows/rust-check.yml is a dispatch-only, off-fleet Rust compile
gate (gh workflow run rust-check.yml): cargo check --locked + unit tests
for crates/jobcache-device and crates/sporewright-server on GitHub
runners. No push trigger, no deployable artifact, no Cloudflare traffic;
delete it once Crow grows a Rust lane. (cratedb-keepalive.yml is the
secondary CrateDB keepalive, not a test lane.)
Budget Policy
Default CI is zero-budget:
- no live LLM calls
- no live scraper spend
- no quota-heavy production sweeps
- no deployed smoke unless explicitly requested
Live provider journeys, deployed realtime proof, and migration proofs against real D1 snapshots are manual or release-gate work. They must be named, explicit, and artifact-producing.