Repository navigation
Reduce mutation and guard CI jobs - #737
Conversation
|
Deletion review using the repository /second-opinion skill, model GPT-5.6 Sol. Each request challenged one claimed High-severity defect. Claim: Deleting unconditional PR shards loses mutation protection for changed projects. Verdict: Claim: Deleting separate guard jobs loses protection when a guard fails or during the required-check migration. Verdict: Claim: Deleting architecture runs outside the input filters loses architecture information or a required check. Verdict: Claim: Deleting duplicate generator tests and no-input runs loses generator or determinism protection. Verdict: My assessment: these alleged protection gaps are not present in the implemented changes. Keep all relevant checks and artifacts, and apply the exact required-check replacement recorded in Manual steps. The first guard request was unavailable because the helper could not parse expression braces; an operational retry produced the verdict above. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed all six changed files for CI coverage regressions, mutation selection correctness, and guard failure propagation.
- Mutation selection: Adds a tested, merge-base-aware selector that skips unrelated PR changes while preserving the existing shard scopes and full scheduled/manual runs.
- Consolidated guards: Runs all five guards in one job, preserving failure propagation, subsequent guard execution, and existing PR/push behavior.
- Artifact generation: Restricts architecture and gating workflows to their inputs, retains artifact uploads and determinism checks, and leaves generator tests covered by
Guard Conventions. - Verification: All 17 selector tests and 72 tooling tests passed. Full .NET/Stryker runs were not repeated locally. The required-check migration is documented in the PR; live branch-protection verification returned HTTP 403 (
Resource not accessible by integration), so that configuration remains unverified.
gpt-6.1-sol | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed the selector hardening in efb08bfb against the prior reviewed head ece98af2, with the full PR diff for context.
- Validated base refs: Rejected malformed refs before invoking Git and added
--end-of-options, while preserving the workflow's supported base refs and full scheduled/manual selection. - Restricted executable lookup: Set the Git child's
PATHto/usr/bin:/binon the Ubuntu runner. - Expanded regression coverage: Added invalid-ref and untrusted-PATH tests. All 27 selector tests passed locally; .NET and Stryker runs were not repeated for this script-only delta.
gpt-6.1-sol | 𝕏
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed 61c9e1a1 against the previously reviewed efb08bfb, with all six files in the full PR diff for context.
- Separated Git execution: Moved the quoted Git diff into the workflow and made the selector consume NUL-separated paths through
--stdin, removing its child-process execution. - Preserved selection semantics: Kept empty PR diffs distinct from full scheduled/manual runs and retained pipeline failure propagation for unavailable base refs.
- Verified the revised interface: Passed all 19 selector tests and exercised the actual workflow shell against scheduled/manual, empty-diff, current-PR, and missing-base cases. The missing-base case failed with exit
128; .NET and Stryker were not rerun for this CI-only delta.
gpt-6.1-sol | 𝕏
* fix: pin analyzer test Pkcs dependency to patched version (#728) (cherry picked from commit 61b0090) * fix: shard pull request domain mutation testing (#729) (cherry picked from commit bcfd81e) * Promote the API redesign with production compatibility checks (#723) * Bring the API redesign tree onto main for #1413 * Preserve calendar connection detection for shipped clients * Prove API and migrated schema compatibility with shipped clients * Trim whitespace in the archived main schema proof * Require the production health response to report the released commit * Bind initial approval previews to stored pending operations * fix: return the bulk skip refresh outcome and split the undo skip query SonarCloud failed the quality gate on two reliability findings in code this pull request brings to main: the bulk skip conflict check read a flag only a lambda wrote (S2583), and the undo skip check loaded Tags and Goals in one query (S8733). The transaction now returns whether every habit refreshed, and the undo skip check splits its query. A new case covers the concurrent change conflict; it failed with the refresh outcome forced to true and passes with the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 5526c9b) * Add per-account feature flag targeting and admin controls (#724) * feat: resolve feature flags per account * feat: administer account feature flags through MCP and REST * test: exclude feature flag targets from rate limit fixture * fix: reconcile account flag tests and migration metadata with redesign (cherry picked from commit 1b886bd) * Add header API versioning for v1 and v2 (#733) * Add header API versioning with v1 compatibility * Verify versioned OpenAPI and browser header compatibility * Preserve skip undo path contract with optional version header (cherry picked from commit ac8b34a) * fix: expose the config response in OpenAPI (#734) (cherry picked from commit a9d8dd5) * Route production redesign accounts through Cloudflare (#735) * Add cookie-based routing for the production redesign web service * Document web routing rollout, permissions, and rollback checks * Fix web routing coverage and disable infra install scripts * chore: regenerate the v2 OpenAPI document on main orbit-api#733 added openapi_v2.json and orbit-api#734 typed the /api/config response in parallel, so main carries a v2 document without the typed config schema and the Build check's stale-document step fails on every merge with main. dotnet build src/Orbit.Api regenerates it; openapi.json is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 9c64770) * Fix habit edit gating, end dates, and reminder updates (#736) * fix: validate habit updates with the resulting time range * fix: preserve end dates when creating root habits * fix: gate slip alert activation and preserve unchanged reminders * fix: compare effective reminder rules across stored formats (cherry picked from commit 7472203) * Reduce mutation and guard CI jobs (#737) * Select mutation shards from changed projects * Consolidate guards and filter artifact generation * Skip project documentation in mutation selection * Validate mutation base refs and restrict Git PATH * Read mutation shard changes from standard input (cherry picked from commit b802f9e) * test: strengthen habit and goal ownership coverage (#739) (cherry picked from commit 0e32628) * test: verify checkout session user metadata (#740) (cherry picked from commit da2f53a) * fix: protect OAuth code delivery with Turnstile (#741) (cherry picked from commit 1149606) * fix: enforce chat interaction scope before loading context (#743) (cherry picked from commit 98faf4e) * fix: erase accountability pairs during account deletion and reset (#745) * fix: erase accountability pairs during account deletion and reset * test: preserve migration compatibility checks after accountability cleanup (cherry picked from commit a9e5fb9) * Fix goal sync dates and deadline reminder counts (#747) * fix: compare streak sync dates in the user timezone * fix: show actual days remaining in goal deadline reminders * test: configure timezone for streak scheduler fixtures (cherry picked from commit 0e63842) * Manage staging landing routing in Terraform (#742) (cherry picked from commit abdd738) * Restrict Web Push endpoints to supported push services (#1503) (#751) Web Push subscriptions accept only HTTPS endpoints on the FCM, Mozilla, Apple and WNS push hosts, and the push HTTP client follows no redirects. Replaces orbit-api#748 as one commit so no commit carries the high-entropy sample fixture. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit d9f847a) * Erase account uploads before permanent deletion (#1507) (#750) * fix: erase uploaded objects before completing account deletion * fix: refuse upload reads after permanent account deletion * fix: grant uploads bucket deletion permissions and verify provider wiring * test: align storage startup checks with erasure requirements * fix: retire deleted Supabase upload storage * test: configure upload erasure providers in deletion fixtures Share the existing object-store fake across account deletion and scheduler fixtures after merging main. Preserve accountability assertions and production provider requirements for thomasluizon/orbit-tickets#1507. (cherry picked from commit fa33a94) * fix: limit anonymous auth and waitlist by email and source IP (ORB-108) (#749) * fix: enforce source IP ceilings alongside anonymous email limits * test: cover both rate limit dimensions before bot verification * fix: isolate BFF email rate limits by verified client IP * fix: generate and persist BFF forwarding secrets (cherry picked from commit de0f42f) * Limit access tokens to fifteen minutes (#738) * fix(auth): limit access tokens to fifteen minutes * fix(auth): align managed JWT lifetime and prove logout rejection (cherry picked from commit ade7016) * fix(auth): equalize account provisioning work (ORB-96) (#744) * test(auth): expose registration dependent sign-in work * fix(auth): perform uniform registration work before sign-in responses * test(auth): cover expired codes and tracked upsert conflicts * fix(auth): isolate signup retries and restore provisioning guards * fix(auth): recover signup work after dispatch failures * fix(auth): roll back failed signup referrals before retry (cherry picked from commit 1bd0d26) * fix: expose redesign controllers in both API versions Apply the carried version declarations to the Notion and proactive controllers and regenerate the v2 contract. Refs thomasluizon/orbit-tickets#746. * fix: honor account flags in proactive engine --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>




Documentation changes currently start every mutation shard, and five small guard jobs each repeat checkout and setup. Select mutation shards before starting .NET, run all five guards as named steps in one
Guardsjob, and avoid regenerating artifacts when their inputs did not change.Closes thomasluizon/orbit-tickets#1521
Approach
.github/scripts/mutation-matrix.mjsowns the existing four shard definitions..github/workflows/mutation.ymlselects a dynamic matrix from a null-delimited, merge-base Git diff. Domain source or tests select both domain shards; Application and Infrastructure select their respective shard. Documentation under those projects is ignored. Renames and deletions retain both affected project paths. Shared build/tool/selector changes select all shards, and each Stryker config selects its project. Missing base refs fail the selector. Nightly/manual runs retain all shards and PR runs retain--since..github/workflows/guards.ymlruns Workflow Syntax, Timeless Text, Dash Ban, Skill and Agent Frontmatter, and Root Allowlist after one checkout and Node setup. Every guard uses!cancelled()so earlier failures still allow the other guards to execute. PR edits, main pushes, bot-body handling, the dash baseline, and title/body checks remain covered..github/workflows/arch-map.ymlandgating-matrix.ymlfilter both PRs and pushes to their generator inputs, tests, and workflow files. Artifact uploads remain. The gating workflow retains generate-twice determinism checking.Workflow audit
tools/arch-map.mjsreads C# under src/tests and the four source project files. The new filters cover those inputs and the generator/workflow itself.src/**/*.csand generator/test/workflow changes. Remove its duplicate generator test step: the unchanged required Guard Conventions job in.github/workflows/test.ymlrunsnode --test tools/__tests__/*.test.mjson the same PRs and main pushes, including this exact test file.Job-minutes
Baseline: one complete successful PR execution, orbit-api#735, head
b44730e2523fcf48b8931ff8aaf54c0b2c31b9aa. Its actual file list contains infra, two other workflow files, and OpenAPI JSON, with no mutated project or generator input changes. Sum each completed Actions job'scompleted_at - started_atacross the runs for that head, excluding queue time and skipped jobs.This replays the same complete PR file set against the new policy, budgeting one minute for the two small jobs. It projects 27.53 fewer job-minutes, about 53%, and 24 running jobs becoming 15. The after total is a forecast, not an observed Actions run: this order explicitly assigns CI waiting to the orchestrator. Actual after-run measurement remains to be collected during that handoff.
Source runs: Mutation, Guards, architecture, gating, API Tests, CodeQL, SonarCloud, Dependency Review, Terraform.
Test evidence
dotnet build Orbit.slnx: exit 0, zero errors. Generated OpenAPI documents have no diff.dotnet test Orbit.slnx --no-buildalso passed after the final commit: all 9,521 tests, zero skipped.dotnet test tests/Orbit.Domain.Tests --no-build: 666 passed;dotnet test tests/Orbit.Application.Tests --no-build: 5,466 passed;dotnet test tests/Orbit.Infrastructure.Tests --no-build: 3,357 passed;dotnet test tests/Orbit.Analyzers.Tests --no-build: 32 passed.node --test .github/scripts/mutation-matrix.test.mjs: 17 passed. Tests drive the real selector against real temporary Git repositories, covering documentation, source/tests in each project, mixed changes, renames/deletions, merge-base behavior, shared/project config, nightly/manual scope, and invalid refs.documentation and unrelated projects select no shards: the unchanged 17-test suite passed at76b90da9, while documentation inside project directories still incorrectly selected shards. After adding project-local documentation to that test,node --test --test-name-pattern='documentation and unrelated' .github/scripts/mutation-matrix.test.mjsfailed before the implementation fix, showing all four shards instead of[]. After excluding documentation extensions, the complete 17-test suite passed. The original workflow also passed actionlint despite its unconditional matrix; lint alone did not catch selection behavior.node --test tools/__tests__/*.test.mjs: 72 passed, including all 15 gating generator tests.concurrency.queuekey. Timeless Text, Dash Ban including its baseline, frontmatter, root allowlist, and whitespace checks passed. No bare narration comments were added.SonarCloud round (
efb08bfb):mutation-matrix.mjsvalidates the base ref before it reachesgit(a strict ref pattern, no leading-, whitespace or..), passes--end-of-optionsbefore the revision range, and runsgitwithPATH=/usr/bin:/bin. This clearsjssecurity:S8705andjavascript:S4036at.github/scripts/mutation-matrix.mjs:28.node --test .github/scripts/mutation-matrix.test.mjs:git, and an untrustedgitearlier on the inheritedPATHran).The mutation workflow's runner log (run 39094713507) shows Ubuntu 24.04 with
/usr/bin/git2.55.0, so--end-of-options(git 2.24 or newer) is supported; local/usr/bin/gitis 2.54.0.SonarCloud round 2 (
61c9e1a1): SonarCloud did not count round 1's argument check orPATHoverride as sanitizers, so the selector no longer runs any command.mutation-matrix.mjsreads the NUL-separated changed path list with--stdinand runs no child process; the "Select changed projects" step runs the quotedgit diff --name-only --no-renames -z --end-of-options "$BASE_REF...HEAD"underset -o pipefailand pipes it in, and runs the selector with no input (all shards) outside pull requests. This removesjssecurity:S8705andjavascript:S4036(no process, no executable lookup) andjavascript:S6353(the validation regex is gone).actionlint .github/workflows/mutation.ymlexit 0.dotnet build Orbit.slnxexit 0;dotnet testDomain 666, Application 5,466, Infrastructure 3,357, all exit 0.External interface evidence
The selector reads Git path output, not a third-party action's guessed response fields.
git diff --name-only --no-renames -z <base>...HEADwas exercised in real temporary repositories by the tests. Moving a file from Domain to Application and deleting an Infrastructure test returned all three paths, so both rename sides and deletions select the affected shards. The empty diff on the initial branch returned zero bytes. A missing ref exited nonzero and emitted no matrix. No mocked Git response fixtures are used.Live API responses were inspected before reading timing or protection fields. Reproduce the complete raw response shapes with
gh api repos/thomasluizon/orbit-api/actions/runs/39085001880/jobs,gh api repos/thomasluizon/orbit-api/branches/main/protection, andgh api 'repos/thomasluizon/orbit-api/pulls/735/files?per_page=100'. The observed jobs response hastotal_countandjobs, with each job supplyingname,started_at,completed_at, andsteps; the protection response hasrequired_status_checks.contextsandrequired_status_checks.checkswithcontextandapp_id. Each baseline run's raw jobs response supplies the measured timestamps above. PR file names come from the realfilenamefield, not an invented fixture.Deletion review
The repository's
/second-opinionhelper was run on four concrete claimed protection defects, one for each deletion/reduction: mutation filtering, consolidated guard jobs, architecture trigger filtering, and gating trigger filtering plus duplicate test removal. GPT-5.6 Sol returnedDISAGREE, high confidence, on every claimed defect. The guard request needed one operational retry after the helper could not parse interpolation braces in its first reply. The complete verdicts are posted in a PR comment. I agree with those verdicts: checks and relevant artifacts remain protected, with the exact check-name migration below.Assumptions
--stdinflag tells an empty pull request diff apart from a nightly run with no input.Manual steps
thomasluizon/orbit-apiGitHub Settings > Branches > main branch protection > Require status checks to pass, replace exactlyTimeless Text,Dash Ban,Skill and Agent Frontmatter, andRoot AllowlistwithGuards, pinned to GitHub Actions app id15368.Workflow Syntaxwas not required. Preserve every other required context and all other protection settings. Verify the current PR has a successfulGuardscheck before replacing the names, and read backgh api repos/thomasluizon/orbit-api/branches/main/protectionto prove the four old names are absent,Guardsis present with app id15368, and the other required contexts remain.completed_at - started_atwith the same method, and replace the forecast with observed after-run minutes. The worker did not wait for or poll new Actions runs.