Single SourceStudios Engage SSS
325 commits · 587 tracked files · Next.js 16 on Supabase Postgres

Every cold email is one paragraph, assembled inside a fixed eight-step pipeline.

SS Leader is a multi-tenant, cold-outreach platform where every send is produced by a fixed, auditable process rather than a freeform model call. A cold email is assembled from a tenant's owner-written voice template with exactly two resolved slots: a deterministic greeting and one LLM-written trigger paragraph. Every other line is fixed by construction. Drafting runs through a fixed eight-step DAG built from eleven covenanted skills, each pairing a human contract, a machine-checkable contract, an implementation, and fixtures.

325 commits
25,737 TypeScript LOC
11 covenanted skills
8-step outreach DAG
53 Supabase migrations
What it is

A fixed eight-step DAG, not a freeform model call.

The outreach engine's runtime entry, runOutreachLogic in src/lib/outreach/logic-runtime.ts:64-71, walks the same eight steps on every send, each one delegating to one of eleven skills under skills/<name>/.

pre_check_suppression
  → resolve_greeting
  → draft_v1
  → critique_v1
  → refine_loop
  → send_invariant
  → render_email
  → deliver

Every run terminates in one of six recorded statuses:

ok NEEDS_MORE_SIGNAL REFINEMENT_GAVE_UP REFINEMENT_CANNOT_PROCEED SUPPRESSED SEND_BLOCKED

The DAG's shape is mirrored in a human-readable LOGIC.md contract, logic/outreach.logic.md, and a drift-detection test (tests/drift-detection.test.ts) parses that contract and compares its step names, needs, and branch conditions verbatim against the TypeScript runtime; the build fails if the two diverge. A second, independent LOGIC.md contract, logic/voice-qualify.logic.md, governs a separate voice-agent qualify, decide, book flow. Terminal statuses and every step's verdict and duration are persisted as a structured trace to engagements.logic_trace (migration 022), surfaced in the admin console.

The application runs on Next.js 16 and React 19 against Supabase Postgres with row-level security, sending through Resend and drafting through NVIDIA NIM. A standalone Python worker handles lead scraping and scoring, and a standalone Python voice agent handles outbound calls. Contract tooling is published as devDependencies: @covenant-md/cli and @covenant-md/core at ^1.0.0, @logic-md/cli and @logic-md/core at ^1.5.0, the same contract families documented at COVENANT.md and LOGIC.md.

Hard numbers

Every figure below traces to a git command, a file count, or a line citation.

Two rows have a documented internal contradiction in the project's own docs. Rather than smoothing it over, this page states both readings and which one it uses; see the notes below the table.

