SuperAPI AI Directory

dym-diagram-design-contributor-gates

Design & creation

View repository

Updated 10-18 01:21

About this skill

Skill: dym-diagram-design-contributor-gates — Contributor branch: check gates and release rules

Why use it: only read this file when you modify Diagram Design itself — add a diagram type, change the extractor, change the icon set. Regular users never need to come here; 01–06 is enough.

What this file generates: a branch that passes the entire CI gate locally before pushing.

This entire file is shell commands. Does not depend on 01–06, but you should read 04 first, because the extractor's exit code contract is something you are not allowed to break.


1. Preparation

git clone git@github.com:cathrynlavery/diagram-design.git
cd diagram-design
python3 --version   # phải >= 3.10; CI chạy 3.11 và 3.12 trên Linux/Windows/macOS

There is no npm install, no mandatory venv. Only two optional things:

python3 -m pip install playwright && python3 -m playwright install chromium  # cho lint-render + render screenshot
python3 -m pip install "Pillow==12.1.1"                                      # cho verify thumbnail README

Both versions are hard-pinned in CI (PLAYWRIGHT_VERSION: "1.62.0", PILLOW_VERSION: "12.1.1"). The reason is written plainly in ci.yml: the oracle of lint-render.py is pixel, so the browser is part of the contract — upgrading Playwright and Chromium must be done together, deliberately.

Process rules from CONTRIBUTING.md §"Before you start":

  • Create an issue first for anything nontrivial (new type, behavior change, touching the import grammar). Small fixes and docs can go straight to a PR.
  • Work on a branch — never commit directly to main.
  • One PR = one concern.

2. RULE NUMBER ONE: do not bump the version in a PR

This is the thing that turns PRs red the most, and it is counterintuitive.

Three manifests — .claude-plugin/plugin.json, .codex-plugin/plugin.json, .factory-plugin/plugin.json — are bumped automatically on main after each merge by the workflow auto-bump.yml (ADR 0009). PRs must leave untouched all three. CI rejects any change to them:

python3 scripts/verify-plugin-package.py --require-no-bump origin/main

Need a release larger than a patch? Write it in the PR description, and the maintainer will attach the label release:minor or release:major before merging; the label decides the bump level. scripts/bump-plugin-version.py still exists but is for workflows and maintainers — contributors never run it.

Design reason: keep open PRs from conflicting with each other on every merge.


3. The 40,000-byte budget of SKILL.md — only 4 bytes left

The semantic-pattern gate limits skills/diagram-design/SKILL.md to 40,000 bytes so the installed skill can still load (ADR 0004; the constant MAX_SKILL_BYTES = 40_000 at scripts/verify-semantic-motion.py:23).

Current size, measured at commit 4451ead:

$ wc -c < skills/diagram-design/SKILL.md
39996

Exactly 4 bytes left. Adding one word to SKILL.md is the CI break. When this gate turns red: reduce duplication or move details into a file that references/ is routed. Absolutely do not remove the routing vocabulary from frontmatter — that is what makes the skill trigger at the right time.


4. Run all gates before pushing

CONTRIBUTING.md provides a chain of && about 48 commands long. Paste it as is:

