feat(skill): pre-draw checkpoint, docs-sync gate, packaged self-check, ADRs
- SKILL.md: confirm type/pattern/size/cuts with the user before rendering; checklist hooks for the checkpoint and the packaged self-check - scripts/verify-docs-sync.py: CI now fails when the frontmatter description loses a type's lexical hook, the gallery can't reach a shipped example, or the README tree names a missing file - skills/diagram-design/scripts/self_check.py: distilled output checker that ships with the skill so installed agents can verify their own diagrams; adversarial suite in scripts/test-self-check.py - assets/index.html: six new tabs (OAuth sequence + five single-variant examples with a data-single variant lock) so every shipped example is browsable - docs/adr/0001-0004: settled policies recorded (pinned controller, taxonomy freeze, reveal-only autoplay, byte cap + trigger-rich description) - README: It's-working-if section, new gates documented; CONTRIBUTING: gate table, ADR guidance, type-addition invariants; CI: two new steps
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# ADR 0001 — Static by default; one pinned controller for motion
|
||||
|
||||
**Status:** accepted (v2.3)
|
||||
|
||||
## Context
|
||||
|
||||
Diagrams are shared as single HTML files and embedded in posts, decks, and docs. Arbitrary inline JavaScript in a shareable artifact is both a security surface and a review burden: every generated file would need its script audited. Motion, however, genuinely clarifies ordered change (queues filling, policy traces diverging).
|
||||
|
||||
## Decision
|
||||
|
||||
Output is static and script-free by default (`data-motion-mode="none"`). When motion is requested, the file may carry exactly one `<script data-diagram-controls>` block whose body must byte-match the reviewed controller in `assets/template-motion.html`. The match is enforced twice: SHA-256 in `lint-skin.py` and string equality in `verify-motion.py`; the packaged `scripts/self_check.py` repeats the check for installed agents.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Any behavior change to motion is a change to `template-motion.html`, reviewed once, and re-propagated verbatim; hand-edited controllers fail every gate.
|
||||
- The controller cannot be extended per-diagram. A diagram needing bespoke interaction is out of scope for this skill.
|
||||
- The check anchors to the template in the same commit, so a PR that weakens template and copies together still passes the identity check — reviewer attention on `template-motion.html` diffs is the real gate.
|
||||
@@ -0,0 +1,17 @@
|
||||
# ADR 0002 — Semantic patterns never expand the 27-type taxonomy
|
||||
|
||||
**Status:** accepted (v2.3)
|
||||
|
||||
## Context
|
||||
|
||||
Auditing behavior-rich figures (queues, policy traces, trust boundaries) showed the skill could arrange boxes but not model system behavior. The obvious fix — new diagram types — would balloon the taxonomy, dilute the selection guide, and force every new behavior into a new layout grammar.
|
||||
|
||||
## Decision
|
||||
|
||||
Behavior is a separate axis. The seven semantic patterns in `references/semantic-patterns.md` each route to the **nearest existing visual type** for layout; a pattern owns semantic primitives and a tighter budget, never a second layout grammar. The visual-type count stays at 27 unless a genuinely new *layout* grammar appears.
|
||||
|
||||
## Consequences
|
||||
|
||||
- "27 visual types" is a stable, verifiable claim (`verify-semantic-motion.py` and `verify-docs-sync.py` both count it).
|
||||
- A new behavior costs one pattern section plus a routing-table row — not a new type reference, template set, and example triple.
|
||||
- If a pattern ever needs a layout no existing type provides, that is the signal to add a type, with the full §10 shipping set.
|
||||
@@ -0,0 +1,16 @@
|
||||
# ADR 0003 — `reveal` is the only sanctioned autoplay
|
||||
|
||||
**Status:** accepted (v2.3, clarified after review)
|
||||
|
||||
## Context
|
||||
|
||||
The motion contract lists "autoplay on load" as an anti-pattern, yet the canonical controller starts a `reveal` run on load. Early drafts of `animation.md` stated both without reconciling them, which reads as a contradiction to anyone copying the template.
|
||||
|
||||
## Decision
|
||||
|
||||
`reveal` mode may run **once** on initial load — it exists for short ordered explanations where a click-to-start would be friction — and then remains complete. It never restarts on viewport re-entry, tab return, or without an explicit Replay action. Every other mode is user-initiated (`step`) or CSS-scoped (`loop`); `none` stays inert. Under `prefers-reduced-motion: reduce` and without JavaScript, all modes show the complete static frame.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The anti-pattern is precisely "repeated or attention-trapping autoplay," not "any motion before interaction."
|
||||
- `verify-motion.py` needs no autoplay heuristic: the pinned controller is the only code that can start a run, and it implements exactly this policy.
|
||||
@@ -0,0 +1,19 @@
|
||||
# ADR 0004 — SKILL.md byte cap and the trigger-rich description
|
||||
|
||||
**Status:** accepted (v2.3, cap raised after review)
|
||||
|
||||
## Context
|
||||
|
||||
`SKILL.md` loads into an agent's context on every skill invocation, so it must stay lean; a byte cap keeps growth honest. But v2.3 initially set the cap at 35,000 bytes and slimmed the frontmatter `description` to fit — deleting all 27 type names. The description is the only text an agent sees *before* deciding to load the skill: removing "flowchart", "Gantt", "org chart" from it removes the lexical hooks that make "make me a flowchart" invoke the skill at all.
|
||||
|
||||
## Decision
|
||||
|
||||
Two rules, in priority order:
|
||||
|
||||
1. The frontmatter `description` must name every visual type in the selection table (enforced by `scripts/verify-docs-sync.py`) plus the import formats and major feature vocabulary. Routing surface is never traded for body prose.
|
||||
2. `MAX_SKILL_BYTES` is 40,000 (enforced by `scripts/verify-semantic-motion.py`). When the file approaches the cap, cut body prose or move detail into `references/` — never the description.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Adding a visual type requires touching the description; CI fails otherwise, by design.
|
||||
- The cap is measured on raw bytes with `core.autocrlf=false` pinned in CI checkout; Windows contributors should keep LF endings for `SKILL.md`.
|
||||
Reference in New Issue
Block a user