Audience analyze signal
Read who a built audience reaches when the signals are already in hand — a signal stack fresh from generate, an explore pool, a pasted audience record, or signals the user names — skip discovery, materialize, and render the two-section read (your signals + discovered). The signals-in-hand way into audience-analyze, behind /watt:audience. Aggregates only — never individual records, never an export. Not a user command. Use when a built audience is in session or the user supplies its signals and asks who's in it — "who's actually in this audience", "what do these people look like".From its SKILL.md
npx -y skills add wattdata/plugin --skill audience-analyze-signalAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.5 KB, as published. Nobody here has run it
Analyze an audience from its signals
Purpose
audience-analyze-signal is the way into the read when the signals already exist — a signal stack fresh from audience-generate, an /watt:explore signal pool, a pasted audience record from a past session, or signals the user names. There's no discovery and no pivot loop: take the signals as given, materialize them, and hand the built stack to the shared read.
This is a delta over audience-analyze: the unique work here is just resolving the supplied signals into a built signal stack; the read and the shareable report are the parent's shared procedure (audience-analyze → The read & report), composed with verbatim — not restated.
Works with
- Called by: the
audience-analyzerouter, when a built audience is in session or the user supplied its signals. - Runs inline:
- name resolution (only when the user supplied bare names) — resolve each named signal to its verified trait inline, following the discovery procedure (
context/discovery.md), driving from meaning. Never used to discover more signals — the user's set is the set.
- name resolution (only when the user supplied bare names) — resolve each named signal to its verified trait inline, following the discovery procedure (
- Runs the read inline — the profiling procedure (
context/profiling.md) in mode A (the stack) → the two-section read; the parent's shared read, run inline on the main thread.
Language
Inherits the parent's table (signals / must-haves / exclusions; lift explained once; sample named). The role column in an audience record — defining (any-of) / must-have (all-of) / exclusion (none-of) — carries the boolean shape exactly; the operator never sees AND/OR/NOT.
The flow
1 — Take the signals as given
- A built audience in session (fresh from generate, or composed in
audience-analyze-search) — use it directly. Confirm which one in a word if there's any doubt. - A re-supplied audience record — read from the saved record file in the working directory, pasted in, or compacted in context — the
rolecolumn (defining/must-have/exclusion) carries the expression exactly as built, and names ride beside hashes; take it as the stack. A past session's reach/headcount is "measured then", not re-measured silently. On a refresh-shaped ask ("refresh this", "is it still ~2M?"), the read's fresh materialization is the re-measure: after the read, re-write the audience record per the record contract (context/record.md) with today's measured reach against the header's original target (reach 2.1M (band 1M–5M) · refreshed), location and roles unchanged. - A signal pool (an
/watt:exploresession's kept signals, or a lookalike pool) — auto-compose it to the default stack: signals the pool marks must-have go all-of, its exclusions none-of, everything else any-of (one OR union). If the pool carries no role markers at all, ask once — "any must-haves or must-have-nots in here, or read them all as one group?" — then build. This is a deterministic reading of the user's picks, the same way a record'srolecolumn reconstructs an expression — never a strategy compose; refining the pool into a tuned stack isaudience-generate's lane, offered if the read shows it's wanted. - Signals the user names, no hashes — the leaf cannot fabricate a hash. Resolve each name to its verified trait inline, following the discovery procedure (
context/discovery.md) — driving from meaning — surface the matches for a one-touch confirm, and only then build the stack. Never pass a name off as a hash, never guess one.
Build the expression from the role column — defining any-of, must-have all-of, exclusion none-of — and reuse the record's workflow_id if it carries one, else generate one. If the supplied set carries no measured reach, measure the headcount once with a count-only entity find (format: "none", location applied if the record fences one).
2 — Run the shared read
Hand off to the parent's shared read & report (audience-analyze → The read & report) in mode A — the signal stack you took in hand (expression, signals, location, reach, workflow_id). The router owns the read, the two-section dashboard, the report, and the next-step options.
How to behave
- The user's set is the set. This leaf reads what was supplied; it doesn't discover more signals or pivot pools. Adding signals is a re-pivot back through
audience-generateoraudience-analyze-search. - Never invent a signal — a bare name is resolved inline (per the discovery procedure) and confirmed, never assigned a guessed hash.
- Don't re-measure silently — a past session's reach is labeled "measured then"; only an unmeasured supplied set gets a fresh count-only measurement. The one exception is a refresh-shaped ask, where the read's materialization is the explicit re-measure (step 1).
- Narrate the read and report the return in one plain line each — never the structured payload.
- Aggregates only — the read and the report carry no record, identifier, or PII; that's
audience-activate's lane. - US-only, adults-only, person audiences only.
Refuse cleanly
- "Show me the actual people." Aggregates only — individuals live downstream in the export, behind the activate step's confirmation.
- A list of identifiers / a CSV of people. That's the
audience-analyze-listway in — say so; this leaf reads from signals, not a people list. - "Add some more signals to this." That's a re-pivot — route to
audience-generate(build) oraudience-analyze-search(discover more from a brief); this leaf reads the set as given.
Failure modes
- A supplied signal name resolves to nothing strong. Surface the closest match flagged; never silently substitute or fabricate a hash.
- A reach probe or the profiler errors. Surface where it stopped and what was measured; never fill the gap with an estimate.