python3 scripts/test-plugin-package.py \
  && python3 scripts/test-maintainer-policy.py \
  && python3 scripts/verify-plugin-package.py --require-no-bump origin/main \
  && claude plugin validate . --strict \
  && python3 scripts/test-lint-a11y.py \
  && python3 scripts/verify-semantic-motion.py --markdown-only \
  && python3 scripts/verify-semantic-motion.py --example-only \
  && python3 scripts/verify-motion.py --shipped \
  && python3 scripts/lint-skin.py --all --baseline \
  && python3 scripts/lint-render.py --self-test \
  && python3 scripts/lint-render.py --all \
  && python3 scripts/test-verify-polar.py && python3 scripts/verify-polar.py \
  && python3 scripts/verify-sequence-oauth.py \
  && python3 scripts/test-verify-semantic-motion.py \
  && python3 scripts/test-verify-sequence-oauth.py \
  && python3 scripts/verify-drawio-import.py && python3 scripts/test-verify-drawio-import.py \
  && python3 scripts/verify-mermaid-import.py \
  && python3 scripts/test-verify-motion.py \
  && python3 scripts/verify-doctor.py && python3 scripts/test-verify-doctor.py \
  && python3 scripts/verify-docs-sync.py && python3 scripts/test-verify-docs-sync.py \
  && python3 scripts/verify-screenshot-freshness.py \
  && python3 scripts/test-build-readme-thumbs.py && python3 scripts/build-readme-thumbs.py --check \
  && python3 scripts/test-self-check.py \
  && python3 scripts/verify-geometry.py --all && python3 scripts/test-verify-geometry.py \
  && python3 scripts/verify-treemap.py --all && python3 scripts/test-verify-treemap.py \
  && python3 scripts/verify-dumbbell.py && python3 scripts/test-verify-dumbbell.py \
  && python3 scripts/verify-slopegraph.py --all && python3 scripts/test-verify-slopegraph.py \
  && python3 scripts/verify-ridgeline.py --all && python3 scripts/test-verify-ridgeline.py \
  && python3 scripts/verify-sankey.py --all && python3 scripts/test-verify-sankey.py \
  && python3 scripts/verify-bubble.py --all && python3 scripts/test-verify-bubble.py \
  && python3 scripts/verify-bump.py --all && python3 scripts/test-verify-bump.py \
  && python3 scripts/verify-beeswarm.py --all && python3 scripts/test-verify-beeswarm.py \
  && python3 scripts/verify-skin-polarity.py --all && python3 scripts/test-verify-skin-polarity.py

A notable pattern: each verifier has an accompanying test. verify-sankey.py that checks the real file; test-verify-sankey.py checks that that very verifier catches both the passing case and the adversarial case. A broken linter must not be allowed to report the repo as clean. If you fix a verifier, you must fix its test too.

Actual measurement results (macOS, Python 3.9.6, clean clone at 4451ead)

Gate rc Note
lint-skin.py --all --baseline 0 153 file(s) checked, 20 skipped, 0 finding(s)
verify-geometry.py --all 0 155 file(s) checked, 0 finding(s)
verify-semantic-motion.py --markdown-only 0 mode, primitive, static fallback, a11y
verify-motion.py --shipped 0 every shipped motion file
verify-drawio-import.py 0 All draw.io import gates passed.
verify-mermaid-import.py 0 All Mermaid import gates passed.
verify-docs-sync.py 0 description hook, gallery, README tree, reference link, routing
test-self-check.py 0 All self-check tests passed
verify-plugin-package.py --current-only 0 Claude/Codex/Factory all 2.6.12
verify-doctor.py 1 red because of the machine environment, not because of the code

Warning about verify-doctor.py: it is not a unit test — it actually runs doctor and returns rc according to your machine's condition. On the Python 3.9.6 machine it prints:

Doctor summary: FAIL (3 pass, 1 warn, 1 fail)
[FAIL] Python runtime: Python 3.9.6 found via python3 at /usr/bin/python3; Diagram Design requires Python >= 3.10.
[WARN] Playwright PNG export readiness: Playwright package is not available in the active Python interpreter.

This gate is red because of the environment, not because of your changes. Upgrade python3 to 3.10+ and run again. The Playwright warning is a genuine false negative — see 01 §4 trap 2: the probe in scripts/verify-doctor.py:158 uses playwright.__version__, a package attribute that does not exist.

Many gates run on 3.9 (CI also has a separate job python39-compat for test-lint-a11y.py and lint-skin.py --all --baseline), but do not rely on that — dev needs 3.10+.


5. How to read gate errors

