drupal-build-unit
Skill0 starsChanged 24 days agoMITView on GitHub
Build one unit of a Drupal site build (drupal-build) — a header, a footer, a recurring element, a media type or shared editing feature, one paragraph type, one taxonomy, one content type or one third-party integration — through a fixed loop: CDC scoping by REQ, targeted Figma confrontation by node id per breakpoint and state, gaps arbitrated for the CDC, a brief and action plan (acceptance criteria tied to REQs, data model, files, accessibility by design, demo content, test strategy) validated unless in auto mode, a build/<id> branch, implementation with gm:drupal and the starter's conventions, self-verification (phpcs, phpstan, build, PHPUnit, Playwright E2E + axe + visual regression on every delivered unit, config idempotence, logs, visual comparison with Figma in Chrome), then drupal-rgaa and gm:review, and delivery (Playwright captures uploaded to GitLab, French local UAT, Draft MR, .build/ update). Loads the reference of its category. One unit per conversation. Use when the drupal-build orchestrator routes here. IMPORTANT: CDC wins over Figma; read only the unit brief and the Contracts of its dependencies; all commands MUST go through Makefile targets; never merge, never write content on preprod/prod.
In this repository17 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- d11Skill
- drupal-build-foundationsSkill
- drupal-build-intakeSkill
- drupal-buildSkill
- drupal-rgaaSkill
- drupal-scaffoldSkill
- gulp-to-viteSkill
- jquery-4-migrationSkill
- lando-to-dockerSkill
- phpcbfSkill
- phpcsSkill
- php-deprecations-auditSkill
- php-docker-upgradeSkill
- php-standardsSkill
- phpstanSkill
- sass-migratorSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 2 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 37
No subagents: When the context grows, write the state to .build/, commit, and resume after /clear.
- Very specific: line 60
If the branch build/<id> already exists, this is a resume: switch to it, read its commits and the brief's Plan, and continue at the first …
- Very specific: line 111
Wait for validation, then record the date in the Plan.
- Distinctive: line 127
No stacking by default: Only when a dependency is in an unmerged MR: branch from that MR's branch instead, target it in the MR, and write « …
- Very specific: line 153
Porting from the source site: start from its bundle (fields, template, behaviour), then rewrite it to the starter — foundations tokens …
- Very specific: line 159
Add the unit's fixture fixtures/<id>.yml to gm_demo (and its assets), then make demo unit=<id>.
- Distinctive: line 169
All of it, before the end validations:
- Very specific: line 184
Never make cex on another site than the driver.
- Very specific: line 190
No arbitrary Tailwind value where a token exists (check in design-tokens.md).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Build one unit
Part of the drupal-build campaign. One unit, one branch, one Draft MR, one
conversation. The category reference says what the unit must deliver and
check: references/categories/<category>.md (header, footer,
recurring, media, paragraph-block, taxonomy, content-type,
integration). With sites: in state.md, also
../drupal-build/references/multisite.md.
Shared references, in ../drupal-build/references/ (relative to this skill's
directory): build-memory.md, demo-content.md, testing.md,
screenshots.md; and ../drupal-build-foundations/references/design-tokens.md
for the token rules.
No subagents. When the context grows, write the state to .build/,
commit, and resume after /clear.
Load only this
cat .build/state.md
cat .build/units/<id>.md
head -4 .build/requirements.md; grep -E '\| <id> +\|' .build/requirements.md
sed -n '/^## Contract/,$p' .build/units/<dependency>.md # each dependency, foundations included
grep -E '^## D-' .build/decisions.md # then only the relevant entriesThen the category reference, and /gm:drupal whenever the unit has
backend work (config, fields, PHP, hooks, services): its rules (services and
dependency injection, thin hooks, cacheability, pure logic with unit tests)
shape the plan of Step 4, not only the code of Step 6. Nothing else: not the full CDC, not a Figma
page, not a dependency's code. When the brief names a source bundle (a
block ported from the source site in state.md), read only that bundle's
files there: its config, template, preprocess and CSS. A Contract that does not answer a question is
completed (in its own file, mentioned in this MR), not bypassed by
reading code.
If the branch build/<id> already exists, this is a resume: switch to it,
read its commits and the brief's Plan, and continue at the first unfinished
step.
1. CDC scoping
List the REQs of the unit with their condensed text. A doubt about one opens
only the CDC page cited in its Source. The CDC wins over everything.
2. Figma confrontation
Load figma:figma-design-to-code. For each row of the brief's Figma
nodes table: get_design_context and get_screenshot on that node id
only, per breakpoint and per state (hover, focus, open, empty, error, long
content). Check the behaviour too (what opens, what moves, what happens with
no item), not just the rendering. Map every value to a foundations token;
note the ones that have none.
3. Gaps
Arbitrated in favour of the CDC, written in the brief's « Gaps and
decisions » (project-wide ones in decisions.md).
- Not drawn (a breakpoint, a state): no question — build the simplest functional version on the foundations (grid, spacing, components), and write one line in the brief saying what was derived. Ask only when the CDC imposes a behaviour the simple version would miss.
- Blocking ambiguity: a question, never a silent assumption.
4. Brief and action plan
Show the scope first as a numbered French list (from the brief), so the
human can reference items. Then the plan, written in the brief's Plan section, presented in French, in the shape of a
/gm:ticket brief without a ticket:
- Objectif — one or two sentences.
- Critères d'acceptation — numbered, each tied to its REQ; deduced ones marked « (inféré) ».
- Modèle de données — bundles, fields (machine name, type, cardinality, required), widgets, formatters, view modes, translatability (asymmetric paragraphs when multilingual).
- Fichiers concernés — config, templates,
includes/<entity>.inc, services, CSS, JS, fixtures, tests. - Accessibilité dès la conception — semantics, landmarks, heading levels, focus order, keyboard handling, ARIA strictly needed.
- Contenu de démo — the fixture cases (long, empty optional fields, min and max items, special characters, translation).
- Stratégie de test — for each acceptance criterion, the level that
verifies it: PHPUnit unit or kernel, E2E, axe, visual, or manual UAT
(
testing.md).
Wait for validation, then record the date in the Plan. Auto mode
(mode: auto in state.md): write the plan, show it, do not wait. Step
mode (mode: step): also pause before each of Steps 5 to 9, saying what
the step will do.
A unit with no REQ of its own (a media type, the editor configuration, a shared card) takes its acceptance criteria from the REQs of the units it serves, listed in its brief.
5. Branch
git fetch origin
git switch -c build/<id> origin/developNo stacking by default. Only when a dependency is in an unmerged MR: branch from that MR's branch instead, target it in the MR, and write « Dépend de !X, à fusionner après » in the description. With several unmerged dependencies on one cascade, branch from the last one of the cascade.
make cex showing drift this unit did not cause: never fold it into the
unit's commit. Revert it and tell the human.
6. Implementation
/gm:drupal (loaded since the plan) for the backend, and follow the
starter:
- the
Gm*entity classes andentityField()for field access; gm_routerslugs instead of any hard-coded id or path;- the
gm_siteservices (routes, settings, SEO) rather than new globals; - theme hooks in
includes/<entity>.inc, not in the.themefile; - config in
config/syncthroughmake cex, nothing edited by hand there except to remove noise the unit did not intend.
Front: Twig and Tailwind with the foundations tokens and components (from
their Contract), vanilla JS only when needed, as a Drupal behavior with
once(), declared in the theme's libraries and attached where used. Colours
the editor chooses go through the palette (--block-* properties), never a
raw value.
Porting from the source site: start from its bundle (fields, template,
behaviour), then rewrite it to the starter — foundations tokens instead of its
CSS, Gm* and entityField(), includes/*.inc, this project's machine
names from the brief. Keep what the CDC asks, drop the rest; the MR says what
was ported and what changed.
Add the unit's fixture fixtures/<id>.yml to gm_demo (and its assets),
then make demo unit=<id>. Add the unit's tests (tests/e2e/<id>.spec.ts,
PHPUnit when logic was added) and its screenshot manifest
(tests/screenshots/units/<id>.ts).
A bug in a delivered unit found on the way: failing test first, then the fix, one change at a time, three attempts max before going back to the root cause.
7. Self-verification
All of it, before the end validations:
make phpcs # 0 errors, 0 warnings
make phpstan # [OK] No errors
make npm-build # no error
make cex && git status --short config/ # nothing left after the unit's commit
make cim # then again: "There are no changes to import."
make cr
make drush c='watchdog:show --count=30' # no PHP error or warning after rendering the demo pages
make cim && make demo && make test-all # every delivered unit, not only this one- Multisite: built on the driver site; then
make cim-all,make demo-allandmake test-allcover every site (multisite.md). Nevermake cexon another site than the driver. - No baseline, no ignore, no
phpcs:ignoreadded to make a count go down. - A failing visual reference of another unit is a regression until proven
otherwise. A reference is updated (
make test-e2e-update c='<spec>') only for an intended change, with « écart voulu » and the reason in the commit body. - No arbitrary Tailwind value where a token exists (check in
design-tokens.md). - Visual comparison with Figma in Chrome (
screenshots.md): every breakpoint, every state (hover, focus, disabled, error, open), on the demo pages. Fix spacing, typography and colour gaps. - A quick
curlcheck of a page needs a browserUser-Agent: the starter's.htaccessanswers 403 to unknown bots. - Visual references are not created at delivery: the spec keeps
ACCEPTED = falseuntil the PO or client accepts the unit (testing.md).
8. End validations — both, in this order
drupal-rgaaon the real rendering, with the unit id, its demo pages and the breakpoints./gm:reviewon the branch diff (git diff origin/develop...HEAD, or against the parent branch when stacked). Withoutgm:review, review the diff yourself for correctness, security (access, XSS in Twig|raw, untrusted input), cacheability (cache tags and contexts on custom render arrays), and the starter's conventions.
Fix every blocking point, re-run Step 7 and the validations it affects. Go to Step 9 only with a clean verdict from both.
9. Delivery
- Captures:
make screenshots unit=<id>, then upload them (screenshots.md). UAT in French, local only — the preprod is filled by the client, no content is created there and the UAT never points to it:
## Recette (en local) Préalables : `git switch build/<id>`, `make cim`, `make demo`, `make npm-build`. Connexion : `make uli` (admin) ou `make drush c='user:login --name=demo-editor'`. - [ ] REQ-006 — https://<projet>.dev.localhost/demo/paragraph-faq : cliquer une question → elle s'ouvre, l'autre se ferme. - [ ] REQ-006 — au clavier : Tab jusqu'à une question, Entrée → même comportement, focus visible. - [ ] Back-office (demo-editor) : /node/add/page → ajouter un bloc FAQ avec 2 questions → enregistré, rendu identique.- Ask before pushing, as its own question, never inside another
choice. If the human prefers to wait, commit only, record « MR on
request » in
state.mdand stop there./gm:merge-request: Draft MR todevelop(or to the parent branch when stacked). No ticket and no chronogram reminder: it is a build project. Description, in French: summary, REQs covered, gaps and decisions, UAT, captures, results of phpcs, phpstan,make test-all,drupal-rgaaand the review; for an integration or a config underconfig_ignore, a « Prérequis de mise en production » section (accounts, keys, env variables, per environment and per site — done by the team, never by us). Withoutgm:merge-request: commit (noCo-Authored-Bytrailer), push,glab mr create --draft. .build/: the unit row instate.md(review, branch, MR), the brief's Contract completed with what was actually built, new project-wide decisions indecisions.md. A stable convention discovered here goes to the projectCLAUDE.md(in this MR), never progress.
Then end as the drupal-build orchestrator says: one line, /clear,
/drupal-build.
Definition of done
- Every REQ of the unit is covered by an acceptance criterion, each criterion by a test level or a UAT line.
- phpcs, phpstan, build,
make test-allgreen;cexclean,cimidempotent; no error in the logs. - Compared with Figma at every breakpoint and state.
drupal-rgaaand the review clean.- Draft MR open with captures and UAT; never merged by us.
- Contract complete;
state.mdupdated.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

