Internal · 2026-08-04 · NiCE Organic Intel

How the system
actually works.

Nine workflows, one Supabase database, two places where a language model is allowed an opinion, and one point where a human takes over and writes. This page is the whole machine — what each part decides, on what number, and where the dials are. Nothing here is aspirational: if it is not built, it says so.

Written so the SEO detail and the management summary live on the same page. Body text is the summary; the collapsed blocks hold the node-level and prompt-level detail.

9
workflows live on schedule
8.4M
rows of first-party search history
0
published articles measured so far
19
steps still done by hand

01 — The loop

Six stages, and only one of them is a person

Blue steps are the machine. The coral step is where it stops and a human writes.

1 · Listen
Google News for our brand and 14 competitors, daily. SEMrush search demand on Mondays. Search Console every day.
machine
2 · Normalise
Every source is forced into one 12-field shape: topic, brand mentioned, which competitors, engagement, sentiment, date. One shared subworkflow, so a new source plugs in without touching the rest.
machine
3 · Judge
A fixed formula scores 0–70 on relevance, presence, engagement and recency. Claude then clusters and adjusts by −15…+30, and may only adjust for things the formula cannot see.
machine
4 · Shortlist
Score ≥40 reaches the Opportunity Board. ≥60 also goes out as a digest. Below 40 is recorded and dropped.
machine
5 · Brief → write
The highest un-briefed opportunity becomes a brief: angle, hook, keywords, formats, a LinkedIn post, a CTA. Then a person writes the article.
human
6 · Answer for it
Paste the published URL back in. 21 days later the system checks whether it moved anything. If it did not, the topic re-enters the board as a Refresh.
machine + 1 paste
The one design decision worth understanding
Every number that ranks or compares is computed by fixed arithmetic. The language model is allowed exactly two jobs: grouping related signals into one opportunity and nudging its score within a bounded range, and writing the brief. It never invents a score, never decides what passes a threshold, and never touches the measurement half.

That is not caution for its own sake — §03 has the incident that caused it.

02 — The nine workflows

What each one does, and what it decides on

Everything runs in n8n. Nothing runs anywhere else except Supabase and the hand-run analysis scripts noted in §06.

#What it doesRunsThe decision it makes
002Signal Spine — the daily engine. News in, scored opportunities out.07:00 dailyScores everything, then two gates: ≥40 to the board, ≥60 to the digest
004Normalise — forces every source into one 12-field shape.calledWhich topic (9 categories, first match wins), is our brand mentioned, which of 14 competitors
014SEMrush — search demand for 12 tracked keywords, plus discovery.MondaysDrops keywords under 50/month; new keywords need 200/month; max 10 new per run
015Search Console — our own search performance, both page and query level.07:30 dailyKeeps query rows at ≥10 impressions; page rows unfiltered
009Brief Agent — turns one opportunity into a writable brief.on demandPicks the highest-scoring un-briefed opportunity, excluding Intel-Only
010Web search — grounds the brief in current facts.calledUp to 4 sources; if empty, the brief is written ungrounded rather than failing
011Trend report — what is rising and dying, per topic and per company.Mon 08:00Last 7 days vs the 7 before; needs ≥2 mentions to count
012Outcome loop — did the published article do anything?09:00 dailyVerdict moved or flat at day 21 — see §05
003Error alert — catches failures from all of the above.on failureWrites the failure to the database first, then tries to notify
Node-level detail — the spine, step by step

002 is generated code, not hand-built in the n8n canvas: scripts/build-spine-workflow.mjs emits it. Edit the builder, never the workflow — a redeploy overwrites UI edits.

Fetch Google News RSS (query built from the entity registry, when:7d) → parse and cap at 25 items, body text truncated to 500 chars → normalise via 004 → on Mondays also pull SEMrush via 014 → combine → dedup within the run → fetch the seen-URL ledger → keep only new → build the scoring prompt → Claude (or the heuristic fallback) → parse and score → gate at 40 → write to Sheet + Supabase → mark processed → gate at 60 → build the digest → post → log.

