More efficient customer search
and automatic with AI.
SocialSelling answers a single question — "Who should I approach First?" — producing a Explainable ranking of prospects that learn from feedback The operator. This document is the project overview and, at the same time, a template good practice development and implementation adopted so far.
- Who's it for?
- Who wants to understand the product and who wants to reproduce the development method.
- Format
- Project documentation
- Depth
- Technical reference · ~2 min for central idea · ~17 min complete
You prefer the essentials first? Read synthesis (~1 min)
1 & scope view
The product makes prospecting efficient and automatic: given a PCI (Ideal Customer Profile), the system discovers candidates, infers structured data, scores the fit/intent/trust, delivery Lead Cards ranked with justification (XAI) and learn from the operator's votes .
In scope
- Explicable prospect ranking (fit · intent · confidence)
- Discovery + incremental enrichment of leads
- Structured justification (drivers +/− and missing signals)
- Learned by feedback like/dislike (ADR-007)
- Cockpit local web (view, weight editing, votes)
Out of scope (guardrails)
- CRM, outreach/messengery automation, cadences
- Database, Redis, Celery, Docker, AWS/Terraform
- Instagram/LinkedIn Scraping
- Automatic generation of outreach messages
2 PoC Architecture
A single Python 3.11+ process, without mandatory server,
No bank, no line.
Persistence in Atomic JSON (write-temp + os.replace).
The only variable cost is the tokens of two cognition/search APIs.
Pipeline deterministic (modules, non-runtime agents)
M3 and M4 are functions pure: same input → byte-identical output. The orchestrator injects customers, cache, clock and config.
Support modules
w_fit/w_intent
from votes ADR-007).
entity_id) (ADR-006).
External sensors
Tavily
Open search (M1). Social snippets and signs of intention.
Gemini (gemini-2.5-flash / flash-lite)
Cognition (M2). Extract structured entities + persona/intention in batches.
Apollo. io ADR-004
B2B Firmography. Incremental ladder; API master requires paid plan (Free blocks p/ entitlement).
3 Semantic layers & inviolable rules
The correction of the system rests on four invariants. They for all New code — including sensors, volume layer and module learning.
1 Layer insulation
An inference is never treated as evidence. No
Shared changeable references. Apollo flips ObservedEvidence, never inference. The feedback (ADR-007)
operates only on the presentation layer — never plays Evidence or Inferences.
2 Byte-identical Determinism
Same memory → same output. Clock and RNG injection; IDs per stable hash; tie-break stable. O feedback model uses full-batch gradient without randomness — same log bit by bit.
3 Open-World
Absence of signal = uncertainty (↑u), never false. Missing Evidence is explicit; failures degrade, not
They break. Dislike is a sign of training — the lead remains visible with a seal.
4 Atomic persistence
All writing is write-temp + os.replace. Never a half-written file — goes for
cache, corpus, ledgers and the feedback store.
4 Architectural decisions (ADRs)
Each conscious decision becomes a versioned and referenced ADR. The source of truth is the ADR-000; the rest are amendments explicit.
PoC Canon Scope local
Fixed SDD v1.0 as spine; database-less; Tavily+Gemini; M1–M5 as pipeline.
Intent layer: hypotheses
Intent = disqualifiers zero the lead.
Local operator IU (FastAPI)
Web cockpit: dense table of leads, detail drawer, Weight tab, feedback buttons.
Parallel Orchestration (Lang Graph) + FinOps
Optional async engine for multi-producer harvesting and pruning early. Deferred by design.
Apollo.io as 2nd sensor firmographic
Incremental enrichment ladder: discovery → org-enrich → reverse by credit. API master requires paid plan.
Cognitive reform: lots + DPR budget
Batch extraction raises the ceiling Gemini; budget requests/day + resumable waves.
Cumulative leads corpus
Runs accumulate (upsert idempotent by entity id). The wave only advances when the cycle produces leads — avoids burning cache without result.
Learning by feedback like/dislike
Logistic regression (Python pure, no dependencies)
readjust w_fit/w_intent from the votes. Auto-apply with 4 locks: gate
sample, L2, shrinkage and clamp. Opt-in via [learning].enabled.
5 Development specifications (SDDs)
Each non-trivial ADR is accompanied by an SDD (Spec-Driven Development: contracts, scenarios, testing plan and WUs. Spec-first — the document precedes the code.
SDD · Apollo (search + incremental enrichment)
Credit ladder, monthly ledger, volatility cache, Open-World degradation.
SDD · Parallel Orchestration + FinOps (LongGraph)
Competing harvest, early pruning, degraded manners. Optional engine.
SDD · Operator Cockpit (IU)
High density grid data, lead drawer, weight tab and feedback buttons.
SDD · Lead Results Table UX
Scan-then-focus pattern: dense table + drawer slide-over. V2 cockpit visual refinement.
Roadmap · Lead volume scale
Theory of restrictions, the four pillars and the status of implementation.
6 Good development practices
This is where the project intends to be template: complexity lives in the construction process, Not in the system. PoC remains dry; discipline is total.
SDD-to-Code Loop (mandatory per module)
- 1Pydantic Contract
- 2BDD + fixtures
- 3Minimum implementation
- 4Green Gate
- 5PR + auto-merge
Operating mode: Day vs. Night (L-057)
☀️ Sessão de dia (interativa)
Specifies and generates cards — no develops the product. Author of ADRs, SDDs, docs, tooling and curation of board. Card only goes to All with 100% DoR (Gherkin, fixtures, without ambiguity).
🌙 Run noturno (autônomo)
Consumes column All via skill github-sdd-sync. Revalida DoR, implements, requires DoD
(green gate, PR CI-green, PROGRESS and updated lessons).
Quality Gate non-negotiable
ruff + mypy --strict + pytest
100% green and deterministic. Flakiness = failure.
Git: branch → PR → auto-merge
Never commit Right on the main. Compulsory CI; merges only with green gate. Squash + delete-branch.
Tags = restore points
Each green WU receives an annotated tag. Public Rollback
via git revertNever reset/force.
Always Mocked APIs
Tests never play network: recorded fixtures + fakes.
Numeric tolerance 1e-9. Surfed API Errors to
user (never silent — L-057).
Opt-in = parity
Every new feature enters offline by default → the baseline
remains byte-identical (smoke E2E). [learning].enabled,
[apollo].enabled, [corpus].enabled.
FinOps by atomic ledger
Credit (monthly) and requisition (daily) budgets
persisted; try_spend/refund/reconciliation. Billing errors (429) propagate the
raw message to the frontend.
Gate command (Windows)
.venv\Scripts\python.exe -m ruff check . # lint
.venv\Scripts\python.exe -m mypy # tipos (strict)
.venv\Scripts\python.exe -m pytest -q # 150+ testes determinísticos
# Ou: .\scripts\gate.ps1 (roda os três em sequência)
7 Volume strategy (local rotation)
Objective: to seek much more leads without leaving local/database-less. It applied Constraint Theory funnel — Enlarge Discovery Without raise the cognitive ceiling only Makes it hit the wall faster. Hence the four pillars.
| Pillar | What do you do? | Status |
|---|---|---|
| A · Cognitive ceiling | Batch extraction + RPD budget + waves resumables (ADR-005) | ✅ core |
| B · Cumulative corpus | Runs accumulate; upsert idempotent; wave advances only result (ADR-006) | ✅ core |
| Apollo · Discovery | People Search + org-enrich + reveal (ADR-004) — API master requires paid plan | ✅ implementado |
| C · Scalable state | JSON monolithic → NDJSON/shards (no seat) | ⏸ diferido |
| D · Entity resolution | Canon domain + exclusion of vendors + dedup cross-provider | ⏸ diferido |
All opt-in ([apollo].enabled
· [corpus].enabled · [gemini].rpd_enabled). Deferred with documented reason — no
Risky refining for completeness.
8 Self-learning process
At the end of each task, learning is distilled into Docs/lices-learned. md
(format L-NNN | Categoria | Lição | Como aplicar) and in memory
persistent. Today they are.
57 lessons that backfeed future decisions — the project
It gets smarter every cycle.
Inject clock and drift IDs by stable hash — never
Random UUID or datetime.now() Internal. Ensures
Byte-identical re-execution. It also applies to the feedback model (full-batch without random).
Fan-out with asyncio.gather(return_exceptions=True) + treat exception
raw: a provider does not drop the lot.
Container fixed inset-0 z-50 closed needs to pointer-events:none; without it an invisible layer swallows
all clicks without visible error.
Logistic regression with full-batch gradient, init in
zeros, samples sorted by company_id and without random → same feedback. json
Forward the wave only when the cycle produces leads. Forward To some "burn" curly queries and hid that the root cause was the billing of the Gemini (corrected on L-057).
Gemini's 429 was prepayment credits depleted,
No free-tier quota. GeminiClient now surfs the error.message raw; the endpoint returns 502 with message
actionable (billing link).
9 Version map (restoring points)
CI-green Foundation: toolchain, contracts, planning.
Functional PoC: pipeline M1→M5 + smoke E2E byte-identical.
Intent motor (hypothesis), actionable Lead Card, IU of operator, persona accuracy.
Volume foundation: Apollo schemas, credit ledgers/RPD, corpus; discovery End-to-end Apollo.
Full volume specs: Apollo ladder (1/2/3), batch+RPD, cumulative corpus. 120 green tests.
Cockpit v2 (dense table + draker), billing degradation with actionable message (L-057), incremental search for waves.
Learned by feedback (ADR-007): regression
deterministic logistics, store of atomic votes, auto-apply weights with 4 locks. 150+
Green tests. Modules: learning/ (model, tuner,
feedback store, schemas).
How to turn on volume + learning (real run)
# 1) runtime.toml
[apollo].enabled = true [corpus].enabled = true
[gemini].rpd_enabled = true [learning].enabled = true
# 2) gravar fixtures (supervisionado — Apollo master exige plano pago)
.venv\Scripts\python.exe scripts\record_apollo_fixtures.py
# 3) rodar o pipeline
.venv\Scripts\python.exe -m socialselling.orchestrator --icp config\icp_criteria.talita.json
# 4) cockpit web (marcar likes/dislikes → reajusta pesos automaticamente)
.venv\Scripts\python.exe -m socialselling.web # → http://127.0.0.1:8000
10 Planning & development operation
The project adopts a governance model that separates author specification (interactive, made by day) implementation (autonomous, made at night). This optimizes Claude Code Pro's quota and maintains repository integrity — the owner uses the day to think and evolve the system; development runs on the scheduled run.
Board Flow (GitHub) Project #1
Card blocked (Incomplete DoR or red gate after 2
attempts) → BLOCKED: in PROGRESS.md and return it to Backlog. Never guess — for and
report.
Day Session — Authorship
- 1.Understand what the owner whether to evolve (and why).
- 2.Draft cards using o DoR/DoD template.
- 3.Charge the DoR — ask the owner for each missing item (Gherkin, fixtures, contract, scope). Never push card incomplete.
- 4.Card with DoR 100% → move to All (only human does that).
- 5.Large developments → break into several small cards (1 WU each).
Night Run — Autonomous Execution
- S1.Read
.ai/state/PROGRESS.md+ card in All major priority. - S2.If blocking → Stop and report (don't guess).
- S3.Revalidate the DoR — if
some item is open, mark
BLOCKED:and returns Backlog. - S4.Run 1–2 steps
of WU (pacing). Rotate
./scripts/gate.ps1. - S5.Green Gate → commit in feature branch; if WU closed: PR auto-merge + tag.
- S6.Update
PROGRESS.md+ lessons. Stop at a secure checkpoint.
src/socialselling/, tests/, fixtures — everything that changes the behavior of
product.
Definition of Ready (DoR)
Card can go from Backlog → All?
- 1 Objective observable in 1 sentence (why + verifiable result)
- 2 Sliced in 1 WU — fits in an execution window
- 3 Pydantic Contract defined; ADR linked if module crosses
- 4 Gherkin: happy path + degraded mode + Open-World
- 5 Identifyed Fixtures; no pay/entitlement network lock
- 6 No open border decision
- 7 Within the canonical scope (§3/§5/ADR-000)
- 8 Viable Determinism (Mocked IPAs, tolerance 1e-9)
- 9 Specific DoD declared in card body
Definition of Done (DoD)
Card can go from In Progress → Done?
- 1 Green and byte-identical BDD scenarios (zero flakiness)
- 2 Committed Fixtures; Tests Do Not Play Network
- 3 Full Gate:
ruff+mypy --strict+pytest✅ - 4 Respected semantic invariants; atomic persistence
- 5 Preserved Scope — Minimum Slice Implemented
- 6 PR with green IC (
gh pr merge --squash --auto) - 7
PROGRESS.md+ lessons updated in the same PR - 8 Card in Done + tag
vX.Y.Zif you've closed a milestone - 9 Fail-closed: red gate after 2 attempts →
BLOCKED:
⛔ Guardrails de autonomia (inegociáveis)
- Never commit/push directly to
main— only via PR with CI green - Never
--force; rollback only viagit revertin PR - Never invent specification — ambiguity →
BLOCKED:and for - No fixtures recorded → does not implement modules that play network (M1/M2)
- Always stop at a secure checkpoint; never end in destructive step
Exceptions to night mode
- Explicit request the owner: "do it now," "Implement this" — the override always wins.
- Critical Hotfix:
mainbroken or critical bug — fix on time via PR + green gate, register later.
Out of these two cases, product implementation = card/night.
State anchor & cadence
📌 .ai/state/PROGRESS.md
Source of truth from where we left off. The run read in start and update at end. Contains: current milestone, green tag, WU in progress, step (S1–S6), branch, next action, blocks and run history.
State never lives in session — lives in git + PROGRESS. md. Any new run rebuilds the context by reading these two.
Recommended cadence
| Window | Early BRT (~02:00) — no containment with interactive use |
| Frequency | 1 run/night at start; adjust for weekly consumption |
| Scope/run | 1–2 steps from a WU (cable in window; ends in checkpoint) |
| Supervision | WUs with network (M1/M2): record fixtures with the present owner; Pure WUs: more safe to run alone |
| Review | Owner reviews morning merges/tags; CI is the safety net |
Reference documents of this layer
operating mode. md
Standard rule day/night, card border, flow authored, self-learning evolutionary.
dor-dod.md
Quality gates per board column + full card template (DoR checklist).
autonomous-ops.md
Autonomous run protocol S1–S6, guardrails, cadence, scheduled agent prompt and failure recovery.
execution-plan.md
WU Master Plan: validation, version and rollback by step.
Devops-sre-iac.md
DevOps/SRE Practices: CI, gate, versioning and PoC's IAC.
versioning-strategy. md
Tags = restore points. Public Rollback via reverse, never reset/force.
Technical reference
11 Contracts & data model
All pipeline operates on contracts Pydantic v2 declared
ed src/socialselling/contracts.py — the only point of truth
data models. Each M1–M5 module produces and consumes well-defined types; never share
changeable references between layers.
Flow of contracts by pipeline
Firmographics geographies, business models) · Technographics (tech mandate/preferred/excluded) · PersonaMatrix (target rolls, minimum seniority) · intent triggers (signs of hypothesis)
evidence_id
(hash SHA-256 stable) · query, source_url, snippet, source_trust · missing_evidence: bool (Open-World explicit)
CompanyEntity
(name, domain, industry, technologies, contacts, social networks) · PersonEntity (name, position, seniority) · derived_from: list[evidence_id] (traceability)
compulsory) · intent_signals, disqualifiers, persona · confidence
fit, intent, confidence, persona_fit, p_score, hard_filter_passed
positive_signals, negative_signals (list of Driver with impact and text) · missing_signals (Explicit Missing Evidence) ·
degraded_mode
display_name,
company, role, sector,
location · links (Instagram first, LinkedIn, website) · contact (email, phone) · score (ProspectScore complete) · why_now[] (immediate reasons) · gaps[] (signs absent) · sources[]
Score Formula (M3)
P = (w fit · Fit + w intent · Intent)
× Trustexp × persona fit
w_fit = weight of
structural fit0.60w_intent = weight
of intention0.40confidence_exponent0.5persona_fit
(founder)1.0persona_fit
(founder)0.0M3 and M4 are pure functions: same input → output
byte-identic (1e-9). Hard filter (disqualifier detected) zeros the lead. Configurable weights
ed runtime.toml and readjustable by feedback
Hypothesis Catalogue (Intent)
Intent = intent_signals detected by M2. Config config/hypotheses_catalog.json.
Founding woman stuck in the operation — stopped growth
Recent Senior Hire / Team Training
Announced expansion — new unit or service
Intention to adopt AI without organized process
Recent completion of course/management mentoring
12 Source structure
Each subdirectory of src/socialselling/ You have a strict responsibility.
delimited. No module imports from a level module above the pipeline.
All pipeline Pydantic models (4 layers): ICPCriteria → ObservedEvidence → Inference (+ CompanyEntity, PersonEntity) → ProspectScore / XAIPayload / RankedProspect → LeadCard. Rule: no business logic here.
modules/
m1_busca.py — Tavily/Apollo, atomic cache
24 hours, ObservedEvidence[]m2_extracao.py — lots Gemini, parsing Pydantic,
Inference[]
m3_score.py — pure linear formula, hard filter,
ProspectScore[]
m4_ranking.py — sort stable by p score, tie-break
by company idm5_xai.py — generates XAIPayload by rules, without AISkills/ — external customers
tavily_client.py — HTTP + cache + degradation
(429/timeout)gemini_client.py — JSON generation, backoff
exponential, surfacia error.message rawapollo_client.py — REST Apollo, 3 endpoints, ledger
integratedCore/ — internal infrastructure
atomic.py — write-temp + os.replace (imprimitive atomic writing)cache.py — cold cache in JSON, key = hash SHA-256
Contentcredit_ledger.py — monthly budget Apollo (try_spend/refund)
request_ledger.py — daily budget DPR Gemini
apollo/ · corpus/ · learning/
apollo/schemas.py — REST contracts Apollo; normalize.py → ObservedEvidencecorpus/store.py — upsert idempotent by entity_id; waves.py — generation of queries per wavelearning/model.py — pure logistic regression; tuner.py — shrinkage + clamp; feedback_store.py — atomic votesorchestrator. py
Synchronous unified pipeline M1→M5. Injects customers,
cache and clock; returns list[LeadCard]. Export
run_pipeline() (CLI and web) and accumulate_and_rank() (corpus+wave).
web/
app.py — routes
FastAPI (run, feedback, weights, status) · services.py — UI business logic · static/ — HTML cockpit + JS · schemas.py — Web API contracts
config/
runtime.toml — all adjustable parameters
(weights, TTLs, limits, opt-ins)hypotheses_catalog.json — hypotheses
priors and surface signalsicp_criteria.*.json — concrete PCIs (talita,
example)scripts/
gate.ps1 / gate.sh — ruff + mypy + pytest in sequencebootstrap.ps1 / bootstrap.sh — zero setup (venv + deps + .env)
record_*_fixtures.py — record actual
Tavily/Gemini/Apollonew_card.ps1 — creates card in GitHub Project with
DoR templatesetup_github_project.ps1 — syncs PROGRESS. md →
board13 Tests, BDD & observability
The test suite is the guarantee that the system is deterministic, byte-identical and Never touch network. Every external call is mocked with supervised recorded fixtures.
Gherkin Features
tests/features/
m1_busca.feature · M2 · M3 · M4 · M5pipeline_smoke.feature — E2E byte-identicalobjetivo_ranking.feature — business objective
Each module requires 3 scenarios: Happy (normal path) + degraded (429/timeout → degrades, does not break) + Open-World (sign missing → uncertainty ↑, never false).
🗂️ Fixtures gravadas
tests/fixtures/
Real API responses captured once, with supervision, via dedicated scripts:
record_tavily_fixtures.pyrecord_gemini_fixtures.pyrecord_apollo_fixtures.py (requires paid plan)Once recorded, the tests use them via FakeTavilyClient / FakeGeminiClient — network is never touched in IC.
Test guarantees
- Byte-identical execution (smoke executes 2×)
- Numeric tolerance
abs(a-b) ≤ 1e-9 - IDs per stable hash SHA-256 (never random UUID)
- Clock injected as parameter (
now: datetime) - Flakiness = failure (zero tolerance)
mypy --strictno errorsStrEnum(nostr, Enum) for Python 3.11+
PoC & SLO observability
📊 logs/cognitive_trace.jsonl
Log append-only with an event by relevant decision of
Pipeline. Each line: {ts, module, action, lead_id, inputs_hash, outputs_hash, tokens, degraded}.
Allows auditing cost, reproducing decisions and, in the future, measuring latency without
extra instrumentation. Traceability: Evidence → Inference → Score → Decision guaranteed via
derived_from.
PoC SLOs
| SLI | Target (SLO) |
|---|---|
| Green tests on the main | 100% (blocking) |
| Pipeline Determinism | 100% byte-identical (blocker) |
| Type coverage | mypy --strict without errors |
| Cost per execution | ≤ budget runtime. Toml |
| Latency (N≤50 leads) | p95 calibrating via trace |
Error zero budget for determinism and testing. Latency/cost: target calibrating — does not block merge in PoC.
14
Central Configuration (runtime.toml)
config/runtime.toml It's the PoC control panel. None
secret here ( API keys stay in .env). All features
opt-in are turned off by default to preserve the parity of the smoke E2E.
[coring] — score formula
w_fit = structural fit weight0.60w_intent = weight of intention0.40confidence_exponent0.5w_fit_tech / w_fit_industry0.60 / 0.40intent_evidence_norm5[persona] — multipliers per type
fundadora1.0
← targetindefinido0.5empresa0.35fundador0.0 ←
hard filter[finops] — cost control
tau_finops —
pruning threshold0.60kappa_degraded —
penalty in degraded mode0.80[gemini] — cognition
modelgemini-2.5-flash-litebatch_size50timeout_seconds120rpd_enabledfalse ← opt-inrpd_cap
req/day1000[cache] · [tavily] · [runtime]
cache.ttl_hours24 htavily.max_queries3tavily.persona_term"founder"runtime.max_leads_per_cycle50[apollus] — Firmographic sensor (opt-in)
enabledfalse ←
opt-inreveal_top_n20org_enrich_ttl_hours720h (30d)reveal_ttl_hours2160h (90d)caps.data_credits_cap100/month[corpus] & [learning] — opt-ins active
corpus.enabledtrue ← connectedcorpus.pathdate/corpus/leads corpus.jsoncorpus.waves_pathdate/corpus/waves. jsonlearning.enabledtrue ← connectedlearning.min_likes / min_dislikes3
/ 3learning.l20.1learning.epochs500learning.shrinkage_max0.5enabled = false Leaves the pipeline byte-identical to the baseline. Connect
a feature = change the hot path; disconnect = zero impact. The E2E smoke validates this every PR.
In short
What SocialSelling is
O SocialSelling makes customer search more efficient and automatic with AI, built with real engineering: decisions recorded in ADRs/SDDs, one SDD-to-Code Loop with deterministic gates and continuous feedback learning.
- Automatic AI prospecting — find and qualify customers with less manual effort.
- ADRs/SDDs — architecture and behaviour documented as a source of truth.
- SDD-to-Code Loop + gates — determinism and Open-World on the critical path.
- Learning by feedback — the system improves with the real result.
Frequently Asked Questions
Frequently Asked Questions
What is the SocialSelling project?
It is a system that makes the search and qualification of customers more efficient and automatic with AI. It was built with disciplined engineering: decisions in ADRs/SDDs, an SDD-to-Code loop with deterministic gates and feedback learning.
How do determinism and Open-World appear here?
The critical path solves what can be solved with rules (deterministic-first) and treats absence of data as explicit uncertainty (Open-World), not as "falso". This prevents AI from inventing qualifications and keeping the result auditable.
What is SDD-to-Code Loop?
It is the cycle in which the specification directs the implementation and the gates validate each step before advancing: the intention is written, the AI implements against it and the tests/gates prove compliance. The feedback learning feeds the spec.