Enrichment Orchestrator
The enrichment orchestrator is a staged prompt system for safely moving source rows from untouched data to validated and progressively enriched records. It separates basic data checks, semantic validation, enrichment research, and spreadsheet mutation so that each concern has a clear contract and stop gate.
The orchestrator is the only component allowed to edit the workbook. Stage prompts evaluate rows or company groups and return structured decisions.
Package structure
docs/prompts/enrich_o/
├── intro.md
├── orchestrator.md
└── prompts/
├── 01-stage-1-check.md
├── 02-stage-2-validate.md
└── 03-stage-3-enrich-1-routing.md
Add one prompt for each future enrichment category. Enrichment prompt numbers
must be contiguous from 1 through the configured max_enrich_steps.
Architecture
Configuration
The required setting is:
max_enrich_steps: 1 # any integer from 1 through the number of registered enrichment prompts
Optional runtime settings:
input_file: path/to/source.xlsx
output_file: path/to/output.xlsx
source_sheet: null # discover when null
retry_errors: false
resume_existing: true
working_projection: zoominfo_minimum
max_enrich_steps counts enrichment prompts only. The readiness and validation
stages always run when their input statuses require them.
Stage 1 compact working file
Stage 1 reads the full source workbook locally, performs the readiness check,
and creates output_file as a smaller working workbook. Every original row is
retained, but only the minimum source columns needed for identity, validation,
and routing are copied. Status and later enrichment fields are appended to this
working file.
For a ZoomInfo export, retain these source columns in order:
source_row— generated from the original worksheet row numberZoomInfo Contact IDZoomInfo Company IDCompany NameWebsiteEmail DomainCertified Active CompanyCompany CountryNAICS Code 1Primary IndustryPrimary Sub-IndustryBusiness ModelQuery Name
The source workbook remains unchanged and is the source of record. The compact
file preserves source_row and available ZoomInfo IDs so results can be joined
back to the full export later without sending personal, dialing, address,
social-profile, or redundant industry columns to the model.
Rows that fail readiness remain in the compact file with bad_data; they are
not removed. Later stage prompts receive only compact fields, prior stage
outputs, and the rows admitted by their status gate.
Row-state model
The canonical workbook column is enrichment_status. Do not reuse a CRM field
such as Status or Lead Status.
| Status | Meaning | Terminal by default |
|---|---|---|
new | The row has never been evaluated by this pipeline | No |
ready | Basic source data is sufficient for semantic validation | No |
valid | Semantic validation passed | Sometimes |
enriched_1 … enriched_n | Enrichment category 1 … n completed | At configured maximum |
bad_data | Basic source data is missing, malformed, or unusable | Yes |
invalid | Data was sufficient to inspect, but semantic validation failed | Yes |
error | A technical or unexpected execution failure occurred | Yes, unless explicitly retried |
bad_data is intentionally distinct from new. A processed failure must never
look like an untouched row.
Recommended operational columns:
| Column | Purpose |
|---|---|
enrichment_status | Current state-machine status |
enrichment_status_reason | Concise reason for the most recent transition |
enrichment_last_completed_step | 0 before enrichment, otherwise the latest completed enrichment number |
enrichment_category | Category completed by the latest enrichment prompt |
enrichment_attempt_count | Number of stage attempts for the row |
Operational columns belong to the orchestrator. Stage prompts may propose their values but may not write them directly.
State transitions
An error row may re-enter the stage that failed only when retry_errors=true
and the orchestrator retains or receives the failed-stage identifier.
Gates
Gate 1: readiness
The row must contain enough basic identity data to support validation. This is a structural and syntactic check. It does not browse the web, infer a market, or decide whether the company is a good prospect.
- Pass:
new → ready - Fail:
new → bad_data - Execution failure:
new → error
Gate 2: validation
The company or account must resolve to a coherent real-world identity, and the supplied row must not contradict that identity. Validation may determine that the row is not eligible for any configured enrichment category without calling the row malformed.
- Pass and continue:
ready → valid, then run enrichment - Pass and stop:
ready → valid - Semantic failure:
ready → invalid - Execution failure:
ready → error
Gate 3: enrichment step
An enrichment prompt must receive the exact status required for its step and may populate only its owned fields.
- Success:
valid → enriched_1orenriched_(k-1) → enriched_k - Execution failure: current status →
error - Maximum reached: stop after
enriched_<max_enrich_steps>
Prompt interface
Every stage prompt receives a common envelope:
{
"stage": "check | validate | enrich_n",
"expected_input_status": "new | ready | valid | enriched_n",
"rows": [],
"company_context": [],
"configuration": {
"max_enrich_steps": 1
}
}
Every stage prompt returns JSON only:
{
"stage": "check | validate | enrich_n",
"results": [
{
"source_row": 2,
"input_status": "new",
"output_status": "ready",
"status_reason": "Company name and business email domain are present.",
"owned_fields": {}
}
]
}
The orchestrator rejects a result if the input status, output status, or field ownership does not match the registered stage contract.
Axioms
- The source workbook is immutable and is never overwritten.
- Stage 1 retains every source row but may omit non-projected source columns from the compact working workbook.
- Values copied into the compact projection must exactly equal their source cell values.
- The orchestrator is the only workbook writer.
- A stage prompt performs exactly one concern and returns structured data only.
- A stage runs only on rows with its declared input status.
- Status transitions are monotonic; stages cannot be skipped or reversed.
newalways means untouched.bad_datameans insufficient basic input;invalidmeans semantic validation failed.errorrepresents execution failure, never a business classification.bad_data,invalid, anderrorstop downstream work immediately.- Each enrichment field has exactly one owning prompt.
- A prompt may not overwrite another prompt's fields.
- Re-running a completed stage with the same inputs must be idempotent.
- Company-level results must be identical across contact rows for the same resolved company.
- Every transition must include a concise machine-readable reason.
- Unsupported facts remain
unknown; they are never fabricated to advance a row. max_enrich_stepsis a hard limit enforced by the orchestrator.- Missing stage prompts are configuration errors detected before workbook mutation.
- Internal research artifacts may support execution but must not create hidden or helper tabs in the delivered workbook.
- The compact working workbook is the pipeline state store after Stage 1.
- Final verification must prove row preservation, projection fidelity, valid transitions, field ownership, and workbook usability.
Adding another enrichment category
To add enrichment step k:
- Create
prompts/NN-stage-3-enrich-k-<category>.md. - Declare its required input status:
validfor step 1 orenriched_(k-1)otherwise. - Declare an exclusive field allowlist.
- Declare its success status as
enriched_k. - Register the prompt in
orchestrator.md. - Add transition, idempotency, and field-ownership tests.
Do not increase max_enrich_steps beyond the highest contiguous registered
enrichment prompt.