Two failure behaviours worth knowing. If Claude returns something unparseable and nothing can be salvaged, the run fails loudly and leaves the signals unmarked so the next run retries them — a broken scorer must never look like a quiet news day. If Claude is simply unavailable, the run silently falls back to the fixed formula and reports scorer: heuristic; the ceiling is then 70, so nothing can reach the "Immediate" tier.

The ledger is built from what entered the prompt, never from URLs the model echoed back — otherwise a hallucinated URL would permanently suppress a real article.

No URLs are ever sent to the model. Clusters reference signals by index number. This is not a privacy rule: the corporate network's inspection stalls large high-entropy payloads, and 25 long Google News redirect URLs in a prompt was the cause of a multi-day hang in July.

How a new source gets added — and why it is cheap

Every source writes into the same 12-field shape via 004, so adding one is a new ingest workflow plus one line in the spine — not a change to scoring, dedup, the board, briefs or measurement. That is why SEMrush took days rather than weeks, and why Reddit is already built and waiting only on credentials.

004 also holds the parts most worth arguing about with the SEO team: the topic dictionary (9 categories, ordered specific to generic, first match wins), the competitor list (14 companies with alias patterns — Genesys includes PureCloud, Salesforce includes Agentforce), and the brand matcher. Cognigy counts as NiCE, never a competitor. Bare "NICE" only counts when a CX word is nearby and no medical or smart-home word is — otherwise NHS guidance and Nice the city would flood the board.

03 — Scoring

Where the number comes from

Two parts. A fixed formula does the ranking; the model is allowed a bounded adjustment on top.

ComponentMaxHow it is computed
Topical relevance25Lookup by topic: AI agents 25 · Contact center 22 · Enterprise AI 21 · Voice AI 20 · Customer experience 18 · Analyst recognition 18 · Workforce management 16 · Competitive landscape 15 · Market moves 14. Anything else scores 8.
Presence158 if we are mentioned, plus 3 per competitor mentioned, capped at 7
Engagement15Logarithmic, so a 10,000-share story does not drown out everything else
Recency15Under 24h 15 · under 48h 10 · under 7 days 5 · older 0. An unreadable date also scores 0 — never assume "now"
Fixed subtotal0–70, fully reproducible — the same input always gives the same number
Claude's adjustment−15…+30One integer per cluster, clamped in code. It may reward newsworthiness, search-demand potential, a format gap, customer proof or corroboration across several signals — and is explicitly told not to re-score relevance, presence, engagement or recency
Why it is split this way — the incident that caused it
An early version let Claude produce the whole 0–100 score. On replay, the same signal scored 72, then 62. A board that reorders itself when nothing changed cannot be used to decide anything, and cannot be compared week to week.

So the measurable half moved into arithmetic and the model kept the judgement half, bounded. The side effect proved the point: through the three weeks the AI budget was exhausted, every part of this kept working — more conservatively, but it kept working. The same principle is why the search analysis in §08 lives in database functions rather than prompts.

What the score turns into

ScoreStatusWhat happens
≥ 80ImmediateBoard, digest, top of the brief queue
≥ 60Weekly QueueBoard and the daily digest
≥ 40MonitorBoard only
< 40droppedRecorded as seen so it never costs us again, then discarded
anyIntel-OnlyOverrides every tier. Anything about share price, valuation, earnings or layoffs stays on the board as market intelligence and is never briefed — no enterprise competitor publishes that content and neither do we
A human can overrule the machine, beside it
The board carries a manager_score column. Set it and the brief queue uses yours instead — but the machine's score is never overwritten. The disagreements are kept deliberately: once there are enough of them they become the dataset for recalibrating the weights above, replacing judgement with observation.

04 — Writing

How an article gets written, and exactly where the machine stops

Say this plainly first
The system does not write articles. It writes briefs. A person reads the brief and writes the piece. Anyone who has been told "the AI writes our content" has been told something untrue, and the difference matters for planning: the machine removes the blank page and the research, not the writing.

What the brief contains

Nine fields, produced in one pass, grounded in a live web search where one is available.

