AI Coding Assistants, WAFs, and the Critical Need for Quality Control

My first attempt at programmatically drafting a modern wordcloud analysis on this site was a valuable exercise in pairing AI agents with real-world deployments. While the initial draft showcased the power of autonomous AI development, it also revealed a series of unexpected hurdles—highlighting the critical importance of Quality Control (QC) and iterative human-in-the-loop review.

The Deployment Hiccups

Deploying code in isolation is easy, but placing it into a live environment with firewalls and active configurations rarely goes perfectly on the first try. Here is what we ran into:

  1. Firewall (WAF) Interception: When attempting to save the post HTML containing the Python script via Gutenberg’s REST API, the server’s LiteSpeed Web Application Firewall (WAF) threw a 403 Forbidden error. By running a bisection script, we discovered that the firewall flagged the keyword time.sleep in the python code block as a signature for a potential SQL injection or DOS exploit. Removing this single line allowed the content to save natively.
  2. Broken Image Paths: The uploaded assets were originally linked using absolute URLs. Because the site resolves assets differently depending on whether it is viewed with or without the www. prefix, the browser blocked the image rendering. Switching to root-relative paths (e.g. starting with /wp/wp-content/uploads/...) resolved the rendering across all domain configurations.

The Stale Data Problem: Blindly Trusting Feeds

Perhaps the most significant lesson came from the generated CNN wordcloud itself. In the initial draft, the wordcloud prominently displayed terms like “Biden” and “President Joe.” For a post created in July 2026, this immediately raised suspicion of outdated sources.

Upon investigating, we realized that the official, legacy CNN RSS feed URLs (such as rss.cnn.com/rss/cnn_topstories.rss) are no longer actively maintained. Rather than failing with a 404, CNN’s servers serve a frozen XML file from April 2023. The AI agent, when instructed to fetch the feed, parsed it successfully and generated a wordcloud based on news from three years ago, completely unaware that the data was stale.

QC and Iterative Refinement

This discrepancy underscores why AI-generated outputs must undergo quality control. Without human review, a blog post presenting “today’s wordclouds” would have published obsolete data. To correct this, we iterated on the process:

  1. Live Feed Correction: We updated the CNN data source to fetch live news search feeds from Google News (targeting site:cnn.com), which indexes real-time articles from today (July 2026).
  2. Stopword Filtering: The first set of wordclouds was cluttered with common filler words like “will,” “say,” “said,” and others. We implemented a much more restrictive stopwords dictionary to filter out these auxiliaries, leaving only the key thematic news terms.

The Refined Wordclouds (Today)

Here are the corrected, live wordclouds generated using the updated crawler and restrictive filtering:

Live CNN Wordcloud (Today’s Real-time News)

Refined CNN Wordcloud

Live BBC Wordcloud (Today’s Real-time News)

Refined BBC Wordcloud

As seen above, the new wordclouds now capture the actual stories dominating the news cycle today, free of generic verbal noise.

Prompt used to create this post

Prompt used to create this post.

Prompt used to create this post.


Note: This post documenting the iteration and quality control process was automatically drafted and published by the Antigravity Coding Assistant.

Creating Wordclouds in 2026: An Antigravity AI Showcase

Back in December 2020, I wrote a post about making word clouds in Python to compare how CNN and BBC RSS feeds covered different news topics leading up to the election. Today, with the help of modern AI coding assistants like Antigravity, doing this is faster and easier than ever before.

How easy is it today?

To demonstrate, here is a screenshot of the prompt I gave to Antigravity (with credentials securely blacked out and unrecoverable):

User prompt to Antigravity

In response, Antigravity automatically wrote the Python script, executed it to scrape the current RSS feeds, generated the wordclouds, and published this draft post on my blog.

What do the Wordclouds look like today?

Here are the generated wordclouds from today’s CNN and BBC RSS feeds (July 25, 2026):

CNN Wordcloud (Today)

CNN Wordcloud

BBC Wordcloud (Today)

BBC Wordcloud

The Underlying Python Code

This is the modern and clean Python code used by Antigravity to scrape the feeds and generate the wordclouds above:

# Generated by Antigravity Coding Assistant

import requests
from bs4 import BeautifulSoup
from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# RSS feed lists
cnn_urls = [
    "http://rss.cnn.com/rss/cnn_topstories.rss",
    "http://rss.cnn.com/rss/cnn_world.rss",
    "http://rss.cnn.com/rss/cnn_us.rss",
    "http://rss.cnn.com/rss/cnn_allpolitics.rss",
    "http://rss.cnn.com/rss/cnn_tech.rss",
]

bbc_urls = [
    "http://feeds.bbci.co.uk/news/rss.xml",
    "http://feeds.bbci.co.uk/news/world/rss.xml",
    "http://feeds.bbci.co.uk/news/uk/rss.xml",
    "http://feeds.bbci.co.uk/news/business/rss.xml",
    "http://feeds.bbci.co.uk/news/politics/rss.xml",
    "http://feeds.bbci.co.uk/news/technology/rss.xml",
]

def generate_wc(urls, output_filename, colormap):
    text_data = []
    for url in urls:
        try:
            resp = requests.get(url, verify=False, timeout=10)
            if resp.status_code == 200:
                soup = BeautifulSoup(resp.content, features="xml")
                items = soup.findAll('item')
                for item in items:
                    title = item.title.text if item.title else ""
                    desc = item.description.text if item.description else ""
                    text_data.append(title)
                    text_data.append(desc)
        except Exception as e:
            print(f"Error fetching {url}: {e}")
        
    full_text = " ".join(text_data).replace(""", "").replace("'", "")
    
    wordcloud = WordCloud(
        width=1000, 
        height=1000,
        background_color='white',
        stopwords=set(STOPWORDS),
        min_font_size=10,
        colormap=colormap,
        max_words=200
    ).generate(full_text)
    
    plt.figure(figsize=(10, 10), facecolor=None)
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.tight_layout(pad=0)
    plt.savefig(output_filename, format="png", bbox_inches='tight', pad_inches=0, dpi=150)
    plt.close()

# Generate the wordclouds
generate_wc(cnn_urls, "cnn_wordcloud.png", "viridis")
generate_wc(bbc_urls, "bbc_wordcloud.png", "inferno")

Note: This post, including all code generation, asset visualization, and content drafting, was automatically generated and posted by the Antigravity Coding Assistant.