TL;DR: 🔥 The day we saw FAF — A .faf was always machine-readable — scoring, versioning with your code. v6.7 is the day it became human-visible. faf show renders the current project.faf to a self-contained project.html and opens it — on-demand, in any browser, for human and team review. The same context your AI reads, shown to you.

The 4th Pillar

FAF has always run on three lanes:

FAF defines.   MD instructs.   AI codes.

One owned thing — FAF, the definition — and non-owned mediums doing one job each. v6.7 adds the fourth, and it was always going to be reached:

FAF defines.   MD instructs.   AI codes.   HTML shows.

The first three are told. README explains in prose, .faf declares in YAML, the AI executes. But a design isn't described — it's seen. HTML is the one render target the whole world already has. project.html introduces the "show-me" for .faf.

.faf → .html, for the Dev and the Crew

One verb:

faf show

Renders the current project.faf to a self-contained, zero-dependency, HTML-escaped project.html and opens it — the score, the tier, the 6 W's, the stack. Scored by the real scorer, never a reimplementation. Deterministic: no timestamps, so a regenerate only differs when the .faf actually changed. .faf for the machine; .html so the dev — and the crew — sees the same truth.

Trophy renders the earned award line. Sub-Trophy renders the honest gaps. The same .faf, two forms: one the machine parses, one a human reviews. faf export --html emits it alongside AGENTS.md / .cursorrules / GEMINI.md; a public render API (generateProjectHtml) means consumers render from the single source instead of reinventing it.

The Cross-Check

project.html is not a vanity card. It is a cross-check: see what your AI sees, then improve what it is working with at the root — the project.faf itself, not the symptoms.

A human opens the render, sees 55%, and instantly sees which slots are empty — who, what, why. They draw the causation themselves: the AI wasn't flawed, it was starved — and here is a picture of exactly what it wasn't given. The score is the score. A RED .faf renders RED. The render doesn't flatter; it shows the truth, and the empty slots are the to-do list.

That reframes the work, and it is honest about whose work it is:

Be vague, get random results.
Be precise, get great code.

Take a stale project.faf — empty 6 W's, empty stack — and it renders ○ RED. Fill those slots with the project's real context and the same render climbs to 🏆 Trophy. Same project, same FAF, same faf show — an incomplete .faf made complete. Not a conversion story. A precision story.

faf show rendering a stale project.faf — empty 6 W's and stack — as RED 38 percent.
Before — a stale project.faf (empty 6 W's & stack) renders ○ RED 38%
faf show rendering the same project.faf, completed, as TROPHY 100 percent with the All Required slots filled award line.
After — the same .faf, completed: 🏆 Trophy 100%
Same project, same faf show. The "after" is a faithful demonstration of a completed .faf — not a live-repo claim.

FAF Became a Team Event — With a Pit Crew

On May 17, FAF became a team event. With a Pit Crew.

The car is your project. A .faf at 🏆 Trophy / 100% is the car set up perfectly — and that is the goal, because AI codes best with 100% context. Not vanity: the only setup the crew can win on. The lanes are the crew's roles:

LanePit Crew role
FAF definesThe setup spec — the car at Trophy
MD / Agents-MD instructsThe crew-chief call sheet — CLAUDE.md + AGENTS.md
AI codesThe crew, executing — choreographed, timed
HTML showsThe pit wall — telemetry the driver and crew read, on-demand

You are the driver and the team principal: you set the goal, you own the call. And everything downstream is gated on the Trophy. The crew chief's call sheet only instructs well because it derives from a 100% .faf. An incomplete .faf is a pit crew working blind on a miscalibrated car. Get the Trophy first; then the crew flows.

That is the through-line of v6.7. The pit wall went up. Humans like visuals. We gave them one.

Try It

Install or update — one line:

npm install -g faf-cli@latest

Then, in any project directory:

faf show

Zero-install — faf is the verb, every surface:

bunx faf show
npx faf show
brew install faf-cli

The workflow stays: init → auto → go → 🏆 — then faf show to see it.

The Numbers

  • v6.7.0 — released May 17, 2026
  • 696/696 tests passing (2,308 expect() calls, 55 files)
  • 🏆 Trophy 100% — faf-cli's own project.faf
  • 513.2 kB npm tarball, 8 files
  • 1 new verb (faf show), 1 new export surface (--html), 7 public API exports

The Receipts

None of this is a brand promise — it's measurement.

  • IANA-registered: application/vnd.faf+yaml (context) — registered 2025-10-30
  • IANA-registered: application/vnd.fafm+yaml (memory) — registered 2026-05-13
  • Anthropic-listed: claude-faf-mcp shipped as "Persistent Project Context Server" in modelcontextprotocol/servers PR #2759
  • MCP Registry: FAF Ecosystem #2759
  • Single-sourced: tier colours from one FAF_HEX record — tiers.ts (ANSI) and project.html (hex) both derive from it. Bronze is now deep cyan #0E8C8C, distinct from Silver.

FAF defines. MD instructs. AI codes. HTML shows.