Readiness Framework — Interactive Criteria Scorecard

Framework v3.0 · audits of 31 July 2026 · click any pillar to expand its criteria.
ND = NodeDough · composite 4.2/10 · not cleared for paid launch F8 = FedM8 Scan · composite 5.00/10 · not cleared for paid launch
How to read this. Each pillar expands to its individual criteria from the v3.0 framework. Every criterion carries the AI's 1–10 rating per project with the evidence behind it, from the 2026-07-31 audit runs (NodeDough · FedM8). Rubric anchors: 1–3 absent · 4–6 partial / manual / untested (no evidence caps at 6) · 7–8 implemented + tested + evidenced · 9–10 automated, monitored, verified <90 days. Pillar scores are the audited values; criterion ratings are the AI's decomposition of the same evidence — where the audit could not see (e.g. FedM8's CI, dependency scanning), the rating reflects absence of evidence, not confirmed absence.

Go-live gate (T1): every pillar ≥ 6 and Security, Billing, Legal ≥ 7. ND fails on Billing 3 · Legal 2 · Obs 4 · Funnel 4 · Retention 3 · Support 3. F8 fails on Billing 4 · Legal 5 · Obs 4 · Funnel 4 · Retention 3 · Pricing 5 · Support 3 (Security passes at 7).
1 Reliability & Infrastructure 15% ND 5F8 6
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Reproducible deploys via CI/CD; no manual prod changesT17Railway deploys from GitHub main automatically; both domains attached.5GitHub Pages deploys on push; CI/branch protection unassessed (no repo access in audit) — capped on absent evidence.
Rollback tested, not just documentedT13No rollback drill on record. Railway redeploy-from-source exists but untested as a procedure.3No rollback drill on record for Pages or the database layer.
Automated DB backups + restore actually testedT14Supabase automated backups exist; a restore has never been drilled.4Supabase backups exist; 692,699 award rows never proven recoverable — restore drill explicitly recommended.
Health checks + auto-restart on the platformT12No healthcheck path configured on the Railway service.6Static origin on GitHub Pages/Fastly — platform-managed; no app-level check exists or is needed at this tier.
Staging environment matching prodT22None. main deploys straight to production.3No staging evidenced; single production surface.
Defined RTO/RPO; DR runbook exercisedT21Not defined, never exercised.1Not defined, never exercised.
Multi-AZ/region, or documented acceptance of single-point riskT32Single region, risk not documented.2Single origin + CDN; risk not documented.
Infrastructure as codeT33railway.json pins start/healthcheck config only; the rest is dashboard state.3Pages config in repo; Supabase config is console state.
2 Security & Compliance 15% ND 6F8 7
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Auth via proven provider/library; MFA available; session expiryT16Supabase Auth (proven provider) ✓; MFA not offered; session expiry platform defaults.6Supabase Auth ✓; MFA not offered; authenticated flows not live-exercised in the audit.
Secrets in a manager — never in code or client bundlesT17Railway variables / Supabase stores; only the publishable key reaches the browser.7Only the publishable key in the client bundle; no secret-prefix matches in served assets.
OWASP Top 10 pass incl. per-endpoint authz (IDOR)T15Anon-callable SECURITY DEFINER RPC surface found 07-31; checkpoint-family EXECUTE revoked from anon same day. No structured scan.8Every negative test as anon denied: opportunities, prime_awards, opportunity_documents, vet_directory all permission-denied; RLS-filtered tables returned empty arrays (correct signature).
TLS everywhere; security headers (CSP, HSTS)T15TLS via Railway ✓; security headers not evidenced.3TLS ✓, but all six headers absent (HSTS/CSP/XFO/XCTO/referrer/permissions) — structural to GitHub Pages. Plus no SRI on the one external script holding the session (highest-risk finding).
Dependency scanning + patch cadenceT12None configured.4Unassessed — no repo access; capped on absent evidence.
Row-level security / tenant isolation verified with negative testsT17RLS on all 16 tables; impersonation probes run 07-31 asserting effects, not just exceptions.9RLS verified with negative tests across the surface; my_plan() non-forgeable; vet_directory opt-in + field-masked + paywalled — correct SECURITY DEFINER use.
Least-privilege access for humans and services; offboardingT25View write-grants and TRUNCATE revoked 07-31; dead-grant sweep run; offboarding process none.6is_admin closed at the privilege layer (no UPDATE grant) ✓; dead anon INSERT/UPDATE/DELETE grants remain on 3 tables; billing.* RLS-off mitigated only by exposed-schemas setting.
Pen test or structured external reviewT33This AI audit is the only structured review.4This AI audit is the only structured review; deeper than NodeDough's (function bodies + grants read).
SOC 2 / ISO track if buyers askT31Not on the roadmap.2Not on the roadmap; likely to matter for gov-adjacent buyers.
3 Observability & Operations 10% ND 4F8 4
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Structured, centralized, searchable logs — no PII/secrets in logsT14Railway platform logs only; not structured, retention short, PII posture unreviewed.3No centralized app logging; static origin logs not accessible.
Error tracking with alerting (Sentry-class)T11None.1None — zero analytics or error tooling matches in source.
Uptime monitoring from outside your infraT12None for nodedough.com.2None evidenced for scan.fedm8.com.
Alerts tied to user-facing symptomsT21No alerting at all.1No alerting at all.
Metrics dashboard: latency, error rate, saturation, trafficT22Railway service metrics only.2Fastly cache stats only, not surfaced.
Incident process: severity levels, runbooks, postmortemsT22None written.2None written.
Distributed tracing where warrantedT3n/an/a — single service, not warranted at this scale.n/an/a — static + Supabase, not warranted.
4 Performance & Scalability 10% ND 5F8 6
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Load test at 3–5× expected launch peakT12Never run.3Never run; DB-side capacity unknown under load.
Core Web Vitals green on key pagesT14Not measured — no evidence either way (capped).8Landing: 31 ms TTFB, 294 ms full load, 6.3 KB transfer — measured in audit.
DB indexed for hot queries; no N+1 on hot pathsT15PK/FK indexes present; no hot-query analysis on record.6Pre-aggregated rollups (award_naics_state, 605 NAICS codes) show deliberate design; no formal query analysis.
CDN / static asset cachingT14Railway direct serve; no CDN.8Fastly CDN caching confirmed working.
Rate limiting on auth, API and checkoutT13Supabase platform defaults only; nothing app-level.3Supabase platform defaults only; nothing app-level.
Horizontal scaling path documented and testedT22Undocumented.3Static tier scales by default; DB path undocumented.
Capacity planning reviewed quarterlyT31Never done.1Never done.
5 Billing & Subscription Infrastructure 15% ND 3F8 4
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Billing via Stripe / Paddle / Chargebee — never customT11No processor integrated; upgrade is “Coming soon”.5Stripe integrated and well-architected, but has never run — 0 webhook events, 0 checkout attempts, both stripe_price_id NULL so checkout cannot open today.
Every webhook handled (created / paid / failed / canceled / changed)T11No webhooks exist.4Handler exists (verify_jwt:false is correct for Stripe), but signature verification and event coverage unconfirmed — code review required before first charge.
Webhook handlers idempotent — replay-testedT11n/a — nothing to replay.5Idempotency by primary key on Stripe event id + attempts counter — right design, replay never exercised.
Full lifecycle tested: trial→convert, up/downgrade, cancel, resubscribeT11No lifecycle exists.2Untested end to end; framework requires a test-mode run as evidence.
Entitlements enforced server-side; plan change reflects in secondsT17assert_paid_feature gating in the DB — the right shape, confirmed in audit.8my_plan() reads auth.uid() + subscriptions, non-forgeable; negative-tested as anon (returned “free”).
Tax handling for actual sales jurisdictionsT11None.2Not configured; Stripe Tax not enabled.
Dunning: retries, card reminders, update-payment promptsT21None.1None.
Grace periods + involuntary-churn recoveryT21None.1None.
Billing state reconciliation job — DB vs processor truthT21None.2rejected_client_price status shows server-side price resolution; no reconciliation job.
Revenue recognition / accounting exportT31None.1None.
6 Pricing & Packaging 10% ND 5F8 5
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Pricing tested with ≥ 20 real prospectsT12$5/mo · $50/yr set by gut feel; zero prospect interviews.2Basic/Pro pricing never prospect-tested; both paid tiers are waitlists.
Anchored against named competitorsT13No comparison doc.3No comparison doc; gov-data competitors exist and are unpriced-against.
Tier structure maps to a real value metricT17Tiers map to real limits (nodes/features) — confirmed in audit.6Free/Basic/Pro map to data access depth (opportunities → awards); coherent.
Free trial or freemium decision deliberate, with conversion hypothesisT14Invite-gated beta is deliberate; no written conversion hypothesis.6Free tier live by explicit strategy (“Free is live today; Basic and Pro are waitlists”); hypothesis implicit, not documented.
Annual/monthly mix with discount rationaleT26$50/yr ≈ 2 months free — present, rationale undocumented.3Monthly only on the published tiers.
Price experimentation + grandfathering planT31None.2sellable flag machinery would support it; no policy. NOTE: Pro held sellable=false by a 07-28 note whose condition (real awards data) now looks satisfied — 692,699 rows live. Highest-value commercial item: confirm FM-3 and flip.
7 Conversion Funnel & Growth 10% ND 4F8 4
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Landing states problem, outcome and price; loads fastT16Clear landing with pricing ✓; load speed unmeasured.7States problem and price plainly; 294 ms full load.
Signup → activation instrumented end-to-endT11No analytics at all.1Zero instrumentation — no GA/PostHog/Segment/Plausible in source. Waitlist table has 0 rows while the site invites “Notify me”: either no signups or a silently failing form, and no way to tell. Test the form manually.
Defined activation moment and time-to-value targetT12Not defined.2Not defined.
Onboarding drives to activationT13Some empty states; no checklist or sample data.3Search works logged-out (free tier); no guided onboarding.
Checkout friction auditT11No checkout exists.2Checkout cannot open (NULL price ids); nothing to audit.
Funnel conversion baselines set; weekly reviewT21Nothing measured.1Nothing measured.
Lifecycle email: welcome, trial-ending, win-backT21None.1None — and the waitlist that would feed it may be broken.
8 Retention & Revenue Health 5% ND 3F8 3
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
MRR, ARR, churn, LTV:CAC tracked from day oneT12Pre-revenue; audit_log only, no metrics.2Pre-revenue; nothing tracked.
Voluntary vs involuntary churn separatedT21n/a until billing exists.1n/a until billing runs.
At-risk signals definedT22audit_log could feed this; nothing defined.1Nothing defined.
Cancellation flow captures reason + offers alternativesT21No subscription to cancel.1No subscription to cancel.
NRR tracked; expansion revenue pathT31None.2Basic→Pro upgrade path exists structurally; untracked.
9 Legal & Trust 5% ND 2F8 5
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
ToS + Privacy Policy reviewed against actual data practicesT11Absent entirely — blocks any paid launch on its own.6Present on site; review against actual data practices (veteran PII, CAGE/UEI) not evidenced.
Refund/cancellation policy published; click-to-cancelT11Absent.3Not published; audit requires it written with a working cancel flow before charging anyone.
GDPR/CCPA basics: consent, export, deletion on requestT12No process; undo-deletion RPC family not even deployed live.4No documented process; sensitive directory is opt-in with field masking, which helps but isn't a rights process.
PCI scope minimized — processor-hosted fieldsT1n/an/a — no card data anywhere yet.8Card data never touches their servers; prices resolved server-side, client-supplied amounts refused.
DPA available for business customersT21None.2None; B2B/gov buyers will ask.
10 Support & Customer Success 5% ND 3F8 3
CriterionTierNodeDough — AI rating & evidenceFedM8 Scan — AI rating & evidence
Support channel with committed response time; billing fastestT12No support channel.3Contact email only; no committed response time.
Docs/FAQ covering the top 10 predicted questionsT12None.3Some in-app explanation; no docs/FAQ section.
Status page or incident comms planT21None.1None.
Feedback loop from support → product backlogT22None formalized.2None formalized.

Source audits: NodeDough 2026-07-31 · FedM8 Scan 2026-07-31 · framework: /framework/ready · library: /framework.
Criterion ratings are AI-derived from audit evidence and inherit the audits' scope limits (FedM8: authenticated flows, CI/CD and edge-function source unassessed). Re-rate on re-audit — dated runs stay immutable. Not legal advice.