本文へ移動
cccskills
無料GitHub で公開

render-toolchain-update

Update Pulp's pinned Skia, Dawn, and optional V8 prebuilts as one milestone-matched render-toolchain release. Use for requests such as "update Skia/Dawn", "move to chrome/mNNN", "find the matching V8", "update the GPU toolchain", or "use the Skia/Dawn/V8 tuple that goes together". Distinguishes milestone-matched V8 releases from v8-builder's newer weekly LKGR releases, verifies exact upstream provenance and asset hashes, updates every Pulp mirror, and runs the provider-identity/ODR gates.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md21.8 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Update the matched render toolchain

This procedure expects ghapp and python3, and operates on tools/deps/manifest.json, tools/scripts/fetch_skia_for_release.py, and tools/scripts/fetch_v8_for_release.py.

Pulp's default is a milestone-matched, provider-validated set: the published skia-builder release, the Dawn revision that Skia itself built from, and the V8 revision from the same Chromium milestone branch. Chromium's raw Skia/Dawn DEPS pins may differ from the later published Skia branch head; that is valid only when the v8-builder release records both generations, binds built_skia/built_dawn to the published provider, and passes the combined provider-identity/ODR gate. v8-builder may also publish newer weekly LKGR releases; those remain valid opt-in V8 choices, but they are not the default pin for a milestone update.

Truth model

Keep these values distinct in notes and manifests:

  • skia: exact commit at refs/heads/chrome/mNNN used by skia-builder.
  • built_dawn: Dawn from that Skia commit's own DEPS; this is the Dawn actually compiled into the Skia/Dawn artifacts.
  • v8: V8 from Chromium refs/branch-heads/<branch> DEPS for milestone NNN, after recording Chromium's raw Skia revision separately from the provider generation validated by the matched release.
  • dawn: Chromium's Dawn pin. It can differ from built_dawn; record the mismatch. Do not claim all three are one identical Chromium DEPS tuple when it differs.

v8-builder/tools/milestone_pin.py resolves and enforces this contract. For example:

python3 ../v8-builder/tools/milestone_pin.py 153 \
  --skia-release-tag chrome/m153 > /tmp/m153-render-lock.json
python3 -m json.tool /tmp/m153-render-lock.json

The result must have the requested milestone, skia_release_tag, exact Chromium skia/v8/dawn SHAs, and exact built_skia/built_dawn provider SHAs. False skia_matches_chromium or dawn_matches_chromium values are disclosed provenance, not failures: acceptance instead requires validated_skia_release to equal the active Skia version, built_skia/built_dawn to equal Pulp's active provider, every asset's embedded pair to agree, and the combined provider-identity/ODR gate to pass.

Release lanes

  • skia-builder publishes chrome/mNNN, then dispatches skia_milestone_published to v8-builder.
  • v8-builder's matched-milestone.yml resolves the lock, skips an exact release that already exists, and dispatches the sealed all-platform build with publication on.
  • v8-builder's release-watch.yml continues its weekly LKGR cadence independently.

For a historical Skia release or recovery, manually start the same idempotent lane:

ghapp workflow run matched-milestone.yml \
  --repo danielraffel/v8-builder \
  -f milestone=153 \
  -f skia_release_tag=chrome/m153

Do not update Pulp's V8 pin until that matched release is published and every requested platform asset is present. Never substitute the newest weekly V8 merely because it is newer.

Matched release collection

Present the Skia/Dawn and V8 release URLs together as the milestone collection, then download only the assets the user needs:

ghapp release view chrome/m153 --repo danielraffel/skia-builder --json url
ghapp release list --repo danielraffel/v8-builder --limit 100 --json tagName \
  --jq '.[] | select(.tagName | startswith("v8-m153-")) |
    "https://github.com/danielraffel/v8-builder/releases/tag/\(.tagName)"'

The collection is a provenance and compatibility convenience, not one combined archive: Skia/Dawn, V8, or both may be consumed independently.

Independent Skia/Dawn advance

When the user explicitly asks to advance Skia/Dawn before the matching V8 build is complete, keep the lanes separate instead of blocking the render update or claiming a matched tuple:

  1. Update the active Skia entry and its built-Dawn provenance from published assets. Leave the V8 version, assets, and its internal paired_* metadata at their last verified milestone.
  2. State the mixed active-provider selection in DEPENDENCIES.md and the V8 manifest notes. Do not rewrite V8's historical skia_release_tag, paired_skia, or paired_dawn to the newer active Skia values.
  3. Run the sealed V8 provider-identity/ODR gate against the new Skia/Dawn provider. Keep this in the required release-path CI surface while the mixed selection is active; a successful one-off local or Skia-only build does not prove mixed-provider safety.
  4. Record a precise follow-up trigger: adopt V8 only after the matched release contains every required platform asset and its embedded pair manifest passes the normal milestone checks.

