Status: design, nothing built. This is the map Greg asked for before we start.
Not a separate project. It is the second half of the same machine: NIGHTSHIFT finds and sells,
the Factory builds and delivers, and both operate on the same businesses row in the same
database. It was briefly split into its own folder for no better reason than the design being new
— and the split immediately cost something real: a lead who signed and paid without replying by
SMS kept receiving follow-up nudges, because the acquisition half had no idea they had converted.
Decided 2026-08-29: split runtime (Claude Code + Hermes) · Greg approves every stage on the
first 3 sites · revisions absorbed within reason. See Decisions.
Takes the onboarding context pack and produces a live, client-approved 10-page website with a blog. It is the missing half of the machine: NIGHTSHIFT finds and sells, this builds.
┌─ SEO ────┐
context pack → DOSSIER → RESEARCH ──┤ ├→ COPY → BUILD → QA → CLIENT REVIEW → LIVE
↑ └─ DESIGN ─┘ ↑ ↑ │ │
└────────────────────────────────-┴───────┴──────┘ │
bounded revision loop (max 2) │
│
ACCOUNT MANAGER ──────────────────────────────────────────────────-┘ → CUSTOMER SUCCESS
(every message to and from the client, through go-live) (everything after)
SEO and Design run in parallel once Research lands. Copy waits on SEO because the page plan decides what each page is for; Build waits on all three and decides none of them.
Two loops, not free-form chatter. See Stopping rules.
| Need | Have |
|---|---|
| Build substrate | client-site skill → Astro + Keystatic starter: 12 page templates, 10 content blocks, 5 theme presets, GitHub mode so the client can edit their own blog |
| Competitor data | NIGHTSHIFT's sweep already holds every same-trade business in their city, with site + rating + reviews |
| Client input | /onboarding/ context pack: answers, voice transcripts, logo, photos, colours, fonts, GMB link |
| Hosting + deploy | Cloudflare Pages, same rails as everything else |
| Copy discipline | verify-claims, stop-slop, content-editor skills |
| Comms rails | Mailgun, SMS gateway, Hermes → Mattermost |
The gap is the orchestration and the QA, not the pieces.
One document per agent lives in
agents/— role, voice, inputs, outputs, tasks, definition of done, hard rules, failure modes, escalation, budget, and how each improves. This section is the summary; those are the specs.
Each is defined by a contract: what it receives, what it must produce, and what "done" means. An agent with no definition of done is how you get four hours and $50 of mush.
dossier-agent)In: context pack, voice transcripts, GMB data (hours, address, rating, reviews, photos), NIGHTSHIFT's record of them.
Out: dossier.md — the single source of truth for the whole build.
Contains: what they do, who for, service list, service area, hours, contact details verbatim,
proof points (only things they actually said or that GMB shows), how they talk (from tone +
own_words transcript), words they use, things not to say, and an explicit ## Unknowns
section listing what we do NOT know.
Done when: every field is either filled from a cited source or listed under Unknowns.
This file is the anti-hallucination device. Every later claim must trace to a line in it. A site that invents "20 years' experience" for a three-year-old business is a real liability, and it is the single most likely way this pipeline embarrasses us.
research-agent)In: dossier (trade, city, service area).
Out: research.md — competitor angle map, what local rivals claim, what customers actually ask
(mined from GMB review text of the trade in that city), the words locals search, and a short
"what would make this site better than the other twelve".
Leash: one pass, capped source count, no open-ended browsing. It reads the competitor set
NIGHTSHIFT already collected rather than going hunting.
Done when: it names at least 3 specific differentiators the copy can actually use.
copy-agent)In: dossier + research + page list from onboarding.
Out: one markdown file per page, plus meta title/description, plus 3 seed blog posts.
Hard rule: may not introduce a fact absent from the dossier. If a page needs something we do
not have, it writes [NEEDS: opening hours for the Riccarton branch] rather than inventing it,
and that becomes a question for the account manager.
Done when: every page written, zero [NEEDS:] unresolved or all escalated.
build-agent)In: copy files, logo, photos, colour + font choices.
Out: a working Astro + Keystatic site in the client's repo, deployed to a preview URL.
Does: scaffold from client-site, pick the closest theme preset and adjust to their colours,
place copy into blocks, optimise and place images, wire nav, write schema.org LocalBusiness from
the dossier, set up the blog with the seed posts.
Done when: npm run build passes and the preview URL serves every page.
design-agent)In: dossier (their picks), research (the category cliché to break).
Out: design.md — a committed direction with named references and one signature move — plus
tokens.css.
Why it exists: sites were coming out correct, defensible and lifeless, because constraints
were choosing rather than filtering. Full spec: agents/10-design.md.
seo-agent)In: dossier, research, GBP listing.
Out: seo.md — real search language, a page plan, titles and meta, LocalBusiness schema, NAP
verification, internal links, and 3 blog topics drawn from actual customer questions.
Why it exists: without it a $400 site is a brochure nobody sees, and "it hasn't done anything"
at month three is the most expensive outcome in the business. Full spec:
agents/11-seo.md.
5a. Machine QA (deterministic, runs first, effectively free). A script, not a model:
lorem, no [NEEDS:], no TODO, no unreplaced {{token}}5b. Editorial QA (qa-agent, runs only after machine QA is green).
Judges what a script cannot: does it sound like the dossier's voice, is every claim traceable,
is each page doing its job, is anything unintentionally comic. Scores each page and returns
specific, addressed-to-an-agent fixes, not vibes.
An LLM reviewing LLM output catches style and misses the wrong phone number. That is why the cheap deterministic pass runs first and gates the expensive one.
orchestrator)Not a chatbot. A state machine that advances jobs, enforces the stopping rules, routes QA findings back to whichever agent owns the fix, and escalates to Greg when a rule trips. Owns the job record, the budget, and the clock.
account-agent)The only agent the client ever hears from. Handles: acknowledging onboarding, asking the
[NEEDS:] questions, sending each page for approval, collecting revisions, go-live notice,
balance invoice.
Autonomy split, same principle as NIGHTSHIFT: answering an inbound client message is low risk
and can be autonomous; proactive messages about money, deadlines and go-live are templated and
gated until Greg raises the dial.
| Rule | Value |
|---|---|
| Internal QA revision rounds before escalating to Greg | 2 |
| Client revision rounds included (per the agreement) | 2 |
| Client rounds absorbed beyond that before Greg is asked | 2 (see Decisions §3) |
| Wall-clock target, unattended | < 2 hours |
| Model spend per site | budget $8, alarm at $15 |
| Any agent producing the same output twice | escalate, do not retry |
| Machine QA red | never advances, no exceptions |
Definition of done for a build: machine QA 100% green, editorial QA above threshold on every page, client has approved every page, balance invoice sent.
Recommendation: split it.
npm run build, run Lighthouse, and diff their own work. That
is what Claude Code is for and what Hermes is not.Hermes triggers a Claude Code run per stage and reads back the result. Neither tool is asked to be the other.
See memory-and-knowledge.md. Hermes memory is a 2.2KB scratchpad that
evicts, the Operator KB already provides contradiction-aware learning (kb_challenge), and the
conversation itself now lives in Postgres client_messages because nothing was storing it.
dossier.md, research.md, copy/*.md, the site
itself. Reviewable, diffable, and the client keeps it if they leave — which the client-site
skill already promises.site_factory schema alongside NIGHTSHIFT: job,
stage, attempt counts, QA results, spend, timings, client approvals.NIGHTSHIFT → SMS → mockup → /start/ sign + $230 → /onboarding/ context pack
│
SITE FACTORY (this)
│
live site → balance $230 → hosting $15/mo
The onboarding submit handler already emails the pack; it would additionally open a job here.
Claude Code headless in the client repo for dossier, research, copy, build, QA. Hermes on the mini for the orchestrator and account manager. Hermes triggers a Claude Code run per stage and reads back a structured result. Neither tool is asked to be the other.
This is about build quality while we learn, and is time-boxed. It is not a client-comms policy —
the client-facing agents are autonomous from day one, because $400 does not buy Greg's time.
The orchestrator holds at each stage boundary and posts to Mattermost with a diff and a preview
link. Deliberately slow: it is how we find out what the agents get wrong before a client does.
Implemented as a per-job gate_level (0 = every stage, 1 = copy + go-live, 2 = escalations only)
so dialling up is a settings change, not a rewrite. Default 0.
Greg's call: keep going until the client is happy. Reviews and referrals matter more than the marginal hour at this price.
"Within reason" has to be a mechanism or the loop never terminates, so it is a counter, not a cliff: rounds 1–2 are contractual, rounds 3–4 the Account Manager grants on its own authority, and round 5 lands in the weekly digest — it does not refuse the client, does not keep going unbounded, and does not interrupt Greg. At $400 he is not the arbiter of a fifth revision; he sees it in the summary and can step in if he wants to.
Each round also records what changed, so a pattern of the same complaint across clients becomes visible — that is usually a defect in the dossier or the brief, not a fussy customer.