Assumptions & Decisions
This is the honesty ledger. The research left gaps; rather than invent
defensible-sounding numbers from thin air, the demo fills each gap with an
explicit, sourced assumption and writes it down here. Every constant, rate, and
formula traces back to channel-dimensional-letter-variable-taxonomy.md — the
authoritative pricing source — and where the taxonomy is silent, the choice is
tagged below with its basis and its risk.
Two things make this credible rather than hand-wavy:
- The seeded numbers reproduce the taxonomy’s two worked examples (see the callout at the end), so the defaults are externally anchored, not guessed.
- Most assumptions feed only the background cost-plus path that drives the margin badge — they never move the price the salesperson sees. Those are flagged in the table.
Assumptions (A1–A19)
Collected from the technical spec’s inline [ASSUMPTION ...] tags. The “feeds” column
notes which path each touches: display = moves the quoted price; badge = moves
only the cost-plus margin estimate; PDF/form = presentation only.
| Tag | Assumption | Basis / risk | Feeds |
|---|---|---|---|
| A1 | signTextLabel added as a display-only field (not in the taxonomy’s Table A) | PDF needs the sign text; zero pricing logic. Risk: none | PDF/form |
| A2 | Demo height ranges 6–60” (CL) / 6–24” (DL), narrower than the taxonomy’s 3–180” | Per-inch rates and the DL grid are calibrated to storefront sizes; outside them the numbers stop being defensible | form |
| A3 | Face options trimmed to white / colored acrylic | clear+vinyl and polycarbonate have no sourced $/sqft | badge |
| A4 | DL thickness folded into each material preset (shown read-only) | The grid gives one thickness per material; an editable thickness field would require invented prices | form |
| A5 | DL finish multipliers applied relative to each grid row’s included base finish | Grids already embed a finish (e.g. cast = brushed); the multipliers are sourced, the relative application is the assumption | display |
| A6 | spacer/standoff DL mount = ×1.0 (“same as flush”) | No sourced uplift; noted in the UI | display |
| A7 | One uniform letter height per quote (total_upright_inches = count × height) | Multi-height sets are future; matches both worked examples | display |
| A8 | Geometry shape factors per inch of height: 2.67 (perimeter), 0.711 (area), 2.13 (stroke) | Back-derived from the taxonomy’s own Example 1; no DXF in the demo | badge |
| A9 | Estimated stroke width = height / 5 (the LED-rows rule) | Typical block letter; reproduces rows = 1 at 18–24” | badge |
| A10 | Halo rate takes precedence over raceway rate when both apply | Sources price the two dimensions separately; halo is the bigger uplift | display |
| A11 | Wire/studs $5 per letter (wire_studs_per_letter) | Example 1 used ~$20 misc on a 4-letter job | badge |
| A12 | Raceway length = Σ letter widths × 1.15 | A raceway spans the letter run; 15% spacing allowance | badge |
| A13 | Fab hours: 0.25 CNC/bend + 0.75 assembly per letter, scaled by clamp(height/24, 0.5, 2.0) | Calibrated to reproduce both labor anchors exactly (8×24” and Example 1’s 4×18”) | badge |
| A14 | Halo cost-plus uses the front-lit material model | No sourced halo-specific material prices | badge |
| A15 | Margin thresholds: red < 0.30, amber < 0.45, else green | Reconciles the two source formulations of the warning; the healthy example sits at 74.7% (deep green) | badge |
| A16 | Install-hours heuristics (CL: 2 + 0.5×count; DL: 1 + 0.25×count) plus access & surface multipliers | Calibrated to Example 1 (≈$500) and Example 2 ($300 exact); all results fall inside the sourced $350–1,500 band | display |
| A17 | Linear interpolation between DL grid anchors, height clamped to 6–24” | The grid gives 4 anchors; lerp is the simplest defensible rule | display |
| A18 | Line items rendered to cents, totals to whole dollars | Standard US quote presentation (a display/PDF rule — the engine stores full float) | PDF/form |
| A19 | Quote validity 30 days; 50%-deposit terms boilerplate | Common US trade practice; pure PDF furniture, owner-editable | PDF/form |
The “feeds: badge” rows are the load-bearing point of this whole page. Geometry (A8/A9), the halo material model (A14), wire/studs (A11), raceway length (A12), and the fab-labor calibration (A13) are all estimates — and they all land inside the silent cost-plus path that only colors the margin badge. The number the salesperson quotes is the per-inch rate (CL) or the grid lookup (DL), which rest on directly sourced rates.
Decisions (D1–D4)
These are spec-level design calls, not gap-filling guesses — each resolves an ambiguity or a latent contradiction in the source material.
| Tag | Decision | Why |
|---|---|---|
| D1 | Design is a flat ancillary design_fee ($150), auto-applied to channel letters only; task labor excludes design hours | Removes the double-count latent in the taxonomy pseudocode (design appearing in both labor and ancillary) and matches both worked examples. DL gets no design line — patterns come with the resold letters |
| D2 | minimum_job_price ships disabled (seeded 0) | A nonzero floor would break the Example 2 anchor ($1,157), and per-shop minimums are an open research question. Asking the friendly shop “what’s your minimum?” live is itself a validation probe |
| D3 | ”Show BOTH” is implemented as two prices — the per-inch quote and a cost-plus reference — in a collapsed “Pricing detail” panel; cost breakdowns render only on Settings | Reconciles the taxonomy’s “show both” with the architecture rule that the salesperson never sees costs. Both displayed figures are prices, not costs |
| D4 | A single permit_fee line | A separate electrical permit / dedicated-circuit fee is future granularity; matches Example 1’s math |
For exactly how D1–D3 surface in the engine and UI, see the Pricing Engine page.
Open questions for the founder
The spec proceeds on a chosen default for each of these, but they remain open for Leo to confirm before the SignFlow validation demo. The defaults are reversible, and several of the questions are themselves good things to ask the shop owner during the meeting.
| Question | Default taken | Trade-off |
|---|---|---|
| Tech stack | Vite + React + TS + Tailwind + @react-pdf/renderer, localStorage — decided | Fastest believable demo; Next.js is the natural later choice if hosted multi-user is needed, and the pure pricing module makes that migration small |
| Brand / product name | Working name “SignQuote” placeholder, slate/indigo palette, logo placeholder box | Zero brand risk in front of the shop; a rename is trivial |
| Seed shop identity | Fictional “Summit Signs & Lighting,” Austin TX | Real SignFlow branding impresses more but needs their rate card pre-demo and risks anchoring them. The Settings screen makes a live swap a 2-minute moment — arguably a feature |
| Deployment | Local laptop only | Hosting (~30 min) lets remote viewers click it themselves but adds surface for the demo to be seen half-broken without narration |
| Trimmed enums | CL = front-lit + halo, flush + raceway; DL = the 5 grid materials | Smallest believable demo; each re-added option needs a sourced rate first (combo/open-face per-inch rates don’t exist in the research) |
| Minimum job charge | Ship disabled (minimum_job_price = 0, constant present in Settings) | A nonzero default makes tiny quotes look saner but contradicts the Example 2 anchor; asking the owner their minimum is a validation question (see D2) |
| Margin thresholds | red < 30%, amber 30–45% | Calibrated so the healthy worked example (74.7%) is deep green and a sub-cost quote is red; real shops may think in net margin. Tunable constant (A15) |
| Subscription price | None baked into the demo | The strategy session floated $300/mo; competitive research supports a $79–149/mo band. Decide before the willingness-to-pay conversation, not before the build |
Sources
The pricing rests on a small, named set of inputs — no fact in the demo comes from an unverified web fetch.
| Source | Role |
|---|---|
channel-dimensional-letter-variable-taxonomy.md | Authoritative backbone — Table A schema, Table B constants, derived-field rules, pricing pseudocode, the DL grid, and the worked examples. The source of truth for any pricing dispute |
research/manufacturing-pricing-deep-research.md | Domain detail: rate and material provenance, LED density & power-supply sizing, install/permit/engineering ranges, labor anchors |
research/competitive-market-deep-research.md | Validation framing: the salesperson-speed wedge, the willingness-to-pay band, PDF-as-table-stakes |
| Notion strategy session (2026-06-04) | Business context: the validation-first purpose and the friendly first user, SignFlow |
The defaults are externally anchored. Seed quote 1001 (“CAFE”, channel letters)
and quote 1002 (“LAW OFFICE”, dimensional) in src/data/defaults.ts are the
taxonomy’s two worked examples. The engine reproduces Example 2 exactly ($1,157) and
Example 1’s per-inch fabrication exactly, with the deterministic install heuristic
landing the total within ~4% of the narrative figure — so the seeded constants in
DEFAULT_SETTINGS are sanity-checked against numbers the demo did not itself produce.
See the worked figures in Acceptance & Testing and tune any constant
on the Settings & Constants screen.