FieldWhat it is
Headline angleA real editorial angle NiCE can credibly own — not a restatement of the topic
HookOne scroll-stopping line
Target keywords3–6 terms a buyer would actually type
Content formats1–3 recommended formats, each with a short outline
LinkedIn postPublish-ready: 120–200 words, hook, one concrete insight, CTA, 2–4 hashtags
Key messages3–5 points to land
CTA, owning team, priorityPriority is now / this-week / backlog — "now" only when genuinely timely or competitive

It lands in three places at once: the running Google Doc the writers work in, Supabase, and the Content Briefs sheet. The Doc entry ends with the line that closes the loop — the webhook call to paste the URL back once it is published.

The brief writer's instructions, verbatim

This is the actual system prompt, unedited. It is worth reading because most of it is editorial policy, not technique — and policy is the part you may want to change.

You are a senior content strategist for NiCE — the enterprise customer-experience /
contact-center AI company (flagship product: CXone; recently acquired Cognigy, agentic/
conversational AI — treat Cognigy as part of NiCE, never a competitor). Main competitors:
Genesys, Five9, Talkdesk, Verint, Cisco.

EDITORIAL SCOPE — hard rule: NiCE is an enterprise B2B vendor. Never produce content
angles about stock price, valuation, earnings, or layoffs (NiCE's or anyone's) — no
enterprise competitor publishes such content and neither does NiCE. If the opportunity
has a financial-news framing, reframe the brief around the underlying product/market/
customer story instead.

Your job: turn ONE scored market opportunity into a ready-to-execute content brief the
organic/content team can act on today. Be concrete and specific to NiCE's positioning —
no generic marketing filler. Confident, expert B2B voice.

When the input includes a 'LIVE WEB SEARCH' section, use it to ground the brief in
current facts — pull in concrete, specific details (figures, quotes, recent developments)
it supports, and fact-check your claims against it. Never invent statistics, quotes, or
dates that the search results or opportunity data do not support; if unconfirmed, keep
the claim general.

Rules:
- STYLE: never use em dashes (—) or en dashes (–) anywhere in your output.
- headline_angle must be a real editorial angle NiCE can credibly own, not a restatement.
- The LinkedIn post must be genuinely publish-ready: strong first-line hook, one concrete
  insight, a clear CTA, 120-200 words, 2-4 relevant hashtags.
- target_keywords must be realistic search terms a buyer would actually type.
- priority: 'now' only if timely/competitive, else 'this-week' or 'backlog'.
- Return ONLY the structured fields requested.

The output is validated against a strict schema. If the model returns something malformed, a second repair call runs automatically before anything fails.

The em-dash rule is enforced twice — asked for in the prompt, then stripped in code regardless. Em dashes are the tell that makes a manager stop reading and say "this was AI".

The scoring instructions, verbatim

Sent as one message per run, with the day's signals numbered beneath it. Note the explicit prohibition on re-scoring what the formula already covers.

You are an organic-intelligence analyst for NiCE — enterprise CX / contact-center AI
(flagship product: CXone; recently acquired Cognigy, agentic/conversational AI — Cognigy
news is NiCE news, not competitor news). Competitors include Genesys, Five9, Zendesk,
Salesforce, ServiceNow, Google CCAI, Zoom CX, Amazon Connect, Sprinklr, Talkdesk, Verint,
Cisco, Avaya, 8x8.

EDITORIAL SCOPE: NiCE is an enterprise B2B vendor. Clusters centered on stock price,
valuation, earnings or layoffs are market intelligence, not content material — no
competitor publishes such content and neither do we. Score them honestly for awareness,
but never frame recommended_formats or why_it_matters around share price or financial
performance.

INPUT: a numbered list of raw signals collected today. Each signal carries a
deterministic base_score (0–70) already covering topical relevance, brand/competitor
presence, engagement and recency.

TASKS:
1. Cluster the signals into distinct topics/opportunities (merge near-duplicates).
2. For each cluster, classify trigger_type — one or more of: Search Demand | Conversation
   | Format Gap | PR/Narrative | Customer Signal.