This is a bounded compatibility state, not a new default release policy. Return to a fully milestone-matched selection as soon as the verified V8 release is available.

Pulp update checklist

For the canonical executable validation and machine-readable result, run:

python3 tools/deps/validate_hosts.py --render-toolchain

The local native arm64 leg performs the full mixed-provider proof. Configured Unix remotes populate and verify their own immutable generation, run the capability probe, and require the second fetch to be a no-download hit. The underlying validate_render_update.py JSON records platform, asset SHA, generation receipt, capability result, cache result, and mixed-provider result; retain those fields in the PR/landing evidence.

  1. Work from current origin/main in a clean worktree. Read release notes from M+1 through the target and search Pulp for removed APIs.
  2. Inspect the published Skia release with ghapp release view chrome/mNNN --repo danielraffel/skia-builder --json assets,publishedAt. Update every platform URL and SHA-256 in tools/deps/manifest.json; do not omit Windows, Linux ARM64, Apple device and simulator slices, WASM, or XCFramework coverage.
  3. Inspect one native archive and external/skia-build/VERSION.md. Confirm the exact Skia and built-Dawn SHAs, deployment floors, and optional archives such as Skottie, jsonreader, and skresources.
  4. Inspect the matched v8-builder release manifests. All assets must agree on pair.pair_kind=chromium-milestone, pair.milestone, pair.skia, pair.v8, pair.built_dawn, and pair.validated_skia_release.
  5. Update the V8 entry, all asset URLs/hashes, DEPENDENCIES.md, V8 provider comments, tools/cmake/FindV8.cmake, tools/cmake/PulpV8Windows.cmake, test fixtures, and tools/deps/min_os.json only from measured release facts.
  6. Update the Skia/Dawn mirrors: external/skia-build/VERSION.md, visual-harness pins, build-script defaults, docs/support matrix, and manifest fixtures.
  7. Run the manifest mirror/audit tests and both fetch-script suites. Fetch a real native Skia asset and matched V8 asset, configure with GPU + Lottie + V8, and run the provider-identity/ODR validation. A pixel-only test is insufficient. Configure that validation lane with PULP_VALIDATE_CAPTURE_STRICT=ON alongside PULP_VALIDATE_V8_PROVIDER_STRICT=ON. The default Three.js native demo capture tests tolerate a build without V8, or a host without a native Dawn adapter, as a skipped PNG assertion, so a toolchain pin that quietly broke the V8 link or the Dawn adapter still shows them green. The strict variants turn both skips into failures, which is what you want from the one lane whose job is to prove the new pins actually render. For m153+, run python3 tools/scripts/verify_skia_m153_capabilities.py --platform <matching-native-desktop-platform> --skia-dir <materialized-generation>. Run each architecture on its matching host; the compile-and-execute probe intentionally rejects mobile, WASM, Windows, and cross-architecture assets. The probe must reject a directory unless its verified asset stamp matches that platform's manifest digest and both Skia and Dawn archives are materialized. It proves the new API and exported-symbol surface against the exact provider; actual Graphite executor dispatch belongs to the integration's measured behavior gate, not this toolchain probe. A darwin-universal provider is the deliberate aggregate exception: run it on darwin-arm64 so the probe compile/links/runs arm64 natively and x86_64 explicitly through Rosetta. Its single JSON result binds both records to the same universal asset digest, generation receipt, probe source, and Pulp source SHA. A universal build/lipo check without that dual-slice receipt is not m153 capability evidence.
  8. Measure every Apple slice actually selected by the manifest. A same-tag asset can leak a higher deployment target than its universal sibling. Measure the exact thin archive when the manifest selects a thin archive; evidence from a universal sibling is not interchangeable. Use the verified selected asset or rebuild rather than publishing a false minimum-OS claim.
  9. Re-bake CI goldens when either prebuilt pin changes, then ship only after required CI and cross-platform asset coverage are green.
  10. Exercise the shared-cache publication path with --cache-lock-timeout: a pin-stale or cold cache must be populated only by the lock owner in a private sibling staging directory, then renamed into an immutable platform-plus-asset-SHA-plus-receipt-schema generation. A waiter must recheck the winner's exact stamp plus platform library before it skips downloading, and a pin bump must preserve the prior generation for bound consumers. Never seed the canonical cache by rsyncing a checkout merely because external/skia-build/build exists. Keep release x64/universal destinations isolated from the host arm64 cache.
  11. Revalidate the independently pinned three.js runtime used by native WebGPU consumers. When PULP_ENABLE_THREEJS_RUNTIME=ON, Pulp fetches or accepts PULP_THREEJS_RUNTIME_DIR and stages the verified payload under share/pulp/threejs; it is not test-only. A render-toolchain change that alters this compatibility or install boundary must update the dependency manifest, attribution surfaces, runtime manifest, and installed-SDK proof.
  12. After merge, prewarm every active build host through the fetcher's normal immutable cache-owner path. For each M3, M5, M1, Mac mini, and Mac Pro host, record the exact asset SHA, materialized libskia.a plus libdawn_combined.a, and a second invocation that reports the complete generation and performs no download. Skip or defer a host only with an explicit offline/retired disposition; never copy a checkout cache between machines.
  13. Treat missing provenance as a cold cache. A materialized library plus a tracked VERSION.md digest is not proof that those bytes came from that archive: without the exact fetcher-written asset stamp, re-download and verify before publication. Source fallbacks must likewise pin the builder revision and fail before copying output unless the built Skia checkout HEAD equals the manifest's immutable skia_commit; a milestone branch name alone is never sufficient provenance.
  14. Treat any provider release marked release_immutable: false as mutable until its publishing workflow is terminal. Record the exact publisher run and release updated_at, collect every asset ID/digest plus metadata and pair digests, then re-query the same release immediately before publication. If any asset, metadata, pair field, or release timestamp changed, invalidate the prior validation, repin the complete platform set, and rerun the provider and cache gates. A successful earlier fetch proves only the bytes that existed at that time; it does not authorize landing after the release was replaced.

