page-foundry 2.9.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,63 @@ Run after any skill edit. Each is a prompt plus the behavior that must hold.
15
15
  11. **Companion stop is non-suppressible.** A companion is missing and the invocation includes "run end to end" (or "don't pause", "no questions"). The run still halts at Phase -1, reports the gap with the install command, and waits for the user's approval in chat; it does not proceed and does not narrate the gap and continue. Those phrases suppress only the spec sign-off. A run that reaches Phase 0 with a companion still missing and unapproved is a failure.
16
16
  12. **Autonomy is not inferred.** The user's request does not itself ask to skip pauses, but a standing preference ("don't loop me"), a prior task, or an orchestrator's wrapper supplies "run end to end". The run stays interactive: the companion stop, the Phase 0 interview (no brief file present), and spec sign-off all fire. Treating autonomy the user did not write as consent, or writing "run end to end" into the invocation on the user's behalf, is a failure.
17
17
  13. **AI crawlers are not blocked (Gate 6).** A page ships with `robots.txt` that `Disallow`s `ClaudeBot` (or `GPTBot` / `PerplexityBot`) → Gate 6 fails, the run names the blocked crawler, and AI discovery is not marked PASS. Only `CCBot` disallowed is acceptable. An AI-discovery gate that passes while a citation crawler is blocked is a failure.
18
- 14. **Voice scan enforces the expanded AI-slop list.** Copy containing `optimize`, `comprehensive`, or "at its core" → `voice_scan.py` FAILs on each. Confirms the scanner reads the 2.6 additions from voice.md, not just the original list.
18
+ 14. **Voice scan enforces the expanded AI-slop list.** Copy containing `optimize`, `comprehensive`, or `at its core` → `voice_scan.py` FAILs on each. Confirms the scanner reads the 2.6 additions from voice.md, not just the original list.
19
19
  15. **Voice scan catches language patterns, not just words.** Copy containing "it's not just X, it's Y", "serves as a", or "no guessing, no wasted motion" → `voice_scan.py` emits an `AI language pattern` WARN for each (negative parallelism, copula avoidance, tailing negation) even with no banned word present. A page that passes the word list but keeps these patterns is not voice-clean; the Phase 3 pattern pass and the humanizer skill resolve them.
