plugins/compound-engineering/skills/html-artifact-mutator/SKILL.md
Mutates a single field or content region of an existing self-contained HTML artifact in place (island-first, no-added-facts, injection-safe) without regenerating the document from scratch. Invoked by a workflow command whenever it needs to back-write into an artifact it already composed -- e.g. a ref/status update, or a content rewrite that must re-project the affected view -- never by the user directly.
npx skillsauth add the-rabak/compound-engineering-plugin html-artifact-mutatorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The update capability of the html-artifacts subsystem (CONTEXT.md → Composer skill is
create; this skill is update). A workflow command invokes this skill when it needs to
change a fact inside an artifact it (or another command) already wrote, without touching anything
else in the document. It never talks to the user directly and never asks for design input.
This is the single, shared owner of every in-place HTML-artifact edit. Every mutating consumer (deepen-plan back-writes, grill-with-docs enrichment, architecture-handoff status flips, ref/status updates from later workflow stages) goes through this one skill, so island-first + no-added-facts + re-projection stay identical everywhere instead of drifting per caller.
Before mutating anything, load:
commands/workflows/references/html-artifacts/island-contract.md — the fixed-core schema, the
serialization primitive, the field-coverage map, and this skill's Mutation contract section
(mutable-region policy, the two mutation classes, render_meta re-projection rules). The
mutation this skill performs MUST conform to it exactly.commands/workflows/references/html-artifacts/primitives-catalog.md — needed only when a
content mutation dispatches re-projection (see Workflow, step 4); the scalar path never needs
it.If the contract cannot be loaded, stop and report it as unavailable instead of guessing at the schema or inventing a mutation shape.
The caller (a workflow command) supplies:
target_path — the existing artifact file to mutate, e.g. docs/plans/2026-07-09-feat-csv-export-plan.html.
The file MUST already exist and already contain a valid #artifact-data island; this skill
never creates a new artifact (that is the composer's job).mutation — exactly one of:
{ class: "scalar", field: string, value: unknown } — field MUST be a dotted path inside
the scalar mutable region (see Mutable-region policy below). Used for back-writes like a
status flip or a refs.tickets_ref fill-in once ticketization exists.{ class: "content", patch: Record<string, unknown> } — each key of patch is a top-level
Tier-2/3/4 island field whose entire value is replaced (supply the complete new value, e.g.
the full slices[] array with one entry changed — not a deep partial diff). patch MUST NOT
contain any Tier-1 envelope key (including render_meta); such a mutation is rejected.If mutation requests a field outside its class's mutable region, stop and report exactly which
field is out of policy rather than attempting an unsafe write.
The authoritative Mutable-region policy table — which scalar/content fields are legal to mutate
per kind (including the architecture kind) and whether each class re-projects — lives in
island-contract.md's Mutable-region policy section. Load it and follow that table; it is
the single source of truth for both mutation classes. Do not re-list or re-derive per-kind field
sets here — that duplication is exactly what causes a second table to drift from the canonical
one.
render_meta is never mutated by either class. Scalar mutations don't touch it because they
never re-project. Content mutations don't touch it because re-projection must reuse the
recorded { archetypes, design_seed }, not regenerate it — that reuse is exactly what keeps the
design stable across edits (no classifier drift between one edit and the next).
target_path's raw file contents. Never scrape rendered HTML for facts — only the
island is ever read for data.island-contract.md's extractIslandData). If extraction fails, stop and report the exact
error code (MISSING_ISLAND / EMPTY_ISLAND / INVALID_JSON / MISSING_REQUIRED_FIELD) —
never attempt a partial or best-effort write against a malformed island.field is in the scalar mutable region (reject otherwise), then
set that one field to value. Every other field on the island object is untouched.patch is a Tier-1 envelope key (reject otherwise),
then shallow-merge patch onto the island object (each key's value fully replaces the
existing value at that key). render_meta is carried forward unchanged.island-contract.md →
"Serialization primitive"): JSON.stringify, then <→\u003C, >→\u003E, /→\u002F,
U+2028→\u2028, U+2029→\u2029. Replace the #artifact-data script tag's inner text with
this string — the opening/closing tags and every other byte of the document stay untouched.
Never re-implement or re-derive this escape — do not use HTML-entity escaping (<)
for the island; it is not reversible inside <script type="application/json"> (see
island-contract.md for why).<span class="badge">{value}</span> for
type/status/date), replace that element's text with the HTML-entity-escaped new value.
If zero or more than one such element exists — or the field's old value was null/absent
and is being set for the first time (e.g. a refs.tickets_ref: null → "..." back-write,
where there is no existing rendered token to find at all) — the in-place rewrite is unsafe or
impossible; instead, append a rendered "Related Artifacts" section near the end of <body>
stating the new value (backed by the same island field, never inventing new facts), and log
that the safer fallback ran instead of an ambiguous in-place rewrite or a silent no-op. This
is light enough to run inline; it never dispatches a subagent.SKILL.md in re-projection mode, the mutated island (already re-serialized and written
to target_path by step 4), and the recorded render_meta from that island. The subagent's
job is to re-render only the affected section(s) of the visible HTML from the current
island content, reusing the exact archetypes/design_seed already recorded — never
reclassifying, never touching unrelated sections, never inventing a fact the island doesn't
carry. The subagent returns only the rewritten artifact path; this skill does not consider
the mutation complete, and must not report success to its caller, until that re-projection
has run — a content mutation that stops after step 4 has updated the machine contract but
left the human view stale, which is exactly the drift this skill exists to prevent.REQUIRED_FIXED_CORE_KEYS entry, and the mutated field(s) hold the requested
new value(s) — every other field is untouched.render_meta is byte-identical to what it was before the
mutation (reused, not regenerated) and that re-projection actually ran (no stale rendered
fact left contradicting the current island).null/absent (newly set for the first time):
there is no existing rendered token to patch, so that case routes to the fallback too, exactly
like zero rendered matches — it must never be treated as a no-op.target_path if extraction fails for any reason — report the exact error code
instead of a partial or silent write. A malformed or missing island is a hard stop, not a
best-effort patch.status/refs.* only; a content mutation is Tier-2/3/4 only and must never include
render_meta or any other Tier-1 key.serialize/extract/mutate module. The only place a reusable
JS implementation of these primitives is allowed to live is tests/support/island-spec.ts
(imported only by tests/html-artifact-island.test.ts and tests/html-artifact-mutation.test.ts),
which this skill never imports.development
Mutates a single field or content region of an existing self-contained HTML artifact in place (island-first, no-added-facts, injection-safe) without regenerating the document from scratch. Invoked by a workflow command whenever it needs to back-write into an artifact it already composed -- e.g. a ref/status update, or a content rewrite that must re-project the affected view -- never by the user directly.
development
Composes a self-contained, interactive HTML artifact (island-first, single file, token-layer themed, injection-safe) from a workflow command's structured plan payload. Invoked by a workflow command at its artifact-write step -- currently `/workflows:plan` -- never by the user directly.
development
Composes a self-contained, interactive HTML artifact (island-first, single file, token-layer themed, injection-safe) from a workflow command's structured plan payload. Invoked by a workflow command at its artifact-write step -- currently `/workflows:plan` -- never by the user directly.
testing
This skill should be used at the end of core compound-engineering workflows to inspect completed artifacts, show the workflow progress checklist, and give the exact next-session command with inputs.