3. score_adjustment: one integer from -15 to +30 per cluster. Reward what the base cannot
   see: PR/newsworthiness, search-demand potential, format-gap severity, customer proof,
   multi-signal corroboration. Penalize thin, duplicative or off-strategy stories. Do NOT
   re-score relevance, presence, engagement or recency — the base already covers them.
4. why_it_matters: ≤2 sentences, concrete.
5. recommended_formats (array), primary_team, supporting_teams (array).
6. Include every cluster — the pipeline computes final = base + adjustment and filters
   at 40 itself.

Could it write the draft too?

Yes, and here is the honest shape of it rather than a pitch.

What it would takeEffortThe real question
A drafting step after the brief, grounded in the same web search plus our own top-performing pagesDays, not weeks — the brief already contains the angle, outline, keywords and messagesNot "can it" but "who edits it". An unedited draft is worse than no draft
A house style guide the model can be held toDepends entirely on whether one exists in writingWithout it, output is generic — which is the failure mode everyone fears and correctly dislikes
A review gate before anything reaches a CMSSmallNon-negotiable. The system should never be able to publish
The recommendation
Do not build drafting yet. The measurement loop in §05 has never seen a real article, so we cannot yet tell a good brief from a bad one — and generating drafts faster from briefs we cannot evaluate multiplies the wrong thing. Publish a handful from the current briefs, measure them, then decide. That sequence also produces the calibration data the scoring model needs.

05 — Measuring

How we would know it worked, and why we do not know yet

The gap, stated first
No published article has ever been measured by this system. The measurement machinery is complete, credentialed and running daily — and the table it writes into is empty, because registering a published article is a manual step that has not yet been taken for a real piece.

Everything in this section works. None of it has been exercised on real content. That is the single most important thing on this page for anyone asking about measurable impact.

What happens when an article is registered

StepDetail
RegisterOne call with the brief ID and the published URL. This is the only human step in the loop.
Wait21 days by default, adjustable per article from 0 to 90.
Check 1 — does it rankSearches the brief's own target keywords and looks for the URL in the results.
Check 2 — did we gain share of voiceCompares our share-of-voice change against the top competitor's change over the same period. We must gain more than 2 points relative to them — so a rising tide does not read as our win.
Check 3 — are AI engines citing itChecks whether the URL started being cited after publication.
Verdictmoved if any check passes · flat if none do. Evidence for every check is stored, not just the verdict.
If flatThe topic re-enters the board automatically as a Refresh at score 55 — high enough to be briefed again with a new angle, not high enough to trigger a digest. That arrow is what makes it a loop rather than a report.
There is no AI anywhere in this half
Every check above is arithmetic and string matching. That is deliberate: a measurement you cannot reproduce is not a measurement, and a model that re-judges the scale each run makes week-over-week comparison meaningless. The verdict is auditable line by line.

What we can prove today

The baseline, which is the part that took real work and is genuinely unusual to have.

AssetScaleWhy it matters
500 days of our own search performance8.4M rowsGoogle keeps ~16 months and deletes the oldest day daily. This history now exists only in our Supabase database and cannot be bought back from any vendor
Page-level totalsreconcile exactlyRe-summing our stored data returns the identical figure Google reports — the data is trustworthy, not approximately right
Every opportunity ever scoredWith its base score and the model's adjustment kept separately, so the weights can be recalibrated against outcomes later
Trend velocity per topic and per companyweeklyRising and dying, computed from signals we collected ourselves

What is needed to close the gap: publish and register roughly ten briefs. At that point the scoring weights stop being a considered guess and start being fitted to observed outcomes. One more dependency: our share-of-voice index was last refreshed 2026-06-17, so checks 2 and 3 would currently return "no data since publication" even for a registered article.

06 — Automation

What runs itself, and the honest answer about how reliably

