forgedock 1.0.17 → 1.0.18

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.
Files changed (131) hide show
  1. package/README.md +34 -1
  2. package/bin/cross-publish.mjs +344 -0
  3. package/bin/forgedock.mjs +229 -17
  4. package/commands/autopilot.md +77 -0
  5. package/commands/design-bench.md +176 -0
  6. package/commands/design-render-critique-loop.md +103 -0
  7. package/commands/design.md +259 -0
  8. package/commands/issue.md +7 -3
  9. package/commands/orchestrate.md +121 -0
  10. package/commands/qa-sweep.md +37 -2
  11. package/commands/quality-gate.md +30 -0
  12. package/commands/review-pr-staging.md +158 -2
  13. package/commands/test-gate.md +929 -0
  14. package/commands/work-on/build/implement.md +5 -3
  15. package/commands/work-on.md +53 -3
  16. package/docs/CI.md +177 -0
  17. package/docs/FORGE-PROTOCOL.md +324 -0
  18. package/docs/articles/b-vs-c-baseline.md +210 -0
  19. package/docs/articles/full-abc-benchmark.md +205 -0
  20. package/docs/articles/selective-spec-loading-token-savings.md +140 -0
  21. package/docs/design/abc-benchmark.md +195 -0
  22. package/docs/design/design-architect-rationale.md +123 -0
  23. package/docs/design/design-memory.md +61 -0
  24. package/docs/design/design-spec-schema.md +248 -0
  25. package/docs/design/design-system-lint.md +150 -0
  26. package/docs/design/divergent-generation.md +106 -0
  27. package/docs/design/effects-appropriateness.md +133 -0
  28. package/docs/design/fixtures/briefs/README.md +47 -0
  29. package/docs/design/fixtures/briefs/cadence.md +39 -0
  30. package/docs/design/fixtures/briefs/plume.md +39 -0
  31. package/docs/design/fixtures/briefs/slipstream.md +39 -0
  32. package/docs/design/fixtures/briefs/tender.md +39 -0
  33. package/docs/design/fixtures/briefs/voltage.md +39 -0
  34. package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-1.html +364 -0
  35. package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-2.html +420 -0
  36. package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-3.html +506 -0
  37. package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-1.html +611 -0
  38. package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-2.html +594 -0
  39. package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-3.html +817 -0
  40. package/docs/design/fixtures/runs/b-vs-c-baseline/runs.json +175 -0
  41. package/docs/design/fixtures/runs/b-vs-c-baseline/scorecard.json +138 -0
  42. package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-1.html +373 -0
  43. package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-2.html +398 -0
  44. package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-3.html +595 -0
  45. package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-1.html +531 -0
  46. package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-2.html +565 -0
  47. package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-3.html +674 -0
  48. package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-1.html +388 -0
  49. package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-2.html +463 -0
  50. package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-3.html +568 -0
  51. package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-1.html +562 -0
  52. package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-2.html +618 -0
  53. package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-3.html +618 -0
  54. package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-1.html +364 -0
  55. package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-2.html +420 -0
  56. package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-3.html +506 -0
  57. package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-1.html +527 -0
  58. package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-2.html +445 -0
  59. package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-3.html +483 -0
  60. package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-1.html +611 -0
  61. package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-2.html +594 -0
  62. package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-3.html +817 -0
  63. package/docs/design/fixtures/runs/full-abc/runs.json +190 -0
  64. package/docs/design/fixtures/runs/full-abc/scorecard.json +144 -0
  65. package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-1.html +496 -0
  66. package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-2.html +447 -0
  67. package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-3.html +564 -0
  68. package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-1.html +373 -0
  69. package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-2.html +398 -0
  70. package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-3.html +595 -0
  71. package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-1.html +622 -0
  72. package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-2.html +475 -0
  73. package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-3.html +660 -0
  74. package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-1.html +531 -0
  75. package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-2.html +565 -0
  76. package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-3.html +674 -0
  77. package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-1.html +525 -0
  78. package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-2.html +446 -0
  79. package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-3.html +463 -0
  80. package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-1.html +388 -0
  81. package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-2.html +463 -0
  82. package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-3.html +568 -0
  83. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-1.html +1068 -0
  84. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-2.html +1423 -0
  85. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-3.html +1245 -0
  86. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-1.html +305 -0
  87. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-2.html +327 -0
  88. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-3.html +428 -0
  89. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-1.html +1270 -0
  90. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-2.html +1172 -0
  91. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-3.html +1532 -0
  92. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-1.html +315 -0
  93. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-2.html +342 -0
  94. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-3.html +353 -0
  95. package/docs/design/fixtures/runs/full-abc-opus/runs.json +190 -0
  96. package/docs/design/fixtures/runs/full-abc-opus/scorecard.json +144 -0
  97. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-1.html +345 -0
  98. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-2.html +396 -0
  99. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-3.html +502 -0
  100. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-1.html +408 -0
  101. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-2.html +446 -0
  102. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-3.html +496 -0
  103. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-1.html +813 -0
  104. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-2.html +711 -0
  105. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-3.html +721 -0
  106. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-1.html +280 -0
  107. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-2.html +291 -0
  108. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-3.html +366 -0
  109. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-1.html +1010 -0
  110. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-2.html +836 -0
  111. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-3.html +930 -0
  112. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-1.html +407 -0
  113. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-2.html +396 -0
  114. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-3.html +529 -0
  115. package/docs/design/foundations/brutalist.css +294 -0
  116. package/docs/design/foundations/editorial.css +300 -0
  117. package/docs/design/foundations/minimal-luxury.css +295 -0
  118. package/docs/design/foundations/technical.css +293 -0
  119. package/docs/design/foundations/warm-photo.css +299 -0
  120. package/docs/design/reference-corpus.md +1726 -0
  121. package/docs/design/render-critique-loop.md +57 -0
  122. package/docs/spec-graph-schema.md +397 -0
  123. package/package.json +1 -1
  124. package/scripts/bench-scorecard.mjs +239 -0
  125. package/scripts/build-spec-graph.mjs +509 -0
  126. package/scripts/classify-lane.sh +0 -7
  127. package/scripts/design-system-lint.mjs +993 -0
  128. package/scripts/graph-query.sh +486 -0
  129. package/scripts/transition-label.sh +10 -2
  130. package/scripts/validate-spec-graph.sh +423 -0
  131. package/templates/workflows/forgedock-review.yml +96 -0
