CtrlK
BlogDocsLog inGet started
Tessl Logo

audience-analyze-list

Read who a supplied list of people is — take a list of people as identifiers (emails, phones, names, addresses, inline or as a CSV) to resolve, or as already-resolved entity IDs (a roster from grouping, or a pasted entity-ID set), and render the discovered half of the read (the traits that define them against the world by lift, plus segmentation). No specified-signals section — the user gave people, not signals. The list way into audience-analyze, behind /watt:audience. Aggregates only — never individual records, never an export. Not a user command. Use when the user brings a list of people and asks who they are — "profile my customer list", "what do these people have in common", "read this roster's groups".

68

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

Analyze a supplied list of people

Purpose

audience-analyze-list is the way into the read when the user brings a list of people, not signals. The list arrives in one of two forms, and they differ only in whether resolution is needed:

  • identifiers — a customer CSV, a pasted set of emails/phones/names/addresses → resolve them to Watt entities first.
  • entity IDs — a roster from the grouping objective, or any pre-resolved entity-ID set the user holds → already entities; skip resolution and read them directly.

Either way, because no signals were specified, there is no your-signals half — only the discovered read: the traits that define these people against the world by lift, plus per-domain segmentation.

This is a delta over audience-analyze: the unique work here is getting the list to a chainable entity set — resolving identifiers, or taking an entity-ID set as-is; the discovered read and the shareable report are the parent's shared procedure (audience-analyze → The read & report), composed with verbatim — discovered-only.

Works with

  • Called by: the audience-analyze router, when the user supplied a list of people — a CSV/identifiers to resolve, or a pre-resolved entity-ID set (a roster from grouping).
  • Runs inline:
    • the resolution procedure (context/resolution.md) (identifiers only) — the supplied identifiers → a workflow:// entity-IDs URI plus the counts (identifiers submitted, entities resolved). The resolve runs inline but stays IDs-only — the leaf handles only the URI and counts, never a contact record. Skipped entirely when the list is already entity IDs — there is nothing to resolve.
    • the profiling procedure — mode B (the entity-IDs URI, no signals) → the discovered-only read. The parent's shared read, run inline (context/profiling.md).

Language

Inherits the parent's table (lift explained once; sample named). The headcount here is a count of the people in hand, not a market total: "N people resolved from your list" for identifiers, or "N people in the set" / "N in this group" for an entity-ID set or roster.

The flow

1 — Get the list to an entity-ID set

Two input shapes; the only difference is whether resolution is needed.

  • Identifiers (a pasted set, or a CSV — uploaded or to upload). Name the identifier types present (email, phone, name, address); addresses need explicit handling, so call them out. Run the resolution procedure inline (context/resolution.md) with the identifiers (inline) or the csv_resource_uri, the entity_type, and a workflow_id. It matches them, dedupes, and returns the entity_ids_uri plus the counts — input_identifier_count and resolved_count (and below_floor_count). Narrate them plainly ("5,000 identifiers in, 4,200 people resolved — reading those"). The resolve runs inline but stays IDs-only — the leaf handles only the URI and counts, never a contact record.
  • Entity IDs already (a roster's roster_uri from grouping, or a pasted entity-ID set). These are the resolved entities — skip the resolution procedure entirely; take the URI as-is and the count of IDs in it. For a roster, the user can read the whole set (the roster_uri) or a single group (its entity_ids_uri); the group_label classification is what lets a per-group read be a separate inline run.

2 — Run the shared read (discovered-only)

Run the parent's shared read & report (audience-analyze → The read & report): run the profiling procedure inline (context/profiling.md) in mode B with the entity_ids_uri (the resolved set, or the roster/group URI taken as-is), the headcount, and the workflow_id — no signals, so the read is discovered-only. Render the dashboard with the discovered half (defining traits by lift, segmentation, the intent panel by reach); there is no your-signals section. Offer the shareable report — built with --no-specified so it drops Section 1 — and the next step (for a roster, a per-group read is the natural deeper cut, one mode-B inline run per group).

How to behave

  • The list is people, not signals — so the read is discovered-only, and the dashboard says so plainly rather than showing an empty your-signals section.
  • Aggregates only, and IDs never become records here. The resolution procedure returns entity IDs; the profiling procedure reads aggregates over them. No name, email, address, or contact data is ever pulled, shown, or written — turning IDs back into people is audience-activate's lane, behind its own confirmation.
  • Honest about the match. For identifiers, both counts are on screen — identifiers submitted vs. people resolved — and the read covers who matched, not everything uploaded; say so. For an entity-ID set or roster there's no match step (they're already entities) — the count is the set size, and for a roster the pruned/coverage from the build still applies.
  • Narrate the inline run and report the return in one plain line each — counts, never identifier values or records.
  • US-only, adults-only, person audiences only.

Refuse cleanly

  • "Enrich my list / give me their emails and phones." That's enrichment/export — audience-activate's lane, behind its confirmation. This leaf reads the list as aggregates only.
  • "Show me which of my people matched." Aggregates only — the read is over the matched set as a whole, not a per-row report; the counts say how many matched.
  • A brief instead of a list ("people interested in X") → that's audience-analyze-search (discover signals) — route there.

Failure modes

  • The resolution procedure matches few or none (bad identifiers, wrong column mapping) — surface the counts (how few of the submitted identifiers resolved) and the likely cause; never read an empty or near-empty set as if it were the list.
  • The profiling procedure errors mid-read. Surface where it stopped and what completed; never fill a panel with plausible numbers.
Repository
wattdata/plugin
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.