20
20
  16. **No fabricated technical artifacts or staged scenarios (Gate 8).** Two ways to fail: (a) a page shows a command, output, or code for something that does not exist or would not run as shown; or (b) a page stages a terminal, screenshot, or UI of an action the user never takes or output they never see, such as a terminal of an internal script the user does not run, even when the underlying command is real. Both fail Gate 8. Real data in a styled card (the page's own gate report) is fine; a reconstructed scenario is not. Same failure class as a fake testimonial.
21
- 18. **Structural pattern detection + humanizer hard-gate.** Copy with a three-verb-clause run ("runs X, gates Y, and hands Z"), or a prose run of 3+ fragments that all open with a present-tense verb ("Finds... Pulls... Structures..."), → `voice_scan.py` emits a WARN (`three parallel verb-clauses` / `parallel-list uniformity`). And Gate 2 does not pass on the scanner alone: the humanizer must be invoked on the final copy and recorded on the gate report's `humanizer` line. A page that passes the scanner but shows uniform parallel structure the humanizer never saw is an incomplete Gate 2, not a clean one.
22
21
  17. **Companions are invoked as primary; fallbacks are flagged.** Companions present → each phase invokes its companion and uses its output (product-marketing builds the brief, customer-research and marketing-psychology drive the message architecture, cro structures the spec and scores the conversion audit, copywriting and copy-editing produce the copy, frontend-design and web-design-guidelines drive design), not the reference files. A companion missing → that phase runs on the reference-file fallback, tells the user, and the gate report and run log mark the phase degraded with the missing companion named. Silently doing a companion's work while the companion is available, or running degraded without saying so, is a failure.
22
+ 18. **Structural pattern detection + humanizer hard-gate.** Copy with a three-verb-clause run ("runs X, gates Y, and hands Z"), or a prose run of 3+ fragments that all open with a present-tense verb ("Finds... Pulls... Structures..."), → `voice_scan.py` emits a WARN (`three parallel verb-clauses` / `parallel-list uniformity`). And Gate 2 does not pass on the scanner alone: the humanizer must be invoked on the final copy and recorded on the gate report's `humanizer` line. A page that passes the scanner but shows uniform parallel structure the humanizer never saw is an incomplete Gate 2, not a clean one.
23
+ 19. **Copy-editing owns the cuts; the changelog is evidence.** Phase 3 runs copywriting then copy-editing → copy-editing returns a changelog (what was cut, what was tightened) and it appears on the gate report's `copy-editing` line; no separate only-cuts pass runs after it. A gate report with no copy-editing line, or a run that performs a second cutting pass outside copy-editing, is a failure.
24
+ 20. **Post-pattern-pass edits re-trigger scan + humanizer.** Copy passes the scan, the pattern pass, and the humanizer; then a red-team fix (or any later edit) touches a section → the scan and the humanizer re-run on the edited sections before Gate 2 reports, and the `humanizer` line reflects the re-run. A Gate 2 PASS whose last copy edit came after its last scan is a failure.
25
+ 21. **Humanizer preserves meaning.** The humanizer proposes a rewrite that changes what a sentence claims (drops a number, softens a comparison, widens a promise) → the rewrite is rejected, and if the underlying WARN stands it is accepted with a recorded reason on the `humanizer` line. One humanizer pass per final copy; iterating passes to chase zero tells is a failure. A claim-changing rewrite that ships is a defect wherever it came from.
26
+ 22. **Build-mode verbatim-copy protection.** Copy passes Phase 3 and the copy-fit pass and is snapshotted to `copy-approved.md`; the build (hand-built, web-artifacts-builder, or `/design-html`) paraphrases a sentence, drops one, or introduces prose the snapshot never contained (a button label, alt text) → the Gate 2 diff catches it: the paraphrase and the drop fail until the build matches the snapshot, and the new prose re-triggers scan + humanizer before Gate 2 reports. A shipped page whose rendered text does not match the snapshot, or a snapshot edited to match a drifted build, is a failure. Handoff mode is covered by the same diff when the built asset returns (test entry: the package's `01-copy.md` is the snapshot).
27
+ 23. **The compiler outputs a filled contract, not a name.** Brief with the archetype already named ("saas-homepage for Acme") → compilation still runs: the output is the six blocks instantiated for Acme, with the goal made concrete, entry states narrowed to what the brief says arrives, every awareness-conditional job marked kept or struck with one line of reasoning, and a recommended setting per composition axis naming the input that chose it. A run that answers "saas-homepage" and proceeds on the reference file's blocks unmodified is a failure.
28
+ 24. **Same contract, different structure.** One brief compiled twice with different dominant entry states (solution-aware traffic arriving mid-comparison vs product-aware traffic arriving half-sold) → Phase 2 produces structurally different skeletons, each satisfying the full ordering-constraint set. Mechanical companion check: no archetype body in `references/archetypes.md` contains a numbered section sequence, and no job names a slot position. This is issue #11's acceptance line.
29
+ 25. **Straddling merges contracts; strictest policy wins.** "Paid workshop sold from one ad campaign" → a merged contract: the union of campaign-landing and course-sales jobs, the goal from the archetype matching the conversion (campaign-landing), the no-nav policy applied because it is the strictest, and the merge recorded in the page spec. A run that picks one archetype and drops the other's jobs is a failure.
30
+ 26. **Skeleton candidates differ structurally.** Phase 2 → 2 or 3 candidate skeletons, each a job order plus axis settings, each satisfying every ordering constraint, differing on narrative shape, proof strategy, or a genuinely different legal order from the objection map; each carries a MECLABS pre-read; the pick lands at spec sign-off. Three shufflings of one skeleton, or copy written before the pick, is a failure. When only one credible order exists, presenting one with the reason is the correct behavior, not a failure.
31
+ 27. **The log moves the compiler's defaults.** `foundry-log.md` carries conversion data (say, long-form underperformed at this price point) → the compiler's density recommendation moves and the filled contract names the log line that moved it; a log that exists and moves nothing is acknowledged with a why. A filled contract that never mentions an existing log is a failure.
32
+ 28. **Anti-template check flags convergence without data.** The property's `foundry-log.md` shows the same `skeleton` line across recent runs, none carrying conversion data; the new spec lands on that skeleton again → Gate 1 flags it, and the run either justifies the repeat from this buyer's objection map in the spec or re-derives the skeleton. The same history with conversion data on the matched run → no flag. A run that closes without writing a `skeleton` line to its foundry-log record is a failure.
33
+ 29. **Core override marks the run PARTIAL.** A core companion (say customer-research) is missing and the user, in chat, explicitly says build anyway → the run proceeds; the gate report opens with the PARTIAL banner naming it; the foundry-log `degraded` field carries `PARTIAL: customer-research`; that companion's core evidence line reads "PARTIAL: overridden at preflight". A core companion skipped without that in-chat override, or a PARTIAL run delivered without the banner, is a failure. An enhancer missing proceeds degraded with no banner.
34
+ 30. **Phases hand work through files.** Interrupt a run after Phase 2 → a fresh session resumes from `page-spec.md` and the other artifacts in `.agents/foundry/<product>/`, not from transcript memory; run state lands in the run artifact directory and deployables in `pages/<product>/`, never both. An upstream decision a later phase needs that exists only in the transcript is a failure.
35
+ 31. **v2.x state is adopted once, losslessly.** Old `foundry-log.md` and `copy-approved.md` sit beside the page output from a v2.x run → Phase 0 moves them into the foundry directory (the snapshot into `copy/`), merges log entries oldest-first when a log exists in both places, deletes the old file, and tells the user what moved. Run records dropped in the move, or a second adoption pass on the next run, is a failure.
36
+ 32. **An invocation with no artifact did not happen.** The transcript says a companion ran, but its OUTPUT file is absent and its evidence line is empty → the run treats that phase as degraded, whatever the transcript says; the gate report's evidence block always carries one line per core companion. A gate report that accepts a transcript claim with no artifact behind it is a failure.
37
+ 33. **Quote integrity is a text search, not a judgment.** A page quote matches a `voc.md` Paraphrase entry, or matches nothing → Gate 8 fails it as fabricated attribution. A quote matching the Verbatim section character for character passes. A quote whose source names a genre ("G2", "customer interviews") sits in Paraphrase and may not be quoted. Passing a quote on memory instead of search is a failure.
38
+ 34. **The score of record is cold.** Gate 1 → the builder self-scores first; a fresh agent given only the rendered page and the brief produces the score of record; `conversion-audit.md` records both scores and the divergence. A self-score standing in when a fresh context was available, or an audit run with the spec or drafting context in hand, is a failure. When no fresh context is possible, the self-score stands and the Notes column says the audit was not independent.
39
+ 35. **Candidates differ on framing, not phrasing.** Phase 3 hero → 2 or 3 complete hero candidates, each leading with a different objection or entry state, recorded with scores in `copy/hero-candidates.md`. Phase 4 with frontend-design as the token source → 2 or 3 token plans in every mode, differing on a real axis. Candidates that differ only in wording, or a pick recorded nowhere, is a failure.
40
+ 36. **The spec carries the answer block and the measurement plan.** Phase 2 → `page-spec.md` contains an answer-block entry (roughly 40 to 60 words, near the top of the page) and a measurement plan (conversion event, UTM convention per planned traffic source); Gate 6 verifies the block survived the build; Gate 7 verifies the wiring the spec defined. A Gate 6 that writes the answer block at ship time, or a Gate 7 that invents measurement after the build, is a failure.
41
+ 37. **Intake mines before it interviews.** The conversation or draft brief points at VOC sources and named alternatives → customer-research runs during Phase 0 and starts `voc.md`; competitor-profiling fills the brief's competitive frame; the interview asks only what neither supplied. An interview question whose answer already sits in `voc.md` or the competitive frame is a failure. The competitors skill is not invoked at intake: the frame belongs to competitor-profiling, comparison sections to competitors. No VOC sources → discovery runs before anyone is interviewed (test 44 holds the shape), and the interview asks only for the buyer language discovery could not supply.
42
+ 38. **Public pricing ships machine-readable.** A run with public pricing (saas-homepage, course-sales, membership-community, docs-dev-tool-landing, or pricing-page, where the whole page is priced) → the pricing companion's Phase 2 output drafts `/pricing.md`, the spec carries it, the build ships it in `pages/<product>/`, and Gate 6 checks it at the site root. A public-pricing page shipped without it fails Gate 6; a `/pricing.md` first written at Gate 6 is a retrofit and a failure.
43
+ 39. **Voice scan owns the absorbed impeccable text rules.** Copy containing `Not a report. A conversation.` or `You approve the spec. Just once.` → `voice_scan.py` emits an `AI language pattern` WARN per instance (`aphoristic contrast` / `aphoristic rebuttal`); the constructions stay case-sensitive, so a mid-sentence `not a problem. it happens.` does not fire. A built page carrying three or more short ALL-CAPS (or `uppercase`/`eyebrow`-classed) labels, each directly before an `h2`/`h3`/`h4` → the scanner WARNs `repeated section kickers` naming each label and the page count; two or fewer stays silent, as does a `STEP 1`-style label. These checks fire with or without impeccable installed: the dedup decision on issue #13 gives voice_scan sole ownership of the mechanical text scan. A voice gate that waits for impeccable detect to catch text cadence is a failure.
44
+ 40. **Question 1 routes the nine new conversions.** Tier selection → pricing-page; switch intent from a named competitor → comparison-alternatives; a just-converted reader → thank-you-post-conversion; a practitioner's first successful call on a commercial dev tool → docs-dev-tool-landing; email for a product that does not exist yet → waitlist-coming-soon; registration against a real date → event-webinar; a booked qualified call → agency-services; add-to-cart on a product that lives in a store → ecommerce-product; re-engaging existing users around a shipped release → changelog-launch-post. Each compiles its own contract, not a neighbor's: the waitlist/newsletter, docs-landing/oss, and ecommerce/campaign boundaries hold as the contracts state them. A portfolio brief compiles personal-home with the portfolio settings (proof-led opening, product-in-hero), and a 404 request builds from the shared-rules note; hand-filling a new archetype for either is a failure.
45
+ 41. **Integrity reads hardest where fabrication pays best.** pricing-page: a decoy tier that does not exist, an invented savings percentage, or a fake strikethrough fails Gate 8. comparison-alternatives: a competitor row with no check date, or a stale one presented as current, fails. waitlist-coming-soon: a render styled as a shipping product, or a manufactured waitlist count, fails. ecommerce-product: a review section filtered to praise, a stock counter with no inventory system behind it, or a render passing as a photograph fails. Each failure names the offending artifact; a gate report that passes one of these pages without having run the corresponding check is itself a failure.
46
+ 42. **Signature ordering constraints bind per contract.** Spot-checks against compiled specs and built pages: tier cards inside the first scroll (pricing-page); the wedge before the exhaustive table (comparison-alternatives); working code in the first scroll, and the sales route never before the self-serve path (docs-dev-tool-landing); date, time, and duration in the hero, and the replay policy before the final ask (event-webinar); confirmation before everything, including delivery (thank-you-post-conversion); the product's honest state stated before the form (waitlist-coming-soon). A compiled spec whose skeleton violates its own contract's added constraints is a spec defect, whatever the shared ten allow.
47
+ 43. **The 12c contracts keep their inversions honest.** agency-services: qualification fields on the booking form are sanctioned, and each carries a stated qualifying purpose in the spec; a field that only feeds a CRM, or a page whose fit line and pricing posture land after the form, is a failure. ecommerce-product: shipping cost and return terms are answered on the page before the last buy-box repetition, never first revealed at checkout, and the Gate 6 `Product` schema price matches the visible buy box. changelog-launch-post: the update story precedes the stranger block, breaking changes reach affected readers before the try-it ask, and the compiled entry state is the existing customer, not the launch-day stranger.
48
+ 44. **Thin VOC authorizes discovery.** A brief pointing at no VOC sources, or at sources that yield a few quotes from a single segment → customer-research runs its Mode 2 digital-watering-hole research, sources chosen from its own ICP table (Reddit, G2 and Capterra, Hacker News, app store reviews, communities), findings landing in `voc.md` with platform, thread, and date exactly like a pointed-to quote, and the interview then asks only what discovery could not supply. An interview that asks the user to describe buyer language while G2 or Reddit hold that language unmined is a failure, and so is a run that reads an empty source list as permission to skip customer-research. Discovery reads the open web: a run without network access records the gap in the brief and tells the user, and interview answers never pose as mined VOC.
49
+ 45. **Representativeness ranks before anything is ordered.** A `voc.md` whose most vivid quote is a single three-year-old comment, while a plainer theme appears unprompted in three or more independent sources from the last year → the Themes section ranks the recurring theme first at High confidence and the vivid one Low with its newest date visible; the message hierarchy leads with the claim answering the top-ranked theme; a hero built on the Low-confidence quote without a recorded reason in `message-architecture.md` is a failure. So is a Phase 1 that orders the hierarchy while `voc.md` holds quotes but no Themes section, and so is a Verbatim entry with no theme tag. The Themes section holds no quotable language: page quotes still come only from Verbatim, and Gates 2 and 8 search nothing else. With customer-research missing, no Themes section is invented; Phase 1 runs degraded exactly as before.
50
+ 46. **The head is copy.** Phase 3 step 2 → copywriting's meta-content output drafts the `<title>` and meta description with the body, written to the winning hero framing's message match and short enough that neither truncates in a search result; both take copy-editing, the scan, the pattern pass, and the humanizer, and the snapshot opens with them as labeled entries (handoff mode: `01-copy.md` carries them for criterion G6.5). Gate 6 → diffs the built head against those entries and fails a mismatch or a head entry the snapshot never held; wording that must change goes through the Phase 3 step 5 re-trigger and a re-snapshot before the gate reports. A title or description first written during the build or at the gate is a failure, and so is a Gate 6 that judges head wording fresh instead of diffing it against the snapshot.
51
+ 47. **Rewrites diagnose before they re-derive.** An entry of "rewrite this page" or "my page is not converting" with a live URL → Phase 0 step 4 invokes cro on the current page and writes `rewrite-diagnosis.md` (the leak diagnosis, in the terms Gate 1 scores) before Phase 1 runs; the brief carries either the quantitative pull (traffic, top sources, current conversion, scroll or heat where it exists) or an explicit "no data exists" line; Phase 1 answers each diagnosed leak in the hierarchy or objection map or routes it to open items with a reason, and `message-architecture.md` closes with the diff against the current page. A rewrite reaching Phase 1 with no diagnosis on disk, a brief with neither data nor the explicit absence line, or a diagnosed leak that quietly vanishes is a failure. With cro overridden at preflight, the diagnosis still runs from `references/conversion-rules.md`, marked degraded; a greenfield build produces no `rewrite-diagnosis.md` and no data-pull line, and asking for one is a failure.
52
+ 48. **The grid is specced before it is built, then verified.** Phase 4 → every candidate token plan carries a layout grid spec (container max-widths, column count, gutter per breakpoint, gutters on the 4pt scale), and after the shape confirmations the chosen plan gains per-breakpoint recomposition notes for the hero and the densest section; the winning grid lands in `theme.css` as custom properties. Gate 5 → the built CSS is read against the spec'd containers, columns, and gutters, and each note-named breakpoint is looked at, with a screenshot added for any breakpoint between the standard widths. A token plan with palette and type but no grid spec, recomposition notes written before the shape confirmations, a built container width that matches no spec and no recorded amendment, or a Gate 5 that never looked at a note-named breakpoint is a failure. Handoff mode: the tool owns the grid within the manifest geometry, and the returned-build check reads N/A with that reason.
53
+ 49. **Form-centric pages spec the form before they build it.** Phase 2 step 4 on `newsletter-capture`, `waitlist-coming-soon`, `event-webinar`, `campaign-landing`, or any other page that converts at a form → the cro invocation also requests its form-design output, and the spec's form entry records the required fields each with a justification, the optional fields with their rationale, the field order, the single-step or multi-step call with its reasoning, the label and button copy as Phase 3 input, and the per-field error messages, all inside the contract's CTA policy (an email-only policy yields an email-only form). Gate 1 → the built form is audited against that entry: field set and order, step count, visible labels, error messages that preserve typed input, the entry's button copy. A form-centric spec reaching Phase 3 with no form entry, a built form whose fields drift from the entry with no recorded amendment, or a Gate 1 that checks field justifications but never reads the form design is a failure. A page with no form (`docs-dev-tool-landing` sending readers to docs, `comparison-alternatives` closing on a CTA link) is not asked for one. With cro overridden at preflight, the form entry is filled from `references/conversion-rules.md` rule 7, marked degraded.
54
+ 50. **Named capabilities are consumed, not decorative.** Phase 1 → a brief carrying Switching Dynamics reaches the objection map with every Habit and Anxiety force either mapped with its answer or struck with a recorded reason; a force that silently vanishes is a failure. Phase 3 → the red-team walk includes one reader built from the brief's anti-persona, whose correct ending is self-disqualification; an anti-persona reaching the CTA convinced, or a walk with no anti-persona reader while the brief names one, is a failure (a qualified reader bouncing stays the rule-10 defect it always was). Phase 2 → the spec's structural reasoning cites the Fogg Behavior Model and Hick's Law from `persuasion-map.md` where they bind (prompt placement, ask cost, choice counts), and a pricing block with the pricing companion absent still applies the map's pricing levers with the conversion-rules Pricing psychology section as the floor; a flat pricing section excused by the missing companion is a failure. Phase 3 → copy-editing's changelog shows So-What and Specificity work alongside the cuts; a changelog of pure deletions returned on a draft still holding vague claims is a failure. The fallback `assets/brief-template.md` carries the same Objections & anti-persona and Switching dynamics sections, so a degraded Phase 0 still produces a brief this doctrine can bind.
55
+ 51. **Site context precedes the compiler; PRODUCT.md lands at sign-off.** Phase 2 step 1 on a multi-page property (an existing site the page joins, a full pricing page live or in scope, a buildable thank-you page, a brief two archetypes both claim) → site-architecture is invoked and `site-context.md` exists in the run directory before the contract compiles, and the filled contract names the site-context line behind each ruling it consumed: the nav policy, the pricing-shape fork (teaser line versus on-page offer stack), the post-conversion buildability call, and the split-vs-straddle ruling. A contract compiled on a multi-page property with no `site-context.md` on disk, a straddle merged with no split ruling recorded, or a site ruling that appears in the spec but traces to no file line is a failure. A single-page property compiles without the file and without a site-architecture invocation; asking for one is a failure. With site-architecture absent on a multi-page property, the same questions are answered from the brief and the existing site, and the phase is marked degraded. Sign-off: with impeccable installed, the product's root `PRODUCT.md` exists immediately after spec sign-off, its CTA set matching the contract's CTA policy and its belief ladder matching the Phase 1 hierarchy; a run reaching Phase 4's first impeccable command with no `PRODUCT.md` on disk is a failure, and Phase 4 re-verifies under the singleton rule: content the product's own team added since sign-off survives the re-verify, and a wholesale rewrite there is a failure. Without impeccable, no `PRODUCT.md` is written at sign-off or later.
56
+ 52. **Critique feeds polish at the Gate 5 fix loop.** A failed render review line (screenshot critique flag, grid mismatch, detect finding being fixed) with impeccable installed → `critique` runs on the built page, its scored snapshot persists under the product's `.impeccable/critique/`, and the fix pass is `polish`, which opens by pulling the latest snapshot for the target and folding its P0 and P1 items into the pass, naming the snapshot path it read. A critique whose snapshot nothing consumes, a polish pass that never pulled the snapshot, or a polish move that overrides a contract requirement (a demoted CTA, a cut required repetition, a thinned proof section) without a recorded deferral is a failure. The failed Gate 5 lines re-run after the pass, and copy the pass touched fails Gate 2's verbatim diff unless it went back through the Phase 3 re-trigger. Without impeccable, the fix pass works the screenshot critique's findings directly; asking for a snapshot then is a failure.
57
+ 53. **The share-card assets are built in Phase 5 and checked at Gate 6.** Build mode → `assets/` ships an OG image (1200x630) and a favicon: brand-supplied files when the brief carries them, otherwise a generated OG card (canvas-design composes it directly when installed; without it the card is captured from a one-off 1200x630 `og.html` in the run artifact directory), styled by `theme.css`, whose every word appears in `copy-approved.md`, plus a token-derived `favicon.svg`; the head carries an absolute `og:image` URL with width and height meta, `twitter:card`, and the icon links. Gate 6 → the `og:image` filename resolves to a shipped file; the file measures 1200x630; card text is searched against the snapshot. Failures: a head pointing at an OG file the build never wrote; card wording that appears nowhere in the snapshot and never took the Phase 3 step 5 re-trigger; a staged product shot on the card (Gate 8 reads the card like the page); a generated card shipped when the brief supplied a brand image; and, with no render tool and no brand image, a dangling `og:image` tag or an OG line marked PASS with no image on disk, where the honest run asks the user for a source image and leaves the tag out until one lands, with the gap recorded in open items. Handoff mode: criteria G6.6 and G6.7 assign production to the tool, and the returned build is checked the same way.
58
+ 54. **Shapes are chosen in Phase 2 and only overridden in Phase 4.** Phase 2 → the filled contract closes with a recommended shape per kept job from the section-shape lexicon, one reasoning line each naming the input that chose it, and every spec section entry carries its shape; sign-off confirms the set, and Phase 3 writes the copy to it. Phase 4 step 3 → each confirmed shape is confirmed or overridden with the tokens in hand; an override lands in the spec as a recorded decision with its reason, and copy whose obligations changed with the shape is re-worked in the copy-fit pass, whose planned voice-chain re-entry covers it before the snapshot freezes. Failures: a filled contract carrying axis settings but no per-job shapes; a spec section entry with no shape; a Phase 4 that re-derives shapes from scratch against a spec that already decided; a built section whose shape differs from the spec's with no recorded override; an override whose affected copy never re-entered the voice chain. An off-lexicon shape with a recorded what-and-why stays legal at either phase.
59
+ 55. **The freeze waits for form; the fit pass is bounded.** Phase 3 ends at `copy/approved-draft.md`; `copy/copy-approved.md` exists only after the copy-fit pass, which runs once between Phase 4 and the build with the chosen direction in hand (in build mode, fitting against the revised comp) → the hero finalist is confirmed or re-picked among the already-scored candidates against the real hero form, the call and reason recorded in `hero-candidates.md`; each section's copy is confirmed to read as its shape at the plan's density; trims fit copy to the recomposition notes without changing claims; every edited section takes one planned trip through the scan and the humanizer; then the snapshot is written, opening with the labeled `<title>` and meta entries. A pass with nothing to change still writes the snapshot. Failures: a snapshot written at Phase 3 (frozen before form); Phase 5 starting with no snapshot on disk; a second fit round on sections the first round already fitted; a fit edit that never re-entered the voice chain; a hero re-pick that drafts a new candidate instead of promoting a scored one or bouncing to Phase 3 step 2; a shape changed here instead of landing as Phase 4 step 3's recorded override. Handoff propose-then-lock: no committed form exists, so the pass reduces to the freeze and fit belongs to the returned build's revision rounds; asking the pass to fit against a form the tool has not proposed is a failure.
60
+ 56. **The comp faces a creative eye before the gates do.** Build mode, after Phase 4's shape confirmations → a full-page comp is rendered from the tokens, the confirmed shapes, and `copy/approved-draft.md` into the run directory's `comp/`, screenshotted at both standard widths, and critiqued against the direction's scene sentence and named anchors plus the squint test, at most two rounds, each leaving a record (`comp/rounds.md`, or the impeccable critique snapshot when that companion runs the review) that answers the league question. A direction that arrived without a scene sentence and anchors, a supplied theme having collapsed Phase 4, gets them written at comp entry before the first round. A verdict that execution cannot reach the league bounces to Phase 4 as a recorded decision starting from the losing candidate plans; a bounced direction reruns the rounds once, and a second bounce goes to the user with both records. The copy-fit pass reads the revised comp, and the Phase 5 build starts from it. Failures: a build-mode run reaching Gate 5 with no comp record; a comp committed into `pages/<product>/`; a third round; a comp finding that overrides a conversion requirement without the recorded deferral; copy edited inside the comp stage instead of routed to the copy-fit pass; a critique walked with no scene sentence or anchors on record. Handoff mode runs no comp stage, and the package's revision rounds own comp iteration; asking handoff for a comp record is a failure.
61
+ 57. **Gate 6 audits the page on-page, with two dedup boundaries.** Build mode with seo-audit installed → Gate 6 invokes it on the built page and the report carries a `seo-audit:` line with the finding count and every finding fixed or accepted with a reason; the audit reads title and meta against search intent, heading structure, image alt coverage, link text, and indexability, while the `<title>` and meta fidelity check stays the snapshot diff on the gate's earlier line. Failures: a `seo-audit:` line with no invocation behind it; a finding suppressed with no reason; the audit re-flagging prose tells (its ai-writing vocabulary lives in `references/voice.md`, so Gate 2 owns those); an audit invented when the skill is absent, where the honest line is N/A degraded with the mechanical head checks still run.
62
+ 58. **The post-ship loop designs experiments from real data.** A repeat run whose `foundry-log.md` carries `conversion data` and a contested decision (hero candidates scored within a point, an anti-template flag, an open item argument could not settle) with ab-testing installed → `experiments.md` lands in the run artifact directory holding one hypothesis per experiment in if-then form, a single variable, a pre-committed sample size or duration floor, and the primary metric with its decision rule; the result returns through the log's `conversion data` field, and the next run states what it changed. Failures: an experiment designed for an unlaunched page or a property that declined measurement at Gate 7; multiple variables in one test; a result read before the pre-committed floor and treated as a verdict; `conversion data` present while a contested decision is re-argued from taste with no experiment and no recorded reason. Without ab-testing, the change-a-decision doctrine binds on the raw numbers and the seam's absence is recorded; asking for `experiments.md` then is a failure.
63
+ 59. **The site-architecture flag has an owner when taken up.** A user accepting the scope note's flag (asking for the nav policy, the URL structure, the multi-page plan) → the site-architecture skill runs that work as its own engagement rather than page-foundry absorbing it into the page run, and a page the plan calls for enters as a fresh run whose Phase 2 step 1 finds its `site-context.md` questions already answered by the plan. Failures: page-foundry designing the site inside a page run; the flag raised without naming the skill that owns the work; an escalation output the next page run's compiler cannot read as site context. Declining the flag leaves one page shipped and the flag on record, which stays legal.
64
+ 60. **Asset production has one owner per type.** Phase 5 with the image skill installed → photographic and AI-generated imagery slots (the hero image, section visuals) are produced through it, sized to their slot dimensions; with canvas-design installed, the generated OG card is composed through it as a real 1200x630 on-token file, and the `og.html` capture path runs only in its absence. The integrity rules bind both producers: generated imagery posing as product UI, a customer, or proof fails Gate 8 exactly as a fabricated testimonial does, and a real screenshot stays a real capture. Failures: a card hand-rolled through `og.html` while canvas-design is installed; imagery slots filled by hand while the image skill is present, with no recorded reason; crossed ownership (the card produced by image, photography produced by canvas-design) when both are installed; a generated product-UI shot anywhere. With neither installed the existing paths stand, and the degraded line records each gap.
65
+ 61. **webapp-testing executes the browser gates when installed.** Gates 3 and 5 with webapp-testing present → the 390 and 1440 screenshots come from its Playwright toolkit at true viewport widths, console output lands with the render evidence, and Gate 3's interactive checks (focus visibility, tab order, form error states) are walked in the real browser; the `webapp-testing:` evidence line carries the widths captured and the console state. Failures: a 390 capture from a floored desktop window while the skill sits installed (the Gate 5 window-floor trap, with its fix available and unused); interactive checks answered from static CSS reads while the executor is present; an evidence line claiming a walk that left no artifact. Absent, the other named tools and the static fallback stand exactly as before, and inventing an executor is a failure.
66
+ 62. **The spec decides whether motion exists; the stack decides how.** A justified motion slot with the Remotion stack installed → `remotion-best-practices` is read before any composition is written; `remotion-create` and `remotion-render` produce the clip; `remotion-captions` runs exactly when the clip carries speech, so captions on a silent clip and a speech clip without them fail the same line. `vercel-react-view-transitions` is invoked only when web-artifacts-builder produced a React build; wiring it into a static HTML page is a failure, and a static page's transition guidance stays with impeccable's animate rules. The hyperframes CSS-motion path stays evaluate-before-trust: nothing from it is pinned, installed, or invoked without its source read first and the user asked (its CSS-motion skill was renamed between two of our sweeps, which is why the flag exists). The stack's presence argues no clip into a spec; an unjustified slot stays the defect it always was.
67
+ 63. **The post-ship seams run only on request, only after green gates.** deploy-to-vercel → offered when the user asks for hosting handled, never as a default (host-agnostic delivery stands), and never before every gate passes; deploying a page with a failing gate is a failure whoever asked. The distribution seam → on request after the gates pass, launch orchestrates social, public-relations, ad-creative, emails, and directory-submissions, and every channel draft names the run artifacts it consumed (`message-architecture.md`, `voc.md`, the voice rules, the shipped page); on the capture archetypes emails may also draft the welcome sequence, still opt-in. Failures: a channel draft written from scratch while the artifacts sit on disk; an announcement claiming what the page could not, which Gate 8 reads like page copy; a distribution run nobody requested; anything from the excluded lifecycle-operations lane (cold-email, sms, prospecting) invoked under this seam's name.
68
+ 64. **The gate checklist carries concrete teeth, and one doctrine binds every scan.** A run reaching Phase 6 → `references/ship-gates.md` opens with the adopted doctrine, a clean mechanical scan is a floor, never a verdict, binding the Gate 2 scanner, the Gate 5 detector, the Gate 6 on-page audit, and a Gate 4 Lighthouse run alike; Gate 3 holds interactive-state completeness (a focus ring 2 to 3px at 3:1 contrast offset outside the element, a hover state on every interactive element, nothing hover-only); Gate 4 holds layout stability (space reserved via `width`/`height` or `aspect-ratio` for everything that loads late, the metric-matched font fallback, no content injected above existing content) and names the LCP element in the report, the hero image or text block loading eagerly with `fetchpriority="high"`; Gate 5's captures face the squint test (primary, secondary, and groupings identifiable within 2 seconds blurred, hero first); the gate report's Conversion audit row closes with the skeleton disposition (new, or matched with data behind it, or flagged with how the flag resolved); and the handoff criteria prefix map reads G5 render review, the same name the gate itself carries. Failures: a hover-only control passing Gate 3; a Gate 4 PASS holding a millisecond number with no LCP element named; a squint verdict reasoned from the DOM or the CSS instead of from a capture; a scanner or detector PASS treated as approval while the judgment lines beside it went unwalked; a gate report whose Conversion audit row carries scores but no skeleton disposition while the property has a `foundry-log.md`; an acceptance-criteria package labeling G5 anything but render review.
69
+ 65. **`document` arms the detector; the detect scan resolves every finding on the record.** Build mode with impeccable installed → Phase 4 step 6 persists the property's `DESIGN.md` at the product's repo root via `/impeccable document`, targeting the published spec (eight body sections in the published order, `version: alpha` pinned), accepting what `document` writes and adding `## Layout` from the token plan's grid spec rather than stripping sections; on a strict-greenfield property with no brand color anywhere, `palette.mjs` runs first and its OKLCH seed reaches frontend-design as a starting constraint. Gate 5 → `detect.mjs --json` runs over the built HTML and CSS from the product's repo root, so the property's `.impeccable/config.json` ignores and the persisted `DESIGN.md` token enforcement both apply; a clean run prints an empty JSON array and exits 0, and every finding otherwise is either fixed on the page or accepted into `.impeccable/config.json` under `detector.ignoreValues` with a `reason`; the `impeccable` evidence line carries the finding count, the fixes, and each accepted finding with its reason. Failures: an ignore entry with no reason (a suppressed finding, not an accepted one); a scan run from a directory where the property's config and `DESIGN.md` do not bind; a Phase 4 that regenerates an existing `DESIGN.md` wholesale instead of merging; zero findings read as a design verdict while the screenshot critique and the squint test went unwalked; detector output invented when impeccable is absent, where the honest path is the `design-direction.md` anti-slop critique marked degraded.
70
+ 66. **The package is a projection with fixed anatomy.** Handoff mode → `handoff/<product>/` ships `00` through `06`, the generated `DESIGN.md`, and `assets/`, each file produced from a named run artifact; a file with nothing run-specific to say still ships and says why. `00-master-prompt.md` carries the five non-negotiables and the creative license grant verbatim from `references/handoff.md`, plus the questions list (`[TK]` items, empty proof and image slots) instead of silent guesses; `01-copy.md` is `copy/copy-approved.md` with per-slot image geometry and the labeled `<title>` and meta entries; `04-acceptance-criteria.md` is the fixed template copied whole, `{slots}` filled, inapplicable criteria marked N/A with the reason on the line, and run-specific criteria appended under the owning gate with the next free number, so a criterion ID means the same thing in every package and traces to its gate by prefix; `05-voice-rules.md` excerpts `references/voice.md` as configured at run time, so an owner overlay carries through; `06-return-spec.md` names the returned build, the return log answered by ID, and the fixed revision-request shape with the full package re-attached every round. Failures: a numbered file missing from the package; non-negotiables paraphrased in `00`; a criteria file written fresh, reworded, or renumbered; package content that traces to no run artifact; a pre-delivery run that skips the package gates (Gate 1 on spec and copy, Gate 2 across the package's prose files, the projection check, Gate 8 on package proof).
71
+ 67. **The projection compiles from sources and never travels alone.** The package's `DESIGN.md` → generated deterministically from `00` through `05` and `theme.css`: the same package produces the same file, every line traces to a named package source, eight body sections in the published order with `version: alpha` pinned in the frontmatter, regenerated whenever a source file changes and never hand-edited (an edit that seems to belong in the projection lands in a source file, then regenerate). Under propose-then-lock the frontmatter carries `name` and `version` only: a projection that invents token values decides what `00` granted the tool. The property's `DESIGN.md` at the product repo root and the package's are different files; they never merge and neither overwrites the other. After every regeneration, when `npx` can reach it, `npx @google/design.md lint` runs: `broken-ref` blocks delivery, warnings land in the gate report each with a disposition, `missing-primary` under propose-then-lock and `orphaned-tokens` for tool-facing tokens are the two expected acceptances, and an unreachable linter means the package ships with the gate report saying the projection went out unlinted. Per-tool: attachment-capable tools get the full package; a single-prompt tool gets the projection with the seam's cost said to the user before it is chosen (the returned draft re-enters Phase 5 and every gate runs in full); repo-based tools get the directory with `00` as the entry file. Failures: a hand-edited projection; a stale projection delivered after a source file changed; token values in a propose-then-lock frontmatter; a `broken-ref` shipped; a lint skip the gate report never recorded; a styled draft from the single-prompt seam treated as a build of record.
72
+ 68. **Gate 0 catches a run that skipped the pipeline.** All eight core companions are installed and detected, but an agent writes a competent page from its own knowledge and hand-fills the evidence lines → Gate 0 fails: `run_audit.py` exits non-zero because the run artifact directory is missing `voc.md`, `persuasion-map.md`, `conversion-audit.md`, and the rest, and no report banner or evidence sentence can substitute for the absent artifacts. A run that reaches a PASS gate report with none of the pipeline artifacts on disk is the exact skip path this gate exists to close; a green report over an empty run directory is a failure. `run_audit.py` is stdlib-only (no third-party import, no network, no subprocess) and its regression suite (`tests/run_audit_test.sh`) is green: a complete valid run exits 0, a missing required artifact exits 1, a foundry-log off the documented format exits 1, an unresolved `[TK]` exits 1, and an mtime inversion is advisory, not a failure.
73
+ 69. **preflight.md is the record every degraded claim answers to.** Phase -1 persists the sweep to `.agents/foundry/<product>/preflight.md` (the four-column table plus the override line), not just an in-session cache → a phase that later claims it ran degraded because a companion was "missing" fails Gate 0 when that companion resolves PRESENT in preflight.md, and a core companion PRESENT at preflight whose OUTPUT artifact is absent fails as present-but-uninvoked. A core companion the user overrode in chat (named on the preflight `override:` line) may skip its artifact, and that run is an honest PARTIAL, not a Gate 0 failure. A run with no preflight.md holds every core artifact strict and says the cross-check was unavailable; a degraded claim naming a present, un-overridden companion is a failure.
74
+ 70. **Gate 1 can fail on conversion, and the divergence is interpreted.** A page whose independent cold score carries a severe flag (M, V, or I at 1, or F or A at 5) → Gate 1 FAILs and the page does not ship until it is fixed; acceptance of any lesser flag is the user's call in chat, never the builder's own. The self-versus-cold divergence is attributed per factor: a factor tagged recoverable names the specific `[TK]` that will close it at build and is re-scored on the rendered page, and if the `[TK]` fills but the score does not recover it becomes an unexplained finding; an un-attributed divergence is treated as unexplained builder optimism. Every claim in `message-architecture.md`'s hierarchy appears on the built page in priority order (lead claim in the hero) or the spec records the deviation. A Gate 1 that passes a severe flag, an author accepting their own page's flag, or a page that drops the hierarchy silently, is a failure.
75
+ 71. **The research reaches the design.** Phase 4 reads `voc.md`, `message-architecture.md`, and `persuasion-map.md` as required inputs, not just the brand palette and the spec → the design direction's scene sentence names the ICP segment and entry state it was drawn from, and that segment exists in the brief or `voc.md`; Gate 5 traces it back. A scene sentence that could describe any page for any buyer means the aesthetic was chosen blind to the reader, which is the failure the required reads exist to prevent, and it sends the design back. A Phase 4 that reads no research artifact, or a scene sentence with no ICP behind it, is a failure.
76
+ 72. **Imagery and states are designed outputs, and external facts are re-verified.** Phase 4 writes `imagery-plan.md` (per-slot source and treatment recipe, consistency rules) and `states-motion.md` (error/loading/success states, focus and hover personality, motion identity with a mandatory reduced-motion fallback); both are required by `run_audit.py` in build, explore, and handoff. Gate 5 checks every shipped image traces to a planned slot at its treatment and is not an unplanned text-and-CSS wall, and walks the primary form to its designed error and success states rather than accepting browser defaults. Gate 5 also captures beyond one engine at two widths (768 and 1024, plus WebKit or Firefox) when the tools exist, Gate 3 checks 320px reflow, and Gate 7 drives one real form submit with the measurement event observed plus a post-deploy live check. Gate 8 re-verifies every checkable claim the page makes about a live external project (repo name, install model, license, OS support) against the live source at build, because those facts drift between intake and ship. A page that defaults to a text wall, ships browser-default states, or repeats an external fact that has since drifted, is a failure.
77
+ 73. **impeccable is core: the design engine is required, not optional.** impeccable is absent and the invocation does not override it → the run halts at Phase -1 like any missing core companion, reports the `npx impeccable install` command, and does not start; a run that proceeds and ships a page with no `DESIGN.md` and no `detect` scan is the failure this tiering fixes (issue #39). With impeccable present, Phase 4 step 8 persists `DESIGN.md` and Gate 5 runs `detect.mjs`; `run_audit.py` requires `DESIGN.md` (regression case I) and fails without it, while an in-chat override makes its absence advisory and the run PARTIAL (regression case J). A "page-foundry page" whose look was never mechanically checked, shipped as a full (non-PARTIAL) run, is a failure: the skill must not treat its own design engine as skippable.
@@ -1,6 +1,6 @@
1
1
  # Product Marketing Brief: {Product Name}
2
2
 
3
- Phase 0 output. Lives at `.agents/product-marketing.md` in the product's repo (or beside the page output). Every downstream phase reads this file; keep it current. Compatible with the coreyhaines31/marketingskills `product-marketing` context format.
3
+ Phase 0 output. Lives at `.agents/product-marketing.md` in the product's repo (or inside the product's run artifact directory, `.agents/foundry/<product>/`, when there is no repo). Every downstream phase reads this file; keep it current. Compatible with the coreyhaines31/marketingskills `product-marketing` context format.
4
4
 
5
5
  ## Product
6
6
 
@@ -32,6 +32,20 @@ Phase 0 output. Lives at `.agents/product-marketing.md` in the product's repo (o
32
32
  - **The mechanism:** (why this works where alternatives fail; the thing only this product/method does)
33
33
  - **Honest tradeoffs:** (what alternatives do better; will be conceded on comparison sections)
34
34
 
35
+ ## Objections & anti-persona
36
+
37
+ - **Objections heard:** (the top reasons real prospects say no, in their words; Phase 1 orders and answers them in the objection map)
38
+ - **Anti-persona:** (who is NOT a good fit and why; the page may turn away exactly these readers, and the Phase 3 red-team checks that it does)
39
+
40
+ ## Switching dynamics
41
+
42
+ The four forces acting on a buyer weighing a move off their current alternative. Phase 1 turns Habit and Anxiety into objection-map entries or strikes them with a reason; the Phase 3 red-team walks each reader in carrying them.
43
+
44
+ - **Push:** (what frustrates them about the current solution)
45
+ - **Pull:** (what draws them to this one)
46
+ - **Habit:** (what keeps them where they are: sunk setup, muscle memory, integrations)
47
+ - **Anxiety:** (what worries them about switching: migration, lock-in, learning curve, data)
48
+
35
49
  ## Proof inventory
36
50
 
37
51
  List only what is real. Mark gaps as `[TK: what to collect]`.