# Discovery

<!-- BEGIN GENERATED: guide-map -->
## Guide map

Read only the section needed for the next decision. Line ranges are exact
for this generated runtime target.

| Section | What it covers | Lines |
| --- | --- | --- |
| [Purpose](#purpose) | Scope, ownership, and the central operating question. | 37-48 |
| [Use This When](#use-this-when) | Tasks and conditions that belong in this guide. | 49-60 |
| [Do Not Use This For](#do-not-use-this-for) | Boundaries and the correct routes for excluded work. | 61-71 |
| [Mental Model](#mental-model) | Concepts and state boundaries needed for correct operation. | 72-85 |
| [Preflight](#preflight) | State, authority, inputs, and readiness to verify before execution. | 86-97 |
| [Risk And Side Effects](#risk-and-side-effects) | Effects, approvals, cost, privacy, and retry boundaries. | 98-112 |
| [Canonical Operating Pattern](#canonical-operating-pattern) | The normal end-to-end execution sequence. | 113-147 |
| [Core SDK Surfaces](#core-sdk-surfaces) | Exact source-backed callable contracts owned by this guide. | 148-159 |
| [Data Contracts](#data-contracts) | Required identities, fields, evidence, handles, and durable shapes. | 160-178 |
| [Source Inspection](#source-inspection) | When the Skill is installed outside this repository, resolve the installed SDK source instead of assuming this repo path: | 179-196 |
| [Examples](#examples) | Representative usage patterns and code. | 197-225 |
| [Verification](#verification) | Evidence required before reporting success. | 226-235 |
| [Troubleshooting](#troubleshooting) | Failure diagnosis and corrective routes. | 236-245 |
| [Related References](#related-references) | Adjacent boundaries and when to cross them. | 246-252 |
<!-- END GENERATED: guide-map -->


Discovery is the fallback guide for finding exact SDK surfaces and inspecting
installed source when the main Skill route map or a narrower reference does not
answer the question.

Do not use this as another task router. Use the main `SKILL.md` Reference Guide
Map first, then the domain reference that owns the work. Come here only when
the exact function name, argument contract, return shape, source file, or test
coverage is unclear.

## Purpose

The SDK ships a generated function index built from `@sdk_function` metadata.
That index powers `vf.help(...)`, `vf.function_index()`, `vf.sdk.describe(...)`, and the
`verbiflow functions search/describe` CLI commands. These surfaces help agents
avoid inventing helpers, guessing call shapes, or trusting stale prose when the
installed SDK source already knows the answer.

The CLI commands are terminal adapters over the same metadata. They are useful
for humans and simple shell inspection, but normal agent execution should still
use typed `vf.*` calls and the domain references.

## Use This When

- The route map tells you the broad reference, but the exact SDK function name
  is still unclear.
- A reference names a function but the argument or return shape seems stale.
- You need to compare several SDK surfaces by `capability_category`, `intent`,
  `side_effect`, or `companion_doc`.
- You need the installed SDK source path before inspecting implementation or
  tests.
- You are about to write a helper and need to prove the SDK does not already
  provide the operation.

## Do Not Use This For

| Task | Use Instead |
| --- | --- |
| Choosing the broad task area | `SKILL.md` Reference Guide Map |
| Audience/source strategy | `audience_discovery.md`, `sources.md`, or workflow references |
| Operating an existing workflow root | `workflow_operations.md` |
| Job/artifact paging, waiting, or export | `artifacts_jobs.md` |
| CRM, enrichment, LinkedIn, host, sequence, sender, billing, or report specifics | The owning domain reference |
| Running provider work or platform mutations | Typed `vf.*` SDK calls with the owning reference and `safety.md` |

## Mental Model

Discovery has two layers:

1. **Metadata lookup** answers "what SDK surface exists and what does it
   claim?" Use `vf.help(...)`, `vf.function_index()`, or CLI search/describe.
2. **Source verification** answers "what does the installed implementation
   actually do?" Inspect the source file and nearest tests named by metadata.

Search results are not permission to execute. They are candidate surfaces. Read
the matching reference, check side effects, inspect inputs/outputs, and verify
with source/tests or a genuinely local/read-only call before running expensive
or customer-visible work.

## Preflight

1. Read the main route map row and the likely domain reference first.
2. Identify the noun and action you are searching for, such as `email enrich`,
   `sequence publish`, `artifact rows`, or `company LinkedIn URL`.
3. Search metadata in process with `vf.help(...)` or, for terminal users,
   `verbiflow functions search`.
4. For a candidate, inspect the exact contract with `vf.sdk.describe(...)`.
   Use `vf.sdk.read_source(...)` to page only that symbol's installed source.
5. Inspect the nearest tests before writing a new helper
   or relying on a surprising argument/return shape.

## Risk And Side Effects

| Surface | Side Effect | Notes |
| --- | --- | --- |
| `vf.help(...)` | local | Reads packaged metadata only. |
| `vf.function_index()` | local | Reads packaged metadata only. |
| `vf.sdk.describe(...)`, `vf.sdk.read_source(...)` | local | Resolve one exact contract and read only its installed source span. |
| `verbiflow functions search/describe` | local | CLI metadata adapters; no provider calls. |
| Source/test inspection | local | Read-only. |

Discovery should never call providers, start jobs, reserve credits, stage
sequence rows, publish sequences, send messages, or purchase domains. If you
find yourself doing any of those from this guide, switch to the owning domain
reference.

## Canonical Operating Pattern

1. Try the route map and domain reference.
2. Search installed metadata.
3. Describe or inspect the candidate surface.
4. Read source/tests for exact behavior.
5. Use the owning reference to execute the typed SDK call.
6. If no surface exists, write a local play/workflow helper only when the logic
   is truly one-off; otherwise propose a real SDK surface.

```python
import verbiflow as vf

print(vf.help("email enrichment", limit=5))

matches = [
    entry
    for entry in vf.function_index()
    if entry.get("capability_category") == "contact_enrichment"
]
for entry in matches[:5]:
    print(entry["sdk_path"], entry["side_effect"], entry.get("companion_doc"))

contract = vf.sdk.describe("enrichment.emails")
print(contract["python_signature"], contract["source"])
print(vf.sdk.read_source("enrichment.emails", max_lines=80)["content"])
```

For terminal-only inspection:

```sh
verbiflow functions search "email enrichment" --limit 5
verbiflow functions describe enrichment.emails
```

## Core SDK Surfaces

<!-- BEGIN GENERATED: core-sdk-surfaces -->
| Surface | Use When | Inputs | Output And Handles To Preserve | Side Effect | Source |
| --- | --- | --- | --- | --- | --- |
| `vf.help(query, supported=True, limit=10, format="text")` | Search installed SDK metadata in process when the route table or namespace doc does not identify the exact function. | `query` string plus optional `supported`, `limit`, and `format="text"/"json"`. | Text bullets or JSON metadata entries with SDK path, description, side effect, and next functions. Preserve the selected `sdk_path`; do not execute from search results without reading the reference/source. | local | installed SDK: `verbiflow/metadata.py:143` |
| `vf.function_index()` | Inspect the full generated SDK metadata list programmatically for filtering by category, intent, side effect, companion doc, or source. | No inputs. | `list[dict]` loaded from `assets/function_index.json`; preserve `sdk_path`, `python_signature`, `argument_summary`, `return_summary`, `side_effect`, and `source_file`. | local | installed SDK: `verbiflow/metadata.py:55` |
| `verbiflow functions search <query>` | Human-terminal adapter for the same metadata search; useful when operating outside Python. | Search terms plus optional `--limit`. | Matching `sdk_path: description` lines only; run `describe` or inspect source before using. | local | installed SDK: `verbiflow/cli.py:423` |
| `verbiflow functions describe <sdk_path>` | Human-terminal adapter for exact function contract details after a candidate SDK path is known. | Exact `sdk_path`. | Rendered metadata with supported flag, intent, category, when/avoid guidance, return summary, signature, arguments, source, and example. | local | installed SDK: `verbiflow/cli.py:435` |
<!-- END GENERATED: core-sdk-surfaces -->


## Data Contracts

Function index entries are dictionaries. Important fields:

| Field | Meaning |
| --- | --- |
| `sdk_path` | Canonical SDK path, such as `enrichment.emails`. |
| `python_signature` | Source-derived Python signature. |
| `argument_summary` | Names, types, required/default state, and descriptions. |
| `return_summary` | Generated return/handle guidance. |
| `side_effect` | Local/read/job/write/mutation classification. |
| `capability_category` / `intent` | Search/routing taxonomy. |
| `companion_doc` | Reference file that owns operation guidance. |
| `source_file` / `source_line` / `source_end_line` | Exact installed SDK source span relative to `verbiflow/`. |
| `next_functions` | Common follow-up calls, not automatic execution. |

Preserve `sdk_path`, `job_id`, `artifact_id`, sequence/source ids, and any
source file references that matter for the next step.

## Source Inspection

When the Skill is installed outside this repository, resolve the installed SDK
source instead of assuming this repo path:

```sh
~/.verbiflow/sdk-venv/bin/python scripts/resolve_sdk_source.py workflows
```

From this monorepo, inspect:

```sh
rg -n "sdk_path=\"enrichment.emails\"|def emails" sdk/python/verbiflow/src/verbiflow
rg -n "enrichment.emails" sdk/python/verbiflow/tests backend/tests data/tests
```

Prefer `rg` over `grep` when available.

## Examples

### Find A Function Without Guessing

```python
import verbiflow as vf

for entry in vf.help("company linkedin url", format="json", limit=10):
    print(entry["sdk_path"], entry["side_effect"], entry.get("companion_doc"))
```

Then read the companion doc and source before calling the function.

### Inspect One Candidate

```python
import verbiflow as vf

candidate = next(
    entry
    for entry in vf.function_index()
    if entry["sdk_path"] == "sources.people.find_at_companies_start"
)
print(candidate["python_signature"])
print(candidate["argument_summary"])
print(candidate["return_summary"])
print(candidate["source_file"], candidate["source_line"])
```

## Verification

- Search returns at least one plausible SDK path.
- The selected path has the expected `side_effect`.
- The companion reference exists and matches the task.
- Required arguments and return handles are clear before execution.
- Source/tests confirm any surprising behavior.
- Expensive or customer-visible operations are routed back to the owning
  reference and `safety.md`.

## Troubleshooting

| Symptom | Likely Cause | Fix |
| --- | --- | --- |
| Search returns too many broad results | Query is too generic | Add nouns, provider names, or expected output fields. |
| Search returns nothing | Wrong vocabulary or function is not indexed | Search the namespace source with `rg`, then inspect tests. |
| CLI output differs from docs | Docs are stale or installed SDK differs from repo | Trust installed source and update metadata/docs if in this repo. |
| Function exists but side effect is unclear | Metadata is incomplete | Inspect source and fix `@sdk_function` metadata before relying on docs. |
| You want to run a shell command as the normal path | CLI adapter confusion | Use typed `vf.*` calls for execution; CLI is for inspection or human terminal use. |

## Related References

- `sources.md` is the broad namespace router.
- `audience_discovery.md` owns provider-backed audience/source selection.
- `artifacts_jobs.md` owns job/artifact lifecycle after a function is chosen.
- `testing.md` owns small-run verification and row quality review.
- `safety.md` owns credit spend and platform mutation gates.
