HOME SKILLS BLOG GITHUB
// CHANGELOG

CLAUDE BLOG V1.9.1
5 GATES, 95/100, NO SLOPPY DRAFTS

DANIEL AGRICI // // 9 MIN READ // CHANGELOG SECURITY RELEASE
Claude Blog v1.9.1: 5-gate Blog Delivery Contract plus 95 of 100 security audit pass

v1.9.1 is two releases in one announcement. v1.9.0 made the blog reviewer blocking instead of advisory, so drafts under 90 of 100 stop existing on disk before they ever reach you. v1.9.1 ran the whole project through an 8-agent cybersecurity audit and closed every HIGH and MEDIUM finding in 24 hours. Both shipped this week. Both ship together because they are the same shift: the gates do the work the human used to have to do.

If you came here from the walkthrough video, the timeline is real. While I was talking through the contract, an agent was generating the Codex vs Claude sample blog on screen in another window. Ten minutes, end to end, including research, hero image, SVG charts, and a passing review against the 5 gates. That post is on the site now. Skim it first if you want to see what the contract produces before reading what the contract does.

The Blog Delivery Contract: 5 Gates Before Any Draft Reaches You

Until v1.9.0, the architecture had a real defect. The blog-reviewer agent existed. It scored drafts. It produced a scorecard. And then the orchestrator handed the draft to you anyway, regardless of the score. Sloppy drafts with no real hero image, broken og:image, SVGs that overflowed on mobile, missing PDFs, and md/html divergence all reached the user before any gate fired. The user ended up being the first reviewer.

v1.9.0 closes that gap. The contract has 5 gates. Gate 4 is the blocking one.

GateWhat it doesBlocks?
1. Capability DiscoveryEnumerates MCP servers, agents, scripts, env vars before drafting. Writes capabilities.json.No (info only)
2. Format CompletenessEvery draft must ship .md + .html + .pdf + a real hero image. Deterministic renderer from one source.Yes
3. Visual VerificationPlaywright renders the HTML at 375, 768, and 1280 px. Asserts no SVG overflow, dark-mode swap works, console clean.Yes
4. Content Review (BLOCKING)blog-reviewer scores the rendered HTML. Threshold: 90 of 100, zero P0 issues. Emits machine-readable BLOCKING: true|false.Yes (hard)
5. Asset + Link IntegrityEvery img src resolves, og:image points to a real file, external links return 200, JSON-LD wordCount matches body within 5%.Yes

On any gate failure, the orchestrator iterates up to 3 times before escalating to the user with a diagnostic. You are no longer the first reviewer. The gates are.

The Hero Image Ladder: 5 Tries Before We Block

Gate 2 demands a real hero image. The old failure mode was a missing image plus a fabricated og:image URL that 404d the moment someone shared the post on LinkedIn. scripts/generate_hero.py now runs a five-step ladder:

  1. Banana MCP (when the nanobanana-mcp server is loaded)
  2. Direct Gemini API via google-genai (when GOOGLE_AI_API_KEY is set)
  3. Premium stock APIs (Unsplash, Pexels, Pixabay) - any key suffices
  4. Openverse public API (CC-licensed, no key required)
  5. Block with setup instructions if none of the above succeed

The block is intentional. A missing hero is a missing hero. No silent fallback to a placeholder gray rectangle that ships to production and embarrasses you on the open graph preview a week later.

v1.9.1: The 8-Agent Cybersecurity Audit Pass

The Blog Delivery Contract introduced new attack surface. generate_hero.py fetches remote images. blog_preflight.py writes provenance files into draft directories. The reviewer reads files the user created. All of that is new pipe between trusted code and the open internet.

So v1.9.1 ran 8 specialist agents against the v1.9.0 surface: OWASP Top 10:2021, CWE Top 25:2024, MITRE ATT&CK pattern matching, supply chain analysis, credential handling review, IaC drift check, AI-generated code audit, and threat-model fitness. Composite score against the audit: 90 of 100. Every HIGH and MEDIUM finding closed in v1.9.1.

