feat(warmup): tier-conditional acquisition (S10-d) - #297
Merged
Conversation
The desktop tier acquires the desktop component and it TAKES the browser engine's slot rather than being added to it; the no-display tier acquires zero component bytes and eagerly acquires the browser engine, which is the rung it will actually use. installedSubstrateExists() is made real (D-S10-3): it answers from an acquisition record written only after the executable it names is probed on disk, so D13 deferral now has a true answer instead of a hardcoded false. A failed or absent component degrades to the browser rung through the resolver's own substrateUnavailable branch, so the reason and the remedy come from one place and warmup still exits 0.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… artifact The spec's replacement pair was unreachable as written: <=320 and ==0 were derived from the browser engine alone, but 218 MiB of the 764 is models and models are tier-independent. Both are now stated over the component directory, where 320 keeps its headroom and ==0 is exact. G-ACQUIRE stays at 800 over the full artifact, where it still prices the models and still catches the doubling. G-TOTAL-DESKTOP is dropped rather than inherited or re-derived: the two gates that already block bound the composed total at 1520 and the lowest value it can take is 1464, so its entire failure window is 56 MiB. CI runs both arms of the pair as a differential — same command, same artifact, same component available to install, only the resolved tier differs.
…le component Both passed under a mutation that made the no-display branch acquire the component, because with no source configured the run degrades and installs the engine anyway — so "engine acquired" was true for a reason unrelated to the tier. With a component sitting there ready, the engine can only be acquired if the tier actually refused it.
resolveBrowserTier() is consulted at the single exit of SmartRouter.fetch, so answering installedSubstrateExists() from a record turned a free constant into a readFileSync plus a stat on every fetched page — and crawl fans out through the same seam, so one crawl of a static docs site would add several hundred synchronous filesystem calls. A 5s TTL costs nothing, since the answer changes at most once per install, and an acquisition in this process invalidates it explicitly so warmup never reports a rung it just stopped being on.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
S10-d — tier-conditional acquisition
Base
45c0e671(S10-c). Targetsstudio-handoff.Makes acquisition depend on the rung the machine resolved to (D-S10-3, D-S10-5), and fixes the three gates my predecessors measured as unreachable.
What each tier now acquires
desktop{"browserEngine":"skipped","desktopComponent":"acquired"}desktop, component already installed (D13)browserTierReason:"installed_substrate_present"desktop, no component availablesubstrate_unavailable, exit 0no-displaysubstrate/absent even with a source availablebrowser/--browserbrowser-acquire.ts's lazy path workinginstalledSubstrateExists()is real: it answers from an acquisition record written only after the executable it names is probed on disk. A directory that merely exists proves nothing — a half-extracted archive would otherwise make the resolver defer acquisition (D13) in favour of a rung that can never start.The three gate corrections
G-ACQUIRE's replacement pair is now scoped to a narrower artifact, not given a bigger number.<=320and==0were derived from the browser engine alone, but 218 MiB of the 764 is models and models are tier-independent. Both gates are now stated over the component directory alone, where 320 keeps its ~6.7% headroom over a measured 300 and==0is exact and achievable.G-ACQUIRE(total, 800) is kept unchanged — it prices the models and still catches the doubling regression at 1064.Neither arm is wired without the other: read alone,
<=320passes trivially on a host that acquired nothing. The claim is the differential — same command, same artifact, same job, opposite tier.G-TOTAL-DESKTOPis dropped, not silently inherited and not re-derived. Rationale inG_TOTAL_DESKTOP_DROPPED: G-DIET (≤720) and G-ACQUIRE (≤800) already jointly bound the composed total at 1520, and the lowest value it can currently take is 1464 — so the entire window in which it could fail while both components pass is 56 MiB, against a sum of two measurements each carrying tens of MiB of churn. It becomes derivable (~1280) once the desktop arm acquires a real component; the arithmetic is recorded.G-RSS-SUBSTRATEstays report-only at 510. Untouched. A 40 MiB blocking gate needs a 19 MiB window against a statistic whose own spread is 21.0, it has no ci-runner observation, and it cannot run onclean-machine-smoke, which installs the published package.Deliberately not built, and why it is not an omission
There is no published artifact to download — a version channel, a URL and a checksum manifest are all products of S16-alpha, which is the phase that decides what the component is. Writing a downloader now would choose an artifact identity on S16-alpha's behalf and then rewrite it (the program's own "build twice" flag). So the fetch step is a named
SubstrateSourceseam and everything around it ships: dispatch, install, verify, record, idempotent re-run, D13, and the degradation path.CI
Today's default desktop run finds no source, degrades, and installs the browser engine — so
clean-machine-smoke'sbrowserEngine: okassertion is unchanged on every row. The two forced-tier budget arms are what exercise both branches.Falsifiability — 11/11 probes red, exact counts
Each mutated, run, exact red count recorded, reverted by reverse-edit,
git diff -- src/ scripts/confirmed empty.installedSubstrateExists()back to hardcodedfalse==0to<=1G-TOTAL-DESKTOP ≤1000doctor's component lineThe self-satisfaction check paid for itself twice
P-2 initially red only 3 of 4. The survivor was "acquires the browser engine eagerly, because that is this host's rung" — it set no component source, so with nothing to acquire the run degraded and installed the engine anyway. It was true for a reason unrelated to the tier, and would have passed on a build whose no-display branch was never written. Fixed by putting a component there ready to install, so the engine can only be acquired if the tier actually refused it. P-2 then red 4/4.
A real perf regression found by reading the call graph, not by a test.
resolveBrowserTier()is consulted at the single exit ofSmartRouter.fetch, so makinginstalledSubstrateExists()answer from a record turned a free constant into areadFileSync+statper fetched page — andcrawlfans out through that same seam. Memoized behind a 5 s TTL with explicit invalidation on acquisition. Its test uses an outside signal (delete the record under a warm cache; the answer must hold; then reset proves the deletion was real) rather than a spy, because ESM cannot be spied and a mock-call count would assert on the mock.Verification
npm test: 10192 collected / 10165 passed / 20 skipped / 7 todo / 864 files (base45c0e671= 10130 / 10103 / 860)npm test -w apps/studio: 345 passed (39 files) ·npm run lint -w apps/studiocleantsc --noEmit0 ·gate:studiogreen ·typecheck:debt412 (3 pre-existingStatusBagfixtures needed the new required field — fixed, not ratcheted)console.log/as anyinsrc/(the 3+1 greps hits are comment false positives, present at base)+1 MiB/desktopComponent: acquired/browserEngine: skipped; no-display+0 MiB/ no component attempt — same command, same available component.Counts: predicted +42, actual +62
Explained rather than waved at: +4 are auto-generated (
it.each(ids)over gate ids gives every new gate 2 protocol tests — spotted during P-8, when adding one gate moved the collected count 138→140); +3 are the unplanned presence-cache tests from the perf regression above; the rest is finer-grained assertions so each probe reds exactly one thing.Windows
No
new URL(...).pathnameand no POSIX mode bits anywhere in the new code or tests. The new tests use realtmpdir()+join, never exec the fixture executable, and the platform-specific browser-path cases injectplatform/existsrather than touching the filesystem. The CI arms aremacos-latest-gated, so no Windows row runs them.