seed_build
[Tier 1 — Seed Build] When: grow ONE territory outward from a seed location until it holds a target number of locations or a target metric sum — 'a franchise territory around this address with 40 stores', 'grow from this point until it reaches $2M revenue', 'the ZIPs around our new branch that cover 300 stores'. The result is an ordinary part-based territory (ZIPs, counties) appended as a new leaf on an existing layer (tal_id) or as a new layer when tal_id is omitted. It grows one territory from one seed. It does not partition, balance, or route. Prerequisites: an ingested point layer (ingest_accounts) — its locations are the values counted or summed; a part_layer (ezt://part-layers); and the seed as {longitude, latitude}. Resolve an address or POI to coordinates first with the address geocoding tool; a map click already gives coordinates. TARGET: target={type: 'location_count', value: N} or {type: 'metric_sum', field: , value: X}. An undeclared field returns UNDECLARED_FIELD — re-ingest with metric_fields. Fit is CLOSEST: growth adds the nearest adjacent part that still fits, then takes the smallest remaining neighbour only when overshooting lands nearer the target than stopping short. target_status reports reached | closest_under | closest_over | frontier_exhausted | max_parts_reached. NO OVERLAP, EVER: with tal_id, parts already in any territory of that layer are never taken — the new territory drifts away from them instead (blocked_part_count, seed_offset_km). A seed inside an existing territory fails SEED_PART_ASSIGNED; pick another seed or reassign parts with realign. There is no allow_overlap flag. SCOPE: growth reads only the seed's neighbourhood — the point layer is indexed once and parts are materialised ring by ring outward from the seed part; it never joins every location to every part, so a national point layer costs the same as a local one. part_filter / part_ids are an ALLOWLIST (parts outside it do not exist for the walk), not a performance prerequisite: pass part_scope='explicit' + part_filter={state_abbr: 'TX'} only when the user wants the territory confined to that state. bbox_intersect / point_matched are accepted and ignored here; the result reports the materialised part count and ring depth the walk touched. ONE SEED PER CALL: for several franchisees call seed_build once per seed with the same tal_id; earlier territories become blocked for later seeds. Async: returns task_id — follow _meta.next_action (sleep_and_poll → consume_result) and sleep the authoritative sleep_ms. The result is handle-only (ts_handle, no inline ts) with created_territory, the grown part ids, target.{requested, achieved, delta}, and do_this_next. Then: analyze(tal_ids=[], map_session_id, analysis_panel='single') so the map dock shows the territory; without dwell Analyze omits workload and returns workload_omitted.ask_user to relay after the stats. Pass map_session_id here to paint the territory on the open map. Full atom: ezt://guidance/workflows/seed-grown-territory. Scenarios: SB-001..SB-004.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| seed | Yes | ||
| tal_id | No | ||
| target | Yes | ||
| user_id | No | ||
| part_ids | No | ||
| max_parts | No | ||
| tal_label | No | ||
| ts_handle | No | ||
| part_layer | No | ||
| part_scope | No | ||
| part_filter | No | ||
| point_layer | No | ||
| map_session_id | No | ||
| territory_name | No | ||
| guidance_handle | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||