What Got Closed

IDSeverityFix
VULN-801 / CHAIN-801HIGH (CRITICAL on cloud)SSRF guard in generate_hero._http_get: scheme allowlist, private/loopback/link-local refuse via ipaddress, 25 MB cap, no-redirect opener. Closes the AWS-IMDS-via-og:image attack path.
VULN-802HIGHCode-enforced iteration counter at <draft>/.iteration-count. MAX_ITERATIONS = 3, exit code 2 on exceed. Was orchestrator-prose-only.
VULN-401HIGHuv.lock with 142 hash-pinned packages. Reproducible install via uv sync --frozen.
VULN-803 / CHAIN-802MEDIUMNonce-bound reviewer provenance. _init_review_nonce writes secrets.token_hex(16), Gate 4 verifies review.md echoes the nonce. Closes counterfeit reviewer pass.
AUTH-001MEDIUMOAuth client_secret split from token blob. Re-read on construction from oauth_client_path.
VULN-804 / VULN-002MEDIUM / LOW_PreflightNoRedirectHandler refuses non-http(s) schemes inline and refuses 30x redirects on Gate 5 link checks.
VULN-404 / 405 / 406 / 411MEDIUM x3 + INFOTightened upper bounds on weasyprint, google-genai, sentence-transformers. setuptools floor at 70.0.0 (CVE-2024-6345 RCE).
VULN-IAC-001MEDIUMSHA-256 hashes for install.sh and install.ps1 published in README. Verify integrity before piping curl into bash.
VULN-S01LOWAPI-key echo in setup_image_mcp.py --project masked as AIza****WXYZ.
VULN-IAC-003LOWinstall.sh validates skill_name against ^[a-z0-9-]+$ before mkdir / cp. Defense in depth against path-traversal in a tampered repo.

The AUTH-002 PKCE finding stayed open as not-in-scope. Installed-app OAuth flow with explicit client_secret.json does not require PKCE; CSPRNG state plus fixed loopback redirect cover the CSRF case.

Quality Gates: Final State

  • Tests: 160 to 187 (+27 targeted at the fixes)
  • Prose hygiene: 0 violations
  • Plugin manifest: valid
  • Version coherence: all 14 surfaces at 1.9.1 (4 canonical plus 10 sub-skill SKILL.md)
  • Dependency lock: present (uv.lock, 142 packages, SHA-256 pinned)
  • Projected security composite: ~95 of 100 (up from 87 pre-fix)

What This Actually Looks Like in Production

The clearest answer is the Codex vs Claude sample blog. That post is the output of one end-to-end run on the v1.9.1 contract. Hero image generated via the ladder. SVG charts inline. JSON-LD validated. FAQ schema present. Score 92 of 100 on the blocking reviewer. Total elapsed time including research, drafting, image generation, rendering, and the full 5-gate pass: about 10 minutes. The folder it produced has the contract artifacts in it: capabilities.json, .iteration-count, .review-nonce, preflight-report.json, review.md. The same gates that produced that post produce every post.

Watch the Walkthrough

Two ways to consume v1.9.1. Flip through the 12-slide release deck for a 60-second skim, or watch the 12:48 walkthrough below for the full demo, including 6 minutes of live agent rendering.

Open the 12-slide release deck →
12-SLIDE DECK · navigate · F fullscreen · S presenter · A autoplay · ? help Open in new tab ↑

The video shows the contract running live: cover image generation, the SVG chart pipeline, the inline embed flow, the 6-minute silent stretch in the middle is the agent rendering the Codex vs Claude post in real time. Skip to 8:17 if you want to jump straight to the install walkthrough and the finished sample.

Upgrade Guidance

If you are on v1.7.x or earlier, this is the right upgrade. Read the security FAQ first (links in the v1.7.1 post). Rotate any Google AI API keys that might have been committed to .mcp.json before v1.7.1. Then update.

