Unapologetically technical · Colombia

How We Work

Skeleton → content model → CSV seed → GHCR deploy → retrofit forward. Same loop every time.

Talk to us Contact

Image
An office lobby at golden hour, a dusty cowboy leaning on the reception desk while the receptionist points him toward the elevators.
An office lobby at golden hour, a dusty cowboy leaning on the reception desk while the receptionist points him toward the elevators.

Start from a skeleton

  • DDEV, PHP 8.3 and MariaDB 11.4 standing on day one
  • A green smoke test before the first feature is written
  • No sprint spent setting up somebody's local environment
Image
A drive-in at dusk, riders on horseback parked among the finned cars, one leaning down to talk to a family in a convertible.
A drive-in at dusk, riders on horseback parked among the finned cars, one leaning down to talk to a family in a convertible.

Model the content first, the interface second

  • Content types, fields and view modes sketched as YAML
  • Templates get rewritten; the content model has to survive that
  • Real content arrives as spreadsheets, so it imports as spreadsheets
Image
A suburban street at golden hour, a cowboy on horseback tipping his hat to a woman carrying groceries while a boy rides past on his bicycle.
A suburban street at golden hour, a cowboy on horseback tipping his hat to a woman carrying groceries while a boy rides past on his bicycle.

Deploy from an image, then retrofit forward

  • An image built on every push, not assembled on the server
  • Keyed deploys onto one host, the same way every time
  • Every lesson worth keeping goes back into the skeleton

Our delivery loop is the same every time.

1. Scope a skeleton. Start from drupal-skeleton (or rust-skeleton for desktop apps). Inherit DDEV, PHP 8.3, MariaDB 11.4, Composer + Node 20, and a green smoke test on day one. No "let's set up the local dev environment" sprint.

2. Model the content first, the UI second. Content types, fields, taxonomies, and view modes get sketched as YAML before a single template is drawn. The content model survives template rewrites; the templates don't survive content model changes.

3. Seed from CSV, validate from CSV. Real content arrives as spreadsheets. A four-command Drush surface — import, export, diff, commit — gives operators a flat, diff-able, comment-able working surface, and gives developers the guarantee that the site reconstructs verbatim from those files.

4. Deploy from GHCR. GitHub Actions builds an OCI image on every push; SSH-keyed deploys to a single Traefik-fronted VPS pull and recreate. Schema-changing deploys destroy and reinstall — no orphaned hook_update_N drift.

5. Retrofit forward. When the project ships, every lesson worth keeping moves back to the skeleton. The next project starts with all of this one's hard-won defaults.

We've used this loop on a bilingual Drupal Commerce property (Mon Petit Café, Bogotá), on a contrib-grade three.js Drupal theme, on a Windows desktop app for matrices, on an ElevenLabs voice-agent integration. The constants travel; the specifics don't.

Want to talk this project through?

Ask the concierge about this project — what it is, how it was built, or get put in touch.