This branch removes the GitHub Actions shadow CI layer (pre-merge.yml, apple-mini-validate.yml, repo-secrets-smoke.yml) and the forge-github-ci-shim.py bridge script, consolidating all CI orchestration onto the canonical forge service at git.pikachat.org. Path filters in ci/forge-lanes.toml and the pikaci Rust crate are cleaned of references to the deleted workflow files and GitHub-only helper scripts. Apple remote lanes switch from the GitHub-step wrapper (pikaci-apple-github-step / with-pikaci-apple-ci-env) to the direct pikaci-apple-remote.sh entrypoint. The pikaci catalog drops the now-unused shadow_recipe field from every staged Linux target. Guardrail tests, documentation, justfile recipes, Nix derivations, and shell helper libraries are all updated to reflect the forge-only CI model.
Tutorial Steps
Delete GitHub Actions workflow files
Intent: Remove the three GitHub Actions workflow definitions that provided advisory shadow CI, Apple mini validation, and repo-secrets smoke testing. These responsibilities are now fully handled by the canonical forge service.
The entire .github/workflows/pre-merge.yml (322 lines), .github/workflows/apple-mini-validate.yml (105 lines), and .github/workflows/repo-secrets-smoke.yml (27 lines) are deleted.
pre-merge.yml contained the full shadow CI matrix: branch lane selection via forge-github-ci-shim.py, nightly scheduling, staged Linux SSH setup, Apple remote Tailscale joins, and summary jobs. apple-mini-validate.yml was a manual-dispatch workflow for narrow Apple mini validation with sanity and bundle lanes. repo-secrets-smoke.yml was a manual-dispatch workflow that decrypted repo secrets and ran helper tests.
All three are superseded by forge-native orchestration from ci/forge-lanes.toml.
Remove the forge-github-ci-shim bridge script and its tests
Intent: Delete the Python shim that translated ci/forge-lanes.toml into GitHub Actions matrix JSON, along with its test suite. With the GitHub workflows gone, this bridge is no longer needed.
The scripts/forge-github-ci-shim.py script (489 lines) provided select and run subcommands that parsed ci/forge-lanes.toml, computed changed paths against a base/head diff, and emitted GitHub Actions matrix JSON via --github-output. Its companion test file scripts/test_forge_github_ci_shim.py (459 lines) is also removed.
References to this shim in ci/forge-lanes.toml path filters (e.g. scripts/forge-github-ci-shim.py as a trigger path for the pikachat-typescript lane) are cleaned up in a subsequent step.
Remove GitHub-specific Apple CI helper scripts
Intent: Delete the GitHub-step wrapper scripts that were used exclusively by the GitHub Actions Apple workflows. The direct pikaci-apple-remote.sh script replaces them.
scripts/pikaci-apple-github-step (336 lines) was the GitHub-specific Apple CI orchestrator that handled tailscale-up and remote-run subcommands, mapped sops secrets to env vars, and wrote GITHUB_OUTPUT artifacts. scripts/with-pikaci-apple-ci-env (148 lines) was the secret-loading wrapper that decrypted sops/age secrets and exported them into the subprocess environment. scripts/write-pikaci-apple-github-env (36 lines) wrote Apple CI config to GITHUB_ENV.
All Apple remote CI now goes through ./scripts/pikaci-apple-remote.sh run --just-recipe <recipe> directly, which handles its own secret loading without GitHub-specific plumbing.
Remove pikaci-tools.sh shell library and its tests
Intent: Delete the shared shell library that provided JSON parsing helpers used by the now-removed GitHub workflow scripts.
scripts/lib/pikaci-tools.sh (103 lines) provided pikaci_tools_json_string, pikaci_tools_json_object, and pikaci_tools_json_array functions used by the GitHub Apple step scripts to build structured JSON output. scripts/test_pikaci_tools_json.py (93 lines) was its Python test harness.
With the GitHub-specific scripts removed, this library has no remaining consumers.
Remove sops secret helper tests
Intent: Delete the test suite for sops secret decryption helpers that were only exercised through the GitHub workflows.
scripts/test_sops_secret_helpers.py (93 lines) tested the check-repo-secret-files script's sops decryption paths. This was invoked by the now-deleted repo-secrets-smoke.yml workflow. The check-repo-secret-files script itself is also deleted.
Clean forge-lanes.toml path filters and update Apple lane entrypoints
Intent: Remove .github/workflows/pre-merge.yml from trigger path lists across all forge lanes, drop the forge-github-ci-shim.py reference, remove GitHub-only Apple script references, and switch Apple lane commands to the direct pikaci-apple-remote.sh entrypoint.
Eight lane definitions in ci/forge-lanes.toml had .github/workflows/pre-merge.yml in their paths array; all are removed. The check-pikachat-typescript lane also drops scripts/forge-github-ci-shim.py.
The apple_host_sanity branch lane and nightly_apple_host_bundle nightly lane both switch their entrypoint and command fields from ./scripts/pikaci-apple-github-step remote-run to ./scripts/pikaci-apple-remote.sh run. The Apple sanity lane's path filter also drops scripts/pikaci-apple-github-step and scripts/with-pikaci-apple-ci-env.
Drop shadow_recipe field from pikaci staged Linux target catalog
Intent: Remove the shadow_recipe field from the PikaStagedLinuxTargetConfig struct and all target configurations, since shadow recipes were only used by the GitHub Actions shim.
The shadow_recipe field is removed from three locations:
The PikaStagedLinuxTargetConfig struct definition
Every match arm in PikaStagedLinuxTarget::config() — ten targets total (PreMergePikaRust, PreMergePikaFollowup, PreMergeAgentContracts, PreMergeNotifications, PreMergeFixtureRust, PreMergeRmp, PreMergePikachatRust, PreMergePikachatTypescript, PreMergePikachatOpenclawE2e)
The PikaStagedLinuxTargetInfoJson struct and its From impl
The main.rs entrypoint also removes the line println!("shadow_recipe={}", shell_escape(config.shadow_recipe)); from the target-info subcommand output.
Remove shadow_recipe from pikaci main.rs and update test fixtures
Intent: Clean up the main CLI entrypoint and its inline test to remove references to the deleted GitHub workflow and shadow recipe output.
The target-info subcommand no longer emits shadow_recipe=... to stdout
The target_spec function for pre-merge-pikachat-apple-followup drops .github/workflows/pre-merge.yml from its hardcoded filter list
A test assertion that used .github/workflows/pre-merge.yml as a sample path for glob matching is updated to use .github/workflows/release.yml instead (a file that still exists)
Drop shadow_recipe from pikaci model tests
Intent: Remove all shadow_recipe fields and assertions from the model test suite's mirror of the staged Linux target catalog.
@@ -1335,7 +1312,6 @@ mod tests {
- let config = lane.target().config();
- assert_eq!(config.shadow_recipe, "pre-merge-rmp-shadow");
The test-only StagedLinuxRustTargetConfig struct in model.rs tests drops its shadow_recipe field. All ten enum variant configs remove their shadow_recipe values. Six assert_eq! calls that verified shadow_recipe values are deleted across the notifications, followup, fixture, pikachat, pikachat_typescript, pikachat_openclaw, and rmp lane test functions. Two test functions also remove now-unused _config variable bindings.
Update guardrail tests to target forge-only CI artifacts
Intent: Rewrite pikahut guardrail tests that previously validated constraints against .github/workflows/pre-merge.yml to validate against ci/forge-lanes.toml and just/checks.just instead. Remove tests that only made sense with the GitHub workflow in place.
Major changes to crates/pikahut/tests/guardrails.rs:
Filter extraction parser updated: extract_pikaci_target_filters now recognizes filters: static_filters(&[ in addition to filters: &[, and the closing-bracket detection handles ]), ]),, and ])}, variants.
Reference scanning pivots: selector_references_in_docs_and_lanes_exist scans just/checks.just instead of .github/workflows/pre-merge.yml.
Regression guard pivots: required_lanes_do_not_regress_to_cli_test_harness reads just/checks.just instead of the workflow file.
Removed cross-validation against pikaci filters: Several tests (pre_merge_pikachat_filter_tracks_checked_in_lane_surface, pre_merge_agent_contracts_filter_tracks_checked_in_lane_surface, pre_merge_notifications_filter_tracks_checked_in_lane_surface, pre_merge_fixture_filter_tracks_checked_in_lane_surface) previously extracted pikaci target filters from main.rs and asserted they were a subset of forge lane paths. These cross-checks are removed — the forge lane paths in ci/forge-lanes.toml are now the single source of truth.
Deleted test: pre_merge_fixture_remote_lane_skips_fork_pull_requests is entirely removed, as it validated GitHub-specific behavior (checking for PIKA_BUILD_SSH_KEY secret references in the workflow).
Apple and infra selector scanning: Updated to scan just/checks.just instead of the workflow file.
Update documentation to reflect forge-only CI model
Intent: Remove all references to GitHub shadow CI, the forge-github-ci-shim, and GitHub-specific Apple CI plumbing from project documentation.
@@ -1,7 +1,7 @@ docs/agent-ci.md
- - changing provider CI gating in `.github/workflows/pre-merge.yml`
+ - changing provider CI gating in `ci/forge-lanes.toml`
@@ -11,7 +11,7 @@ docs/agent-ci.md
-These lanes are defined canonically in `ci/forge-lanes.toml` and orchestrated by the forge on `git.pikachat.org`. GitHub mirrors them through `.github/workflows/pre-merge.yml` as advisory shadow CI:
+These lanes are defined canonically in `ci/forge-lanes.toml` and orchestrated by the forge on `git.pikachat.org`.
@@ -55,22 +55,19 @@ docs/pikaci-apple-remote-access.md
-The narrow GitHub live-validation entrypoint is the dedicated `apple-mini-validate` workflow.
+Use the direct Apple remote wrapper when you want the narrow live-validation path:
@@ -13,13 +13,9 @@ docs/rmp-ci.md
-- GitHub workflow: `.github/workflows/pre-merge.yml` as advisory shadow CI
-- GitHub shadow approval gate:
Documentation updates across seven files:
agent-ci.md: read_when frontmatter and body text now point to ci/forge-lanes.toml instead of the GitHub workflow. Removes mention of GitHub as advisory shadow CI. Nightly probes section drops "with GitHub mode=nightly as an advisory mirror".
compatibility-testing-spec.md: Nightly lane reference updated from .github/workflows/pre-merge.yml to ci/forge-lanes.toml.
pikaci-apple-remote-access.md: Replaces the gh workflow run apple-mini-validate.yml examples with direct ./scripts/pikaci-apple-remote.sh run invocations. Removes paragraphs about GitHub workflows mapping AGE_SECRET_KEY to SOPS_AGE_KEY, step-local secret loading via with-pikaci-apple-ci-env, and the GitHub-side dependency on AGE_SECRET_KEY.
rmp-ci.md: Removes all GitHub workflow and shadow approval gate references from both pre-merge and nightly sections. Drops the note about forge-github-ci-shim.py.
ci-selectors.md: Policy class descriptions change from "GitHub pre-merge" to "canonical forge CI". Apple lane command references switch from pikaci-apple-github-step to pikaci-apple-remote.sh. The "Apple Live Validation Workflow" table section is entirely removed.
integration-matrix.md: Similar reference updates.
pika-git/README.md: Removes the bullet about GitHub mirroring via forge-github-ci-shim.py.
Update justfile and checks.just recipes
Intent: Remove justfile recipes and references that targeted the deleted GitHub workflow and shim script, and update check recipes accordingly.
@@ -5,13 +5,6 @@ just/checks.just
-# Run the GitHub CI shim selector for branch mode
-ci-shim-select-branch *ARGS:
The justfile loses several shadow recipes: pre-merge-pika-rust-shadow, pre-merge-pikachat-rust-shadow, pre-merge-agent-contracts-shadow, pre-merge-notifications-shadow, pre-merge-rmp-shadow, and nightly-shadow. These all invoked forge-github-ci-shim.py run --mode branch/nightly --lane-id <id>.
just/checks.just loses the ci-shim-select-branch and ci-shim-select-nightly recipes that wrapped the shim's select subcommand, plus the ci-shim-test recipe that ran the shim's Python test suite.
Update Nix derivation and flake to remove shim dependency
Intent: Remove the forge-github-ci-shim from the Nix CI check derivation's file list and from the flake's lint/check targets.
nix/ci/linux-rust.nix removes scripts/forge-github-ci-shim.py from the source file list copied into the CI sandbox.
flake.nix removes the forgeGithubCiShimTest check derivation that ran python3 scripts/test_forge_github_ci_shim.py, the pikaci-tools-json-test derivation that ran scripts/test_pikaci_tools_json.py, and the sopsSecretHelpersTest derivation that ran scripts/test_sops_secret_helpers.py. The shellcheck-scripts derivation is also updated to remove the deleted scripts from its input list.
Remove check-repo-secret-files script
Intent: Delete the repo secret validation script that was only invoked by the deleted repo-secrets-smoke workflow.
scripts/check-repo-secret-files (57 lines) iterated over sops-encrypted files in the secrets/ directory, decrypted each one, and verified the decryption succeeded. It was invoked exclusively by repo-secrets-smoke.yml. With that workflow gone, the script has no remaining caller.