Update Skia
Use this skill as the source of truth for both a developer-run update and the automated sync.
The workflow only supplies resolved inputs, a prepared host, and automated PR delivery.
Skia C++ -> SkiaSharp C API -> generated P/Invoke -> managed wrappers
Run from the mono/SkiaSharp repository root. Each phase lives in a separate reference so only
the current work enters context.
Start state
Automation exports the SKIA_SYNC_* variables below. A local run resolves them in Phase 01.
Never replace supplied automation values with assumptions about main, skiasharp, or branch
names.
| Runtime value |
Environment variable |
Meaning |
{CURRENT} |
SKIA_SYNC_CURRENT |
Milestone on the parent base |
{TARGET} |
SKIA_SYNC_TARGET |
Requested target milestone |
{UPSTREAM_REF} |
SKIA_SYNC_UPSTREAM_REF |
chrome/m{TARGET} or main |
{BASE_BRANCH} |
SKIA_SYNC_BASE_BRANCH |
Parent PR base |
{PARENT_BASE_SHA} |
SKIA_SYNC_PARENT_BASE_SHA |
Exact parent base commit used for metadata comparison |
{SKIA_BASE_BRANCH} |
SKIA_SYNC_SKIA_BASE_BRANCH |
mono/skia PR base |
{SKIA_BASE_SHA} |
SKIA_SYNC_SKIA_BASE_SHA |
Exact mono/skia commit recorded by the parent base |
{HEAD_BRANCH} |
SKIA_SYNC_HEAD_BRANCH |
Feature branch used in both repositories |
{IS_RELEASE} |
SKIA_SYNC_IS_RELEASE |
Whether the selected base is a release line |
{BASE_UPSTREAM_SHA} |
SKIA_SYNC_BASE_UPSTREAM_SHA |
Exact upstream commit recorded by the parent base |
{TARGET_UPSTREAM_SHA} |
SKIA_SYNC_TARGET_UPSTREAM_SHA |
Exact fetched target upstream commit |
{PLATFORM} |
SKIA_SYNC_PLATFORM |
Native Cake target suffix |
{ARCH} |
SKIA_SYNC_ARCH |
Native architecture |
SKIA_SYNC_AUTOMATION=1 selects the automation handoff in Phase 11. Without it, use the
repository PR templates and normal developer pushes.
Initialize the artifact directory once:
ARTIFACT_DIR="${SKIA_SYNC_ARTIFACT_DIR:-${TMPDIR:-/tmp}/skia-sync-agent}"
mkdir -p "$ARTIFACT_DIR"
Definition of success
An update is complete only when:
- The authoritative old-upstream-to-target range was analyzed before merging.
- The mono/skia result is a genuine two-parent merge with every fork patch and dependency
decision accounted for.
- The updated native source builds; downloaded old native artifacts were never substituted.
- Bindings were regenerated and every required managed wrapper was reviewed.
- The final unfiltered
tests/SkiaSharp.Tests.Console.slnx run passes every host, including
every GPU backend required by GpuPolicy on the validation host.
- The parent points to the exact tested mono/skia commit.
- Both PR descriptions identify untested platforms and are ready for human review.
Working rules
- Create feature branches in both repositories before changes; never commit to protected branches.
- Use a genuine two-parent merge in mono/skia; never use a tree-override merge.
- Preserve every fork patch unless upstream contains an equivalent or improved form.
- Mark a removed patch
upstreamed only after enumerating every independent behavior in its old
delta and locating each one in the target; one upstreamed hunk does not cover another lost hunk.
- Classify dependency revisions against the fork base, not only the prior upstream milestone.
- Treat final
DEPS as ground truth: every enabled revision that differs from the fork base must
have a matching final decision, exact-SHA evidence, and reconciled Component Governance metadata.
A dependency recorded as preserved must still equal the fork-base revision.
- Let
update_versions.py identify dependency changes from exact base/final DEPS. For every tracked
changed dependency, and every legacy tracked registration missing verification evidence, derive
the semantic version from checked-out source and complete the skia_dependency fields before the
helper can pass. Never update a manifest version when its DEPS identity did not change.
- Components not sourced from Skia DEPS, including ANGLE and its dependencies, are updated in
separate dependency PRs rather than bundled into a Skia upstream sync.
- Never use
externals-download after a submodule/native/C API change.
- Never hand-edit
*.generated.cs; regenerate it.
- Keep public managed ABI additive.
- A focused project test is diagnostic only; it never satisfies the final gate.
- GPU bring-up failures are test failures. The validation environment must provide every backend
required by
GpuPolicy for its platform.
- Diagnose failures from repository evidence. Do not add one-off compiler/GN flags, skip tests,
weaken assertions, or encode milestone-specific answers to make one run green.
- Execute the update phases in this agent. Do not delegate the full update, or any mutating,
build, test, or delivery phase, to a general-purpose/background agent. Only Phase 03's explicitly
read-only discrepancy review may be delegated.
- Run long builds and full test suites in the foreground as one shell invocation. Do not use
nohup, &, or agent-turn progress polling. If the shell tool keeps a command running, block on
that existing session and inspect its output once after it exits.
- Keep complete logs and broad diffs in
$ARTIFACT_DIR; inspect bounded excerpts instead of
streaming large generated files, manifests, or successful build/test logs into model context.
- Do not create PRs, write automation handoff files, or report completion while any gate fails.
- In automation, no-work is handled before the agent starts. A started agent that cannot
complete must fail rather than return success-shaped output.
Modes
| Mode |
Version behavior |
| Normal milestone |
Advance milestone, soname, assembly/file, and package versions |
| Release-line bug-fix |
Keep versions; advance Skia hashes only |
Upstream main tip |
Keep versions; still regenerate, build, and test because APIs may change |
CURRENT == TARGET means bug-fix behavior only when {UPSTREAM_REF} != main.
Phase router
Open the router's exact linked phase file once, complete its gate, then move to the next row. Do not
glob for alternate phase names or reread an unchanged phase file.
| Phases |
Read when starting |
Required outcome |
| 01–03 Resolve & research |
references/phases/01-03-research.md |
Authoritative runtime state, diff analysis, and independent review |
| 04–05 Branch & merge |
references/phases/04-05-branch-and-merge.md |
Correct branches and audited two-parent upstream merge |
| 06–07 Update & native build |
references/phases/06-07-update-and-build.md |
Version files consistent and updated native source builds |
| 08–10 Bindings & tests |
references/phases/08-10-bindings-and-tests.md |
Bindings reviewed and final unfiltered solution green |
| 11–11 Ship |
references/phases/11-11-ship.md |
Local PRs or automation handoff; no merge without approval |
Do not preload other phase files. The current phase file names any narrower reference section
needed for that phase.
Deterministic helpers
- Automation stages this entire skill outside the mutable product checkout and exports its path as
SKIA_SYNC_SKILL_DIR. After changing the product branch, continue reading phase references and
running helpers from that staged directory rather than the branch-local .agents tree.
scripts/update_versions.py updates and validates version surfaces, Skia hashes, and deterministic
DEPS-to-Component-Governance identity/review signals.
scripts/regenerate_bindings.py runs every binding configuration from the checked-out
source and reports new native functions.
scripts/audit_fork_patches.py compares the old and new fork deltas and fails while any
added, removed, or changed patch lacks a final evidence-backed disposition.
These scripts are idempotent and are the source of truth for their phases. Do not manually
recreate their behavior.
Additional references
- references/known-gotchas.md — read only the phase-specific
sections directed by a phase file.
- references/breaking-changes-checklist.md —
detailed Phase 2 audit checklist.
- references/validation-prompt.md — independent Phase 3 prompt.
- documentation/dev/dependencies.md —
dependency and
cgmanifest.json model.
Completion
Report the upstream ref/SHA, fork-patch and dependency decisions, C API/binding changes,
exact build and per-host test results, both PR links, and unresolved cross-platform review.
Do not merge either PR without explicit approval.
1---2name: update-skia3description: Update the Skia graphics library to a new Chrome milestone in SkiaSharp's mono/skia fork. Handles upstream merge, fork-patch preservation, dependency compatibility, C API adaptation, binding regeneration, full backend testing, and coordinated dual-repo PRs. Use whenever the user asks to update/bump Skia, merge upstream Skia, update the Skia submodule, sync a milestone or release line, merge upstream main, or check the current Skia milestone/version. For an individual dependency update, use native-dependency-update.4---56# Update Skia78Use this skill as the source of truth for both a developer-run update and the automated sync.9The workflow only supplies resolved inputs, a prepared host, and automated PR delivery.1011`Skia C++ -> SkiaSharp C API -> generated P/Invoke -> managed wrappers`1213Run from the mono/SkiaSharp repository root. Each phase lives in a separate reference so only14the current work enters context.1516## Start state1718Automation exports the `SKIA_SYNC_*` variables below. A local run resolves them in Phase 01.19Never replace supplied automation values with assumptions about `main`, `skiasharp`, or branch20names.2122| Runtime value | Environment variable | Meaning |23|---|---|---|24| `{CURRENT}` | `SKIA_SYNC_CURRENT` | Milestone on the parent base |25| `{TARGET}` | `SKIA_SYNC_TARGET` | Requested target milestone |26| `{UPSTREAM_REF}` | `SKIA_SYNC_UPSTREAM_REF` | `chrome/m{TARGET}` or `main` |27| `{BASE_BRANCH}` | `SKIA_SYNC_BASE_BRANCH` | Parent PR base |28| `{PARENT_BASE_SHA}` | `SKIA_SYNC_PARENT_BASE_SHA` | Exact parent base commit used for metadata comparison |29| `{SKIA_BASE_BRANCH}` | `SKIA_SYNC_SKIA_BASE_BRANCH` | mono/skia PR base |30| `{SKIA_BASE_SHA}` | `SKIA_SYNC_SKIA_BASE_SHA` | Exact mono/skia commit recorded by the parent base |31| `{HEAD_BRANCH}` | `SKIA_SYNC_HEAD_BRANCH` | Feature branch used in both repositories |32| `{IS_RELEASE}` | `SKIA_SYNC_IS_RELEASE` | Whether the selected base is a release line |33| `{BASE_UPSTREAM_SHA}` | `SKIA_SYNC_BASE_UPSTREAM_SHA` | Exact upstream commit recorded by the parent base |34| `{TARGET_UPSTREAM_SHA}` | `SKIA_SYNC_TARGET_UPSTREAM_SHA` | Exact fetched target upstream commit |35| `{PLATFORM}` | `SKIA_SYNC_PLATFORM` | Native Cake target suffix |36| `{ARCH}` | `SKIA_SYNC_ARCH` | Native architecture |3738`SKIA_SYNC_AUTOMATION=1` selects the automation handoff in Phase 11. Without it, use the39repository PR templates and normal developer pushes.4041Initialize the artifact directory once:4243```bash44ARTIFACT_DIR="${SKIA_SYNC_ARTIFACT_DIR:-${TMPDIR:-/tmp}/skia-sync-agent}"45mkdir -p "$ARTIFACT_DIR"46```4748## Definition of success4950An update is complete only when:5152- The authoritative old-upstream-to-target range was analyzed before merging.53- The mono/skia result is a genuine two-parent merge with every fork patch and dependency54 decision accounted for.55- The updated native source builds; downloaded old native artifacts were never substituted.56- Bindings were regenerated and every required managed wrapper was reviewed.57- The final **unfiltered** `tests/SkiaSharp.Tests.Console.slnx` run passes every host, including58 every GPU backend required by `GpuPolicy` on the validation host.59- The parent points to the exact tested mono/skia commit.60- Both PR descriptions identify untested platforms and are ready for human review.6162## Working rules6364- Create feature branches in both repositories before changes; never commit to protected branches.65- Use a genuine two-parent merge in mono/skia; never use a tree-override merge.66- Preserve every fork patch unless upstream contains an equivalent or improved form.67- Mark a removed patch `upstreamed` only after enumerating every independent behavior in its old68 delta and locating each one in the target; one upstreamed hunk does not cover another lost hunk.69- Classify dependency revisions against the **fork base**, not only the prior upstream milestone.70- Treat final `DEPS` as ground truth: every enabled revision that differs from the fork base must71 have a matching final decision, exact-SHA evidence, and reconciled Component Governance metadata.72 A dependency recorded as preserved must still equal the fork-base revision.73- Let `update_versions.py` identify dependency changes from exact base/final DEPS. For every tracked74 changed dependency, and every legacy tracked registration missing verification evidence, derive75 the semantic version from checked-out source and complete the `skia_dependency` fields before the76 helper can pass. Never update a manifest version when its DEPS identity did not change.77- Components not sourced from Skia DEPS, including ANGLE and its dependencies, are updated in78 separate dependency PRs rather than bundled into a Skia upstream sync.79- Never use `externals-download` after a submodule/native/C API change.80- Never hand-edit `*.generated.cs`; regenerate it.81- Keep public managed ABI additive.82- A focused project test is diagnostic only; it never satisfies the final gate.83- GPU bring-up failures are test failures. The validation environment must provide every backend84 required by `GpuPolicy` for its platform.85- Diagnose failures from repository evidence. Do not add one-off compiler/GN flags, skip tests,86 weaken assertions, or encode milestone-specific answers to make one run green.87- Execute the update phases in this agent. Do not delegate the full update, or any mutating,88 build, test, or delivery phase, to a general-purpose/background agent. Only Phase 03's explicitly89 read-only discrepancy review may be delegated.90- Run long builds and full test suites in the foreground as one shell invocation. Do not use91 `nohup`, `&`, or agent-turn progress polling. If the shell tool keeps a command running, block on92 that existing session and inspect its output once after it exits.93- Keep complete logs and broad diffs in `$ARTIFACT_DIR`; inspect bounded excerpts instead of94 streaming large generated files, manifests, or successful build/test logs into model context.95- Do not create PRs, write automation handoff files, or report completion while any gate fails.96- In automation, no-work is handled before the agent starts. A started agent that cannot97 complete must fail rather than return success-shaped output.9899## Modes100101| Mode | Version behavior |102|---|---|103| Normal milestone | Advance milestone, soname, assembly/file, and package versions |104| Release-line bug-fix | Keep versions; advance Skia hashes only |105| Upstream `main` tip | Keep versions; still regenerate, build, and test because APIs may change |106107`CURRENT == TARGET` means bug-fix behavior only when `{UPSTREAM_REF} != main`.108109## Phase router110111Open the router's exact linked phase file once, complete its gate, then move to the next row. Do not112glob for alternate phase names or reread an unchanged phase file.113114| Phases | Read when starting | Required outcome |115|---|---|---|116| 01–03 Resolve & research | [references/phases/01-03-research.md](references/phases/01-03-research.md) | Authoritative runtime state, diff analysis, and independent review |117| 04–05 Branch & merge | [references/phases/04-05-branch-and-merge.md](references/phases/04-05-branch-and-merge.md) | Correct branches and audited two-parent upstream merge |118| 06–07 Update & native build | [references/phases/06-07-update-and-build.md](references/phases/06-07-update-and-build.md) | Version files consistent and updated native source builds |119| 08–10 Bindings & tests | [references/phases/08-10-bindings-and-tests.md](references/phases/08-10-bindings-and-tests.md) | Bindings reviewed and final unfiltered solution green |120| 11–11 Ship | [references/phases/11-11-ship.md](references/phases/11-11-ship.md) | Local PRs or automation handoff; no merge without approval |121122Do not preload other phase files. The current phase file names any narrower reference section123needed for that phase.124125## Deterministic helpers126127- Automation stages this entire skill outside the mutable product checkout and exports its path as128 `SKIA_SYNC_SKILL_DIR`. After changing the product branch, continue reading phase references and129 running helpers from that staged directory rather than the branch-local `.agents` tree.130- `scripts/update_versions.py` updates and validates version surfaces, Skia hashes, and deterministic131 DEPS-to-Component-Governance identity/review signals.132- `scripts/regenerate_bindings.py` runs every binding configuration from the checked-out133 source and reports new native functions.134- `scripts/audit_fork_patches.py` compares the old and new fork deltas and fails while any135 added, removed, or changed patch lacks a final evidence-backed disposition.136137These scripts are idempotent and are the source of truth for their phases. Do not manually138recreate their behavior.139140## Additional references141142- [references/known-gotchas.md](references/known-gotchas.md) — read only the phase-specific143 sections directed by a phase file.144- [references/breaking-changes-checklist.md](references/breaking-changes-checklist.md) —145 detailed Phase 2 audit checklist.146- [references/validation-prompt.md](references/validation-prompt.md) — independent Phase 3 prompt.147- [documentation/dev/dependencies.md](../../../documentation/dev/dependencies.md) —148 dependency and `cgmanifest.json` model.149150## Completion151152Report the upstream ref/SHA, fork-patch and dependency decisions, C API/binding changes,153exact build and per-host test results, both PR links, and unresolved cross-platform review.154Do not merge either PR without explicit approval.