Common traps

  • release-path-pr-gate.yml's darwin runner resolver runs resolve_release_runners.py --apply-class-label pulp-release-pr-gate after a sparse checkout. With PULP_RELEASE_CLASS_TOKENS unset the selector is verbatim; set, a self-hosted selector gains pulp-release-pr-gate, so a gate run that never starts may be an unserved class, not a toolchain failure.

  • A Skia milestone name alone does not select a V8 revision. Resolve through Chromium's milestone branch, preserve its raw Skia SHA, and separately prove the release's validated built_skia/built_dawn pair equals Pulp's active provider.

  • Skia's Dawn pin and Chromium's Dawn pin are separate dependency surfaces.

  • The SDK's share/pulp/runtime-pins.json (embedded in every bundle's pulp-build-info.json) is DERIVED, not edited: PulpRuntimePins.cmake parses **Release:**, the "Skia branch tip is <sha>" sentence, and **skia-builder ref:** out of VERSION.md, decodes kDawnVersion from the linked dawn/dawn_version.h, and takes wgpu-native from the single PULP_WGPU_NATIVE_VERSION in PulpDependencies.cmake. Rewording those VERSION.md lines turns the pins into null; the cmake-bundle-build-info-contract ctest compares them with the manifest's Skia version and Dawn notes (DEPS file at <sha>, Dawn SHA1 <sha>), so keep those phrasings too. A wgpu-native bump now edits that one variable plus PulpWgpuUniversal.cmake's slice digests and shared-source-contract.txt.

  • PulpDependencies.cmake sets CMAKE_DISABLE_PRECOMPILE_HEADERS ON around SDL3's FetchContent_MakeAvailable only. SDL3 precompiles src/SDL_internal.h into every object, and ccache refuses to cache a TU compiled against a PCH unless pch_defines sloppiness is on (measured on 3.2.12: 188 of 214 SDL3 calls "could not use precompiled header"). Keep the scope tight when bumping SDL3: the save/restore of the previous value is what keeps a later PCH user (the Catch2 test carriers in PulpTestSuite.cmake) unaffected. The test-pch-wiring ctest asserts SDL3-static compiles with no PCH.

  • GitHub release tags containing / must remain correctly URL-encoded/handled.

  • Linux x64 Skia and V8 assets must retain the portable glibc floor; do not replace their portable releases with a normal ubuntu-latest artifact.

  • fetch_skia_for_release.py platform keys must match the manifest exactly (notably wasm-wasm32).

  • After a Skia pin bump, the gate VMs download the new archive until each tartci host's artifact cache holds it (scripts/artifact-cache.sh add --url <asset> --sha256 <pin> in tartci). That is a speed loss only: the fetcher prefers $TARTCI_ARTIFACT_CACHE/sha256/<pin> and falls back to the network on a miss.

  • fetch_skia_for_release.py retries the asset download, but only for failures a second attempt can fix: 408/425/429 and 5xx, plus URLError, TimeoutError, ConnectionError and IncompleteRead, with exponential backoff from 2s capped at 30s and a numeric Retry-After taking precedence. A 403/404 raises immediately, because at this stage that means the pin names an asset that is not there, and spending the backoff first buries that error under minutes of silence. A bare OSError is deliberately not transient either: it is what a full disk raises on the write side, and retrying re-downloads hundreds of megabytes to fill the same disk. When a pin bump fails here, read which class it was before assuming the network.

  • Keep release-fetch progress output ASCII-safe. Windows release runners can use a cp1252 console, where decorative Unicode arrows raise UnicodeEncodeError before an asset download starts; exercise the full Windows fetch path with cp1252 stdout.

  • Compare extracted-generation receipts in a host-independent canonical path order. Windows Path ordering is case-insensitive while ZIP member names use POSIX, case-sensitive ordering; directly comparing those sorted lists can reject an otherwise byte-identical authenticated archive (for example SkBlendMode.h and SkBlender.h). Keep path/hash/size integrity checks exact, but canonicalize both projections by their serialized archive path before comparing them.

  • JS-engine wording in tools/deps/manifest.json, tools/deps/min_os.json, and tools/cmake/FindV8.cmake describes a selection contract, not just prose. The contract is: auto/quickjs compile QuickJS only; jsc additionally compiles core/view/src/js_jsc_engine.mm and links JavaScriptCore.framework on Apple; v8 selects the sealed prebuilt. JSC is opt-in, never implied by "Apple". Older text said "default is QuickJS, JSC on Apple", which reads as JSC being automatic on Apple platforms and is wrong. Likewise iOS is no longer "JSC-only": Pulp has no device/AUv3 V8 runtime acceptance or packaging contract. The m153 V8 release includes a jitless simulator framework only for provider/header provenance validation; it is not selectable as an iOS runtime. QuickJS is the default and JSC stays opt-in. When a pin or min-OS note is edited, keep these three files saying the same thing — they are the only place the engine contract is written down outside the CMake modules.

  • Matched V8 cold-fetch validation resolves the immutable builder tag through the GitHub API. CI callers must expose their read-only ${{ github.token }} as GH_TOKEN; otherwise a valid sealed asset can fail after download when the unauthenticated API budget is exhausted. The fetcher deliberately sends that credential only to https://api.github.com and refuses redirects; it is never forwarded to release-asset or cross-origin targets.

  • A source dependency pinned by per-file SHA-256 must be checked out with EOL conversion off, or Windows breaks it before anything builds. Git for Windows defaults to core.autocrlf=true, so every LF becomes CRLF on checkout, every digest in tools/cmake/threejs-runtime-manifest.json mismatches, and PulpDependencies.cmake hard-fails with "Three.js runtime file does not match pinned revision". Three.js opts in by passing verbatim-eol to ensure_shared_git_source in setup.sh, which expands to -c core.autocrlf=false -c core.eol=lf on the clone and pins both keys repo-locally; the FetchContent_Declare carries a matching GIT_CONFIG for the no-shared-cache path. Never fix this by normalizing bytes before hashing — the digest's whole job is to prove the shipped files are upstream's exact bytes. Any future digest-pinned source dependency needs the same opt-in. Note that GIT_CONFIG on FetchContent_Declare alone is not enough on the release path: pulp_register_fetchcontent_source short-circuits FetchContent whenever the shared cache exists, and the release leg primes that cache with ./setup.sh --ci --deps-only first.

  • Repairing an already-converted cache with git checkout --force -- . silently does nothing. Git decides a file is current from the index's cached stat data and never reads the bytes, and the bad checkout recorded its own stat when it was written; --force means "overwrite local modifications", and by the stat cache there are none. git checkout-index -a -f and git read-tree --reset -u fail the same way. The primitive that works is dropping .git/index and then git reset --hard (gitattributes(5)'s own renormalisation recipe), which needs no network even on a --filter=blob:none partial clone. This trap is not specific to line endings — any repair phrased as "check the worktree out again" hits it. A test written the obvious way (poison, immediately repair, assert) will certify the broken primitive, because git distrusts a stat inside its own timestamp granularity and falls back to comparing content; settle the fixture with touch -t 202001010000 plus git update-index --refresh or the test grades its own homework.

  • The visual harness has two raster pins on two different version lines, and "re-bake CI goldens" only means one of them. The C++ Skia archive rasterizes nothing in tools/harness/visual/: its committed PNG golden is produced by the skia-python wheel, pinned separately as determinism.skia_python_smoke_version in tools/deps/manifest.json (mirrored into pins.SKIA_PYTHON_SMOKE_VERSION and the Dockerfile ARG, cross-checked by check_skia_pin.py). That wheel deliberately trails the C++ milestone, so a Skia/Dawn milestone bump leaves the PNG golden and pins.RASTER_GOLDEN_SHA256 correct and untouched, while bumping only the wheel invalidates both without moving a single release-asset digest. When changing the wheel, regenerate through python3 -m tools.harness.visual.runner --generate --all --surface canvas2d and update the recorded sha256 in the same commit: a golden regenerated without its digest fails tests/test_raster_golden.py before any raster runs. pins.RASTER_GOLDEN_VERIFIED_PLATFORMS records which hosts that identity was actually measured on, so add a platform key only after a run on that platform reported the matching digest.

  • The design importer browser runtime is split across bin/browser_capture-v1 and bin/jsx-runtime. Release workflow tests must stage and verify both roots because capture.mjs resolves the materialized binding contract through the sibling path. Keep the source module canonical under tools/import-design/jsx-runtime and test the missing sibling as a failure.

