Cookbook
Give every record an owner in one pass
An account with no owner is not on anybody's list, does not appear in anybody's number, and gets remembered only when a customer emails to ask why nobody called. This is the pass that ends that, done in one batch.
The situation
You ran the gaps pass and it told you how many records have no owner. Now you have to set them, and the number is too large to do one at a time and too small to justify a project. This is the shape of job a batch is for.
What must be true when you are done
- Every account and open deal has an owner.
- The batch reports what it applied, per row, rather than a total.
- Anything it could not resolve is named, not skipped quietly.
- Re-running it does not create a second copy of anything.
Decide the split before you touch anything
The batch is the easy part. Deciding who gets what is the part worth spending twenty minutes on, because doing it twice is worse than doing it slowly. Territory, industry, existing relationship, or simply whoever last spoke to them: pick one rule and write it down where the next person can read it.
If your rule is "whoever last spoke to them", the account brief already knows that, so ask for it rather than guessing.
Send it as one batch
Give the agent the rule and let it apply the whole set in one call. A batch is bounded, so a large book goes in groups of a hundred rather than all at once, and the agent handles that without being asked.
You
Agent
Nine applied, nothing failed. The report is per row rather than a single status, which matters more than it sounds: a batch that says "done" when four of its rows did nothing is the failure mode that makes people stop trusting bulk operations, and reading a count of successes against a count of attempts is how you catch it in one glance.
The two refusals worth meeting on purpose
Both of these are the product declining to guess, and both are easier to understand now than during a real import.
An identity it cannot settle. A company with no domain, whose name exactly matches one already there, is not merged and not duplicated. It comes back as ambiguous, with the candidate it found:
Agent
That is the one case where an exact name match is the weakest evidence available, because two businesses genuinely share a name far more often than two businesses share a domain. Supplying the domain resolves it; so does telling the agent to create it as a distinct record, once you have looked.
The same key, different intent. Re-running a batch with the same idempotency keys but changed values is refused rather than applied:
Agent
This is the behaviour that makes a scheduled job safe to retry. A repeat of the same work is a no-op; a repeat that has quietly become different work is stopped and handed back to you. It is worth triggering once deliberately so that the message is familiar when a nightly job produces it at three in the morning.
Verify it
- Re-run the gaps question. The unowned counts should be zero, or should name exactly the records you deliberately left alone.
- Total the pipeline by owner again. The unowned row should be gone, and the amounts should now sit against people. If a person's total surprises them, that is the conversation this pass existed to start.
- Run the whole batch a second time. Nothing should change and nothing should be created. If a second run reports work, your keys are not stable and the job is not safe to schedule.
Run it again
After every joiner, leaver and territory change, and as a sweep whenever the gaps pass says the unowned count has crept back up. When it is a person leaving rather than a gap, handing over a book of accounts is the fuller version of this, because it moves the history and the open work as well as the name on the record.