Skip to main content

Three-Plane CI Setup

InfoConnect CI has three execution planes. The control plane is the fast, required pull-request gate. Blacksmith runs the heavy GitHub Actions jobs. CircleCI runs the non-blocking nightly batch workflow.

Plane map

PlaneConfigurationWorkloadsMerge policy
GitHub control.github/workflows/control-plane.ymlRuff lint and format, Python just typecheck, frontend typecheck and lint, Python/docs/frontend license auditsRequired
Blacksmith heavy.github/workflows/ci.ymlQdrant-backed pytest and coverage, issue #108 acceptance, docs/frontend production builds, frontend tests and bundle sentineltest is the merge gate; the remaining active heavy checks are visible, non-blocking evidence
CircleCI batch.circleci/config.ymlNightly Python lint/format/typecheck and advisory license audit, docs/frontend license and quality checks, issue #108 acceptance, real-Qdrant isolation and coverage, docs build, and frontend tests/build/sentinelNon-blocking

Cloudflare Pages deployment and release workflows remain on stock GitHub-hosted runners.

Provider status

Blacksmith

The Blacksmith GitHub App is installed for the NeuralEngine-AI organization, has access to infoconnect-search-engine, and provides the blacksmith-2vcpu-ubuntu-2404 label used by all four heavy jobs. The control plane remains on ubuntu-24.04. No self-hosted runner registration is required.

CircleCI repository connection and schedule

CircleCI is connected through the GitHub OAuth integration for github/NeuralEngine-AI/infoconnect-search-engine. The pipeline definition reads .circleci/config.yml, and the existing VCS trigger watches all pushes.

The checked-in justfile owns the nightly phase recipes and the advisory Python license verdict, while .circleci/config.yml invokes those recipes and owns the run_nightly guard. The parameter defaults to false; the nightly-regression workflow still runs only when an external trigger supplies true. The nightly-regression-schedule workflow invokes the same job directly from CircleCI's config-file scheduler.

Every nightly check runs in one nightly-regression-suite job on CircleCI's Docker small resource class (cimg/python:3.11-node plus the pinned Qdrant service container). The suite mirrors every active non-security control and heavy check. It does not attach the restricted infoconnect-ci context because no current step needs a secret, which allows the CircleCI scheduling system to own the run.

Required schedule

The config file declares the schedule; no captain UI action remains:

nightly-regression-schedule:
triggers:
- schedule:
cron: "0 2 * * *"
filters:
branches:
only:
- main

CircleCI's config scheduler runs the shared nightly batch plane every day at 02:00 UTC on main. The schedule cannot set run_nightly; the existing parameter-gated workflow remains available for valid user/API-triggered pipelines, while the scheduled workflow selects the same nightly-regression-suite job directly. This keeps one job graph and does not create a second nightly command convention.

Permission denied diagnosis

The manual trigger recorded in PR 211 returned Permission denied, and live inspection initially showed an empty branch picker. The pipeline definition and all-pushes trigger were present, so the failure occurred while CircleCI resolved repository branches through the triggering user's GitHub OAuth grant, before config execution or restricted-context authorization.

Opening https://app.circleci.com/settings/user and selecting Refresh permissions restored the displayed dnth and NeuralEngine-AI connections. A second manual-trigger check could select fm/ic-ci-3plane-followup for both config and checkout sources, auto-filled run_nightly, and enabled Run pipeline. Submitting that authorized-looking form with run_nightly=true still returned Permission denied; no CircleCI pipeline was created. Refreshing CircleCI's permission cache is therefore insufficient.

Only the CI captain may perform CircleCI's full GitHub re-authentication: sign out of CircleCI, open GitHub Settings → Applications → Authorized OAuth Apps → CircleCI, select Revoke access, clear CircleCI browser cookies, then sign back into CircleCI through GitHub and grant NeuralEngine-AI access. GitHub organization approval or SSO authorization may require a NeuralEngine-AI owner. Full re-authentication clears CircleCI user keys, so automation and other contributors must not perform it.

