Files
PaperClipAI/doc/plans/2026-10-29-incremental-ci.md
T
DottaandPaperclip f5dcc505c0 perf(ci): select affected suites and cache task results (#18214)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Pull request CI checks the server, UI, packages, Runner, and release
paths.
> - An ordinary PR starts 48 jobs even when its diff affects only a
small part of the repository.
> - Repeated pushes also repeat successful tests with unchanged inputs.
> - This PR selects affected suites before runner allocation and caches
deterministic task results with Turbo.
> - Required checks validate the plan. Unknown inputs and failed
comparisons keep full verification.
> - The benefit is fewer runner jobs and less repeated work, with full
post-merge verification retained.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The GitHub Actions PR workflow repeats unrelated suites for each push.

**Subsystem affected**

Cross-cutting CI routing, test execution, and required-check
aggregation.

**Current behavior**

An ordinary UI component change starts the complete 48-job PR workflow.
Existing dependency and compiler caches do not reuse successful test
results.

**Proposed behavior**

A trusted planner reads the tested merge diff and task inputs. A UI
component change such as `ui/src/components/Sidebar.tsx` selects 18
jobs, including build and browser coverage. Successful general,
serialized, and standalone Rust tasks can reuse unchanged results across
pushes in the same PR.

**Reason and benefit**

Reduce unrelated jobs and repeated test execution. The 48-to-18
comparison measures planned job count. Remote wall-clock savings have
not yet been measured.

**Breaking changes**

No application API changes. Required `verify` and `e2e` names remain
stable. `verify` also checks serialized suites and the canary dry run.

## What Changed

- Added explicit task inputs and a pinned Turbo version. An execution
adapter calls existing package scripts without adding script aliases.
- Added trusted diff planning and dynamic matrices with complete
fallback matrices.
- Added PR-scoped task result caches. External-state and
revision-stamped checks remain uncached.
- Added and created the `full-ci` override label, plus repository modes
`enabled`, `shadow`, and `full`. Forced and shadow runs bypass result
caches.
- Added candidate-workflow qualification, planner and aggregate tests,
and a real Turbo cache fixture.
- Kept the repository-wide CLI guidance guard in the uncached typecheck
lane so UI-only diffs retain this security check.
- Documented rollout controls, input maintenance, and local inspection
commands.

## Verification

- Passed 537 focused CI policy, routing, matrix, cache, and shard tests,
plus 146 existing release workflow tests.
- Passed actionlint for all four changed or added workflows and `git
diff --check`.
- Passed `pnpm -r typecheck` and `pnpm build` on the implementation
base.
- Checked real repository task plans for existing general-test and
native Rust commands. A real server partition passed, then restored from
cache: Turbo task time was 20.022 seconds for execution and 151 ms for
the cache hit, excluding wrapper/setup overhead.
- The real Turbo fixture exercises the execution adapter and proves
source, argument, toolchain-scope, and environment invalidation, result
restoration, and retry of failed tasks.
- Stopped the serial local `pnpm test:run` after over 30 minutes in
favor of the complete parallel GitHub suite. A local parallel
database-lane attempt had PostgreSQL startup errors and timeouts. The
direct migration fixture passed, then all 273 database tests passed with
one local worker. This recovery does not establish the exact cause of
the earlier startup failures. The full GitHub PR suite and candidate
qualification passed on commit
`0bf07ae071c9fe7903edc604d44b5a175727fed0`. Greptile is 5/5 with no
unresolved review threads.
- All 40 CLI guidance safety tests passed with the exact uncached
workflow command.
- Verified that master rulesets require only `ci / verify` and `ci /
e2e`; both names remain unchanged.
- Trusted workflows load from master. The added GitHub-hosted
qualification workflow exercises this candidate planner before merge.

## Risks

- Changes to global inputs, including task definitions and execution
helpers, force execution and disable cache restore/save for the full PR
diff. Missing a cross-package filesystem read could omit a suite. Inputs
include known server reads of UI files and shared tests of UI assets.
Unknown paths, malformed or truncated diffs, and definition download
failures select all suites.
- Task result reuse requires complete inputs. Keys include Git source
files, scripts, resolved dependencies, environment, toolchain, checkout
path, and unclassified source files. Generated build artifacts are
excluded from input hashes. Registry smoke, browser, and
revision-stamped tasks remain uncached.
- Maintainers must update task inputs when suites start reading new
paths. `shadow` reports selection while running all work. `full` and
`full-ci` disable selection and result reuse.
- The implementation becomes active after merge. Full post-merge
verification remains unchanged.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool
use, and code execution. The session does not expose a verifiable exact
runtime model ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-29 16:56:28 -05:00

3.4 KiB

Incremental PR CI

Goal: select existing PR suites from their inputs before allocating runners, and reuse successful deterministic task results across pushes. Keep the current test partitions, trusted runner admission, required checks, and full post-merge verification.

Delivery: a reviewable PR on codex/incremental-ci. The planner supports report-only, enabled, and forced-full execution. Source/configuration uncertainty selects the full suite. Task definitions and GitHub orchestration belong to the CI subsystem; application behavior is outside scope.

Acceptance:

Case Required evidence
UI component change UI/browser/build coverage selected; independent Rust and server suites omitted
UI source read by server tests Server suites selected
Shared contract, fixture, or shipped prompt Every consuming suite selected
Rename or deletion Both sides of renames and deleted inputs accounted for
Stack, profile request, unknown path, failed/truncated diff Existing stack policy or full verification preserved
Repeated identical task inputs Real Turbo execution restores the successful task result
Changed source, toolchain, environment, or command Cache miss; failed tasks never reused
Required checks Selected failures/cancellations and unexpected skips reject the PR
Candidate workflow GitHub-hosted qualification runs candidate planner/cache tests before trusted master adopts it

First feedback loop: dependency-free Node tests against real Git diffs and the planner, then a small real Turbo cache fixture. Full required repository checks and remote CI follow once the wiring is stable. Current server tests read select UI files; Runner static and final Vitest lanes also execute server integration tests. These are explicit task inputs, not inferred from package names.

Implementation: the trusted routing workflow downloads a pinned task graph and selects matrices before runner allocation. General and serialized Vitest suites and standalone Runner Rust tests use PR-scoped Turbo result caches. Stable required checks validate selected and skipped jobs. Full build and external-registry smoke tasks remain uncached because their results depend on revision stamps or external state.

Local evidence: repository typechecking and build passed. Planner tests cover real Git renames, missing/truncated comparisons, cross-package source reads, trusted definition downloads, full-suite overrides, and required-check failures. A real Turbo fixture proves execution through the existing package scripts, result reuse and restoration, source and argument invalidation, environment invalidation, and failed-task retries. The execution adapter keeps task aliases out of package manifests. The real server partition also passed through the adapter: Turbo reported 20.022 seconds for execution and 151 milliseconds for the repeated cache hit. These are task timings, excluding wrapper and GitHub setup overhead.

The planner selects 18 jobs for ui/src/components/Sidebar.tsx, compared with the existing 48. This is a job-count reduction; remote wall-clock savings have not yet been measured. The serial local full-suite attempt was stopped after more than 30 minutes in favor of the complete parallel GitHub suite. Remote PR checks remain the final qualification gate. Activation follows merge because trusted PR execution loads workflow and planner definitions from master.