WorkflowWhenTimezone
002 Signal Spine07:00 dailyNew York
015 Search Console ingest07:30 dailyBelgrade
011 Trend reportMon 08:00server default
012 Outcome review09:00 dailyserver default
014 SEMrushMondaystriggered by the spine
009 Brief agenton demand
The answer to "does this all run automatically"
Yes — while a laptop is awake. n8n runs locally. The schedules are armed and correct, and they simply do not fire when the machine is asleep or the process is not running.

This is not theoretical. Nothing ran from 31 July to 3 August. Every workflow was active the whole time; the process was not up. Nobody noticed for four days, because the alerting path writes to Supabase and posts to a test address that discards it.

Moving n8n to a server is the single change that would make "it runs automatically" true without qualification. Everything else on this page is sound and sits on that foundation.

Two scheduling details that are wrong today and should be fixed

The Search Console ingest does not run after the spine, despite being named that. The trigger node is literally called "Daily 07:30 — after the spine", but the spine is pinned to New York and the ingest to Belgrade. In August that is 11:00 UTC versus 05:30 UTC — the ingest fires about five and a half hours before the spine.

It causes no harm today because search data does not yet feed the spine. It will cause a silent wrong-order bug the moment it does. Pin both to one timezone.

Two workflows have no timezone set at all (trend and outcome review) and inherit whatever the server has. Worth making explicit before the pipeline moves anywhere.

What is still done by hand

Nineteen distinct steps. These are the honest ones, not a tidy summary.

Every time n8n starts

operational
  • Start it with a specific certificate flag, or every Supabase write fails while Search Console reads keep working — a corporate proxy intercepts supabase.co and not googleapis.com
  • Keep the machine awake
  • Restart by enumerating processes, never by killing one — Windows orphans a child process that then hijacks the next start

The content loop

the important one
  • Register every published article by hand. Nothing detects publication. This is the step that has never been taken for a real piece
  • Run the weekly page-competition snapshot manually
  • Run the six search analyses by hand — there is no digest narrating them yet

Configuration

occasional
  • Paste SQL into the Supabase SQL editor for any schema change — the pipeline is REST-only and deliberately cannot alter its own schema
  • Edit the topic-relevance list directly in Supabase, table gsc_icp_terms (no redeploy needed)
  • Create credentials; share new Google Docs with the service account
  • Drag a workflow between folders — the API cannot do it

07 — The dials

Where to change each thing

Two of these are editable without touching code or redeploying, which makes them the natural first place to tune with the SEO team.

What you want to changeWhere it livesNeeds a deploy?
Which queries count as "our category"Supabase table gsc_icp_termsNo — edit rows directly
A manual score override on an opportunitySupabase column manager_scoreNo
The 12 tracked SEMrush keywords and 4 discovery seedsworkflow 014Yes
Scoring weights, the 40 / 60 gates, the Intel-Only rule, the modelthe spine builder scriptYes — regenerate then deploy
Topic dictionary, competitor list, brand matchingworkflow 004 + the entity registryYes — run the sync script
The 21-day review windowworkflow 012, or per article at registrationPer article: no
Trend windows (7 vs 7 days, ≥2 mentions)workflow 011Yes
All credentials and secretsone env file → n8n credentialsRun the credential script
The one that needs SEO ownership
The list deciding which search queries count as our category was written by reading the data, not agreed with anyone in SEO. It currently keeps 55 of the top 60 opportunities and correctly rejects things like mape and unknown caller — but it is one person's judgement sitting in a table, and it silently shapes what the whole search side surfaces. It is a table precisely so it can be argued about and edited without an engineer.

08 — GEO

The part of search that is changing, and what we actually know

Only measurements here. Where we do not know something, it says so.

What we measuredFindingWhat it means
Google Discover presencezeroThree entire Google surfaces return nothing for us. For a vendor publishing this much thought leadership, that is a strategic gap worth naming
Google News presencezero
Video presencezero
Keywords where an AI Overview appears848Identified by SEMrush on our domain and never examined. Cross-referencing these against our zero-click queries would size the AI Overview problem instead of guessing at it
Citations by AI enginePerplexity 24 · Claude 3 · Gemini 3 · GPT 3We are cited eight times more often by one engine than by the others. Nobody has investigated why, and it is a genuine lead
Whether an AI Overview is taking our clicksunknownSearch Console cannot answer this at all. SEMrush can, and it is one afternoon of work
Why this connects to everything else
Our own click-through data shows a pattern that AI Overviews would explain — see 007 for the numbers. But it is equally well explained by ranking for questions the search result already answers, and the two lead to completely different content strategies. One says change the format; the other says consolidate pages.

