Commits

External agents, autonomous posts, and own analytics

External agents with signed webhooks, the complete autonomous posts cycle,

A day on three fronts: opening the CMS to external agents, closing the autonomous posts system, and leaving the house monitored. By the end of the night, own analytics.

External agents with signed webhooks

From Settings → Agents I can now register external agents with single-use tokens, scopes, and editable instructions. The CMS is exposed via OpenAPI (the proxy was hiding it because it was outside /api/; now it's at /api/v1/openapi.json) and the token is stored as a hash. E2E test in production: manifest, 61 routes, registration of a scheduled article, and revocation with 401.

The strong piece is the webhooks: persistent deliveries with HMAC SHA-256 signature, three retries, and a log per agent. They're emitted on article publish or unpublish, and on comment creation. Two fixes along the way: the service wouldn't start because a list[int] annotation resolved to the built-in list() method (renamed to list_deliveries), and a failed deployment left the web container down even though the API and database were healthy.

Autonomous posts, from concept to full cycle

Today's decision: autonomous posts publish themselves, generated two days in advance. And it already works: the cron creates slots, picks a topic from a fixed list (or the AI proposes one if it runs out), passes textual and semantic duplicate filters, writes with Keyword + Tavily, rewrites SEO, generates the featured image, and translates to all active languages with the same publish_at. If a phase fails, the execution remains retryable without duplicating the article.

Fixes along the way: the textual dedupe was using a scalar iterator for two columns and failed before creating anything; the homepage URL has disappeared from the panel because the backend already reads the homepage through the internal web service; and with a single fixed topic, the fallback now proposes variants (care, nutrition, guide, costs...) instead of leaving it empty.

Cleaner generated content

Three fixes that leave the AI more polished: the "general improvement" becomes a job with polling (the proxy was cutting off with 504), no article starts with a duplicate H1 (the title is already the public h1), and images with invented URLs are removed: sanitize_images only accepts /api/media/. Retroactive cleanup: 17 articles without an initial h1 and 14 without fake images.

Editable legal pages

Legal notice, cookie policy, and privacy policy are now edited from the panel with shared identity macros: you change the contact data once and all three pages follow the change.

Robustness and own analytics

Webhook retries survive restarts (counter in database and tick every 5 minutes), scheduled publications trigger their article.published when due, and there's an incident monitor in the panel. And the last hit: own analytics without cookies. Own beacon, visitor as daily hash of IP+UA+salt, country via Cloudflare with GeoIP backup (the DB-IP database failed due to volume permissions, reassigned) and panel with 7/30/90 days: views, uniques, articles, countries, cities, sources, and devices. The first real visit came out with country ES and the correct city.

Raw data retention at 90 days. No third parties.

Other diary entries