If you are on v1.8.x, update straight through. The two soft-compat shims in v1.9.1 mean nothing breaks if your reviewer config is older. The shims emit a deprecation warning and will be removed in v1.10.0, so update your oauth_client_path config and let your draft regenerate the .review-nonce file once.

If you build CI around the skill, pin to v1.9.1 in your install command and use uv sync --frozen against the committed uv.lock for reproducible installs. The 142 hash-pinned packages mean PyPI mirror compromises and typosquats cannot land malicious code at install time.

Install or Update

curl -sSL https://raw.githubusercontent.com/AgriciDaniel/claude-blog/main/install.sh | bash

Verify installer integrity against the SHA-256 hashes published in the README before piping curl into bash. Reproducible alternative via git clone plus uv sync --frozen is documented in docs/INSTALLATION.md.

Conclusion

v1.8.x taught a lesson. Seven hardening waves in 48 hours, each consuming the previous round's audit output as the next round's input, lifted the security baseline from "good enough" to "audited and locked." v1.9.0 applied that lesson one layer up: from the project's own code to the project's output. v1.9.1 then re-ran the security playbook against the expanded surface. Both shipped together because they are one shift. Audits ladder you up to your asymptote. Infrastructure raises the asymptote. The reviewer is no longer the last advisory voice. It is the gate.

// AUTHOR

Daniel Agrici

AI Automation Specialist based in Chisinau, Moldova. Creator of 21 open-source repositories with 4,900+ GitHub stars total, including Claude Blog and Claude SEO. GovTech Hackathon Moldova first-place winner. Writes about evidence-led AI content workflows, security hardening of AI tooling, and the operator's view of running Claude Code in production.

Follow: GitHub // YouTube // Skool // LinkedIn

// FAQ

FREQUENTLY ASKED QUESTIONS

The Blog Delivery Contract is a 5-gate pipeline that runs before any draft reaches you. Gate 1 enumerates capabilities, Gate 2 checks format completeness (md + html + pdf + real hero), Gate 3 runs Playwright at 375 / 768 / 1280 widths, Gate 4 is the BLOCKING content reviewer (score 90+ or no delivery), Gate 5 verifies every asset and link. The reviewer used to be advisory. Now it blocks.
BLOCKING means the orchestrator does not return the draft if the blog-reviewer agent scores it below 90 of 100 or surfaces any P0 issue. The orchestrator iterates up to 3 times against the gates before escalating to the user with a diagnostic. The user is no longer the first reviewer. The gates are.
An 8-agent cybersecurity audit against OWASP Top 10:2021, CWE Top 25:2024, and MITRE ATT&CK surfaced 11 findings. v1.9.1 closes every HIGH and MEDIUM: SSRF guard in hero generation (VULN-801, closes the AWS-IMDS-via-og:image attack path), code-enforced iteration counter (VULN-802), nonce-bound reviewer provenance (VULN-803), uv.lock with 142 hash-pinned packages (VULN-401), no-redirect HTTP handler (VULN-804), tightened dependency upper bounds, OAuth client_secret split from token blob (AUTH-001), API-key echo masking, and skill_name regex defense-in-depth on the installer. Test suite is now 187 tests, up from 160.
No. Two soft-compat shims keep older flows working through v1.9.x. First, the nonce-bound reviewer provenance soft-passes with a deprecation warning when the .review-nonce file is absent. Second, the OAuth path falls back to legacy token-file client_secret if oauth_client_path is unset. Both shims will be removed in v1.10.0, so update your reviewer config and re-authorize OAuth to silence the warnings now.
It is a real post produced end-to-end by the v1.9.x gates as proof of skill. Topic: ChatGPT Codex vs Claude Code, who wins in 2026. Generated in about 10 minutes including research, hero image, SVG charts, FAQ, and a 5-gate review pass. Read it here to see what the contract actually produces, not what the docs claim it produces.
// RELATED

KEEP READING

UPDATE TO V1.9.1
TODAY.

$
curl -sSL https://raw.githubusercontent.com/AgriciDaniel/claude-blog/main/install.sh | bash
VIEW ON GITHUB ALL ARTICLES >