The measurement to settle it exists in a tool we already pay for. That is the highest-value unstarted work on this page.

09 — Opportunities

What to do, split by how long it takes to know if it worked

This week

grounded in measurements we already have
  • Check the SERP features on our zero-click queries. One afternoon in SEMrush against the 848 AI-Overview keywords. Settles the strategy fork in §08
  • Consolidate ai call center. Six of our own pages compete for it; the glossary entry outranks the commercial page; between them they earned one click. This is a page-merge, not a writing job
  • Publish and register three briefs. Starts the measurement loop that everything else waits on
  • Agree the category term list with SEO so the search side stops running on one person's judgement

This quarter

structural
  • Move n8n off a laptop. Turns "it runs automatically" from mostly-true into true
  • Wire a real alerting channel. The four-day silent outage is the argument; it is a URL and minutes of work
  • Feed measured click loss into the refresh loop. Today a page is re-briefed when a search probe cannot find it; we now have the real click history to trigger on actual decline instead
  • Weekly narration of the search analyses so the six queries in §06 arrive as a readable summary rather than something someone must remember to run

Once there is outcome data

needs ~10 measured articles first
  • Recalibrate the scoring weights against what actually moved. The weights in §03 are considered guesses until then, and we kept the data to fix that
  • Decide on draft generation — with evidence about which briefs produce results, not on enthusiasm
  • Connect market demand to our own visibility: what the market searches for versus what we are visible for. The data for both halves now exists
If only one thing happens
Publish and register three articles. It costs almost nothing, it is the only thing that converts this from a well-instrumented system into a measured one, and every calibration question above is blocked behind it.

10 — Limits

What this does not do

Is everything really in n8n?

Almost. All nine workflows are, and they are the operating system. Two things sit outside it: the Supabase SQL functions that compute the search analyses (deliberately — they run over millions of rows, which is a database's job, and they kept working while the AI budget was out), and a handful of hand-run scripts for the initial history load and the weekly page-competition snapshot.

Nothing is hidden in a spreadsheet formula or someone's local notebook.

How much does it cost to run?

The AI scoring and brief writing are the only per-use cost, and both are bounded — at most 40 signals per day enter the prompt, and one brief is generated per request. Search Console is free within a daily quota we use about a tenth of. SEMrush consumes prepaid units, capped per run. Supabase is roughly $25/month on the Pro tier. There is no per-seat licence and no new vendor.

What is the most likely way this produces something wrong?

Two ways, both known.

The topic dictionary is the weak point. Anything it does not recognise scores 8 out of 25 on relevance, which usually keeps it off the board. A genuinely important story in a category nobody listed is the most likely miss — and it fails quietly, as an absence.

The category term list on the search side is one person's judgement and shapes what surfaces there. Both are editable, both should be reviewed by someone who owns the category.

Can it publish anything by itself?

No, and it has no credential that would let it. It writes to a Google Doc, a spreadsheet, Supabase and a chat channel. It has no CMS access and no ability to obtain any. That is a deliberate boundary, not an oversight, and it should stay that way even if draft generation is added.

What would break it tomorrow?

The laptop being closed — that has already happened. Everything else fails safely: if the AI is unavailable, scoring falls back to arithmetic; if the web search fails, the brief is written ungrounded; if SEMrush errors, the news run continues; if the chat channel is unreachable, the digest is still stored.

The uncomfortable version: it fails quietly and well, which is correct for production and wrong for getting a human's attention. That is what the alerting channel in §09 fixes.

→ What the search data says (007) → The same, as diagrams (008) → What is still blocked (006) → All documents