Windows GPU slices

For Windows GPU consumers, record separate windows-x64 and windows-arm64 release assets in the manifest. Select the slice from the CMake target architecture (CMAKE_GENERATOR_PLATFORM when cross-compiling) and mirror each release digest in external/skia-build/VERSION.md before running the fetcher and host validation gates.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

aax

無料

Optional AAX support for Pulp, including developer-supplied Avid SDK setup, CMake enablement, DigiShell/AAX Validator workflows, and local AAX builds on macOS or Windows.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

Configure, implement, and test Pulp's optional desktop Ableton Link tempo-sync adapter while preserving the developer-supplied SDK, licensing, realtime, latency-compensation, and no-install boundaries.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

Maintain Pulp's installed design-time agent capability manifest and public-surface ledger. Use when adding, removing, renaming, or materially changing public audio, MIDI, signal, timebase, or sequence APIs; registering a new algorithm for generators; changing capability support or deprecation state; or repairing agent-capabilities freshness, schema, fingerprint, tombstone, or installed-SDK tests.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

android

無料

Android platform development for Pulp — NDK cross-compilation, Oboe audio, Dawn/Skia GPU rendering, JNI bridge, touch interaction, emulator workflows, and end-to-end smoke validation. Covers build, deploy, debug, and the gotchas discovered during bringup.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