MetricValueEvidence
Total commits325git log --oneline | wc -l
First commit2026-04-25, 5101508 "chore: initial commit — docs and reference materials"git log --reverse --format='%ad %h %s' --date=short | head -1
Last commit2026-07-24, a9e2a4a "docs: record the self-serve onboarding arc in STATUS + CHANGELOG"git log --format='%ad %h %s' --date=short | head -1
Commit authorsRainier Potgieter 323, Operator 2git shortlog -sn --all
Git tags / releases0git tag -l (empty)
Commits by monthApr 2026: 14, May: 122, Jun: 159, Jul: 30git log --format='%ad' --date=short | cut -c1-7 | sort | uniq -c
Tracked files (total)587git ls-files | wc -l
TypeScript LOC25,737 lines / 207 files (excl. .d.ts)git ls-files | grep -E '\.ts$' | grep -v '\.d\.ts$' | xargs wc -l
TSX LOC7,427 lines / 55 filesgit ls-files | grep -E '\.tsx$' | xargs wc -l
Python LOC7,316 lines / 48 files (worker/, voice/, python-webscrape/)git ls-files | grep -E '\.py$' | xargs wc -l
SQL LOC (migrations)4,381 lines / 53 filesgit ls-files | grep -E '\.sql$' | xargs wc -l
Markdown LOC20,803 lines / 154 filesgit ls-files | grep -E '\.md$' | xargs wc -l
JS/MJS LOC3,491 lines (16 .mjs scripts, 1 server.js)git ls-files | grep -E '\.(mjs|js)$' | xargs wc -l
Vitest tests (self-reported, latest)593STATUS.md:23 (dated 2026-07-24)
Vitest call sites (grep-counted, independent)528 it( + 8 test( + 2 it.each() groups, 61 filesgit ls-files | grep -E '\.(test|spec)\.(ts|tsx)$' | xargs grep -ohE "\b(it|test)(\.each\([^)]*\))?\(" | sort | uniq -c
Worker (Python) pytest functions50git ls-files | grep -E '^worker/tests/.*\.py$' | xargs grep -c "def test_"
Voice (Python) pytest functions51git ls-files | grep -E '^voice/tests/.*\.py$' | xargs grep -c "def test_"
Covenanted skills11 (11 SKILL.md + 11 COVENANT.md)git ls-files | grep -E '^skills/.*(SKILL|COVENANT)\.md$' | wc -l
Supabase migrations53, spanning 001_leads_table.sql to 20260724000000_046_onboarding_selfserve.sqlls supabase/migrations | wc -l
API routes (route.ts)8find src/app/api -name route.ts
LOGIC.md contracts2: logic/outreach.logic.md, logic/voice-qualify.logic.mdls logic/
Published package deps for contracts@covenant-md/cli / core ^1.0.0, @logic-md/cli / core ^1.5.0 (devDependencies)package.json:36-39
.db files in repo tree2, both inside the gitignored sa-lead-pipeline/ subtreefind . -name "*.db"; cross-checked against .gitignore:45,48
sa-lead-pipeline local SQLite row countspipeline.db: businesses 2074, pipeline_runs 38, reviews 0. admin_leads.db: leads 1253sqlite3 -readonly ... "SELECT COUNT(*) ..."
Live tenant lead-row counts (self-reported, not independently verified)ss-leader 11,874; kamel-potteries 1,305; ccs-pos 3,614STATUS.md:8-9, cross-referenced by CHANGELOG.md
Deploy target (Next.js app)cPanel + Phusion Passenger, lead.singlesource.co.za, booted by server.jsDEPLOY.md:1-3
Deploy target (scrape worker)Render, two services (ss-leader-scrape-worker, ss-leader-scrape-cron)render.yaml:12-31, DEPLOY.md:74-97
Test count, not reconciled

STATUS.md reports two different Vitest totals in the same file: 593 at line 23 (dated 2026-07-24) and 549 in its own gates section at lines 100 to 101, stale relative to line 23 and never reconciled in the document. This page uses 593, the later and more current figure, and separately verifies scale through the grep-counted call-site row above, which is independent of either self-reported number.

Deploy target, docs disagree

README.md and CLAUDE.md both state the Next.js application deploys to Render, served at lead.singlesource.co.za. DEPLOY.md gives an explicit cPanel plus Phusion Passenger target for that same URL, is the more detailed and more recently structured account, and flags the cPanel cron residue from any earlier scrape attempt as legacy. This page follows DEPLOY.md; only the separate Python scrape worker deploys to Render.

Architecture

One drafting engine, one cross-channel funnel, two ingestion paths.

The Next.js 16 App Router app (src/app/) serves a public marketing, pricing, and checkout surface, a per-tenant admin console under src/app/t/[tenant]/admin/{leads,outreach,pipeline,settings}, and a 9-step self-serve onboarding wizard under src/app/onboarding/. Server code lives under src/lib/, split into outreach/ (31 files: the drafting-and-send engine, including logic-runtime.ts, logic-expr.ts, nim-client.ts, resend-client.ts, and WhatsApp and Zernio-calling variants), orchestration/ (the cross-channel state machine: journey.ts, consent.ts, callback-queue.ts, router.ts, send-hook.ts), billing/, booking/, onboarding/ (AI document extraction via unpdf and mammoth), admin/, and supabase/ (SSR client factories).

/api/book /api/checkout/status /api/contact /api/health /api/webhooks/payfast /api/webhooks/resend/[tenant] /api/webhooks/resend/inbound /api/webhooks/zernio

Above the email pipeline, HARNESS.md specifies a cross-channel funnel: a per-lead journey state machine, per-channel consent gates, an inbound-signal routing table, and a callback-queue lifecycle, implemented in src/lib/orchestration/ and held in lockstep with the spec by tests/harness-drift.test.ts. Channels: email (cold, POPIA legitimate-interest basis plus opt-out) and WhatsApp via Zernio plus voice calls (warm opt-in only; no cold path exists in the routing table). The standalone voice/ Python package runs a second LOGIC.md-governed qualify, decide, book flow and shares a Google Calendar client with the email and booking path.

Data flows into the businesses table from two paths: the vendored, read-only lead-pipeline/ and sa-lead-pipeline/ Python stacks (Google Places discovery, Playwright enrichment, scoring), and scripts/import-leads.mjs, a CSV importer with three-layer dedup and a confidence-tiered name-write gate. A separate standalone Python worker/ (Python 3.12, asyncio, deployed to Render) runs its own claim-and-execute scrape loop against pipeline_jobs rows, independent of the vendored pipelines. Persistence is Supabase Postgres with row-level security and tenant_id scoping across tenant-owned tables; 53 migrations run from 001_leads_table.sql (initial schema) to 20260724000000_046_onboarding_selfserve.sql (storage buckets and document metadata for self-serve onboarding).

Engineering decisions

Five decisions visible in the commit history.

Monolith-to-DAG refactor

no behaviour change

Before what the repo's own docs call "Prompt J," the entire outreach pipeline lived inline in a single roughly 1,100-line server-action file, outreach-actions.ts, that built prompts, called NIM, validated, critiqued, refined, gated sends, and rendered email in one place, with no record of how a given draft was reached. It was refactored, without changing behaviour, onto three layers: eleven covenanted skills, a DAG runtime, and a LOGIC.md contract kept honest by a drift test.

docs/architecture/outreach-as-logic.md:11-31

Rebrand from a prior client project

May-Jun 2026

The repository's early history is a differently branded product built for a named client, RH Improvers (rhimprovers.co.za). Commits through May and June 2026 systematically rename brand tokens, environment variables, and UI copy from that client to SS Leader and SingleSource AI. The old client's Supabase project reference and tenant config remain in immutable historical migrations (007, 013, plus the RH config set) but are net-removed by migration 026; the documented live-database invariant checked at go-live is zero RH Improvers rows.

git log; CLAUDE.md:61-68; supabase/migrations/20260602010000_026_remove_rh_tenants.sql

Anti-hallucination by construction, not by prompting

two validators

The drafter is constrained to write one paragraph into an owner-verbatim template rather than a full email, and a tenant's validator_config (banned phrases and patterns, required phrases) is enforced twice: once as the drafter's non-throwing advisory check, and again as a send-time hard, throwing gate. The codebase's own documentation describes this as "two validators, not merged."

CLAUDE.md:50; skills/banned-phrase-validator/

Purpose narrowed, then partially reversed

held locally

STATUS.md records a 2026-07-19 decision not to pursue self-serve SaaS "for now," with tenants hand-provisioned instead. Five days later, on 2026-07-24, held locally and not yet pushed as of the last commit, a full self-serve onboarding arc shipped anyway: one-command tenant provisioning (scripts/provision-tenant.mjs) and a 9-step wizard with AI document pre-fill.

STATUS.md:11-18

Split deploy targets, not one platform

docs disagree

The Next.js application deploys to cPanel and Phusion Passenger, while the Python lead-scrape worker deploys separately to Render as two services. README.md and CLAUDE.md both state the application itself deploys to Render, served at lead.singlesource.co.za, which contradicts DEPLOY.md's explicit cPanel target for the same URL. DEPLOY.md is the more detailed and more recently structured account, and explicitly flags the cPanel cron residue from any earlier scrape attempt as legacy; this page follows DEPLOY.md.

DEPLOY.md:1,76; README.md:128; CLAUDE.md:20; render.yaml
Timeline

Four months, 325 commits, one rebrand in the middle.

14Apr 2026 commits
122May 2026 commits
159Jun 2026 commits
30Jul 2026 commits
0git tags cut
2026-04-25 to early May

Project scaffold: Next.js init, Supabase leads table, initial contact API, all under the pre-rebrand client identity.

May 2026, 122 commits

Bulk of core buildout: outreach drafting, review and critique, tenant config, and the engagement rename and refactor in migration 009.

June 2026, 159 commits, the largest month

Rebrand from the prior client identity to SS Leader and SingleSource AI across brand tokens, environment variables, and database config; RH-tenant removal in migration 026; the outreach-to-covenant, skill, and DAG refactor documented in docs/architecture/outreach-as-logic.md.

Early to mid July 2026

Cross-channel funnel build across briefs 026 to 039: WhatsApp send and inbound via Zernio, an email-reply intent classifier, voice callback drain, booking plus Google Meet, a release-readiness audit in brief 037, and off-limits-boundary documentation hardening in brief 038.

Mid to late July 2026, 30 commits

Lead-scoring completeness (score_v3 across all seven axes), an operator-triggered backfill, the hook system opened from a closed union to tenant-defined strings, drafter resilience (bounded parse-retry, an expanded model chain), and the self-serve onboarding wizard in migration 046, held locally as of the last commit.

Boundary

What this dossier does not cover.

Out of scope, by design
  • This dossier covers only the ss-leader repository as committed to its own git history.
  • It excludes the vendored, gitignored lead-pipeline/ and sa-lead-pipeline/ Python subtrees, each its own separate git repository and read-only per project policy, from the LOC and test metrics above, though their two local SQLite databases are reported in the Hard numbers table.
  • No production Supabase database was queried for this dossier. The live tenant row counts above are self-reported in project documentation, not independently verified against a live database.
  • Several claims in STATUS.md, including migrations 042 through 046 and the self-serve onboarding arc, are explicitly marked as held locally and not yet applied to the live database as of the last commit. They are reported here as documented, not as deployed.

Evidence: compiled from the ss-leader repository on 2026-08-03. Every number on this page traces to a file path or command output in the source tree. Last updated: 2026-08-03.

Single Source

Every number on the dossier and whitepaper pages traces to a file path or command output in the source tree.

LinkedIn Facebook (c) 2026 Single Source Studios (Pty) Ltd