Repository navigation
ci: rebuild CI around one fast required check (ci-ok) - #1315
Conversation
|
Maple Auth development preview: https://5b731d43.maple-auth-dev.pages.dev Commit: Uses development services. Cloudflare Access applies. Provider OAuth is not configured for PR URLs; use the stable Auth Dev host for OAuth rehearsal. |
|
Maple development preview: https://c293e7af.maple-ca8.pages.dev Commit: Uses development API, billing, flags and PCR configuration. Cloudflare Access applies. |
ff1a842 to
cc623ef
Compare
|
This PR's own runs (every gate lane, packaging, Research Android and the EIF candidate; all cold, since PRs never save caches). Run 1 (40453021288) found four problems:
Run 2 (40455950361): all green,
Ordinary PRs select far fewer lanes than this CI-infra PR does, and run warm once master has saved caches. Packaging and Android only run when their own paths change or on a label. Both EIF candidates were substituted from FlakeHub, so their outputs are identical to master's existing builds; the dev PCR0 equals |
21092f1 to
16166d7
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…vate the repo lane The manual Windows signature probe's `actions: read` moves from the workflow to its one job, as the read-only workflow-permissions policy requires; the job's token is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…om ci.yml Activate the remaining Agent lanes (full Linux/macOS/Windows suites, supply chain, provider, store bench, PR packaging rehearsals), add nightly.yml with one ci-nightly issue, make agent-desktop-build.yml master-only with exact-key release caches and a Blacksmith Windows builder, and delete agent-ci.yml, the SQLCipher and store workflows and the dependency archive, cache-scope, measurement and selector scripts. test_windows_updater_workflow.py reads the Windows Rust pin from setup-agent-windows, which windows-build now uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Activate the sdk-ts, sdk-rust, proxy, deps-{research,sdk,proxy},
proxy-container(-arm64), research-web, research-rust, research-ios,
research-android, research-desktop-{macos,linux,windows}, research-dev-macos,
auth, updates and agent-updates lanes. PR lanes restore only caches that
master writes and never save one. frontend-tests, web-build and rust-tests
become push-only evidence twins (rust-tests on Blacksmith, writing
ci-v1-research-rust); proxy-rust keeps only the release rehearsal. Delete the
twelve workflows these lanes replace.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…docs Signed Research workflows get job timeouts and job-level OIDC and attestation scopes; Maple Dev TestFlight builds only for Research web or iOS inputs (dispatch always builds); CodeQL runs on every master push, per SHA, never cancelled. The temporary policy and contract allowlists are gone. The pre-commit hook selects components with `plan.py hook --staged` from the lane table, and the Agent hook runs the agent-lint and agent-test recipes. docs/ci.md is new, docs/repository-workflows.md is rewritten, AGENTS.md gains CI rules for agents, and the unused flake apps.ci-* outputs are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- os-sdk-e2e and os-helpers select on their own entry scripts; the OpenSecret selector routes inert paths too, so its routing is verbatim - widen the Agent packaging selector to the scripts packaging calls, the Agent flake and (macOS) the Xcode pin; agent-windows runs the native Windows tests; acp-only and proxy-only clippy move into ci-lint - os-eif: PRs to master only, plus a ci:eif label; os-flake-check builds the x86_64 package again; opensecret-eif.yml runs on every PR to master - ci-ok calls `plan.py verdict`; lint checks special jobs' runners and timeouts; setup-bun saves no PR cache; agent-test on 32 vCPU - ci.yml's nightly run covers deps and supply chain; the reporter needs today's scheduled run - drop PR-only scripts from the signed-build selector; Auth push paths rehearse publisher edits again; docs fixes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep services/opensecret/ byte-identical to master, as the OpenSecret port requires: restore its README, nitro-deploy.md and hook comment. The C7 docs contract skips that subtree; its docs move with OpenSecret PRs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…package build - opensecret_change_detection.py lists services/agent-updates/ as an independent root. Since #1214 every agent-updates change selected every OpenSecret check, including both EIF builds. Unknown roots still select every check. - os-flake-check runs only the component `nix flake check`. Nothing consumed the x86_64 `#default` package: the shipped EIF is aarch64, and os-rust, os-sdk-e2e and the EIF lanes compile and test the same code. - deps-opensecret follows its own Cargo.toml, Cargo.lock and deny.toml instead of the selector's `audit` output, which CI files also trigger. CI edits no longer select any deps lane, so new RustSec advisories surface in the nightly run instead of failing unrelated PRs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…not failed check_opensecret_eif.sh exits 3 for a PCR mismatch and prints the built pcr.json; usage, build and comparison failures keep their non-3 statuses (a Nix build failure is now always 1, never 3). opensecret-eif.yml's compare step, identical in eif and eif-trusted: - master push or dispatch: a mismatch is a notice, with the built PCRs in the step summary, and the job passes; - pull_request: a mode must match only if the PR's own diff (merge base to head, SHAs through env) edits that mode's pcr<Env>.json or pcr<Env>History.json; otherwise its mismatch is a notice; - dispatch outside master: a mismatch fails, as before; - any other non-zero status fails. Job conditions, runners, permissions, cache steps and the matrix are unchanged; opensecret-eif-release.yml does not call the script. services/opensecret/README.md and docs/nitro-deploy.md now name ci.yml instead of the deleted workflows and describe the new verdicts, so C7 no longer skips services/opensecret/. The eif-dev and eif-prod derivations are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- opensecret-eif.yml: the EIF compare step accepts only full 40-hex PR base and head SHAs before it diffs the approval files. Anything else fails the job, so an option-like or abbreviated value cannot make an edited mode's mismatch look neutral. Both approval jobs keep the same step; test_contracts covers option-like and abbreviated SHAs. - docs/ci.md: the advisory rule is scoped to the deps-* lanes, and names the two gate lanes that still audit advisories (agent-supply-chain, sdk-ts). - services/opensecret/.githooks/pre-commit: the comment names ci.yml's os-rust and os-flake-check lanes and drops the removed package build. Comment lines only; the eif-dev, eif-prod and eif-preview drvPaths are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new Windows Clippy lane is the first CI job to lint the Agent's cfg(windows) code. Both findings are intentional, so they get a scoped allow with the reason; behaviour is unchanged: - filesystem_kind joins "\" to the path prefix on purpose: joining a rooted path keeps the prefix, so C: becomes C:\ for GetDriveTypeW. - The Windows-only hard-link cleanup test clears the read-only attribute, not Unix mode bits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first ci.yml run timed out agent-lint and agent-supply-chain at 15 minutes on a cold cache, and a lane that times out never saves its cache. Timeouts now cover a cold run (lint and test 40, supply chain 30). The lint lane joins agent-test on the 32 vCPU runner, since it is on the Agent PR path whenever a dependency bump misses the cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Agent PR packaging rehearsals build with thin LTO and 16 codegen units. They prove the packaging scripts, not the optimizer; master's signed builds keep fat LTO. A profile change rebuilds every dependency, so the rehearsals keep their own cache, which ci.yml's nightly master run saves. - research-android restores the Research Rust cache rust-tests.yml writes. Cargo fetches every git dependency in the lockfile for any target, so the Android build was spending most of its time fetching Goose and PDFOxide. - The store benchmark leaves CI: no ci:perf lane and no nightly job. The crate and `just store-bench` remain for local runs. - docs/ci.md, AGENTS.md and the Agent skill say when a label is worth adding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1316 (signed Windows Agent updates) landed while this branch moved the Windows jobs. Carry its contracts over: - agent-package-windows replaces the deleted PR-only windows-unsigned job, so it now exports MAPLE_PACKAGE_BUILD_NUMBER, which windows-release.py requires: the Actions run number, or 1 outside Actions (as package-release.sh does), so `just lane agent-package-windows` still runs locally. - test_contracts C2 asks the publisher to trust a run with Windows too, and pins MAPLE_PACKAGE_BUILD_NUMBER to github.run_number on every job that packages or verifies Windows (the assertion #1316 added to the deleted test_agent_workflows.py). - The manual signature probe checks that each Windows Prod job ran on windows-2025. The unsigned build now runs on Blacksmith, so the build job may also report blacksmith-8vcpu-windows-2025 (signing and verification still must be GitHub's). A new C2 contract runs the probe's producer check against this workflow's jobs and runners. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agent-windows-updater-tests.yml (from #1316) becomes the agent-windows-updater lane, reported by ci-ok: - Selected by the workflow's own paths on pull requests, the merge queue and master pushes alike, by ci:windows and ci:full, by CI edits, and nightly. Only the deleted workflow's own path is dropped. - It runs scripts/ci/windows-app-typecheck.ps1, then scripts/ci/windows-updater-tests.ps1, unchanged, with pwsh from the repository root and the workflow's environment (RUSTFLAGS -D warnings, CARGO_TERM_COLOR never, no incremental build, no debug info). Both always run, as the two parallel jobs did, and either failure fails the lane. - A special ci.yml job keeps both receipts and Cargo logs as one artifact even on failure. It uses setup-agent-windows, the pinned Rust, MSVC, native Perl and linker the workflow set up by hand, and restores no cache. The fxc selection is not carried over: GPUI compiles shaders only in builds without debug assertions, so a dev-profile cargo check never runs fxc. - It runs on the Windows lane runner (Blacksmith, CI_WINDOWS_RUNNER to fail over) instead of GitHub's windows-2025. The native reparse fixtures need the symlink privilege, so this PR's own run is the first proof on Blacksmith. test_windows_updater_workflow.py now tests the lane, the job and the scripts instead of the workflow's YAML: no authority, the pinned toolchain and no cache, selection through the planner, both scripts running (with a stub pwsh) and the retained evidence. The script assertions are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- agent-package-windows also runs on its own Windows inputs: the Windows packaging scripts, build-release.sh (its Windows branch), release-info.py, the release profile files and the Windows toolchain. #1316 put Windows on the Agent feed, and on master every Agent PR built, installed and smoke-tested an unsigned Windows package; label-only selection assumed Windows was not published. ci:package and ci:full still add it. - test_contracts C2 evaluates each agent-desktop-build.yml job's `if:` and `needs` for a master push and a dispatch, so a condition that skips a Prod job the publisher requires fails the contract. Bare true, false and null evaluate as GitHub's literals. - A new C2 contract runs every lane that calls windows-release.py package or verify with stand-ins and checks they receive MAPLE_PACKAGE_BUILD_NUMBER: the Actions run number, or 1 outside Actions. - C7 also checks quoted or bold workflow display names in docs; updates.md named the deleted Agent Windows Updater Tests workflow and now names the agent-windows-updater lane. - magic-nix-cache-action counts as a cache writer unless use-gha-cache is disabled. opensecret-eif.yml's eif job (fork PRs that edit approvals, manual runs outside master) is the one exempt pull-request writer: no FlakeHub, no id-token, branch-scoped cache. The workflow is unchanged; the cache docs now name the exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first Blacksmith run of agent-windows-updater failed one native test: the updater's storage validation rejects the test image because Blacksmith's workspace inherits a foreign write ACE, which GitHub's workspace does not. The validation is right, and #1316 proved these tests on windows-2025, so agent-windows-updater and agent-full-windows (which runs the same tests) use GitHub's image again. The Windows Clippy lane and the unsigned builds stay on Blacksmith. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Windows Clippy lane is the first CI job to lint #1316's Windows-only updater code. Five mechanical fixes, no behaviour change: three collapsible ifs (two as let chains), a range check written with RangeInclusive::contains, and PROCESSENTRY32W built with its size in the initializer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run 5 built, packaged and verified the unsigned Dev installer on Blacksmith, then the installer smoke test (setup.exe /S into a temporary directory) failed there. Master's install smoke for the same installer runs on GitHub's windows-2025 (agent-desktop-build.yml verify-windows), which also passes the updater's native tests, so the PR rehearsal runs there too. It no longer restores master's Blacksmith-written release cache, which a GitHub runner cannot read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…earsal Run 6 cancelled research-rust at its 20-minute timeout: 14.7 minutes went to Cargo fetching Goose's git history before master's Research cache exists. research-rust and research-android get 45 minutes. The Windows packaging rehearsal uses the same thin-LTO profile as the Linux and macOS ones; master's signed Windows build keeps fat LTO. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1bc9a41 to
3e74486
Compare
What this does
This PR replaces Maple's pull-request CI with one workflow,
ci.yml, and one required check,ci-ok.scripts/ci/lanes.py, defines every check (a "lane"): its paths, events, labels, runner, Nix shell, command and timeout.scripts/ci/plan.pyreads the diff and picks the lanes.ci-okpasses only when every picked lane passed.just lane <id>read the same table, so every lane also runs on a laptop.Why. Over 10-10..10-26 (6,000 runs):
cancel-in-progresscancelled Agent CI on 36 of 136 commits. With the red-by-design EIF approval status, only 40% of master commits had every workflow green.Before and after
"Before" is measured from the 10-10..10-26 run data. "After" is an estimate; this PR's own run is the first measurement.
agent-teston 32 vCPU: a cold clippy + test build took 6m22s, against 11m25s on 8 vCPU)services/agent-updates/)agent-updatesonlyci.yml+ the EIF approval workflow), +1 for a Pages/Auth previewdeps-*audits block only PRs that change that manifest, lockfile ordeny.toml; otherwise the nightly opens oneci-nightlyissueci-okTiers
git commitjust ci-lint+just ci-test)ci.yml:plan→ selected lanes →ci-ok. Linux fmt/lint/tests per component, Agent macOS clippy, OpenSecret checksci-okci:full,ci:package,ci:windows,ci:ios,ci:android,ci:research-dev-macos,ci:eifagent-windows-updater, same paths on PRs and master), Research iOS/Android/desktop, Agent Windows, EIF candidateci.ymlnightly lanes, advisories included;nightly.yml: Bun audit and the SQLCipher provider suite on 3 OSes; oneci-nightlyissueci.ymlwithlanes=<ids>orallRunners: Blacksmith runs everything someone waits on (8 vCPU Linux; 32 vCPU for
agent-test; macOS 26 with Xcode 26.5; Windows 2025; ARM Linux for every trusted EIF build). Free GitHub runners take light lanes, attestation, Windows signing and the publishers. The repository variablesCI_LINUX_RUNNER,CI_LINUX_HEAVY_RUNNER,CI_MACOS_RUNNERandCI_WINDOWS_RUNNERmove a lane to another runner without a PR.docs/ci.mdis the how-to (lanes, labels, local runs, adding a lane).docs/repository-workflows.mdis the reference (caches, concurrency, contracts, signed builds).What is deleted
agent-ci,agent-sqlcipher-supply-chain,agent-store-performance,agent-updates-tests,agent-windows-updater-tests,android-pr-build,desktop-pr-build,mobile-pr-build,opensecret-change-detection,opensecret-ci,sdk-integration,pages-tests,release-gates-tests,repository-checks,proxy-container,proxy-supply-chain,supply-chain,sdk-publish-tests,sdk-rust,sdk-supply-chain,sdk-typescript,updates-tests.agent-windows-updater-tests.yml(added by Add signed Windows Agent updates and versioned installation #1316) is now theagent-windows-updaterlane: the same 20 path filters minus its own file, the same two scripts unchanged (both always run; either failure fails the lane), the same Rust 1.98.0, MSVC, Perl and linker pins through.github/actions/setup-agent-windows, no cache, secret or environment, and its receipts kept as an artifact even on failure. Differences: it runs onblacksmith-8vcpu-windows-2025instead of GitHub'swindows-2025, master runs are no longer cancelled, and the typecheck no longer selects fxc (cargo checkon the dev profile never compiles shaders). Add signed Windows Agent updates and versioned installation #1316's manualagent-windows-signature-probe.ymlstays; itsactions: readmoved from the workflow to its one job.agent_cache*.py,agent_measure.py). It was slower than no cache everywhere it was measured.agent_change_detection.py,agent_master_selection.py,hook_change_detection.py), replaced by the planner; their cases moved totest_plan.py.test_contracts.pynow asserts the contracts, andtest_workflow_policy.pythe rules (pinned actions, read-only permissions, timeouts, no PR cache writes).agent-desktop-build.yml's PR trigger (the rehearsal is now theagent-package-*lanes); six dead PR routes inchange_detection.py; the root flake's 14 unusedci-*apps (its checks go from 13 to 7);docs/agent-ci-performance.md; the Linux fat-LTO job (a duplicate of the Linux bundle); the Agent store benchmark from CI entirely (the crate stays for local runs).nix build '.?submodules=1#default'), owner-approved (below).Size: workflows 52 files / 9,134 lines → 32 / 6,815 (non-release lines 6,155 → 3,836).
scripts/ci119 / 29,689 → 108 / 25,852. The PR: 129 files, +5,750 / −12,138.What is untouched
release.yml,pages-publish,proxy-publish,updates-publish,zapstore-publish,sdk-publish-npm,sdk-publish-rust,agent-updates-publish,auth-pages-publish,opensecret-eif-release. Exactly one workflow is namedRelease, and every listener still finds its producer.agent-desktop-build.ymlkeeps its path (sorun_numberis still the build number), every job namepublisher.pyneeds (macOS, Linux and, since Add signed Windows Agent updates and versioned installation #1316, Windows: build, sign and verify), its artifact names,MAPLE_PACKAGE_BUILD_NUMBER: ${{ github.run_number }}on the Windows packaging and verification jobs, its master-only signing and GitHub-hosted attestation.test_contractsC2 runs master's ownpublisher.trust_run(…, linux=True, windows=True)against this workflow, with each job'sif:andneedsevaluated for a master push and a dispatch. Its builders now use exact-key caches on Blacksmith; the unsigned Windows build moved to Blacksmith, signing stays on GitHubwindows-2025.ci_evidence.pykeeps its file and id, runs on master push with the same push filters, and is never cancelled.ios-dev-testflight.ymlkeeps its name.release.ymlrestores, the 13 environment names, and every release and publisher script (_common.sh,*-release.sh,web.sh,updates.sh,build-sdk-publish.sh,publisher.py,ci_evidence.py,test-release-gates.shand the rest) are unchanged.flake.lockchanged, no component flake changed, and the root dev shells are the same derivations.OpenSecret changes the owner approved, and their proofs
The rule for this PR was "OpenSecret verbatim". The owner approved five exceptions:
Agent update service PRs stop running OpenSecret. The OpenSecret selector did not know
services/agent-updates/(added later, in PR #1214), so it treated it as a new root and ran every OpenSecret lane, both EIF builds included. The prefix is now listed. A genuinely unknown directory (for exampleservices/new-service/) still runs everything; a test covers both.The x86_64
#defaultpackage build is gone. Nothing consumed it, the shipped EIF is aarch64, and the other OpenSecret lanes compile and test the same code.os-flake-checkkeeps the componentnix flake check.A master EIF/PCR mismatch is a notice, not red.
check_opensecret_eif.shnow exits 3 for a PCR mismatch (and prints the builtpcr.json); build and output failures still exit 1. Inopensecret-eif.yml:pcrDev.json+pcrDevHistory.json, orpcrProd.json+pcrProdHistory.json), from the PR's merge base. The base and head SHAs come throughenv:and must be full commit ids; otherwise the job fails;Only the last step of the
eifandeif-trustedjobs changed, identically in both. Theirif:conditions, runners, permissions, cache steps and matrix are identical to master.opensecret-eif-release.ymlis byte-identical and never calls the check script.OpenSecret docs name the new lanes.
services/opensecret/README.mdanddocs/nitro-deploy.mdstop naming the deleted workflows, and the hook comment inservices/opensecret/.githooks/pre-commitnames the new lanes. The docs check now coversservices/opensecretwith no exception.Dependency audits (
deps-*) no longer run on CI-only edits. They run when their manifest, lockfile ordeny.tomlchanges, withci:full, and nightly. A new advisory in someone else's crate should not turn a CI fix red.Proof that the PCRs cannot change.
nix evalof each EIF's derivation path (services/opensecret,submodules=1,aarch64-linux) gives the same result on master and on this branch:109188c4and this branchbwycsxmw56bs5qksr62pz8zr3s28zwd3hdzf3hidwamjqbg8214p31c08ha8xckw060l38vsx63bjr87l6nxbsn4sv3r4srrThe same evaluation does see source changes: PR #1184 (OpenSecret
src/edits) moved eif-dev fromx0pfcwdr…tobwycsxmw…. The EIF build, verify and publish scripts and the EIF fixtures are unchanged.Validation done locally (at the final head)
nix flake check: all 7 checks pass (501 CI-script tests, 133 publisher tests, 158 Pages, 27 PCR-compatibility, the release gates, actionlint).scripts/citest (501), the publisher tests (133, including Add signed Windows Agent updates and versioned installation #1316's Windows publisher tests),test_ci_evidence.py(21) andtest-release-gates.sh(31/31) pass; the edited test modules also pass on Python 3.9.plan.py lintand thescripts/cisuite, so bisect never lands on a red one. The exception is the first commit, which still carries master's owntest_agent_workflows.py: its provenance test is locale-dependent (it fails under Nix bash with an emptyLC_ALLon master too, and passes withLC_ALL=C); the next commit deletes it.test_contractsagainst a fixture git history: 16 event, ref, SHA and mode cases × exit statuses 0, 1, 2, 3 and 42, including option-like and abbreviated SHAs.plan.py lint: all 2,220 tracked files are owned or inert, and eachci.ymljob's runner and timeout match its lane.agent-updates-publish.yml),auth-pages-dev-publish.ymland all ofservices/agent-updates(includingpublisher.py) are identical to master, both at the base109188c4and at the current tip1df4cf70.Which lanes a PR gets (
plan.py explain):ci.yml,plan.py,lanes.py)deps-*lane, no EIF buildplan+ci-ok)What only this PR's own run can prove
This PR edits
ci.ymland the planner, so its run selects every gate lane (includingagent-windows-updater), Agent packaging on Linux, macOS and Windows, Research Android and the EIF candidate (nodeps-*lane). Everything runs cold, because no master cache exists yet. The run should show:ci.yml, theplanmatrix and theci-okverdict over real job results.agent-package-windowsbuilds the release-profile Windows binary (fxc, cargo-about,+crt-static), packages it with the run number as the build number, and passesverify --unsigned --smoke; master's Prod Windows build, whichpublisher.pynow consumes, runs the same build on the same runner class.agent-windows-updaterruns Add signed Windows Agent updates and versioned installation #1316's native tests, which so far passed only on GitHub'swindows-2025: the reparse fixtures need the symlink privilege, one test expects an elevated Administrators owner, and the script checks the catalog signature ofpowershell.exe. Blacksmith's Windows jobs run asrunneradminon awindows25-fullimage, like GitHub's. If either lane fails on the runner rather than the code, setrunner=Runner("windows-2025")on the lane andruns-on: windows-2025on its job (and onagent-full-windows).agent-windows(Clippy with-D warnings) lints Add signed Windows Agent updates and versioned installation #1316's roughly 4,000 lines ofcfg(windows)code for the first time; the typecheck only rancargo check.os-sdk-e2epasses with its PostgreSQL service,os-helperspasses on ARM, andos-eifbuilds dev and prod. The candidate PCRs should equal the latest master EIF build, because the derivations are unchanged.changesreportseif=trueandpcr_approvals=false, and both approval jobs skip.Adding
ci:fulland re-running also exercises the full Agent suites on macOS and Windows, the Research desktop, iOS and Dev-app lanes, and the deps lanes. Expectdeps-researchto fail there until the Research advisories are fixed (follow-up 4).Only master can prove cache saves, never-cancelled master runs, the signed builds with their new caches, the Dev TestFlight gate skipping a non-Research push, CodeQL on push, the EIF approval notice and the nightly issue.
Before merging
publisher.pynow requiresBuild Windows binary (prod),Signed Windows (prod)andVerify downloaded Windows (prod)and the Prod Windows artifact (publication itself stays behindinclude_windowsandAGENT_WINDOWS_UPDATES_ENABLED).windows-buildon Blacksmith (signing stays on GitHubwindows-2025). This matches macOS and Linux, whose Prod builds already compile on Blacksmith, and the publisher README's "compiled on the workflow's Blacksmith runners". It needs one change to a Add signed Windows Agent updates and versioned installation #1316 file: the manual signature probe (windows_signature_reference.py) requiredwindows-2025for all three Windows Prod jobs, and now also acceptsblacksmith-8vcpu-windows-2025for the build job only. Signing and download verification must still reportwindows-2025;test_contractsruns the probe against this workflow. To keep the probe strict instead, the build must go back towindows-2025(the master Windows chain then stays at 53–90 min).agent-package-windowsnow runs when its own inputs change (apps/maple-agent/scripts/windows-*,build-release.sh,release-info.py,release-profiles.json,release_profile.rs,.github/actions/setup-agent-windows/,scripts/ci/agent_windows.py; 15 of 174 Agent commits on master over the last three months, about 9%) or withci:package/ci:full. To go back to label-only, set its paths to()inlanes.py.109188c4(PR #1316). Master has since gained three Agent-only commits (PR #1320, staged Windows build validation inbuild-release.sh; PR #1309, local API controls; PR #1321, version bump).git merge-treewith1df4cf70is clean.After merge, master's trusted EIF build runs once, because the workflow, check script and selector changed; a revision whose PCRs are not approved yet shows a notice, not red.
Owner follow-ups after merge
ci-okin the master ruleset (source: GitHub Actions; strict off; keep the review rules). Until then the old checks are gone andci-okis advisory. A few working days without a false red is a good point to switch it on.ci:eif. The other CI labels already exist. Name a triage owner for theci-nightlyissue.deps-researchfails on advisories published after its last green run: reported as zstd-sys and zvariant (RUSTSEC-2026-0370, RUSTSEC-2026-0372); a local run on 10-27 found 14 advisories in zstd 0.13.3, zstd-safe 7.2.4 and zstd-sys 2.0.16 (RUSTSEC-2026-0391, 0395–0406, 0410). This PR does not change Research dependencies; it needs a Research dependency PR.xcode-27image (about 40 min) because Blacksmith's macOS 27 image lacks the Metal Toolchain. experiment: Agent macOS 27 builds on Blacksmith (do not merge) #1308 exports it on GitHub (36 s) and imports it onblacksmith-6vcpu-macos-27, where a cold Agent build passed in 15m50s. After the rebase, ci: build Apple lanes with Xcode 27.1 #1266's change becomes the macOS runner constant inlanes.py, its label in.github/actionlint.yaml, the Xcode pin, and the import step; most of its shape-test edits disappear.Smaller decisions, no rush:
agent-supply-chain(cargo-deny) andsdk-ts(bun audit) still audit advisories whenever they are selected, CI edits included. Decide whether they should follow the deps rule.change_detection.pyhas noservices/agent-updates/prefix, so an Agent update push to master still starts the signed Research builds. That was outside the approved OpenSecret scope.opensecret-eif.yml'seifjob (fork PRs that edit approvals, manual runs outside master) is the one pull-request job that saves a cache:magic-nix-cachewrites its Nix store to the branch-scoped GitHub cache, which master and other PRs cannot read. It is unchanged from master; the policy test now counts it as a writer and pins the exemption, and the cache docs name it. Disabling it (use-gha-cache: disabled) would make fork EIF checks build cold.agent-testdefaults to 32 vCPU; a 16 vCPU runner can be tried throughCI_LINUX_HEAVY_RUNNERwithout a PR.nightly.ymlonce and runopensecret-eif-releasewithdry_run.🤖 Generated with Claude Code