Decisions — gnhf run 2026-06-06

D001: Mode A — Go-to-Market Deepening

Choice: Mode A (GTM deepening for one existing product)

Rationale:

  • The portfolio already has 5 distinct concepts (7 products). Adding a 6th concept has diminishing marginal value compared to making one real.

  • At least one product (invoicer) is genuinely strong: 100% stories complete, working auth, working E2E flow, proven $20B+ market.

  • The gap is GTM work (market positioning, deployment, billing seams, PDF export), not features. This is exactly what Mode A is for.

How to overturn: If market research reveals that invoicing is genuinely unwinnable (e.g., every wedge is already occupied), pivot to Mode B. But this seems unlikely given the self-hosted/privacy-first angle.


D002: Product Selection — invoicer (QuickInvoice)

Choice: Take invoicer to market.

Rationale (scored against the rubric):

Criterion invoicer cronpulse pagesignal webhookvault waitwise

Pain intensity

5

4

4

3

2

Willingness to pay

5

4

4

3

2

Build completeness

5 (15/15)

4 (19/21)

4 (19/19)

3 (16/21)

3 (19/19)

Has auth/login

Yes

Yes

Yes

No

Yes

Defensible wedge

Strong

Moderate

Moderate

Weak

Weak

Market size

$20B+

$200M

$500M

$50M

$20M

  • invoicer is the only product at 100% of planned stories with working auth.

  • Invoicing is a massive, proven SaaS category (FreshBooks $100M+ ARR, Wave acquired for $400M, Zoho Invoice part of $1B+ Zoho).

  • Clear ICP: freelancers and micro-agencies (1-5 people) in the EU who care about GDPR/privacy and want a simple, self-hosted tool.

  • The "single binary, no cloud dependency, own your data" wedge is genuinely differentiated from the SaaS incumbents.

Rejected alternatives:

  • cronpulse: Strong product but cron monitoring is a smaller niche; Healthchecks.io already nails the "simple, self-hosted" angle with a freemium model.

  • pagesignal: Status pages are commoditized; Atlassian Statuspage dominates, and the open-source alternatives (Cachet, Upptime) are mature.

  • webhookvault: Missing its core value (forwarding relay); too much feature work needed before GTM makes sense.

  • waitwise: Very niche market; hard to identify a paying audience.


D003: Keep existing stack (axum + askama)

Choice: Keep the existing axum + askama stack. No rewrite.

Rationale: Mode A explicitly says "keep the chosen product’s existing stack." The axum + askama stack is working well and is pragmatically correct for a server-rendered CRUD app.


D004: PDF generation approach — printpdf crate

Choice: Use the printpdf crate for server-side PDF generation.

Rationale: printpdf is the most established pure-Rust PDF library. It has no external dependencies (no wkhtmltopdf, no headless Chrome), which aligns with the "single binary, no external deps" value prop. The trade-off is lower-level API (manual layout), but for a structured invoice document, the layout is predictable and templates aren’t needed.

Alternative considered: genpdf (higher-level wrapper around printpdf) — but it has fewer downloads and the last publish was 2022. Going with the maintained foundation directly is safer.

How to overturn: If printpdf proves too cumbersome for good-looking output, switch to genpdf or generate PDF from the existing HTML preview using a headless renderer (but that adds a runtime dependency).


D005: Email sending — trait with mock, no real SMTP

Choice: Define an EmailSender trait with a mock/log implementation. No real SMTP wired.

Rationale: Per mission constraints, we cannot wire real credentials. The trait seam lets a human plug in real SMTP (via lettre crate) post-launch. The mock implementation logs to stdout, which is useful for development/testing.


D006: Billing — trait with mock, plan/tier model

Choice: Define a PaymentGateway trait with plan/tier domain types and a mock implementation. No real Stripe.

Rationale: Same as D005 — trait seam for future Stripe integration. The domain types (Plan, Subscription, BillingCycle) model the pricing tiers from the GTM plan.


D007: Currency — EUR-only for v1 launch

Choice: Keep EUR-only for the initial launch.

Rationale: The ICP is EU-based freelancers. Multi-currency adds complexity (exchange rates, per-client currency, display formatting) that doesn’t justify its cost for the launch wedge. It’s the #1 post-launch feature request to expect.

How to overturn: If market research shows significant demand from non-EUR markets (UK freelancers, US freelancers), add multi-currency before launch.