Swazee mark Product (type slug) Tool (chevron-wrench) Experiment (4-point star) Active (filled diamond) Shipped (hollow diamond) Shelved (diamond + slash) External link (↗) Search (angular magnifier) Filter (funnel) Close / Esc (chunky X) Move down (j) Move up (k) Return / Enter
SWAZEENET
VOL. I · NO. 01 · EST. MCMLXXXVII
BROADSIDE 12 active · 2026·05·14
№ 05 · product · PHP 8.3 / Python 3.10 · 2024—

vikingsintel,
a Vikings beat, automated and accountable.

vikingsintel.com --- Minnesota Vikings news, analysis, and intel. PHP 8.3 frontend, Python 3.10 automation, MySQL utf8mb4 on LiteSpeed. No editorial committee.

php python news

A working Vikings beat that ships every day. The frontend is hand-written PHP with mobile-first CSS Grid; the backend is four cron-driven Python agents that scout RSS, draft articles through Claude with a pre-publish lint gate, refresh cap-state context, and ingest social embeds for review. The site is live, indexed in Google News, and accountable: drift in personnel facts is surfaced in an admin dashboard so unpublished articles can be requalified before they ever face a reader.

ITech scope

IIAutomation

Four agents run on a 30-minute cron driven by automation/automation_engine.py. Each is idempotent — running the same tick twice yields the same database state — and each fails loudly: a missing field, a 5xx, or a parse error increments a per-agent failure counter and surfaces in the admin dashboard before it can become a silent gap.

An accuracy dashboard piggy-backs on the same 30-minute tick. A self-hosted RSS hub on the MasterAgent box runs every 15 minutes, FTPs RSS XML and a manifest.json to the site, and SocialScout reads from there — which means the social ingest pipeline is independent of any third-party rate limit on the publishing host.

IIIEditorial gates

One lint function (article_lint()) enforces canonical-fact validation across every surface that publishes — the publish gate, the drift dashboard, and the truth engine all call the same code path. The lint reads the canonical-fact table (current roster, current contract status, current depth-chart) and refuses to publish an article that contradicts it without a hedging qualifier. When a player’s status changes — released, traded, retired, suspended — previously-published articles that reference the now-stale fact are unpublished automatically and held in a "requires editor" bucket until a human inserts the right qualifier ("former", "ex", "then-", "now-Bears").

The structural choice that makes this work is "0 editorial committee." The publish decision belongs to one person, which is what makes a 30-minute automation cadence sustainable; a committee would not approve every drafted article fast enough for the news cycle, and a multi-author shop would need to trade auto-unpublish for a different reconciliation policy. The cap of one human owner is the load-bearing constraint behind the speed.

Fig. I.
01upstream sources 02draft-scraper 03automation 04rss-hub 05PHP frontend 06CDN
as of 2026-04-26
Fig. II.
PHP2056053% HTML901423% Python564915% CSS36659%
PHP frontend + Python automation · as of 2026-04-26
Fig. III.
public (PHP+HTML) 28178 73% design_handoff · 4920 automation draft-scraper · 1518 rss-hub · 1168
top-level dirs · as of 2026-04-26

IVNumbers

The numbers reflect a one-operator beat. Two languages (PHP for the frontend, Python for the automation), one cadence tied to the NFL calendar (free agency, draft, training camp, regular season, playoffs — each with its own publishing rhythm), and a 30-minute automation tick that does not assume game-week traffic patterns. The automation modules are scheduled, idempotent, and fail loudly: a missing field, a 5xx upstream, or a parse error increments a per-agent failure counter and surfaces in the admin dashboard before it can become a silent gap. Missing a week is preferable to publishing a hallucinated stat. The PHP-heavy line count above is the public-site rendering surface, not application logic; the actual editorial decisions live in the smaller Python automation tree.

VConstraints

No third-party comment system, no analytics beyond server logs, no signed-in surface for readers. Automation is allowed to summarize box scores and roster moves verbatim from official sources but is never permitted to invent quotes, infer intent, or attribute thoughts to a player without a citation. When LLM rewrites are used (sparingly, and only on copy-edit passes), they are constrained to text the operator has already approved as factually correct — never generation from prompts alone, and never restructuring of the source quotes. The ‘0 editorial committee’ plate is structural: the entire publishing decision belongs to one person, which is what makes a 30-minute automation cadence sustainable in the first place. A multi-author shop would need to trade auto-unpublish-on-fact-drift for a different reconciliation policy, and the cadence would slip with it.

:/ ESC