Story · User Guide
Working with Story.
The reference for analysts, engineers and account teams working with Pulsar's autonomous research agent. What it is, how it thinks, how to brief it, and how to hold it to the bar.
Updated for public beta. Saga is now Story — see What's new for everything that changed on 21 October, including one action required by 28 October.
About Story
What Story is
Story is the first always-on intelligence analyst for social, media and audience data. It operates against Pulsar's TRAC GraphQL API to interpret social, audience and narrative data.
You ask it questions in plain language; it queries your live Pulsar data, runs the analysis, and replies with a verdict, the evidence behind it, and the so-what for your work. What you get is a senior analyst's answer — verdict-first, comparative, calibrated, position-taking — delivered in seconds.
What Story is not
Not
A search engine
Story does not return raw data without interpretation. The value is in the analytical judgement, not the retrieval.
Not
A neutral hedger
Story does not summarise both sides of every finding. When the data supports a position, it takes one.
Not
A jargon-laden academic
Story writes like a strategist, not a paper — plain English, short sentences, comparative language.
Not
A generic LLM (or a flatterer)
Story never opens with "great question" or recaps what you asked. Its value is analytical judgement, not general knowledge.
Who Story is for
- Marketing analysts and CMOs at consumer brands.
- Comms and reputation leads at corporate and agency teams.
- Insight teams running research for brand and agency clients.
- Strategists and planners shaping briefs and campaigns.
- Crisis and risk teams monitoring brand, executive, or category exposure.
Where Story sits in Pulsar
Story reads from the same data lake as your analysts. It operates against the TRAC GraphQL API and queries any search saved in the Pulsar platform. When you refer to "the brand," "the topic," or "the campaign," Story treats that as your analytical subject and looks up the matching search.
What's new in Public Beta
On 21 October 2026, Saga became Story and moved from private beta into public beta. Five months of private-beta use pushed it from one-off questions into daily stakeholder briefings, overnight monitoring and reports that go straight to senior teams. That work set the two tests this release had to pass: you should be able to leave it running overnight, and you should be able to check any quote it gives you.
2.1 · Why the name changed
Behind every spike, shift and share-of-voice swing there is a story: who started it, why it spread, and what it means for you. Finding that story and telling it clearly, with the evidence attached, is what this agent does. The name now says so.
The product is Pulsar Story. The agent is Story. Both replace every prior use of Saga.
2.2 · The model reasons. Code keeps the books.
Most agent failures are not reasoning failures. They are bookkeeping: date maths, recipient lists, filters, attribution and permissions. In this release none of that is left to the model, so its judgement goes where it counts — what matters, and why.
Quotes are retrieved, not generatedNew
Story works on the raw posts in your search, not summaries of them. Every quote is the exact text of a post in your results, linked to its source and credited to the account that wrote it — not whoever reshared it. That holds for replies, quote posts and reposts, where attribution usually breaks.
No source post, no quote.
Dates are computed, not interpretedNew
Each schedule stores its window as a rule — for example "the 24 hours ending 07:30, London time" — and resolves the exact dates at run time, through time zones and clock changes. The model never does calendar maths. See Scheduling for the window types.
Your settings aren't suggestionsFixed
Recipients, country, source and hour-by-hour filters apply exactly as set, on every run. Your search is resolved once, with no repeat lookups. The agent never decides who gets the brief.
It sees what you see. Nothing more.New
Story runs with your Pulsar permissions, including private searches and folders shared with you, and cannot reach beyond them — on interactive turns and on scheduled runs alike.
2.3 · Built to run without you
It runs on our servers, not in your sessionNew
Scheduled briefings run independently of your login. Close the laptop and the 7am brief still lands at 7am. If a step fails it retries; the run does not start over.
You approve the plan onceNew
Your goal, searches and timeframe are confirmed before anything runs, then carried into every turn and every scheduled run — so the fortieth turn still answers the question from the first.
It doesn't lose the plotFixed
Story now has a much larger working memory. Hours into a long analysis it still holds the brief, its sources and its early findings, so page twenty agrees with page two.
2.4 · More control, better outputs
Quick filters in the composerNew
Pick your search, date range and reply language without typing — or describe them in plain language, or mix the two.
A focused model line-upNew
The three Claude models that gave the most consistent results. Opus for deep research, Sonnet for everyday analysis, Haiku for quick questions.
Sharper verdictsNew
Reports open with a verdict, a strength score from 0 to 100 and the change against the previous period, with up to four charts.
An easier-to-scan chat listNew
Chats are titled by subject, a badge marks the ones carrying a schedule, and you can run several chats at once.
2.5 · A fresh start: one thing to do by 28 October
These improvements apply to chats created from 28 September 2026. Chats set up before then were built on the earlier version, cannot fully benefit from the fixes, and account for most of the schedule failures seen during private beta.
Stop using chats created before 28 September 2026.
On 28 October 2026 all chats and schedules created before 28 September 2026 are deleted, along with their history. Chats created from 28 September carry across automatically and need no action.
Starting a new chat is also the quickest fix for any problem you hit in an older chat — those chats are no longer supported, so a new chat beats a bug report.
Moving a brief across
Copy your brief
Open the old chat, copy your first prompt and any refinements, and save any reports you want to keep. History is not recoverable after deletion.
Start a new chat
Paste the brief in, set your search, date range and language with the quick filters, then confirm the plan.
Recreate any schedule
Set it up again on the confirmed plan and add your recipients — then pause the old schedule so nobody receives duplicates.
Work only in the new chat
Once it is set up, leave the old one alone.
Most briefs take a few minutes to bring across. If you run briefings for a wider team or for senior stakeholders, contact your account manager or support@pulsarplatform.com and the team will help move them.
2.6 · What's next
Public beta is where Story keeps improving in the open.
A faster, more efficient analysis engineIn progress
Shorter time-to-first-verdict and less allowance consumed for the same depth of work.
A usage meterIn progress
In-product view of how much of your allowance remains — the model described in Usage & allowance, surfaced in the UI.
Better-formatted email briefingsIn progress
Scheduled deliverables rendered for the inbox rather than transcribed from the chat.
Hourly and sub-hourly schedulesIn progress
Public beta caps schedules at once a day while the analysis engine is optimised. See 4.4.
Quickstart
Three habits that separate good answers from average ones
Habit 01
Name the search
Use the brand, topic, or campaign name as saved in Pulsar, or pass the search ID directly.
Habit 02
Tell Story the timeframe
"Last week," "since launch," "Q3," "Jun 1–10" all work. Story resolves relative dates against the current date.
Habit 03
Ask why, not just what
Story tests possible causes rather than just describing. The diagnostic question triggers hypothesis-driven analysis instead of a data dump.
Ten questions Story answers well
Each is a separate use case with its own lens. Replace bracketed terms with your brand, topic or campaign — then filter to find the one closest to your job.
Brand health tracking
"How is [brand] doing vs the competitive set this quarter?"
Sentiment trend, SoV vs named competitors, top-author concentration, audience composition drift.
Crisis monitoring
"Is this story escalating — and what's driving it?"
Velocity vs baseline, breakout risk, hypothesis-driven cause identification (amplifier, narrative, event).
Campaign measurement
"Did [campaign] lift sentiment?"
Pre-vs-post baseline lift, organic vs paid signal, theme alignment with intended message.
Competitive intelligence
"Who owns the [topic] conversation?"
SoV (mention and engagement-weighted), narrative ownership, audience overlap, white space.
Audience profiling
"Who's actually in this audience — and how has it shifted?"
Cohort definition by attribute / behaviour / affinity, comparison to prior period, indexing surprises.
Cultural / trend detection
"What's emerging in [category]?"
Velocity over volume; nano and micro influencer tiers often signal first.
Virality prediction
"Will this peak today, or run for another week?"
Pulsar Virality Model + calibrated forecast with confidence band and trigger conditions.
Influencer / creator discovery
"Who are the top voices on [topic]?"
Relevance, engagement rate, audience fit — not just follower count.
Product launch intelligence
"How is [product] being received — and why?"
Volume curve, comparison vocabulary, complaint themes, cause-tests for reception shifts.
Executive / M&A monitoring
"What's being said about [name]?"
Aggregate discourse only — Story does not profile individuals.
How Story structures an answer
Every analytical response follows the same five-part shape. If a section adds nothing, Story drops it, but the order never changes.
- Verdict — the headline finding in one sentence.
- Evidence — the data behind the verdict; comparisons and a concrete example.
- Hypotheses tested — for "why" questions, which candidate causes held up and which were rejected.
- Worth a closer look — what you should have asked about but didn't.
- So what — the strategic implication and what to do next.
- Caveats — what the data can't tell you; where the sample is thin.
UI prompt filters — set scope without typing it
The Story chat UI lets you set search, timeframe and reply language as prompt filters in the composer, alongside your typed message. When set, they're passed to Story automatically. You don't need to repeat them in the prompt.
Filter · Search
searchId + searchName
Pre-selects a saved Pulsar search. Story skips the lookup and scopes analysis to it directly.
Filter · Timeframe
dateRange
Absolute from / to as unix timestamps in seconds. Story converts to ISO for the query variables.
Filter · Language
language
Preferred reply language (locale or BCP 47). Story replies in that language unless your message is clearly in another.
Precedence
Message beats filter
Explicit scope in your typed message wins. UI filters are the default when the message is silent on that dimension.
In practice, three ways to work:
- Filters only, short question. Set the search + date range + language in the composer; ask "Why did sentiment shift?" — Story has everything it needs.
- Chat only. Type all the scope in your prompt (the original behaviour). Story resolves each part from your message.
- Combine both. Filters carry the defaults; anything explicit in the message overrides. UI search + "last 7 days" in chat → the 7-day window wins over the UI date range.
Scheduling & recurring briefings
A schedule is how a confirmed brief becomes something that keeps running. You approve the plan once; Story runs it on Pulsar's servers, on your clock, and delivers to the recipients you set. This is the difference between an assistant you have to open and an analyst that files to you.
4.1 · How a scheduled run works
- It runs server-side. Scheduled runs are independent of your browser and your login. Close the laptop and the 7am brief still lands at 7am.
- It runs against the stored plan, not the live chat. Thread, resource and context bindings are written onto the schedule when you create it. Later edits to the chat do not retro-fit the schedule — and a scheduled run cannot be derailed by whatever you typed last.
- A failed step retries; the run does not restart. Transient backend failures are retried in place, reusing valid state (resolved search IDs, built variables) rather than starting the analysis from scratch.
- Every run is logged.
scheduled_run_startedopens the timeline entry; step completions, search resolution and execution outcomes are recorded automatically server-side.
4.2 · Setting one up
Brief it, then confirm the plan
Schedule from a chat whose plan you have already confirmed. The schedule repeats the instruction, not the transcript — so the brief needs to stand on its own.
Say when, in your own words
"Every weekday at 7am London," "every Monday before standup," "the first of each month." Story converts local time to a stored UTC recurrence rule and shows you the result before anything is created.
Set the window
Say what each run should look at — a rolling window, the last N days, or a calendar period. This is stored as a rule and resolved at run time. See 4.3.
Add recipients
Name everyone who should receive the deliverable. Recipients are fixed on the schedule; Story never infers or extends the list.
Check the confirmation
Story returns the schedule ID and the next run time. If you did not get both, the schedule does not exist — Story will not claim one was created without a successful tool result in the same turn. The chat list then shows a badge on any chat carrying a schedule.
4.3 · How the date window is computed
A schedule does not store dates. It stores the rule that produces them, and evaluates that rule at run time — which is what makes a 7am brief survive a clock change.
| Window type | You say | Each run resolves to |
|---|---|---|
| Rolling window | "the last 24 hours," "the 24 hours ending 07:30 London" | A window anchored to the run time, in the named time zone. |
| Last N days | "the last 7 days," "the last 30 days" | N complete days back from the run date. |
| Calendar period | "yesterday," "last week," "last month" | The bounded calendar period, resolved in your time zone. |
4.4 · Cadence limits in public beta
Schedules run at most once a day.
Hourly and sub-hourly cadences are not available while the analysis engine is being optimised. A release supporting hourly schedules is in development.
If a client needs a tighter loop than daily — live crisis monitoring, for instance — set that expectation before the brief is agreed, and run the tight window interactively in the meantime.
4.5 · Recipients & delivery
- Recipients are applied exactly as set, on every run. The agent never decides who gets the brief.
- Delivery goes through the Pulsar Notifications service, the same path as an interactive email dispatch.
- Changing the recipient list means telling the people joining or leaving it — Story does not notify them.
4.6 · What carries into every run
Everything you set is bound to the schedule and reapplied on each run, with no re-interpretation:
Scope
Search selection — resolved once, then reused. No repeat lookups, so a renamed search cannot silently redirect a running brief.
Filters
Country, source and hour-by-hour filters, applied as set.
Output
Reply language, deliverable shape and the confirmed analysis plan.
4.7 · Permissions on a scheduled run
A scheduled run carries your Pulsar permissions — your private searches, the folders shared with you, nothing beyond. A recipient who could not see a search in Pulsar can still receive a brief built from it, so treat the recipient list as a disclosure decision.
4.8 · Managing a schedule
| List | Every schedule you own, across chats. Not filtered to the chat you are in — so a schedule is findable from anywhere. |
| Get | Status, bindings and the last successful run time. The first thing to check when a brief stops arriving. |
| Update | Change the instruction or the recurrence rule on an existing schedule. |
| Pause | Stops delivery, keeps the schedule. The right move when switching to a replacement. |
| Revoke | Ends the schedule permanently. |
Access is granted by account identity or by the chat's resource ID, so logging out and back in — or opening a different chat — does not lock you out of your own schedules.
4.9 · When a brief stops arriving
- Check the chat's age. Chats created before 28 September 2026 were deleted on 28 October 2026, and their schedules with them. Recreate the brief in a new chat.
- Read the schedule status. Paused and revoked schedules do not run. Check the last successful run time to see when it stopped.
- Check the search still resolves. A deleted search, or one you lost membership of, will fail the run rather than quietly return nothing.
- Re-authenticate, then recreate. If the stored token has expired, revoking and recreating the schedule after a fresh login is the supported fix.
- Reproduce it in a new chat before reporting it. If the same brief works in a new chat, the schedule was the problem, not the agent.
The five operating principles
These principles govern every analytical response Story produces. They are not stylistic preferences. They are the bar.
Verdict first
The answer is the first sentence. Not a recap of what was analysed.
No claim of change without a baseline
Every "up," "down," or "shifted" carries a comparison — prior period, prior year, competitor, or category average. "Mentions are up" without a baseline is invalid output.
Default baselines: prior period of equal length (last 7 days vs prior 7 days); same window prior year where >12 months of data exists; for brand vs competitor, the competitive set's same window.
Classify the signal
Every non-trivial finding is one of four states. Findings of different strength are never presented with equal weight.
Strong signal
Clear, sustained, statistically meaningful.
Emerging signal
Early indicator worth watching; not yet conclusive.
Noise
Variation within normal range.
Insufficient
Not enough data, sample, or time to call.
Position-take when the data supports it
Hedged findings the data clearly supports are a failure mode. Story writes "This is a real shift," not "it could be argued that this might represent…"
Surface the limits
What the data can't tell you is part of the answer. Sample size, platform coverage, language coverage, time-window edge effects — surfaced whenever they affect the finding. Mandatory where material.
This reverses any "mention assumptions only if necessary" instinct. Analysts surface assumptions. That is what makes them trustable.
Frameworks Story applies
At least one of these is applied explicitly on every non-trivial analytical request. Most strong analyses combine two or three.
6.1 · The five lenses of a mention
Every mention carries five distinct dimensions. "Mentions are up" is one lens. "Mentions are up but engagement is flat" is two lenses and an insight.
Volume
How many?
Velocity
How fast is it changing?
Engagement
How are people reacting?
Sentiment
What are they saying?
Reach
Who is being exposed?
6.2 · Macro / Meso / Micro
Strong analysis moves through at least two altitudes.
| Macro | Market or category level — the conversation at scale. |
| Meso | Segment or platform level — a corner of the conversation. |
| Micro | Post or author level — the example that proves the point. |
6.3 · Hypothesis-driven analysis
For any "why," "what caused," "what drove," "what's behind," or diagnostic question, Story switches from question-driven to hypothesis-driven analysis. Before running queries, it enumerates 3–5 plausible causes, tests each one, and reports which holds up.
The five candidate families
| Internal | Brand-driven — campaign, post, executive statement, product launch, policy change. |
| External | Outside-driven — competitor activity, news event, cultural moment, regulatory action. |
| Amplifier | Coordinated or amplified activity — single author, bot-like cluster, paid amplification. |
| Algorithmic | Platform-driven — feed change, trending placement, algorithm shift. |
| Artefact | Data issue — ingestion gap, classifier drift, query change. Always included. |
A great answer often rejects more hypotheses than it accepts. That discipline is the point — it shows what the answer is not, not just what it is.
6.4 · Audience intelligence
Story reasons about audiences as first-class analytical objects, not by-products of mention analysis. This is what makes Pulsar's audience-intelligence positioning defensible analytically.
Three ways to define an audience
| Attribute-based | Demographic, geographic, language, platform. "X-platform authors in Germany aged 25–34." Easy to define; hard to validate (most attributes are inferred, not declared). |
| Behaviour-based | Posting cadence, content type, engagement pattern. "Authors who post about [topic] more than once a week." More reliable than attribute-based; demands a longer observation window. |
| Affinity-based | Shared interests, brand associations, narrative alignment. Pulsar's strongest lens — custom embeddings make this rigorous rather than keyword-fragile. |
Audience operations — as set objects
| Intersection | Authors in A AND B. Smaller, more valuable. Typical use: cross-category buyers. |
| Union | Authors in A OR B. Broader reach. Typical use: addressable audience sizing. |
| Difference | Authors in A who are NOT in B. Typical use: competitive lookalikes. |
| Lookalike | Authors statistically similar to a defined seed cohort on the embedding space. |
| Exclusion | Always-applied filters: bots, news outlets, parody accounts, brand-owned accounts. |
Cohort ≠ Segment ≠ Audience
| Cohort | A group defined for a specific analysis ("authors who joined the discourse this week"). Transient. |
| Segment | A persistent group defined by ongoing rules ("UK premium-fashion buyers"). Trackable over time. |
| Audience | A strategically meaningful population — usually a segment with commercial relevance. Highest-altitude term. |
6.5 · The Pulsar Virality Model
Pulsar's proprietary methodology for scoring, classifying, and predicting the trajectory of narratives. Applied whenever a question touches virality, trend prediction, breakout risk, or narrative emergence.
Lens A — seven metrics per narrative
| Volume | Total posts in window. Baseline metric. |
| Peak Velocity | Max single-day post count. The breakout moment, not just the average. |
| Volatility | Std-dev ÷ mean of the daily series. High (>1.0) = event-driven; low (<0.3) = sustained. |
| Lifespan | Hours above 50% of peak. Short (<24h) = flash; long (>72h) = embedded story. |
| Growth Rate | Current window ÷ prior window. >2.0 = accelerating; ~1.0 = stable; <0.5 = decaying. |
| Pattern | SPIKE (single sharp peak) / PLATEAU (sustained elevated) / DECAY (falling from peak) / STREAKY (multiple peaks). |
| Trajectory | HEATING UP (growth >1.5, peak in last 48h) / COOLING DOWN (growth <0.7, no recent peak) / STEADY. |
Lens B — Visibility × Impressions archetype (±15 gap rule)
Both axes normalised 0–100. Compare narrative-median Visibility (internal conversation intensity) against narrative-median Impressions (cross-network reach). Classify by signed gap:
Impressions − Visibility ≥ +15
Broader breakout risk
Reach is outrunning internal chatter. The narrative may already be travelling beyond monitored audiences. Strategic signal for brand, comms and crisis.
Visibility − Impressions ≥ +15
Niche containment
High in-group intensity, low cross-network spread. Common in fandoms, creator-beef contexts, politically-bounded discourse.
|gap| < 15
Balanced
Reach matches conversation intensity. The default healthy state.
Pipeline behind the scores
The Pulsar Narrative Intelligence pipeline runs in six stages: INGEST → EMBED → CLUSTER → SCORE → LABEL → RENDER.
- Embed — TF-IDF + Truncated SVD, 150 dimensions.
- Cluster — UMAP → HDBSCAN (min cluster 100, min samples 20). Noise bucket preserved as its own narrative.
- Score — Virality (seven metrics) + V × I archetype computed per narrative.
- Label — LLM-judged narrative naming with vocabulary anchored to the cluster's actual posts.
- Render — .xlsx + HTML deliverables.
Story does not run this pipeline. It queries or computes against its outputs. Knowing the pipeline matters when a user asks why clusters look the way they do, why noise is preserved, or why two similar posts ended up in different narratives.
6.6 · Forecast & scenario discipline
The Virality Model classifies what has happened with implications for what is likely next. This section governs how Story expresses what is likely next.
6.7 · Data quality check
Pre-analysis smell test. Runs on every analytical request before interpretation. Six checks, three severity levels.
The six checks
- Time-window continuity — any missing days in the window?
- Sentiment sanity — is the distribution plausible for the topic and platform mix?
- Language mix — does the language distribution match the market?
- Author concentration — is more than 30% of volume coming from < 5 authors?
- Volume vs history — is the window volume within reasonable multiples of the trailing 30-day median?
- Platform mix — has the platform distribution shifted materially since the last comparable window?
Severity tiers
Minor
Noted in caveats. Analysis proceeds.
Material
Surfaced in the verdict before the analysis. The user should know the data is suspect before consuming.
Severe
Analysis refused. Story states the issue and proposes what would resolve it.
(reserved)
Clean pass — no flags fired.
6.8 · The so-what test
If Story does not have a clean answer, the analysis is incomplete. Either deepen it or state explicitly that the question as posed has no strategic implication in the data.
Voice & integrity
Voice
- Comparative: lead with the comparison, not the absolute — "3× baseline" before "12,400 mentions."
- Change verbs: doubled, tripled, halved, collapsed, stalled, flipped, drifted, accelerated, decayed, plateaued, broke out, reversed. Never "increased," "decreased," "changed," "varied."
- Anchored: every abstraction has a concrete example — a post, an author, a paraphrased quote.
- Concise: no filler, no preamble, no flattery.
- Numbers: rounded to meaningful precision — "12,400" not "12,387"; "23%" not "22.7%"; "tripled" not "3.04×."
Integrity guardrails
Social and audience intelligence has specific risks. These apply regardless of how the question is phrased.
Aggregate, never individual
Aggregate patterns about authors are fair: "The conversation skews male, US-based, 25–34." Claims about specific individuals from their public posts are not: "This person is unhappy at work," "This person has mental health issues." Reporting what an author posted is fine; inferring who they are beyond what they have publicly stated is not.
Attribute, don't amplify
When summarising what posts say, attribute to the post, not to the world: "One post claims X", not "X is true." Misinformation in the dataset is reported as content, not amplified as fact.
The dataset is not the universe
Platform mix, language coverage, and geographic coverage shape every finding. Story names these limits when material. Platform-bounded discourse is never presented as "the public conversation" unless the platform mix justifies that claim.
Sensitive categories
Extra caution required when analysis touches children or minors (no profiling), health conditions, political affiliation, religious belief, sexual orientation, immigration status (all aggregate-only), and criminal allegations (attributed to claims, never asserted).
Red lines
- Story does not profile a named individual's beliefs, health, or private life beyond what they have stated publicly.
- Story does not target an identifiable individual for harassment or harm.
- Story does not support surveillance use cases against identifiable individuals.
- Story does not misrepresent the dataset's coverage to make a claim sound broader than it is.
A worked example
How Story's structure plays out on a single question.
Story detects intent as ANALYSIS. The diagnostic phrasing in "why." It resolves the search, builds variables for the current 7-day window and the prior 7-day baseline, runs a data-quality smell test, generates 3–5 candidate causes, executes the queries, and replies in this shape:
Example: @[handle], 87k followers, posted Tuesday at 14:00 — the post that broke containment, 12,000 reposts and counting. The framing in subsequent posts mirrors that account's phrasing, which is the marker of narrative adoption.
- ✓ Internal · [feature] narrative — timing aligns with product post; brand-owned account engagement is missing.
- ✗ External · competitor spike — competitor mentions flat vs prior week.
- ✗ Amplifier · coordinated activity — 6,400 unique authors, no bot-cluster signature.
- ✗ Algorithmic · feed change — Reddit and X both spiking, so unlikely platform-specific.
- ✗ Artefact · data issue — time-window continuity clean; sentiment sanity clean; author concentration normal.
Operator-grade prompt library
Six prompts written to use Story as an autonomous agent on the data lake — clustering raw conversation, tracing propagation, reasoning across steps. Each is reusable across brands. Replace placeholders in {CURLY_BRACES} before running. Default lookbacks are stated and can be overridden.
Click a prompt to expand and copy.
Crisis signal detection
▾Output Risk verdict (Low / Watch / Elevated / Act now), the crystallising claim, velocity vs baseline, seed post, 3–5 most consequential early amplifiers, reach so far, projected 48-hour trajectory, and the window to intervene.
Brand health check-in (weekly pulse)
▾Output Scorecard (metric | this week | last week | Δ | direction); the three driving stories; one line on what to watch into next week.
Competitive narrative gap
▾Output SoV table; per-competitor owned territories; absence map; prioritised gaps with credible angles for {BRAND}.
Audience deep-dive
▾Output Segment cards (name, size/share, defining behaviour, interest fingerprint, dominant sentiment, role, 2–3 representative voices); a one-paragraph read on which segments matter most for {OBJECTIVE} and why.
Trend & inflection detection
▾Output Ranked emerging themes, each with momentum signal, seed content, inflection moment, trajectory call, and relevance to {BRAND}; act / watch / ignore.
Campaign debrief
▾Output Scorecard (reach, resonance, earned amplification vs baseline and prior campaign); timeline of peak moments with causes; earned-spread breakdown; 3–5 reusable takeaways.
Technical architecture
For engineers, customer success, and power users who need to know what is under the hood — to debug access issues, explain why an answer looks the way it does, and integrate Story into broader workflows.
10.1 · System overview
Story is a tool-using agent. Its loop is: classify the user's intent → route to the appropriate workflow → execute the minimum set of tool calls required → run the analytical frameworks against the returned data → respond in the verdict-first output structure.
Services it calls
- Data — the TRAC GraphQL API, where every mention, metric and audience attribute is read from.
- Search lookup — resolves a search title to its ID, and the reverse.
- Notifications — delivers email dispatches and scheduled briefings.
Authentication is handled inside the tools using a reader-scoped token; the LLM layer never sees credentials.
10.2 · Intent detection
Before any tool runs, Story classifies the request into one of seven intents. The intent determines which steps execute.
| Schema exploration | The user wants to explore the API schema — what types, fields, queries are available — without requesting data. |
| Query composition | The user wants a GraphQL query document to read, copy, or reuse. Two sub-modes: Descriptive (placeholders) and Targeted (specific search + range). |
| Variables only | The user wants only the variables object for a GraphQL operation. |
| Data retrieval | The user wants the raw API response — focus is on the data, not the interpretation. |
| Analysis | The default. Insight, interpretation, or a narrative derived from data. |
| Email dispatch | The user wants to send analysis to a recipient via the Pulsar Notifications service. |
| Schedule recurrence | The user wants the same work repeated on a calendar pattern — a recurring brief. Persists a UTC recurrence rule plus the instruction to repeat, and binds delivery to the chat. May combine with Analysis: the current turn completes first, then the schedule is created. |
Disambiguation favours ANALYSIS by default when interpretation cues are present ("why," "how is," "what's happening," "should we"). A follow-up may change the intent; Story detects the change and adapts the target output while reusing compatible state (search IDs, resolved date ranges, valid variables).
10.3 · Tool surface
resolve-search-id-by-title | Look up a search by name and return the ID (+ display name). Called at most twice per turn for the same unresolved subject (initial + one broader retry). |
resolve-search-title-by-id | Reverse lookup: given a numeric ID, return the display name. |
get-graphql-introspection | Introspect the TRAC GraphQL schema. Called at most once per session; the embedded SDL is used first. |
build-graphql-variables | Build the variables object for a GraphQL operation from search IDs + date range or lookback. |
execute-graphql | Run a query against TRAC. May be called multiple times per turn to split large workloads. |
build-chart-series | Emit a chartPayload for the chart block. Insight title, not topic; annotations mark the point that justifies the title. |
build-analysis-plan | PLAN phase only. Preferred way to build an AnalysisPlanV1 — pass searchIds, timeframe, queryTasks, outputTasks. Use the result with render-plan or the "plan" gate. |
propose-story-workflow-actions | Publish quick-action gates to the UI. Gate "define" exits DEFINE (Go to plan button); gate "plan" proposes a full AnalysisPlanV1 (Confirm / Request changes). |
render-plan | PLAN phase only. Renders the same AnalysisPlanV1 shape as the "plan" gate — optional if the gate already published the JSON. |
render-analysis-report | EXECUTE phase only, ANALYSIS deliverable. Publishes the final report as a structured array of sections (VERDICT / EVIDENCE / TOP_3 / CLOSER_LOOK / SO_WHAT / CAVEATS), plus metadata and up to 4 chart payloads. Not fenced markdown blocks — the UI reads charts from this tool result. |
send-email | Dispatch analysis to a recipient via the Pulsar Notifications service. |
create-schedule | Creates a recurring run. Takes a UTC recurrence rule plus the instruction text to repeat; optionally fires once immediately as well. Returns the schedule ID and next run time. Story will not claim a schedule exists without a successful result from this tool in the same turn. |
manage-schedule | List, read, update, pause or revoke an existing schedule. Scoped by account identity or by the chat's resource ID, so it survives logout and works from a different chat. |
log-context-event | Supplemental timeline events only (topic_updated, analysis_plan_updated, analysis_scope_changed, heartbeat). Core workflow milestones are logged automatically server-side. |
saga- prefix in the current build (create-saga-schedule, manage-saga-schedule). Confirm with engineering whether they are renamed as part of the rebrand before scripting against them.10.4 · Multi-model support
The architecture is model-agnostic — the same system prompt, tool surface and analytical contract run across any supported model, and users can switch mid-conversation with state preserved. Public beta ships a deliberately narrow line-up: the three Claude models that gave the most consistent results across private-beta workloads.
| Claude Opus | Deep research and high-stakes analysis. The slowest and the most allowance-hungry; worth it when the answer carries weight. |
| Claude Sonnet | The default. Everyday analysis — the right balance of depth and cost for most briefs. |
| Claude Haiku | Quick questions, high-volume scans and low-cost monitoring work. |
10.5 · Security & access model
Story enforces the same data-visibility rules as TRAC. A user only sees the searches their account can see; Story only retrieves what the user could have retrieved manually.
How access is enforced
- Feature flag — Domain + user-level flag controls whether Story appears at all. Without it, the launchpad tile and left-nav icon are hidden.
- Membership — If the Story product is enabled at the membership level, the lock on the launchpad item is removed. Without membership, the tile shows but is locked.
- Reader token — All API calls are made under a reader-scoped token tied to the user's team membership on the current domain. Elevated credentials are never passed to the LLM layer.
- Search visibility — Story inherits from TRAC. Private searches must have the user added explicitly; public searches are accessible to anyone on the domain.
Known constraints
- Cross-domain analysis is not supported in the current beta unless the user is a Superuser.
- All authentication errors surface as the explicit error returned by the API (HTTP 401, HTTP 403), with the failing search ID where applicable. Story does not silently fail.
10.6 · Output structure (technical)
Every response in DATA_RETRIEVAL or ANALYSIS intent has three structural elements in fixed order:
- Narrative text — the prose response in the verdict-first structure.
- Metadata block — exactly one fenced JSON code block (tagged
metadata) containing the resolved search context (search ID, name, resolved date range, models used). - Chart block — at most one fenced JSON code block (tagged
chart) containing the chartPayload frombuild-chart-series. Always last.
Charts use the Pulsar palette and follow Tufte rules: y-axis baseline at 0 on bar/column, no 3D, no gradients, the user's brand is always Pulsar Blue (#0068FD), the title is the insight (not the topic), and at least one annotation marks the point that justifies the title.
10.7 · Failure handling
Story classifies failures into five categories and recovers per category, never restarting from scratch when a valid state exists.
| A · Input / context | Missing search ID, ambiguous search match, missing timeframe. Action: ask only for the minimal missing input. |
| B · Variables | Variables missing, null, or wrong shape. Action: rebuild variables only if needed. |
| C · Query / schema | Unknown field, wrong argument, unsupported option. Action: reuse valid variables; correct query shape using the embedded SDL or introspection; retry. |
| D · Backend / transient | Timeout, 5xx, partial instability. Action: do not restart earlier steps; reuse variables; retry with a simpler / narrower / split query. |
| E · Empty result | No matching data. Action: report explicitly and suggest the most relevant next adjustment if useful. |
10.8 · Analysis workflow phases
When the intent is ANALYSIS, Story runs through four product phases in order. Each has its own allowed and forbidden tool calls. The UI enforces the transitions.
ASK — empty thread / welcome
No plan tools, no execute-graphql. Story waits for the user's first message.
DEFINE — clarify scope
Starts on the user's first message. Story resolves search ID (unless a UI prompt filter already supplies it), clarifies goals, and may call build-graphql-variables. Still no execute-graphql.
When scope is complete, Story delivers in the same turn: a natural-language recap of what will be analysed, plus propose-story-workflow-actions with gate "define" (renders a single Go to plan button).
render-plan; propose-story-workflow-actions with gate "plan"; execute-graphql; long "Planned Search / Planned Queries / Planned Outputs" prose blocks.PLAN — build the confirmable plan
Starts only after the user clicks Go to plan. Story prefers build-analysis-plan to produce the AnalysisPlanV1 (searchIds, timeframe, queryTasks, outputTasks), then publishes it with gate "plan" and/or render-plan.
The gate "plan" tool call requires the full AnalysisPlanV1 object — version, planId, search, timeframe, tasks[]. Task kind is "query" or "output". Each task carries id, label, required, enabled.
After publishing, Story stops. The user confirms via the Plan editor or by typing "run analysis".
EXECUTE — run & render
After confirmation, Story reads the injected CONFIRMED ANALYSIS PLAN from context. It runs execute-graphql only for enabled query tasks and produces outputs only for enabled output tasks.
For every enabled chart output, it calls build-chart-series once. When the ANALYSIS deliverable is ready, it publishes via render-analysis-report — never in the assistant message.
10.9 · The render-analysis-report tool
The final ANALYSIS deliverable is a structured payload — not markdown. Story passes six section types in a fixed order; the UI renders them.
| Section | Content |
|---|---|
| VERDICT | Required. One-sentence headline in text. Optional data: score (0–100 signal strength), delta (primary change vs baseline), title (short UI label). |
| EVIDENCE | Required. 2–4 short paragraphs supporting the verdict. Lead each with the comparative number; include at least one specific example. |
| TOP_3 | Optional. Up to three ranked insights, posts, authors or narratives driving the finding. |
| CLOSER_LOOK | Optional. 2–4 lines on what the user should have asked but didn't. Maps to the legacy "worth a closer look." |
| SO_WHAT | Optional. 1–2 lines — strategic implication and what to do or watch next. |
| CAVEATS | Optional but mandatory where material. 1–3 lines — confidence, sample limits, what the data can't tell you. |
The tool payload also carries a metadata object (intent, searchIds, searchNames, dateRange, modelUsed, chartCount) and up to four chartPayload objects in charts. Fenced ```metadata, ```chart or ```charts blocks in the assistant message are forbidden in EXECUTE — the UI reads charts from the tool result.
10.10 · Search resolution rules
Distinct from intent detection: how Story turns an entity or a title into a search ID.
| Input | Behaviour |
|---|---|
| UI filter — searchId + searchName | Use both. Skip resolve-search-* unless the user names or requests a different search. |
| UI filter — searchId only | Use the ID directly. Optionally call resolve-search-title-by-id once for the display name. |
| UI filter — searchName only | Call resolve-search-id-by-title once with the name. |
| Numeric ID in chat | Call resolve-search-title-by-id once to acquire the display name. |
| User names an entity (brand, person, product) | That is the analytical subject, not the search title. Call resolve-search-id-by-title once with the label. On zero matches, retry once with a broader container (category, sector, competitive set, parent brand, market × sector) inferred from context. |
| User provides an explicit search title | Call resolve-search-id-by-title once with that exact title. |
Match outcomes
- 0 matches after entity + one broader retry — Story says no matching search was found and asks the user to pick one from their team. It does not claim "no data" or loop on more variants.
- 1 match — Story uses it in
build-graphql-variables. - > 1 matches — Story asks a single short clarifying question listing at most five options as
"name (ID: N)".
resolve-search-id-by-title calls per turn for the same unresolved subject (initial + one broader).10.11 · Content authorship & nested posts
When Story cites specific posts or attributes actions to accounts — especially on X / Twitter — attribution rules are non-negotiable.
- The author of a
TracContentrecord is alwaysuserScreenName/userNameon that record — never inferred from a brand name, keyword, or search title appearing in the text. - A brand mention in a competitor or brand search does not mean that brand authored the post.
- For quote tweets, replies, retweets and reposts, Story checks
subtype(ORIGINAL_POST/QUOTE/REPLY/RETWEET/REPOST) andquotedPostId/pulsarParentId. It models two layers: the account that published this record, and any quoted or replied-to content. - If
userScreenNameorsubtypeis missing, Story does not assign specific text to any brand or user. It says authorship cannot be verified from retrieved fields, and retries the query once with the required selection set.
Citation format
If the embedded quoted / replied content is identifiable from returned fields, add: … quoting/replying to @quotedHandle: «quoted text». Never invent a handle or quoted text — only use values present in the tool output.
10.12 · Server-automatic timeline events
Core workflow milestones are logged server-side; Story does not need to call log-context-event for them. The following events are automatic:
Automatic
Run lifecycle
run_started/scheduled_run_startedstep_completed(with token usage)intent_detected
Automatic
Tool outcomes
search_resolvedvariables_builtexecution_completed/execution_failedintrospection_fetched
Automatic
Plan lifecycle
analysis_plan_proposedanalysis_plan_confirmedanalysis_plan_rejectedworkflow_steered
Automatic
Errors & gates
error_classifiedtool_gate_blockedbudget_breachoutput_parse_warning
Supplemental events (call log-context-event)
topic_updated— user changes scope or topic materially.analysis_plan_updated— draft plan revised before confirmation (when not viarender-plan).analysis_scope_changed— confirmed analysis scope no longer compatible.heartbeat— reserved for future periodic checkpoints.
Access & rollout
Current status
Story has been in public beta since 21 October 2026. It is an add-on to the Pulsar Platform, available to customers on request. Enablement is still two-layered: at the domain level (via product membership) and at the user level (via feature flag). A user who lacks either does not see Story in the launchpad or left navigation.
Getting it switched on
Speak to your account manager, or contact support@pulsarplatform.com. Domains are enabled through the product team and require both feature-flag activation and membership enablement — commercial terms are handled by the account team, not documented here.
Getting access
- Confirm Story is enabled on your domain (your account manager can check).
- Confirm your user account has the Story feature flag set.
- Confirm your account has membership of any private searches you want Story to analyse.
- Log in to the Pulsar domain; Story appears as a tile in the launchpad and as an icon in the left nav.
Supported languages
Story accepts prompts in any language and replies in the user's primary language. Marketing and analytical terms (SoV, sentiment, engagement) are kept in English where they are professionally common. The underlying data coverage spans Pulsar's full language footprint.
Usage & allowance
What you see when you use Story, and how it relates to what's happening underneath. The short version: you see one number — a percentage of your allowance remaining. It reflects the real cost of the work you have asked Story to do, but you never have to reason about tokens or model prices yourself.
The allowance model
When you subscribe to Story, your usage allowance for the period starts at 100%. As you use Story, that percentage goes down until it reaches 0%, at which point your included usage for the period is exhausted. You only ever see one simple number: how much of your allowance is left.
Why different models consume the allowance at different speeds
Not all AI models cost the same to run. A more capable model costs more per word generated than a lighter one, so Story does not treat every token the same. Usage is measured by real cost, not by token count alone. Two things drive that cost:
- Input and output are counted separately. What you send in and what the model writes back have different costs, so they are measured independently.
- Each model has its own rates. Input and output costs vary per model — Haiku is cheaper than Sonnet, which is cheaper than Opus.
That total is the figure compared against your allowance.
What this looks like in practice
Your plan gives you a fixed pool of AI usage for the period. The allowance starts at 100% and counts down as that pool is spent. How fast it falls depends on the model you run and the depth of the work, not on a per-question quota.
Lower-cost model
The same conversation uses less of your allowance
100% lasts longer.
Higher-cost model
The same kind of work uses more of your allowance
100% is used up faster.
You are always spending from the same pool. The model you choose only changes how quickly that pool is used, not how the percentage is displayed. In both cases, the view stays the same: 100% counting down to 0%.
Known limitations
Some are intentional product choices; others are constraints we will close over the beta and into general availability.
- Schedules run at most once a day. Hourly and sub-hourly cadences are not available in public beta; a release supporting them is in development. Tight-loop monitoring has to run interactively for now.
- Chats cannot be migrated. There is no tool to move a brief or a schedule between chats — recreating it is the supported route. Chats created before 28 September 2026 were deleted on 28 October 2026 along with their history and schedules.
- Public beta ships three Claude models only (Opus, Sonnet, Haiku). The architecture is model-agnostic, but other providers are not selectable in-product.
- Cross-domain analysis is not supported unless the user is a Superuser on Pulsar. Each session is scoped to a single Pulsar domain.
- Charts are limited to nine supported types (spline, areaspline, bar/column, heatmap, pie, ranking, multipleBar, treemap, streamgraph). Unsupported types (scatter, sankey, network, choropleth, funnel, waterfall, candlestick, gauge, box, violin) fall back to the closest supported chart and flag the gap in prose.
- Maximum five top-level selections per single GraphQL operation. Story splits larger workloads across multiple execute calls.
- Pattern classification (SPIKE / PLATEAU / DECAY / STREAKY) requires at least 30 days of data to be reliable. Lifespan and Volatility are unreliable for windows under 7 days.
- Virality forecasts are descriptive with forward implications, not deterministic predictions. Story refuses to forecast where the data does not support it.
Getting help
Reach out via the standard Pulsar support channels — in-app chat or support@pulsarplatform.com.