ara

無料

Optional ARA support for Pulp, including developer-supplied ARA SDK setup, CMake enablement, adapter companion APIs, validation, and ARA-aware plugin implementation guidance.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

The measurement surface for ALL Pulp DSP and audio-pipeline work — read it BEFORE writing or gating DSP, not only when something already sounds wrong. Covers the C++ harness (signal generators, metrics, assertions, RenderScenario, contracts), the offline Audio Doctor (magnitude/frequency response, THD/THD+N, phase/group delay), and their Python sibling the Audio Quality Lab (tools/audio/quality-lab — null residual + alignment, LTAS log-spectral distance, spectral flux/centroid, HNR, Theil-Sen drift slope, Kaiser-sinc resampling, license-guarded corpus, regression-net ratchet). TRIGGER on AUTHORING work — "build/design an oscillator/filter/synth/effect", "add a DSP module", "what should the acceptance gate be", "how do I measure aliasing / anti-aliasing / alias floor", "null against a reference", "is this DSP correct", "choose a tolerance", "golden/regression corpus for audio", "measure drift or jitter", "A/B two renders" — AND on DEBUGGING work — "is there sound / no audio / I hear nothing", "does this filter/compressor/synth/delay produce the right signal", "prove the DSP / prove the contract", "measure the frequency response", "what's the THD / is it distorting", "what's the group delay / phase response / measured latency", "magnitude response curve", "render a test tone and assert", "audio regression", "64-frame works but 128 is silent", "sample-rate change pitch-shifted it", "describe what's in this buffer", "audio doctor", "compare before/after a DSP refactor". Reach for this BEFORE hand-rolling any FFT, null test, alias measurement, pitch tracker, or golden-render script — most of it already exists in one of the two lanes. Test/tool layer over HeadlessHost — deterministic, no audio device, no speakers. Off the realtime thread entirely.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

Generous-Corp のスキルをすべて見る

このスキルの問題を報告する