@@ -0,0 +1,150 @@
1
+ # Design-System Linter — `scripts/design-system-lint.mjs`
2
+
3
+ > **Status:** Committed — the deterministic anti-slop gate for the UI Taste Harness (milestone #13, issue #884).
4
+ > Consumes the [`FORGE:DESIGN_SPEC` schema](design-spec-schema.md) (#881); enforces the machine-checkable
5
+ > negatives from the [reference corpus](reference-corpus.md) (#880); invoked by the
6
+ > render → critique loop (#882) and/or quality-gate.
7
+ > Extended: `checkFoundationUsage` check for per-archetype CSS foundation class usage (#1048).
8
+
9
+ ## Purpose
10
+
11
+ The positive, deterministic floor of the harness. It **hard-fails** generated landing-page output that
12
+ violates the committed design system, rather than hoping prose prevents regression to generic AI defaults.
13
+
14
+ > Don't let the LLM "reason its way" back to generic defaults — **constrain it out of them deterministically**.
15
+ > Prose is a suggestion; a failing lint is a constraint. This raises the floor and never lets it regress,
16
+ > regardless of model variance. (Same philosophy as the #639 fix.)
17
+
18
+ The linter and the vision critic (#882) check the rendered output against the **same** committed intent
19
+ (the `FORGE:DESIGN_SPEC`). The linter owns the **deterministic** negatives; the critic owns the perceptual ones.
20
+
21
+ ## Scope — what the linter owns
22
+
23
+ The [corpus](reference-corpus.md) tags each negative with its check surface. The linter implements exactly the
24
+ deterministic ones; the rest are left to the vision critic.
25
+
26
+ | Negative | Check | Default severity | Surface |
27
+ |---|---|---|---|
28
+ | **N1** | Purple/blue gradient hero on a white/near-white background | BLOCKING when spec opts in | `checkHeroGradient` |
29
+ | **N2** | Inter / system-default typeface at default weights as the display/body face | BLOCKING (typography is core taste) | `checkTypography` |
30
+ | **N4** | Exactly three identical feature cards (structural pattern only) | WARNING — icon judgement is the critic's | `checkRepeatedCards` |
31
+ | **N5** | A single radius applied to everything, or off-scale radii | BLOCKING when a multi-token `radius.scale` exists | `checkRadius` |
32
+ | **N6** | Default Tailwind palette (slate/gray/zinc/neutral/indigo/violet) used as the brand color | BLOCKING when `no-default-tailwind-palette` is set | `checkPalette` |
33
+ | **N7** | The boilerplate skeleton: hero → 3-cards → testimonial → CTA, in that order | BLOCKING when `layout_grammar.sections` exists | `checkSectionSkeleton` |
34
+ | **N24** | Static product mock: `product_mock.type` is committed (not `"none"`) but the rendered hero has a `.product-window` or `.mock-*` element with no `animation`, `transition`, or JS `addEventListener` present <!-- Added: forge#1045 --> | BLOCKING when `product_mock.type` is set and not `"none"` | `checkProductMock` |
35
+ | **N25** | Truncated narrative: `scroll_narrative` is committed in spec but the rendered page has ≤1 below-fold section (`<section>` or `<div role="region">` elements outside the first/hero section) <!-- Added: forge#1046 — spec only; .mjs implementation follows --> | BLOCKING when `scroll_narrative.section_count_min` is set | `checkScrollNarrative` |
36
+ | **N26** | Missing social proof: `scroll_narrative.social_proof_section` is committed (not `"none"`) but no element with class `section-social-proof`, `social-proof`, or `[data-section="social-proof"]` is present <!-- Added: forge#1046 — spec only; .mjs implementation follows --> | BLOCKING when `scroll_narrative.social_proof_section` is set and not `"none"` | `checkSocialProof` |
37
+ | **N27** | Single CTA: `scroll_narrative.cta_placements_min` is ≥ 2 but the rendered page has fewer than 2 elements matching `.btn-primary`, `.cta-button`, `[data-cta]`, or `<a>` with class containing `cta` <!-- Added: forge#1046 — spec only; .mjs implementation follows --> | BLOCKING when `scroll_narrative.cta_placements_min` ≥ 2 | `checkCTACount` |
38
+ | — | Foundation class usage: a foundation CSS file was injected (Stage 3, #1048) but none of `.btn`, `.card`, `.badge`, `.input` appear in the generated HTML — generator replaced foundation classes with Tailwind equivalents <!-- Added: forge#1048 --> | WARNING when `meta.archetype` maps to a known foundation file | `checkFoundationUsage` |
39
+ | — | Off-scale spacing (padding/margin/gap not on `spacing.scale`) | WARNING | `checkSpacing` |
40
+ | — | Contrast: `color.foreground` vs `color.background` below `acceptance.a11y.contrast_min` | BLOCKING when a contrast floor is declared | `checkContrast` |
41
+
42
+ **Opt-in trigger for N24**: `product_mock.type` present in spec and not `"none"`. When `product_mock.type: "none"`,
43
+ N24 is skipped entirely — the architect deliberately opted out of a mock, and no check is needed.
44
+
45
+ **Opt-in trigger for N25**: `scroll_narrative.section_count_min` present in spec. The check counts `<section>`
46
+ (and `<div role="region">`) elements in the rendered HTML; when the count is below `section_count_min`, the check
47
+ blocks. When `scroll_narrative` is absent from the spec, N25 is skipped.
48
+
49
+ **Opt-in trigger for N26**: `scroll_narrative.social_proof_section` present in spec and not `"none"`. Checks for
50
+ social proof element presence using class-name patterns (`section-social-proof`, `social-proof`) and
51
+ `[data-section="social-proof"]` attribute. When `social_proof_section: "none"`, the architect deliberately opted
52
+ out and N26 is skipped.
53
+
54
+ **Opt-in trigger for N27**: `scroll_narrative.cta_placements_min` ≥ 2. Counts CTA elements using class-name
55
+ patterns (`.btn-primary`, `.cta-button`, `[data-cta]`, and `<a>` elements with class containing `cta`). When
56
+ `cta_placements_min` is absent or < 2, N27 is skipped.
57
+
58
+ **Out of scope** (vision-critic-owned, #882): N3 (everything centered), N8 (stock illustration / generic 3D),
59
+ N9 (glassmorphism overuse), N10 (no visual hierarchy), N11 (abstract copy / no product shown),
60
+ N12 (decorative effects that serve nothing), N24 perceptual quality (whether the 2 interactions feel right — the critic
61
+ judges that; the linter only checks that interaction signals are present at all), N25/N26/N27 narrative quality
62
+ (whether the section content is compelling — the critic judges that; the linter only checks structural presence).
63
+ These require perceptual judgement and are not deterministically checkable.
64
+ N12 / effect justification specifically is governed by the [effects-appropriateness doctrine](effects-appropriateness.md) (#885)
65
+ and judged by the vision critic (#882) against the per-section `justification`; the perf gate (#875) owns the hard `budget`. The linter stays out.
66
+
67
+ ## Spec-driven gating
68
+
69
+ Which checks **block** (vs. merely warn) is driven by the spec, not hardcoded — so the same linter serves any
70
+ archetype. A check escalates to `BLOCKING` when the spec opts in via:
71
+
72
+ - `color.rules` — e.g. `"no-default-tailwind-palette"` (gates N6/N1), `"contrast>=4.5"` (gates contrast).
73
+ - `negatives[]` — e.g. `"N6"`, `"N7"` (raw IDs, `{ "id": "N6" }` objects, or descriptive strings are all accepted).
74
+ - Presence of the relevant token field — a multi-entry `radius.scale` opts N5 in; `layout_grammar.sections` opts N7 in;
75
+ a committed non-default `typography.display_family` opts N2 in; `acceptance.a11y.contrast_min` opts contrast in;
76
+ `product_mock.type` set to any value other than `"none"` opts N24 in;
77
+ `scroll_narrative.section_count_min` present opts N25 in;
78
+ `scroll_narrative.social_proof_section` set to any value other than `"none"` opts N26 in;
79
+ `scroll_narrative.cta_placements_min` ≥ 2 opts N27 in;
80
+ `meta.archetype` matching a known foundation archetype opts `checkFoundationUsage` in (WARNING only — see #1048). <!-- Added: forge#1048 -->
81
+
82
+ `--strict` forces **every** deterministic check to block regardless of spec opt-in.
83
+
84
+ ## Usage
85
+
86
+ ```bash
87
+ node scripts/design-system-lint.mjs --spec <spec.json> --html <page.html> [options]
88
+ ```
89
+
90
+ | Option | Meaning |
91
+ |---|---|
92
+ | `--spec <path>` | The `FORGE:DESIGN_SPEC` JSON (required) |
93
+ | `--html <path>` | The generated HTML to lint (required, unless `--selftest`) |
94
+ | `--css <path>` | Optional separate CSS file (inline `<style>` and `style="…"` are always read) |
95
+ | `--baseline` | Report findings but always exit `0` (survey existing slop, never fail the build) |
96
+ | `--strict` | Every deterministic check blocks, even without spec opt-in |
97
+ | `--json` | Emit findings as JSON on stdout (for the #882 critique loop to consume) |
98
+ | `--selftest` | Run internal self-checks (contrast math, palette table) and exit |
99
+ | `--help` | Show usage |
100
+
101
+ ### Output
102
+
103
+ Plain mode prints one finding per line with the established severity prefixes, then a summary:
104
+
105
+ ```
106
+ BLOCKING: [N6] Committed color accent=#4f46e5 is a default Tailwind palette value — not a brand color.
107
+ WARNING: [SPACING] Off-scale spacing value(s): 17px — not on spacing.scale [4, 8, 12, 16, 24, 32, 48, 64, 96].
108
+ OK: [N1] No purple/blue-gradient-on-white hero detected.
109
+
110
+ === Summary ===
111
+ Checks run: 13
112
+ Blocking: 11
113
+ Warnings: 1
114
+ ```
115
+
116
+ `--json` emits `{ blocking, warnings, baseline, findings: [{ severity, negative, message }] }`.
117
+
118
+ ### Exit codes
119
+
120
+ Matches the scripts-layer convention (`scripts/verify-env-vars.sh`):
121
+
122
+ | Code | Meaning |
123
+ |---|---|
124
+ | `0` | Pass — no blocking findings |
125
+ | `1` | Blocking findings present |
126
+ | `2` | Warnings only (or bad invocation) |
127
+
128
+ `--baseline` always exits `0`.
129
+
130
+ ## Integration
131
+
132
+ - **Render → critique loop (#882):** call the linter with `--json` on the generated HTML before the vision pass.
133
+ Blocking findings short-circuit the iteration (the page is regenerated against the spec) without spending a
134
+ vision-critique turn. The linter is deterministic and dependency-free, so it is cheap to run every iteration.
135
+ - **quality-gate:** invoke as a sibling scripts-layer check (like `scripts/verify-*.sh`) and key off the exit code.
136
+ Use `--baseline` for a non-failing survey, or default mode to hard-gate.
137
+
138
+ ## Design notes
139
+
140
+ - **Zero runtime dependencies** — Node built-ins only (`node:fs`), matching `scripts/gen-logo.mjs`. HTML/CSS is
141
+ scanned with tolerant regex (attribute order, quote style, and whitespace are accommodated); no jsdom/cheerio.
142
+ - **Injection-safe** — inputs are read as data and never interpolated into a shell; there is no `eval`/`exec`
143
+ (avoids the class of review-findings #73 / #335).
144
+ - **Deterministic** — no network, no randomness, stable finding order. The contrast check uses the standard WCAG
145
+ relative-luminance formula (self-tested: `#000`/`#fff` = 21:1).
146
+ - **Parser limitations** — being regex-based, the linter reads inline `<style>` blocks and `style="…"` attributes
147
+ plus Tailwind utility classes; it does not resolve an external Tailwind build's computed colors. Ambiguous cases
148
+ (e.g. a committed font that cannot be confirmed in the output) are reported as `WARNING`, not `BLOCKING`, to avoid
149
+ false hard-fails. For computed/rendered-pixel checks (e.g. N8–N12), defer to the vision critic with a real render
150
+ (Playwright, #875).
@@ -0,0 +1,106 @@
1
+ # Divergent generation + archetype sampling + taste-judge selection
2
+
3
+ > **Status**: committed foundation doc for the UI Taste Harness (#883).
4
+ > The variance lever: how the harness produces *different* good pages instead of mode-collapsing to one.
5
+ > Consumes: [reference-corpus](reference-corpus.md) archetypes (#880), the [design-architect rationale](design-architect-rationale.md) (#886).
6
+ > Produces: a `FORGE:DESIGN_CANDIDATES` set whose winner hands off into [`FORGE:DESIGN_SPEC`](design-spec-schema.md) (#881).
7
+ > Judge is independent from the render → vision-critique loop (#882) and the [ABC benchmark judge](abc-benchmark.md) (#878) — anti-Goodhart.
8
+ > Part of #877.
9
+
10
+ ## Purpose
11
+
12
+ Two failure modes bracket AI UI generation. **Mode collapse**: "make it beautiful" yields the same gradient-hero
13
+ template every time — zero variance. **Incoherent blending**: averaging archetypes ("a bit editorial, a bit
14
+ brutalist") yields mush — variance without taste. This doc defines the lever that sits between them: **commit to one
15
+ archetype, then diverge *within* it across N distinct directions, and let an independent taste-judge pick the winner.**
16
+
17
+ Variance between runs comes from *which archetype + which direction* is chosen — never from blending. Coherence within
18
+ a run comes from committing and not drifting.
19
+
20
+ ## Step 1 — Archetype sampling (commit, never blend)
21
+
22
+ From the design-blind brief + the architect rationale (#886), select **exactly one** archetype from the five committed
23
+ in [reference-corpus](reference-corpus.md) (#880). The ids are fixed tokens — they must match exactly, because the
24
+ selected id is written into `meta.archetype` in the [spec](design-spec-schema.md):
25
+
26
+ | `archetype` id | When it fits |
27
+ |---|---|
28
+ | `editorial-typographic` | considered, magazine, type-led products; content-forward |
29
+ | `technical-dense` | dashboards, compute, infra; capable, data-forward |
30
+ | `minimal-luxury` | premium, lots of air; restraint as the message |
31
+ | `bold-brutalist` | opinionated, high-contrast; a stance |
32
+ | `warm-photographic` | human, approachable; image/people-led |
33
+
34
+ **Selection rule** (from the corpus): pick the one appropriate to *product nature* + *audience* inferred from the
35
+ brief, then **commit**. No blending, no averaging, no "60% A / 40% B". The variance lever is the *choice between*
36
+ archetypes across runs and the divergent directions below — not a blend within a run.
37
+
38
+ ## Step 2 — Divergent generation (N distinct directions)
39
+
40
+ Within the committed archetype, generate **N distinct directions** (default N=3). Each direction is a genuinely
41
+ different interpretation of the *same* archetype + rationale — different layout grammar, different signature move,
42
+ different typographic instantiation — not N near-duplicates with a hue shift. Divergence is structural, not cosmetic.
43
+
44
+ Each direction carries:
45
+ - a one-line concept (the interpretation),
46
+ - its **signature move** (from the rationale's diary — the non-obvious idea that makes it *this* page),
47
+ - the salient token/grammar choices that distinguish it from its siblings.
48
+
49
+ Sampling within one archetype keeps every direction coherent; requiring *structural* difference keeps them genuinely
50
+ divergent. If two directions collapse to the same signature move, one is rejected and re-rolled — duplicate directions
51
+ defeat the lever.
52
+
53
+ ## Step 3 — Taste-judge score + select
54
+
55
+ An **independent taste-judge** scores the N directions and selects one winner. The judge:
56
+ - scores each direction on a small taste rubric (hierarchy/intent, signature-move strength, archetype fit, restraint),
57
+ - rejects any that trip the corpus negatives or duplicate a sibling,
58
+ - selects the highest-scoring surviving direction; ties break toward the stronger signature move.
59
+
60
+ ### Judge independence (anti-Goodhart) — non-negotiable
61
+
62
+ This taste-judge is **distinct** from both:
63
+ - the **render → vision-critique loop** (#882), which judges a *rendered* page against its committed spec, and
64
+ - the **ABC benchmark judge** (#878), which scores arms blind against arm C for evaluation.
65
+
66
+ Reusing either as the selection judge would let the harness optimize directly against its own evaluator — the textbook
67
+ Goodhart failure. The selection judge scores *candidate directions* (pre-render intent); the critic scores *rendered
68
+ output*; the benchmark scores *finished arms*. Three separate judges, three separate jobs.
69
+
70
+ ## Step 4 — Hand-off to DESIGN_SPEC
71
+
72
+ The winning direction is what gets fully specified: it hands off into [`FORGE:DESIGN_SPEC`](design-spec-schema.md)
73
+ (#881) — `meta.archetype` = the committed id, `layout_grammar`/`signature` = the winning direction. The losing
74
+ directions are retained in the `FORGE:DESIGN_CANDIDATES` annotation (below) so the choice is auditable and so
75
+ [design-memory](design-memory.md) (#887) can later diverge from past winners.
76
+
77
+ ## The `FORGE:DESIGN_CANDIDATES` annotation
78
+
79
+ Registered in [FORGE-PROTOCOL](../FORGE-PROTOCOL.md). Posted at the divergent-generation step, between the rationale
80
+ and the spec. It records the committed archetype, the N directions, and the judge's selection + scores — so the
81
+ variance decision is a first-class, machine-queryable artifact, not a hidden roll.
82
+
83
+ ```markdown
84
+ <!-- FORGE:DESIGN_CANDIDATES -->
85
+ ## Design Candidates — {product}
86
+
87
+ **Archetype (committed):** {one of the 5 corpus ids}
88
+ **Directions:**
89
+ 1. {concept} — signature: {move} — {distinguishing grammar/tokens}
90
+ 2. {concept} — signature: {move} — {…}
91
+ 3. {concept} — signature: {move} — {…}
92
+ **Judge scores:** 1) {score} 2) {score} 3) {score}
93
+ **Selected:** #{n} — because {reason}
94
+
95
+ → Winner produces DESIGN_SPEC: {link}
96
+ ```
97
+
98
+ ## Acceptance (worked expectation)
99
+
100
+ On the seed set, the same brief produces a *committed archetype* and visibly different *directions*:
101
+ - **Voltage** (`technical-dense`): directions differ on whether the signature move is a scaling-compute visualization,
102
+ a code-first hero, or a benchmark-grid — same archetype, three structures.
103
+ - **Plume** (`minimal-luxury` / `editorial-typographic`): directions differ on keyboard-motif vs cycle-timeline vs
104
+ pure-type hierarchy — all restrained, all coherent.
105
+
106
+ Variance shows up as *which archetype + which direction wins*, across runs — never as a blend within a run.
@@ -0,0 +1,133 @@
1
+ # Effects-appropriateness layer
2
+
3
+ > **Status**: committed foundation doc for the UI Taste Harness (#885).
4
+ > Consumes: [reference-corpus](reference-corpus.md) effect-usage patterns (#880),
5
+ > [design-spec-schema](design-spec-schema.md) `effects_plan` slot (#881).
6
+ > Enforced by: the perf gate (#875, hard/objective) and the vision critique loop (#882, perceptual — N12).
7
+ > Stays out of: the deterministic [linter](design-system-lint.md) (#884) — effect justification is not deterministically checkable.
8
+ > Authored to be consumed by: the [design-architect rationale](design-architect-rationale.md) (#886) and [design-memory](design-memory.md) (#887) phases.
9
+ > Part of #877.
10
+
11
+ ## Purpose
12
+
13
+ The schema (#881) gives every page an `effects_plan` — a slot for *which* heavy techniques run *where*, at *what*
14
+ intensity, with a *budget* and a *never* list. The slot is a placeholder. This doc is the **reasoning doctrine that
15
+ fills it**: how the harness decides, **from the design-blind brief alone**, when a heavy effect earns its cost and
16
+ when restraint is the more confident choice.
17
+
18
+ The thesis: AI UI mode-collapses toward gratuitous motion because "make it impressive" has no cost model. The fix is
19
+ to treat every effect as a spend that must be *justified against the content it serves and the budget it consumes* —
20
+ and to make the default **restraint**, with effects added only on evidence, never by reflex.
21
+
22
+ ## The core asymmetry
23
+
24
+ Not all effects reward the same posture. This is the single most important rule in this doc:
25
+
26
+ > **Compositional contrast rewards *more* intention. 3D/WebGL, parallax, and multi-layer depth reward *restraint*.**
27
+
28
+ Flattening this into "less is always more" loses the doctrine. Low contrast is itself a slop tell (flat, equal-weight,
29
+ nothing directs the eye — see N12's sibling failures). Deliberate contrast is almost always correct. The *decorative*
30
+ effects (depth, motion, 3D) are the ones that must earn their place against a hard cost.
31
+
32
+ ## Effect taxonomy + appropriateness/cost
33
+
34
+ Derived from the corpus effect-usage table (#880); this layer formalizes the `Earns its place when…` / `Slop when…`
35
+ columns into authoring rules with an explicit cost axis.
36
+
37
+ | Effect | Posture | Earns its place when… | Slop when… | Primary cost |
38
+ |---|---|---|---|---|
39
+ | **Compositional contrast** | *more* intention | almost always — direct the eye, establish hierarchy | flat, equal-weight, everything the same size/color | ~none (CSS) |
40
+ | **Multi-layer depth** (glass / grain / gradient) | restraint | one hero backdrop; foreground/background separation that aids reading | over-glass, muddy contrast, applied everywhere | contrast/a11y risk; minor paint |
41
+ | **Parallax / scroll-driven** | restraint | a single progressive-capability reveal where depth *is* the message | on every section; jank/CLS; fights readability | INP/CLS; JS |
42
+ | **3D / WebGL** | strong restraint | the product is spatial/visual; exactly one premium hero centerpiece with a fallback | bolted onto non-visual B2B; wrecks LCP; no reduced-motion/no-WebGL fallback | LCP + JS-kb (largest) |
43
+
44
+ ## The 6 decision inputs
45
+
46
+ The architect/rationale phase (#886) infers all six from the brief alone, then writes them into `effects_plan`:
47
+
48
+ 1. **Product nature** — is the product itself *spatial/visual* (renders, maps, 3D, creative tooling), *technical/data*
49
+ (compute, dashboards, infra), or *text/workflow* (trackers, docs, email)? Spatial → a heavy hero may be earned;
50
+ text/workflow → near-zero decorative.
51
+ 2. **Archetype** — the committed archetype carries an **effects posture** prior (#880): `bold-brutalist` →
52
+ "sharp, near-zero decorative"; `technical-dense` → "code/data motion welcome"; `minimal-luxury` →
53
+ "restrained micro-motion"; `editorial-typographic` → "minimal, type-led"; `warm-photographic` → "image-driven, soft motion".
54
+ 3. **Section job** — what is *this* section for? A hero may carry one centerpiece; a pricing table or feature grid
55
+ carries none. Effect intensity is assigned **per section**, not per page.
56
+ 4. **Audience expectation** — engineers who "read the code sample closely" reward technical credibility and are
57
+ *repelled* by gratuitous motion; a consumer/creative audience tolerates more spectacle.
58
+ 5. **Measurable perf budget** (#875) — LCP / CLS / INP / JS-kb ceilings. This is the **hard gate**: an effect that
59
+ blows the budget is rejected regardless of how good it looks.
60
+ 6. **Accessibility** — `prefers-reduced-motion` must be honored; depth must not destroy contrast; every WebGL/3D
61
+ centerpiece needs a static fallback. A11y failures are not negotiable against aesthetics.
62
+
63
+ ## Mapping decision inputs → `effects_plan`
64
+
65
+ The fields mirror [design-spec-schema](design-spec-schema.md) exactly:
66
+
67
+ `effects_plan { per_section[{ section, effect, intensity, justification }], budget{ lcp_ms, max_js_kb }, never[] }`
68
+
69
+ - **`per_section[].effect` / `.intensity`** — from inputs 1–4. Default `intensity: none`. Raise it only when product
70
+ nature + archetype + section job *agree* that the effect serves the content. Each step up in intensity needs a
71
+ stronger justification.
72
+ - **`per_section[].justification`** — one sentence stating *what content the effect serves*. "Looks premium" is not a
73
+ justification; "the spatial product *is* the demo, shown once in the hero" is. The critic (#882) reads this field
74
+ and judges whether the rendered effect actually delivered on it (N12).
75
+ - **`budget{ lcp_ms, max_js_kb }`** — from input 5. The hard ceiling. The perf gate (#875) measures the rendered arm
76
+ against it; over-budget = fail, no aesthetic override.
77
+ - **`never[]`** — from inputs 2 + 6. Per-archetype prohibitions (e.g. `bold-brutalist` → `never: [parallax, glass]`)
78
+ and universal a11y rules (`never: [motion-without-reduced-motion-fallback]`).
79
+
80
+ ## Enforcement split
81
+
82
+ Three mechanisms, deliberately non-overlapping — no single check owns the whole problem:
83
+
84
+ | Mechanism | Owns | Nature |
85
+ |---|---|---|
86
+ | **Perf gate** (#875) | `budget` — did the effect stay within LCP/CLS/INP/JS-kb? | **Hard, objective.** Earned its *ms*. Blocking. |
87
+ | **Vision critic** (#882) | N12 — did each effect *serve the content* it claimed to? | **Perceptual.** Earned its *place*. Finding. |
88
+ | **Deterministic linter** (#884) | nothing here | Effects are explicitly **out of scope** — not deterministically checkable. |
89
+
90
+ The perf gate answers "could the user afford it?"; the critic answers "was it worth it?". An effect must pass **both**:
91
+ within budget *and* serving the content. Within budget but gratuitous → critic N12 finding. Justified but over budget →
92
+ perf-gate fail. The linter stays out because perceptual judgement can't be reduced to a regex without false hard-fails
93
+ (consistent with `design-system-lint.md`'s N8–N12 out-of-scope list).
94
+
95
+ ## Worked inferences (seed set)
96
+
97
+ Demonstrating that the doctrine produces **visibly different effect intensity from the briefs alone** — the acceptance
98
+ criterion. Each is derived purely from the design-blind brief; no visual direction is given.
99
+
100
+ ### Voltage — serverless compute / GPUs for ML engineers
101
+ - **Product nature**: technical/data (compute), with a *credible* spatial story (containers scaling zero→thousands).
102
+ - **Audience**: engineers who read the code sample closely → reward technical credibility, repelled by spectacle.
103
+ - **Inference**: `technical-dense` archetype; **one restrained** technical hero visualization (subtle scaling/compute
104
+ motion that *is* the product story), `intensity: subtle`. Code sample is the real hero. No parallax, no glass.
105
+ - `effects_plan`: hero → `effect: technical-motion, intensity: subtle, justification: "the zero→N scaling IS the product, shown once"`;
106
+ all other sections → `none`. `never: [parallax, decorative-3d]`. Tight JS budget (audience will notice bloat).
107
+
108
+ ### Plume — fast, keyboard-driven issue tracker for software teams
109
+ - **Product nature**: text/workflow. Speed and focus are the message.
110
+ - **Audience**: craft-focused technical teams who find heavy tools heavy → motion that slows them is *anti-product*.
111
+ - **Inference**: `minimal-luxury` / `editorial-typographic`; **near-zero motion**. The product's own speed is the
112
+ argument; any decorative effect contradicts it. Contrast and typography do all the work.
113
+ - `effects_plan`: every section → `intensity: none`; `never: [parallax, 3d, glass]`. Restraint *is* the design.
114
+
115
+ ### Slipstream — git-connected deploy platform / global edge
116
+ - **Product nature**: technical/infra; "confidence and restraint" stated explicitly in the brief.
117
+ - **Audience**: frontend/full-stack devs; serious, opinionated platform.
118
+ - **Inference**: restrained, typographic-technical. At most **one** subtle scroll reveal for the push→production flow
119
+ (depth *is* part of that narrative), `intensity: subtle`; everything else `none`. Restraint as the move.
120
+ - `effects_plan`: hero/flow → `effect: scroll-reveal, intensity: subtle, justification: "push→prod is a sequence; one reveal shows it"`;
121
+ rest → `none`. `never: [decorative-3d, glass]`.
122
+
123
+ **Differential**: Voltage gets one subtle *technical* hero motion; Plume gets *zero*; Slipstream gets one subtle
124
+ *scroll reveal* — three visibly different intensities, inferred from product nature + audience alone. None reaches for
125
+ 3D/WebGL, because none is a spatial/visual product. That restraint is the doctrine working.
126
+
127
+ ## Authoring checklist (for the rationale phase, #886)
128
+
129
+ - [ ] Default every section to `intensity: none`; raise only on agreement of inputs 1–4.
130
+ - [ ] Every non-`none` entry carries a content-serving `justification` (not "looks premium").
131
+ - [ ] `budget` set from #875 ceilings; `never[]` set from archetype posture + a11y.
132
+ - [ ] Reduced-motion + WebGL/3D fallback covered in `never[]` or per-section notes.
133
+ - [ ] Contrast treated as *expected*, not optional; low contrast flagged as a tell.
@@ -0,0 +1,47 @@
1
+ # Seed Briefs — Fixtures
2
+
3
+ > Reproducible fixtures for the [ABC benchmark](../../abc-benchmark.md) (#878, milestone #13).
4
+ > Each brief is **design-blind** (describes only what the product *does*) and uses an **anonymized**
5
+ > product name. These are the fixed inputs re-run as the harness evolves.
6
+
7
+ ## What a brief is
8
+
9
+ A brief is the single input shared by all three arms (A = ForgeDock `/design`, B = raw one-shot model,
10
+ C = the real reference). It is derived from a real reference page by **stripping every visual cue** —
11
+ no colors, no typefaces, no layout, no "make it like X" — and keeping only a factual description of what
12
+ the product does, who it is for, and what the page must communicate.
13
+
14
+ ## Anonymization is load-bearing — do not leak the real brand
15
+
16
+ Each brief maps to a real reference page (arm C), but the brief **must never name the real product or brand**.
17
+
18
+ A real brand name lets the generation model recall that brand's actual page from training. That measures
19
+ **brand recall, not taste**, and it unfairly inflates arm B (the raw model would reproduce a page it has
20
+ memorized). Treat any real-brand reference inside a brief file as a fixture bug.
21
+
22
+ The mapping below is kept in this README — **separate from the brief files** — so the generator, which is only
23
+ ever handed a single `*.md` brief, never sees which real page it is being compared against.
24
+
25
+ ## Brief → reference (C) mapping
26
+
27
+ | Anonymized brief | Real reference (arm C) | Archetype it exemplifies | Category |
28
+ |------------------|------------------------|--------------------------|----------|
29
+ | **Cadence** | resend.com | Clean / warm-minimal | Email API / developer tooling |
30
+ | **Tender** | stripe.com | Polished / enterprise-dev | Payments API |
31
+ | **Slipstream**| vercel.com | Stark monochrome / brutalist-minimal | Deploy platform |
32
+ | **Voltage** | modal.com | Technical / playful | Serverless compute |
33
+ | **Plume** | linear.app | Refined minimal / dark technical-luxury | Issue tracking |
34
+
35
+ The references and archetypes are drawn from the [reference corpus](../../reference-corpus.md) (#880). The
36
+ mapping is an internal record for scoring and the C-as-calibration check — it is **not** part of the brief
37
+ input handed to any arm.
38
+
39
+ ## Adding a brief
40
+
41
+ 1. Pick a corpus reference (#880) not already represented, or one that adds a distinct archetype.
42
+ 2. Strip it to a design-blind, factual product description. Remove every visual cue.
43
+ 3. Choose an **anonymized** product name (no resemblance to the real brand).
44
+ 4. Save as `fixtures/briefs/<name>.md` following the structure of the existing briefs.
45
+ 5. Add the `<name> → real reference` row to the mapping table above.
46
+ 6. Keep n high enough: the benchmark runs 3–5 generations per arm across 3–5 products — adding a sixth brief
47
+ is fine, but never run fewer than three.
@@ -0,0 +1,39 @@
1
+ # Brief — Cadence
2
+
3
+ > Design-blind seed brief. Describes only what the product does. No visual direction.
4
+ > Anonymized name — do not infer or reproduce any real brand.
5
+
6
+ ## Product
7
+
8
+ **Cadence** is an email-sending API for developers and product teams. It lets engineers send
9
+ transactional and marketing email from their applications with a few lines of code, and gives
10
+ non-engineers a way to write, manage, and schedule those emails without touching the codebase.
11
+
12
+ ## Who it's for
13
+
14
+ Developers integrating email into a product, plus the marketing and product people on the same team
15
+ who own the content of those emails.
16
+
17
+ ## What it does
18
+
19
+ - A simple REST API and SDKs to send email from application code.
20
+ - Deliverability tooling: domain authentication, suppression handling, and bounce/complaint tracking.
21
+ - A way to author emails as reusable templates, including from React-style components.
22
+ - Analytics on opens, clicks, deliveries, and bounces.
23
+ - A test/preview mode so teams can see an email before it ships.
24
+
25
+ ## What the landing page must communicate
26
+
27
+ - That sending email from code is genuinely simple here (show, don't claim).
28
+ - That deliverability is handled — the hard, invisible part of email is taken care of.
29
+ - That both engineers and content owners have a place in the workflow.
30
+ - Credibility: this is production infrastructure, not a toy.
31
+
32
+ ## Primary call to action
33
+
34
+ Get started / sign up with an API key.
35
+
36
+ ## Constraints
37
+
38
+ - Honest, concrete copy about what the product does — no vague promises.
39
+ - The page should read as current, well-resourced SaaS for a technical audience.
@@ -0,0 +1,39 @@
1
+ # Brief — Plume
2
+
3
+ > Design-blind seed brief. Describes only what the product does. No visual direction.
4
+ > Anonymized name — do not infer or reproduce any real brand.
5
+
6
+ ## Product
7
+
8
+ **Plume** is an issue tracking and project management tool for software teams. It is built to be fast and
9
+ keyboard-driven, and it organizes work into issues, cycles, and projects so a team can plan, prioritize,
10
+ and ship without ceremony.
11
+
12
+ ## Who it's for
13
+
14
+ Software engineering teams and the product and design people who plan alongside them — small, fast-moving
15
+ teams that find traditional project tools heavy.
16
+
17
+ ## What it does
18
+
19
+ - Issues with statuses, priorities, labels, and assignees, navigable almost entirely by keyboard.
20
+ - Cycles (time-boxed sprints) and longer-running projects to organize work.
21
+ - Roadmap and progress views so leads can see where things stand.
22
+ - Tight integrations with code hosting so issues track real development.
23
+ - A fast, responsive interface that stays out of the way.
24
+
25
+ ## What the landing page must communicate
26
+
27
+ - Speed and focus: the tool is fast and respects the user's attention.
28
+ - It is opinionated and designed for teams who care about craft.
29
+ - Planning and shipping live in one place, without bureaucracy.
30
+ - A premium, considered product for discerning technical teams.
31
+
32
+ ## Primary call to action
33
+
34
+ Get started / sign up.
35
+
36
+ ## Constraints
37
+
38
+ - Crisp, confident copy; minimal and precise.
39
+ - Reads as a refined, premium, well-funded product for technical teams.
@@ -0,0 +1,39 @@
1
+ # Brief — Slipstream
2
+
3
+ > Design-blind seed brief. Describes only what the product does. No visual direction.
4
+ > Anonymized name — do not infer or reproduce any real brand.
5
+
6
+ ## Product
7
+
8
+ **Slipstream** is a platform for building and deploying web applications. Developers connect a git
9
+ repository and every push is built and deployed automatically to a global edge network, with preview
10
+ environments for each change and zero server management.
11
+
12
+ ## Who it's for
13
+
14
+ Frontend and full-stack developers and the teams shipping web apps who want to deploy without operating
15
+ infrastructure.
16
+
17
+ ## What it does
18
+
19
+ - Git-connected deploys: push to a branch, get a live URL.
20
+ - Preview deployments for every pull request, so changes can be reviewed running, not just as a diff.
21
+ - A global edge network and CDN so apps are fast everywhere by default.
22
+ - Serverless and edge functions for backend logic without managing servers.
23
+ - Collaboration features so a whole team can see and comment on deploys.
24
+
25
+ ## What the landing page must communicate
26
+
27
+ - Speed and immediacy: from push to production is effortless and fast.
28
+ - Zero infrastructure burden — no servers, no ops.
29
+ - It is the obvious home for modern frontend frameworks.
30
+ - Confidence and restraint: this is a serious, opinionated platform.
31
+
32
+ ## Primary call to action
33
+
34
+ Deploy now / start for free.
35
+
36
+ ## Constraints
37
+
38
+ - Concrete and direct copy; let the capability speak.
39
+ - Reads as a stark, confident, well-funded developer platform.
@@ -0,0 +1,39 @@
1
+ # Brief — Tender
2
+
3
+ > Design-blind seed brief. Describes only what the product does. No visual direction.
4
+ > Anonymized name — do not infer or reproduce any real brand.
5
+
6
+ ## Product
7
+
8
+ **Tender** is a payments platform and API for internet businesses. It lets companies accept payments,
9
+ send payouts, and run subscription billing through a single integration, and handles the regulatory and
10
+ financial plumbing — fraud screening, currency conversion, compliance — on their behalf.
11
+
12
+ ## Who it's for
13
+
14
+ Engineers building checkout, billing, or marketplace flows, plus finance and operations teams at the
15
+ companies that run on top of those flows.
16
+
17
+ ## What it does
18
+
19
+ - A unified API to accept cards and local payment methods across many countries and currencies.
20
+ - Subscription and usage-based billing with proration and invoicing.
21
+ - Payouts and money movement for marketplaces and platforms.
22
+ - Fraud detection and risk scoring built in.
23
+ - A dashboard for finance teams to see revenue, disputes, and payouts.
24
+
25
+ ## What the landing page must communicate
26
+
27
+ - Breadth and reliability: this handles serious money at scale, globally.
28
+ - Developer-first: integration is clean and well-documented.
29
+ - Trust and compliance are handled — the regulated, scary parts are someone else's problem now.
30
+ - It serves both the engineers who integrate and the finance teams who reconcile.
31
+
32
+ ## Primary call to action
33
+
34
+ Start integrating / view the docs.
35
+
36
+ ## Constraints
37
+
38
+ - Enterprise-credible but not stuffy; concrete about capabilities.
39
+ - Reads as a high-stakes, well-funded developer platform.
@@ -0,0 +1,39 @@
1
+ # Brief — Voltage
2
+
3
+ > Design-blind seed brief. Describes only what the product does. No visual direction.
4
+ > Anonymized name — do not infer or reproduce any real brand.
5
+
6
+ ## Product
7
+
8
+ **Voltage** is a serverless platform for running compute-heavy and AI workloads. Developers write
9
+ ordinary Python, attach the resources they need — including GPUs — and Voltage runs it in the cloud on
10
+ demand, scaling from zero to thousands of containers and back without provisioning anything.
11
+
12
+ ## Who it's for
13
+
14
+ Machine-learning engineers, data scientists, and backend developers who need heavy or bursty compute
15
+ (model inference, batch jobs, training) but do not want to manage clusters.
16
+
17
+ ## What it does
18
+
19
+ - Run Python functions in the cloud by adding a decorator — no Dockerfiles or YAML required.
20
+ - On-demand GPUs and large CPU/memory, billed only while running.
21
+ - Scale to thousands of parallel containers and back to zero automatically.
22
+ - Schedule jobs, serve inference endpoints, and run long batch pipelines.
23
+ - Fast cold starts and a local-feeling developer loop.
24
+
25
+ ## What the landing page must communicate
26
+
27
+ - Power made simple: serious compute, but the developer experience feels like writing local code.
28
+ - Pay-for-what-you-use economics — idle costs nothing.
29
+ - It is built for the AI/ML era specifically.
30
+ - Technical credibility: the audience is engineers who will read the code sample closely.
31
+
32
+ ## Primary call to action
33
+
34
+ Run your first function / get started.
35
+
36
+ ## Constraints
37
+
38
+ - Technical, code-forward copy; show a real usage example in spirit.
39
+ - Reads as a capable, modern, well-funded compute platform.