Problem
The evaluation genre resolves from metadata.provenance.preset (or the per-call genre param), but nothing can set that stamp on its own:
apply_preset writes it — but only as a side effect of applying the preset's entire token set and components, which is wrong for a canvas that already has its own design system (you want the genre, not the restyle).
- The per-call
genre param works but is ephemeral — every future canvas_evaluate/canvas_autofix caller (and the viewer, which reads only the provenance stamp for its quality panel) must remember to pass it. A genre is a property of the canvas, not of one evaluation call.
So the only way to durably declare "this canvas is a dashboard" without restyling it is hand-editing the repo JSON. That's not hypothetical: it's exactly what happened in the #150 incident — the agent hand-stamped provenance.preset on a bound canvas, which is how the stale-evaluation-cache hole was found. PR #154 fixed the cache; the missing capability that caused the hand-edit is still missing.
Proposal
A minimal, explicit stamp — e.g. canvas_set_genre({ canvasId, genre }) (or genre: null to clear). Writes metadata.provenance.preset, bumps lastModified, done. Alternatives considered:
genre param on canvas_create / apply_structure — nice ergonomics for new canvases, but doesn't help the common case (an existing canvas that needs calibrating), so it's a complement, not a substitute.
- A generic metadata-stamping tool — broader surface than the need; genre is the only metadata field agents legitimately want to set directly today.
Whatever the shape: since v1.10 the evaluate result's genre.source field distinguishes explicit vs provenance, so a stamped genre stays auditable.
Notes
- Guardrail worth keeping: the GOTCHAS "never use genre to dodge flags on a marketing page" guidance should appear in the new tool's docstring too — a one-call stamp makes gaming the gate one call easier.
- The
versionHash (Phase 23) deliberately excludes metadata, so stamping a genre would NOT invalidate recorded approvals — that's correct and worth stating in the docstring.
Workaround in the meantime
Pass genre explicitly on every canvas_evaluate/canvas_autofix call, or run apply_preset and accept the token churn (it preserves workspace/project-inherited tokens, but canvas-level overrides get replaced).
Problem
The evaluation genre resolves from
metadata.provenance.preset(or the per-callgenreparam), but nothing can set that stamp on its own:apply_presetwrites it — but only as a side effect of applying the preset's entire token set and components, which is wrong for a canvas that already has its own design system (you want the genre, not the restyle).genreparam works but is ephemeral — every futurecanvas_evaluate/canvas_autofixcaller (and the viewer, which reads only the provenance stamp for its quality panel) must remember to pass it. A genre is a property of the canvas, not of one evaluation call.So the only way to durably declare "this canvas is a dashboard" without restyling it is hand-editing the repo JSON. That's not hypothetical: it's exactly what happened in the #150 incident — the agent hand-stamped
provenance.preseton a bound canvas, which is how the stale-evaluation-cache hole was found. PR #154 fixed the cache; the missing capability that caused the hand-edit is still missing.Proposal
A minimal, explicit stamp — e.g.
canvas_set_genre({ canvasId, genre })(orgenre: nullto clear). Writesmetadata.provenance.preset, bumpslastModified, done. Alternatives considered:genreparam oncanvas_create/apply_structure— nice ergonomics for new canvases, but doesn't help the common case (an existing canvas that needs calibrating), so it's a complement, not a substitute.Whatever the shape: since v1.10 the evaluate result's
genre.sourcefield distinguishesexplicitvsprovenance, so a stamped genre stays auditable.Notes
versionHash(Phase 23) deliberately excludes metadata, so stamping a genre would NOT invalidate recorded approvals — that's correct and worth stating in the docstring.Workaround in the meantime
Pass
genreexplicitly on everycanvas_evaluate/canvas_autofixcall, or runapply_presetand accept the token churn (it preserves workspace/project-inherited tokens, but canvas-level overrides get replaced).