Skip to content

Capstone: lead-finder as a pure declarative pipeline (#94) - #117

Merged
serge-ivo merged 1 commit into
mainfrom
feat/94-lead-finder-declarative
Aug 1, 2026
Merged

Capstone: lead-finder as a pure declarative pipeline (#94)#117
serge-ivo merged 1 commit into
mainfrom
feat/94-lead-finder-declarative

Conversation

@serge-ivo

Copy link
Copy Markdown
Contributor

Part of #94 — the capstone proof. Reference definition + end-to-end composition test + gap map. The running lead-finder agent/worker is untouched; everything lives in workers/api/src/lib/pipelines/.

Proven composable spine (100% declarative, end-to-end through the real executePipelineStep + real map/filter/dedupe handlers; only outbound HTTP + sink DO mocked):
geocode(city→centre) → http_request places:searchNearby (vault key header, FieldMask, responseMap → typed rows) → map (derive category/status + geo) → filter (websiteUri missing) → dedupe_upsert (key place_id) → sink leads, with a per-record {step,detail,at} audit trail. Test drives a realistic 3-business response (no-website / dead-site / live-site) → surviving lead is the no-website one, upserted once on re-run.

Verdict: the spine yes, the full sweep not yet. Four runner/step primitives stand between the spine and the complete sweep — each asserted by a GAP test and filed as a #94 child:

None require the running agent — all are platform primitives. A green test hiding any of these would have been the wrong outcome; each is proven present.

Verify: tsc clean · capstone 9/9 pass · full api suite 889 (880 baseline + 9, 0 regressions) · biome clean.

🤖 Generated with Claude Code

…e proof (#94)

Author the lead-finder as DATA, not code: lead-finder.json is a PipelineDef
(source=geocode+http_request Places, map=reshape/derive, filter=no-website,
dedupe_upsert by place_id, sink=`leads`), validated by validatePipeline and
driven end-to-end through the real runner (executePipelineStep) + real
map/filter/dedupe handlers in lead-finder.test.ts. Only the two I/O boundaries
(outbound HTTP, the collection sink DO) are mocked; the composable spine +
per-record audit trail (attachAudit) are proven with the right 2->1 no-website
lead and place_id dedupe.

Honest about the four expressibility gaps the composition hit (each asserted as
a "GAP #N" test, documented in README.md, filed as #94 children):
- #113 grid fan-out flatten (forEach -> array-of-arrays, no flatten primitive)
- #114 dotted access into a forEach item ($param:"item.field")
- #115 enrich-merge (join a forEach result back onto its records)
- #116 map/responseMap type-select of Google addressComponents

Reference-only: lives entirely in the platform repo; the running lead-finder
agent + worker are untouched. api tsc clean; api suite 880 -> 889, 0 regressions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants