Skip to content

perf(rules): cut custom-rule host overhead - #981

Merged
kvlonge merged 4 commits into
mainfrom
perf/custom-rule-phase
Oct 6, 2026
Merged

kvlonge merged 4 commits into
mainfrom
perf/custom-rule-phase

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Why

The custom-rule phase spent most of its time on overhead rather than evaluating rules: starting the host, encoding and decoding the project payload, resolving project-tree reads, and digesting whole-project facts again for every recorded read. This change makes the phase faster without changing which findings are reported or their order.

Changes

  • Hosts start while the parent writes the payload. Each host waits for the payload to be published atomically and imports the rule harness only when it is used. Garbage collection is paused while the payload is loaded.
  • If the payload write fails, hosts are released through an abandon marker, and the original error is raised. Hosts also exit promptly when their parent process exits.
  • Hosts now receive only the project and model state that Rule facts read. An integration guard checks that every fact gives the same value and digest with the full and trimmed projects. The fixture fills every trimmed field, so a fact that starts reading one of them fails CI.
  • Project-tree read_text resolves through cached directory listings.
  • Whole-project facts are digested once per run.

Verification

  • Medians of 5 alternating base/head runs on synthetic dense projects with custom rules, cold: custom-rule phase 4.1 → 1.8 s at 3k models and 12.5 → 6.7 s at 10k; mid-size projects with several custom rules also improve on edits.
  • Raw diagnostics were byte-identical between base and head across every measured pair.
  • New end-to-end edit-chain test runs the real CLI and checks that findings are byte-identical with the cache on, the cache off and --no-cache. A deliberately broken invalidation makes it fail.
  • One independent review plus follow-up; make test, make check-ci.

Hosts now start before the parent writes the project payload and wait for
it to be published, so interpreter start-up overlaps the payload encoding.
A failed write publishes an empty payload so waiting hosts exit promptly.

Hosts load the project with cyclic collection paused and then freeze it,
and the rule-test harness is imported only when a test calls it, so rule
modules no longer pull the compile pipeline into every host.
… read

The host payload drops model fields and project state that no Rule fact
exposes, such as the second authored query copy, lineage columns, and the
scope index, so the parent encodes and every host decodes less. Model
fields are dropped while the payload is written, after hosts have started,
so runs whose custom results are all cached pay nothing extra.
Reading a regular, non-symlink file resolves its directory once per tree
and checks the file itself with one lstat. Symlinks, missing files, and
directories still take the full resolution, so outcomes and errors match.
Whole-project facts such as project.sources repeat objects shared between
resources: every source declared in one file carries that file's contents
and entries. Digests of these facts now encode each compiler dataclass once
and refer to it by content digest, so the digest grows with distinct
content instead of with repetitions. Model and project-tree facts keep the
digest a host observes.

A real-CLI edit chain with model- and project-subject custom rules split
across hosts compares every warm compile with a cache-free oracle, and the
oracle is shown to fail when source digests are deliberately stale.
@kvlonge
kvlonge enabled auto-merge (squash) October 6, 2026 14:27
@kvlonge
kvlonge merged commit 7000d36 into main Oct 6, 2026
30 checks passed
@kvlonge
kvlonge deleted the perf/custom-rule-phase branch October 6, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant