All steps Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 Phase 6 Phase 7 Planned Config & master data
Safety boundary. This map defines an automated, programmatic pipeline end-to-end: every accepted node executes deterministically with no human manually keying data in the loop. It does not by itself authorize live scraping, posting, outreach, publishing, lead routing, payment, or any external network action beyond what each node's own accepted implementation explicitly supports. Nodes 05-10's live demand-data acquisition is a CORE REQUIREMENT: as of 2026-08-17 all six nodes have a real, tested automated-fetch implementation, gated off by default until the user opts in and (for 4 of the 6) supplies API credentials -- see the Demand discovery child map for exactly which.
Closed demand-to-outcome loop Double-click a node to open its dedicated child process map. Single-click opens its purpose, automated contract, test, evidence and dependencies.
Nodes 01–04 Target ingestion 1 — Target & conversion definition
master (ingestion)100% · Complete, plus extension shipped 2026-08-18 -- Node 01 candidate clustering, Phase 2 approval branch, and bulk CSV import all built, tested (26 new pytest cases across this build: 15 in test_console_server.py taking it 65->80, plus 11 in shared/test_candidate_expansion.py), and live-verified against the real run (see Planned lane); existing Nodes 01-04 behavior unchanged and still real/working ⟳ Planned update — winner-triggered candidate clustering & bulk import, see Planned lane → Nodes 05–10 Demand discovery 2 — Demand intelligence
master (demand_intelligence)100% · Automated (code complete for all 6 nodes; 2/6 run live today, 4/6 need user-supplied API credentials -- see child map) → Nodes 11–15 Strategy and path intelligence 3 — Opportunity & path strategy
master (strategy)100% · Automated (Nodes 11-15 all automated, incl. Node 15's live-signal chain re-derivation) → Nodes 16–19 Knowledge and asset factory 4 — Canonical knowledge & assets
master (assets)100% · Complete, plus extension shipped 2026-08-18 -- Node 18 winner-replication loop-back built, tested (2/2 new pytest, a real gap-fill since this endpoint had zero coverage before today), and live-verified against the real run (see Planned lane); existing Nodes 16-19 behavior unchanged and still real/working ⟳ Planned update — Node 18 winner-replication loop-back, see Planned lane → Nodes 20–27 Distribution and conversion 5 — Placement, destination & capture
master (distribution_conversion)Mixed · Nodes 20/21/26 accepted & console-wired. Node 27 real and working but pending formal board acceptance. Nodes 22-25 deferred (MVP) -- real local package-builder code exists for all four but zero external dispatch was wired; reusable, evidenced connections now identified for Node 22 (YouTube upload, epics/ep_048_YTA/scripts/upload_video.py) and Node 23 (X/Twitter post, TradeApps/breakout/fs/social_publisher.py) -- adapter work, not yet built. → Nodes 28–31 Lead lifecycle intelligence 6 — Lead lineage, qualification & routing
master (lead_lifecycle)Pending acceptance · Nodes 28-31 are real and tested (26/26 own-suite tests re-verified 2026-08-18) but have no formal board ACCEPTED event -- corrected from a prior false "not started" label found in the Operational Console's own status table. → Nodes 32–37 Performance and learning loop 7 — Outcome learning & allocation
master (learning)Pending acceptance · Nodes 32-37, same status as Phase 6 -- real and tested, no formal board ACCEPTED event yet. Full winner-replication & scale-out extension shipped 2026-08-18: cost ledger, headless pipeline driver, Campaign Queue view, and the runFullPipeline auto-propose-on-winner loop, all built, tested (80/80 + 11/11 full suite), and live-verified (see Planned lane). ⟳ Planned update — Campaign Queue & cost ledger roll up this phase's output, see Planned lane Phase 1 — Target & conversion definition Nodes 01–04
Nodes 01–04 Target ingestion 1 — Target & conversion definition
master (ingestion)100% · Complete, plus extension shipped 2026-08-18 -- Node 01 candidate clustering, Phase 2 approval branch, and bulk CSV import all built, tested (26 new pytest cases across this build: 15 in test_console_server.py taking it 65->80, plus 11 in shared/test_candidate_expansion.py), and live-verified against the real run (see Planned lane); existing Nodes 01-04 behavior unchanged and still real/working ⟳ Planned update — winner-triggered candidate clustering & bulk import, see Planned lane Phase 2 — Demand intelligence Nodes 05–10
Nodes 05–10 Demand discovery 2 — Demand intelligence
master (demand_intelligence)100% · Automated (code complete for all 6 nodes; 2/6 run live today, 4/6 need user-supplied API credentials -- see child map) Phase 3 — Opportunity & path strategy Nodes 11–15
Nodes 11–15 Strategy and path intelligence 3 — Opportunity & path strategy
master (strategy)100% · Automated (Nodes 11-15 all automated, incl. Node 15's live-signal chain re-derivation) Phase 4 — Canonical knowledge & assets Nodes 16–19
Nodes 16–19 Knowledge and asset factory 4 — Canonical knowledge & assets
master (assets)100% · Complete, plus extension shipped 2026-08-18 -- Node 18 winner-replication loop-back built, tested (2/2 new pytest, a real gap-fill since this endpoint had zero coverage before today), and live-verified against the real run (see Planned lane); existing Nodes 16-19 behavior unchanged and still real/working ⟳ Planned update — Node 18 winner-replication loop-back, see Planned lane Phase 5 — Placement, destination & capture Nodes 20–27
Nodes 20–27 Distribution and conversion 5 — Placement, destination & capture
master (distribution_conversion)Mixed · Nodes 20/21/26 accepted & console-wired. Node 27 real and working but pending formal board acceptance. Nodes 22-25 deferred (MVP) -- real local package-builder code exists for all four but zero external dispatch was wired; reusable, evidenced connections now identified for Node 22 (YouTube upload, epics/ep_048_YTA/scripts/upload_video.py) and Node 23 (X/Twitter post, TradeApps/breakout/fs/social_publisher.py) -- adapter work, not yet built. Phase 6 — Lead lineage, qualification & routing Nodes 28–31
Nodes 28–31 Lead lifecycle intelligence 6 — Lead lineage, qualification & routing
master (lead_lifecycle)Pending acceptance · Nodes 28-31 are real and tested (26/26 own-suite tests re-verified 2026-08-18) but have no formal board ACCEPTED event -- corrected from a prior false "not started" label found in the Operational Console's own status table. Phase 7 — Outcome learning & allocation Nodes 32–37
Nodes 32–37 Performance and learning loop 7 — Outcome learning & allocation
master (learning)Pending acceptance · Nodes 32-37, same status as Phase 6 -- real and tested, no formal board ACCEPTED event yet. Full winner-replication & scale-out extension shipped 2026-08-18: cost ledger, headless pipeline driver, Campaign Queue view, and the runFullPipeline auto-propose-on-winner loop, all built, tested (80/80 + 11/11 full suite), and live-verified (see Planned lane). ⟳ Planned update — Campaign Queue & cost ledger roll up this phase's output, see Planned lane Planned — pending sign-off Winner-replication & scale-out design, agreed 2026-08-18. See plans/20260818_1645_ep050_winner_replication_and_scale_out.md. Nothing here is board-accepted; cards are dashed/purple to mark design-or-unverified state, distinct from the real progress badges elsewhere on this map.
This lane exists so the new requirements are visually trackable before implementation, without claiming any of them are complete. Node cards this touches in the main pipeline (Phase 1, Phase 4, Phase 7) carry a matching ⟳ Planned update tag.
Node 18 (extension) Winner replication Format-diversification loop-back
planned (node_18_replicate_winner)Built, unverified · Reruns the real Node11-17 chain against the same proven cluster/facts, varying only template_version, to mint several new real video-asset variants per detected winner. Code exists (handle_node18_replicate_winner + console.js button) but not regression-tested, version-bumped, or board-accepted yet. Node 01 (extension) Candidate clustering One-hop geo/service expansion
planned (candidate_targets)Design only · Auto-registers new (service, geo) candidate targets one hop from a detected winner, from a curated real adjacency list (geo) and trade taxonomy (service) -- never a compound jump. Each candidate independently earns real Phase 2 signal + Node 16 facts before Phase 3 runs; no signal, no campaign. Console orchestration Campaign Queue Run many campaigns concurrently
planned (campaign_queue)Design only · Extends Campaign Overview from one loaded run to a multi-run queue and drives Run Full Pipeline concurrently across queued run_ids. Server (ThreadingHTTPServer) and per-run isolated storage already support this safely today -- the gap is orchestration/UI only. Nodes 01/02/03 (bulk) Bulk campaign import Spreadsheet → Campaign Queue
planned (bulk_import)Design only · CSV import matching the real Node 01+02+03 required fields exactly, validated row-by-row through the same rules as manual entry (no bypass), per-row pass/fail reporting, feeding straight into the Campaign Queue. Cross-cutting Cost ledger Real spend per node/action
planned (cost_ledger)Design only · Any node performing a real paid action stamps a real cost_gbp (its provider's actual published rate) onto its own lineage event; Campaign Overview rolls up spend-to-date, cost-per-lead, cost-per-win. Zero everywhere today -- no node spends real money yet. Configuration & Master Data — required for scale Cross-cutting, not a phase
Added 2026-08-19 after de-hardcoding swept the pipeline: every place a node used to assert a specific town, trade, cost or claim as a literal, it now either derives from real upstream data or fails closed. That removed the fabrication, but it also means the pipeline currently knows almost nothing about the world beyond what one campaign's own signal tells it -- it has no independent source for postcodes, adjacent geography beyond one hand-curated list, real cost rates, or verified business claims. Scaling to many campaigns needs these captured as real, owned, versioned master data -- not invented per-request, and not re-hardcoded as a "fix". Dashed/purple = not yet built as a genuine config space, matching the Planned lane's convention.
shared/candidate_expansion.py Geo adjacency Which towns are "next door"
config (geo_adjacency)Exists, but as a Python dict literal · GEO_ADJACENCY currently holds exactly one entry (Blackheath -> Lewisham/Greenwich/Catford/Charlton/Eltham), curated by hand in code. Real and fail-closed (an uncurated locality raises DerivationError rather than guessing) -- but not yet a genuine master-data space: adding a new source town means editing Python, there is no postcode-district granularity, and nothing verifies the list stays current if a business's real coverage area changes. shared/candidate_expansion.py Service adjacency Which trades a business plausibly also offers
config (service_adjacency)Exists, same shape as geo adjacency · Corrected once already (2026-08-18) after two guessed entries -- boiler_installation, central_heating_repair -- turned out not to be real services this business offers, and had already minted 2 real candidate campaigns before the user caught it live. That correction is the whole argument for this lane: a guessed default is worse than no default, and the fix belongs in owned data the business confirms, not a fresh code guess each time. Not yet started Postcode / locality master list The example the user asked for directly
config (postcode_master)Missing entirely · Node 17's ad copy used to assert a fixed postcode ("SE3") for every campaign regardless of its real town; fixed 2026-08-19 by removing postcodes from rendered copy rather than inventing a mapping, since no real source exists anywhere in this pipeline. Postcode-level targeting/copy cannot resume until this exists as real, sourced data -- e.g. ONS postcode-to-district lookup or a business-confirmed coverage list -- not a hand-typed literal per campaign. .env (repo root) Live-fetch provider config Which external APIs are wired, and their real limits
config (live_fetch_credentials)Exists and working, not yet centrally documented · EP050_LIVE_FETCH_ENABLED, EP050_FIRECRAWL_API_KEY (falls back to the Firecrawl CLI's own stored credential), EP050_YOUTUBE_API_KEY, EP050_REDDIT_CLIENT_ID/SECRET all live in .env today, fail-closed by default. Firecrawl's real quota (1,000 credits/month on the current Free tier, ~2 credits per Node 05 search) is nowhere written down as a scaling constraint -- confirmed 2026-08-19 not to survive "thousands of continuous campaigns" without a paid tier, but that ceiling exists only in conversation right now, not in any doc a future session would find. Cost ledger (see Planned lane) Real provider cost rates What a paid action actually costs, per provider
config (cost_rates)Missing, blocks the cost ledger · The cost ledger (Planned lane) requires each node stamp cost_gbp from "that provider's actual published rate" -- there is nowhere that rate is captured today. Needs to exist before any node goes live for real spend (paid Search past free tier, a real render service, ad spend, a paid CRM/dispatch fee), or the ledger has nothing real to read from and risks the exact estimated/invented-figure problem this whole lane exists to prevent. Node 16 (extension) Verified fact / claims sources Where a business's real claims come from
config (fact_sources)Missing, currently blocks every campaign at Node 16 · All real campaigns today are blocked at Node 16 because the only fact ever registered was verification_source="manufacturer_manual_fixture" -- purged 2026-08-19 as unreal. Node 16 itself is real and working; what is missing is a genuine source of verified claims per business/vertical (a real manufacturer document, trade-body guidance, regulation, or the business owner's own confirmed statement) that a campaign can cite instead of a fixture placeholder. Also covers product/audience content: candidate campaigns currently copy Blackheath's product/audience description verbatim rather than sourcing their own -- legitimate as a starting configuration, per user clarification 2026-08-19, but not yet independently verified per campaign. server.py (extension) Campaign quality gates Which numeric thresholds decide "real enough to proceed"
config (quality_gates)Two real gates now, both deliberately blunt · GATE 1, commercial intent: live-tested 2026-08-19, mars_spaceship_builder (Catford) sailed through Node 05’s non-zero-results check and Node 11/15 to the SAME needs_facts state as every real boiler campaign, since a live web search returns something for almost any query. MIN_COMMERCIAL_INTENT_SCORE (currently 0) excludes classifications scoring 0 -- accepted cost: Greenwich/Lewisham/Charlton/Eltham all score 0.0 too on “restore hot water quickly” (no COMMERCIAL_KEYWORDS hit), so real quiet demand is excluded alongside nonsense. GATE 2, service relevance, added the same day after gate 1 proved insufficient: snowmobile_repair (Catford) returned real local car-mechanic businesses (whocanfixmycar.com, checkatrade.com) -- genuinely local and commercial, just the wrong trade -- and audience_hunter (not a real service anywhere) returned “Hunters Catford”, a real local ESTATE AGENT, purely on the coincidental surname token “Hunter” (confirmed via a controlled Firecrawl probe: the identical query against Reykjavik, with no such coincidental business, correctly returned only generic travel content). Both passed gate 1 since their queries contained real commercial words. Gate 2 requires the service’s OWN distinctive name tokens to appear together in at least one real result -- catches both cases, exempts manually-curated (non-live-search) signals entirely, since there is no fetched result to check relevance against. Both named as single constants (MIN_COMMERCIAL_INTENT_SCORE, _SERVICE_TOKEN_STOPWORDS) specifically so they can move here properly and become tunable per vertical once there is a real need to vary them.