Red gate Meaning and how to fix
verify-plugin-package.py Reports version change → drop the manifest change from the branch. Reports packaging → keep every marketplace pointing to the repo root and shared skills at skills/diagram-design/SKILL.md.
lint-skin.py The message states the file, line, category: color, font-family, a11y, external-asset, pure-black, script. Colors must come from the palette in style-guide.md; fonts from the allowed list. The linter also requires controllers pinned by SHA from template-motion.html verbatim, and rejects remote resources, CSS @import, CSS url() that is not a fragment, event handlers, srcdoc, executable URLs, and leftover scripts.
verify-*.py The extractor's real behavior no longer matches the fixture/docs, or the reference/command/prompt wiring is off. Fix the source of truth — do not loosen the test to make it pass.
verify-geometry.py A label mask overlapping a node declared after it → the fill node will clip the label at render. Move the label to the empty stretch of the connector, keep a 6–10px gap with the stroke per SKILL.md §6, and do not shrink the mask to dodge it.
verify-slopegraph.py The two axes disagree on scale/origin, or the endpoint is drawn in the wrong place relative to the value it declares. Fix the coordinates, not the label — and do not move points to keep two labels from touching, because crowded labels mean the two values are actually close.
verify-ridgeline.py A ridge drawn to its own amplitude, a baseline off-pitch, a ridge sampled on its own x-axis, or a range printed wider than the bin it declares. Do not renormalize a ridge just to make it readable.
verify-bubble.py A bubble drawn off the shared scale, a radius disagreeing with the area constant r = K·√size, the second bubble wearing an accent, a small bubble drawn under a large one when they overlap. Fix the geometry, not the constraint.
verify-bump.py A peak sits off the rank grid, one mark's rank is not a permutation 1..N, the connecting segment is curved. A rank between two ranks is not a rank.
verify-beeswarm.py A dot off the value scale, two dots with the same value in two positions, a pair of dots overlapping instead of dodging, a second radius appearing, or positioning a mark with CSS (transform, translate/rotate/scale, geometry property, motion path) through any carrier — attribute, style inline, or a rule <style>. Crowding is data; dodging is the only honest way to handle it.
verify-skin-polarity.py A legend/caption calling the ramp direction by brightness (darker is larger) in a file where the ramp runs the other way. ink is role, not color — it comes out near-black on light paper and near-white on dark paper. Call the direction by contrast against the paper (stronger contrast is larger), that sentence survives a skin change, and ship the same sentence in every variant.
verify-treemap.py A cell does not match the value it carries as a label, or the label does not fit the cell.
verify-screenshot-freshness.py A minimalist light example or its PNG changes but the catalog has not been refreshed in sync. Install Playwright, run python3 scripts/render-canonical-screenshots.py, review all 39 renders, then commit the new PNG + docs/screenshots/manifest.json.
build-readme-thumbs.py --check A README preview is missing/stale/broken/wrong-sized/orphaned/no longer linking to the full PNG. Install Pillow==12.1.1, run build-readme-thumbs.py, commit the WebP + docs/screenshots/thumbs/manifest.json.
Icon assets You changed scripts/vendor/icons/ or scripts/build-icons.py but the generated file is stale. Re-run python3 scripts/build-icons.py and commit icons.html + references/primitive-icons.md.

The most important prohibition

Do not add files to scripts/lint-skin-baseline.txt to bypass.

Baseline (currently has 20 lines) is only for legacy pre-2.0 examples that inherently predate the current skin — and they still are subject to a11y checks. Adding new files there is gate fraud.


6. Gates for each type of change

You touch Run at minimum
A new example python3 scripts/lint-skin.py skills/diagram-design/assets/example-my-type.html then --all --baseline
A new diagram type add references/type-*.md + example + table entry SKILL.md §3 → verify-docs-sync.py + lint-skin.py --all + 40,000-byte budget check
Import path verify-drawio-import.py + test-verify-drawio-import.py + verify-mermaid-import.py
Icon set build-icons.py then git diff --exit-code on icons.html and primitive-icons.md
Motion verify-motion.py --shipped + test-verify-motion.py + verify-semantic-motion.py (both modes)
Doctor verify-doctor.py + test-verify-doctor.py
Any docs file verify-docs-sync.py — it checks both reference links and the command/prompt surface

7. ADR — read before debating design

docs/adr/ has 9 decisions. The four most often stumbled on:

  • 0001 — static by default, a single pinned controller.
  • 0003 — reveal is where autoplay is allowed only.
  • 0004 — the byte threshold of SKILL.md + trigger-rich description.
  • 0009 — version bump on main after merge, not in the PR.

Along with docs/cookbook.md (operating formula) and docs/superpowers/ (template plan + spec for a new type, using polar chart as an example).


8. This step is done when

  • The entire chain && runs green locally (verify-doctor.py requires Python 3.10+ to be green).
  • No manifest version is touched in the diff.
  • wc -c < skills/diagram-design/SKILL.md stays under 40,000.
  • No new lines in scripts/lint-skin-baseline.txt.