After full GitHub OAuth re-authentication, a captain may still trigger a feature branch with boolean run_nightly=true to validate the manual path. A created pipeline whose nightly-regression workflow starts nightly-regression-suite is the execution evidence; config validation or an enabled Run pipeline button is not execution evidence.

The config-file schedule removes the former captain-owned post-merge scheduling step. The first scheduled pipeline after this change should be attributed to the config-file schedule and should start nightly-regression-schedule on main at its configured 02:00 UTC window.

Security follow-up

The GitHub Actions security job remains disabled with if: ${{ false }}. Its gitleaks, pip-audit, Semgrep, Docker smoke, and Trivy body remains intact for a separate re-arm.

CircleCI's nightly intentionally excludes all security scans, Docker runtime smoke, Trivy scans, and their artifacts. Those checks remain wholly owned by ic-security-rearm.

Follow-up issue ic-security-rearm owns the security re-arm and the PYSEC-2026-3716 remediation. This CI quota follow-up makes no datasets dependency or pip-audit remediation change.

Secrets, contexts, and variables

Secret names below are exact; values must be provisioned in the named provider and must never be committed.

GitHub Actions

NameScopeUseCurrent status
CODECOV_TOKENRepository or organization secretCodecov authentication for the preserved test coverage upload when the Codecov project requires token authNo repository-level value was visible to this task's GitHub token; tokenless upload remains supported if Codecov accepts it
CLOUDFLARE_API_TOKENRepository or organization secretExisting Cloudflare Pages deploy workflowReferenced by .github/workflows/cloudflare-pages.yml; verify the organization-level secret if deployment runs
CLOUDFLARE_ACCOUNT_IDRepository or organization secretExisting Cloudflare Pages deploy workflowExisting repository secret
DOCKERHUB_USERNAMERepository or organization secretFuture registry push onlyNot used or required: security builds images locally
DOCKERHUB_TOKENRepository or organization secretFuture registry push onlyNot used or required: security builds images locally

The deferred Blacksmith security job builds local infoconnect-api and infoconnect-embedding images for smoke and Trivy scans when ic-security-rearm removes its disabled guard. It does not push to a registry, so that follow-up requires no registry credential.

CircleCI

NameScopeUseCurrent status
infoconnect-ciExisting restricted CircleCI contextReserved for future provider-side valuesNot attached; the active nightly needs no secret
CODECOV_TOKENinfoconnect-ci context variable, only if neededFuture CircleCI Codecov uploadNot used by the current config; add it to the context rather than as a project plaintext variable

The CircleCI schedule needs no project token or secret. GitHub OAuth supplies repository access only after the CI captain completes the full re-authentication flow above.

Branch protection recommendation

Require these GitHub checks before merging into main:

  • The three checks from Control Plane: Python quality and license audit, Docs dependency license audit, and Frontend quality and license audit.
  • Blacksmith test (the Qdrant-backed pytest and Codecov job).

Keep issue #108 acceptance, docs build, frontend tests/build/sentinel, CircleCI nightly, and the disabled security follow-up non-blocking. Do not make the nightly batch a merge gate; it is intentionally scheduled and may be delayed by CircleCI jitter.

Validation commands

Run these checks when editing the provider workflow or CircleCI config:

go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 \
-ignore 'label "blacksmith-2vcpu-ubuntu-2404" is unknown' \
.github/workflows/ci.yml .github/workflows/control-plane.yml
uvx --from yamllint yamllint \
-d '{extends: relaxed, rules: {line-length: disable}}' \
.github/workflows/ci.yml .github/workflows/control-plane.yml .circleci/config.yml
circleci config validate .circleci/config.yml

When the CircleCI CLI is not installed, use the official container instead:

docker run --rm -v "$PWD:/repo" -w /repo \
circleci/circleci-cli:latest circleci config validate .circleci/config.yml

The CircleCI nightly contains no placeholder or future-suite job. Security scans remain deliberately disabled and owned by ic-security-rearm.