Skip to content
bflo.sh

Overview — a blog that builds itself

One repository, four tiers, a machine-checkable contract as the only shared surface — and an AI agent team doing the building.

Adapted from the repo's README.md — Part of Internals: the platform's design set, published as content on the platform it describes.

A file-based blog: articles are Markdown files on disk — no admin panel — indexed and served on schedule by a read-only Laravel API and rendered by a Next.js reader front-end. Built contract-first by a Claude Code agent team: one repository, strict tier ownership, and a versioned machine-checkable contract as the only surface the tiers share.

Status: delivery roadmap complete (Phases 0–4, docs/master-blueprint.md §11). Contract v0.8.1 (OpenAPI 3.1 + AsyncAPI 3.1, contract/CHANGELOG.md); ADRs 0001–0017 Accepted.

Stack: DDEV · PHP 8.5 · Laravel 13.x · PostgreSQL 16 · Redis · Next.js 16 (Node 22)

Run it

ddev start

First-time setup, publishing articles, verify commands, troubleshooting: docs/runbook.md.

How it works

The filesystem is the CMS (ADR-0005): content lives under backend/storage/app/content/ — each directory a section, each *.md file an article, path = URL. A scheduler reindexes every minute and honours each file's publication schedule; publishing is save the file — a relay → signed webhook → revalidateTag loop (ADR-0016) makes it live in well under 90 seconds, no restarts. The public API is read-only and unauthenticated (ADR-0006). Full technical walkthrough with diagrams: docs/how-it-works.md.

Layout

Path Purpose
CLAUDE.md The operating constitution every Claude Code session loads: stack, roster, rules, verify commands
contract/ OpenAPI 3.1 + AsyncAPI 3.1 + Spectral ruleset + changelog — the team-to-team boundary
backend/ Laravel API tier (Http → Domain → Data); its README.md is the tier's design doc
frontend/ Next.js reader tier; consumes the API only through the contract
infra/ DDEV topology source of truth; generates .ddev/
docs/ Canonical design set — architecture, product blueprint, team, orchestration, rules, working agreement, UI/UX, runbook, ADRs (reading order: docs/README.md)
.claude/agents/ The member roster: contract-owner, backend-api, domain-engineer, data-engineer, frontend-engineer, platform-engineer

Requirements

The host is deliberately kept agnostic — everything runs inside DDEV. The only host requirements are:

  • DDEV ≥ 1.23.5 and a Docker provider.
  • Claude Code with Agent Teams enabled (preconfigured in .claude/settings.json).

No host Node.js or PHP is required or assumed. If a tool isn't reachable through ddev, that's a gap to close in infra/, not a missing host dependency.

Template heritage

This repository was spun from a reusable contract-first project template; the tier model, stack baseline (ADR-0003/0004), roster, and rules of engagement come from it unchanged. To spin a new project from the same scaffold (referenced by docs/runbook.md § First-time setup B):

# 1. Copy the template and make it yours
cp -r <this-template> my-project && cd my-project && git init
grep -rl '<PROJECT_NAME>' . --exclude-dir=.git | xargs sed -i 's/<PROJECT_NAME>/my-project/g'

# 2. Bootstrap the runtime (DDEV + PostgreSQL 16 + Redis + frontend service + lint cmd).
#    The host needs only Docker + DDEV — no Node.js or PHP.
infra/ddev/bootstrap.sh my-project

# 3. Install the framework skeletons (Laravel into backend/, Next.js into frontend/)
#    following the runbook in infra/README.md

# 4. Lint the contracts (Spectral runs inside the DDEV web container)
ddev contract-lint

Then open Claude Code in the repo root: CLAUDE.md is the operating constitution, and the roster in .claude/agents/ is ready to be spawned as an agent team.