agenttru.st

Juan Lentino bronze

juanlentino.com

“Read-only agent surface over this site: analytics, content health, provenance and deploy status. Speaks MCP, not A2A JSON-RPC — see preferredTransport before dispatching.

a2a https://juanlentino.com/wp-json/signal-noise/v1/mcp talk to it https://juanlentino.com/.well-known/agent-card.json its card
Checked 3d ago pushNotifications, stateTransitionHistory, streaming

we checked this    the operator says this

Community rating 0 0 up · 0 down — sign in to vote

Verified by agenttru.st

Everything here is a check agenttru.st performed itself. Assurance, protocol, hosting and freshness are in the card above and are not repeated.

Certificate
Issued by Google Trust Services domain-validated
Valid until 14 Dec 2026. A wildcard certificate: its other hosts are invisible here, because CT logs the wildcard, not them.
Control of the hostname was checked; nothing about who operates it.
DANE / TLSA
Not verified
Discovery
Well-known document
This host also publishes an ARD catalog (/.well-known/ai-catalog.json) declaring 6 resources. The catalog's entries are the publisher's claims, not something agenttru.st verified.
AI use policy
Search: yesAI input: yesAI training: nouse: reference
Content licence (RSL): https://juanlentino.com/license.xml
What this site's robots.txt says about how AI may use its content. Recorded as the operator wrote it, not enforced — these are preferences about use, not access, and agenttru.st only reads the agent's own discovery documents.
AI-facing documents
Publishes /llms.txt — “Juan Lentino” a curated map of the site's content for language models
Fetched from this host during verification. Neither document is how this agent was discovered.
First seen
5 Sep 2026
View verification details
Assurance
bronze Bronze — agent card fetched over HTTPS with a valid certificate
Protocols
A2A verified by handshake or card fetch, not merely advertised
Hosted in
? Unknown · Cloudflare, Inc. (AS13335)
The address did not geolocate — usually anycast hosting, where one address answers from many places at once.
Last checked
3d ago

What this agent says it can do

Declared in the agent's own card. agenttru.st has not tested whether it completes any of these tasks — the operator of juanlentino.com controls every word below.

AI Prompt-Cache Probe Status

Returns the prompt-cache probe verdict: whether enabling Anthropic prompt caching would pay on this site, and for which model. Call this before proposing or enabling prompt caching for any AI feature, and when reviewing AI spend — it answers with recorded evidence instead of an estimate. Read-only; never enables caching and never makes an AI call. The probe records every Anthropic call the site makes (including other plugins routed through the WP AI Client) via a read-only http_response hook, keeping a rolling 200 entries with a 300-second repeat window. `state` is the answer: `candidate` (a prefix clears the model minimum AND repeats inside the TTL — caching would pay), `no_repeats` (prefix is large enough but never repeats, so a cache write would never be read), `below_floor` (prefix never reaches the model minimum cacheable size — 1024 tokens on Sonnet 5, 4096 on Haiku 4.5, so the same prompt can be cacheable on one model and silently not on another), `unknown_floor` (the model minimum is not in the

Provenance anchor overview

Aggregates every Note's latest anchor state: pending anchors with their in-flight Bitcoin transaction and confirmation count, plus confirmed/total counts.

Bing Webmaster: the stored window

What the site earns in Bing search over the last synced window (28 days ending on the newest day Bing reports): totals (clicks, impressions, days counted) and the top queries (clicks, impressions, CTR, average impression position). source is always "bing" so a consumer holding the Search Console reading beside it never confuses the two. synced:false with null totals means nothing has synced: that is not a zero. Read-only over data the daily sync already stores.

Edge Cache Freshness

Reports whether the edge is serving the current render, from the same derive layer the Classic Admin cell and the OpenStation tile render — so all three surfaces cannot disagree. `last` is the verdict of the most recent purge: `fresh` (the edge served the current render), `stale` (it did not), `pending` (a purge fired and its deferred verification has not run yet — an auto purge, which is what a plugin or theme update triggers, writes no verdict until its cron verify lands about 75 seconds later), or `unknown` (no usable report at all). READ `pending` AS A KNOWN STATE, not a failure: a purge demonstrably happened and `last_time` says when. `post_save` counts POST-SAVE probes only — manual purges do not write there, so those figures cannot be moved by pressing Purge, and a rising `stale` there means a per-post purge genuinely failed to clear the edge. `state: never_probed` means no verdict has ever been recorded, which is an absence of evidence and never a clean edge. Read-only; triggers no probe, becaus

Scan operational rhythms for cadence deviations

Deterministic rhythm watch, no AI: z-score of the CURRENT gap against each rhythm's own history — the publishing cadence (EWMA) plus every cron hook with enough recorded firings (median/MAD, burst-resistant). One-sided (late only; a burst never flags), conservative (three sigmas). A hook never flags before 1.5x its registered interval — the registration is ground truth. Each flag carries expected_gap (the rhythm the history implies); the legacy ewma key mirrors it. Honest unknowns: thin history never flags, an on-demand hook with no registered recurrence is watched but never flagged (its cadence tracks site activity, not cron health), a rigid metronome is watched but unquantifiable, a window that has not spanned a week (and whose learned rhythm does not match its registered schedule) is watched but untrusted, and a failed cron-history read skips that section and says so (cron_skipped). Computed on demand from bounded local reads.

Cloudflare Status

The Cloudflare monitor's last stored reading: the API token's status and expiry (GET /user/tokens/verify), the zone's last seven days from GraphQL httpRequests1dGroups (requests, cached share, bytes, threats, 4xx/5xx), and the firewall's last 24 hours from firewallEventsAdaptiveGroups, or from the raw firewallEventsAdaptive grouped locally when the plan lacks the grouped one (`dataset: raw`; events by action, top rules). READ `needs_permission: true` AS A GAP, never as zero: for the zone reading the token lacks Zone › Analytics › Read; for the firewall the zone's plan lacks both datasets, and no grant changes that. `state: never_run` means the daily monitor has not stored anything yet. Cloudflare publishes no rate-limit headers, which is why this reading exists instead of a quota row. Since 15.4.0 `posture` carries the daily REST reads of what the edge is SET TO: zone settings (SSL mode, min TLS, Always Use HTTPS, Development Mode and readings), DNSSEC status, and the custom WAF rules by name, action and

Find the existing notes a draft echoes

Scores ONE draft against the rest of the corpus and returns the existing notes it most overlaps, so the writer sees the overlap while changing course is still cheap. Same kernel as near-duplicate-scan (TF-IDF cosine over the same corpus walk), asked from the other direction: one document against many, rather than all pairs. The draft is excluded from its own comparison corpus. Below the threshold (clamped 0.3-0.95, default 0.45 — lower than the 0.6 cousin bar because a draft in progress covers only part of the ground its finished twin does) the answer is an EMPTY list, never the least-bad match. Pass content to score unsaved editor text; omit it to score the saved body. No caching, no writes, nothing on the reader-facing render path.

Edge 5xx summary

The last seven days of 5xx from the daily edge rollup: total, which paths failed, who answered (edge vs origin status, request source), and since 18.2.0 one row per day with who asked (visitor, worker, other, unrecorded; unrecorded rows predate 17.9.3 and are the pre-filter leftover). Cloudflare's own Early Hints cache lookups are excluded (17.9.3); they were ~98% of every stored 5xx and no visitor ever saw one. Read `query.error` before trusting a zero: a failed read is not a clean week. Same reader as cloudflare-status errors_5xx. Read-only; never fetches.

Edge Sampling Probe

Two LIVE Cloudflare GraphQL reads over the last 24 hours of 5xx (each run spends two API calls; read-only, writes nothing). `sampling`: count, count × sampleInterval and the sampleInterval range across the sampled 5xx groups, so whether adaptive sampling is active at this volume is measured (`sampled_rows` > 0 means some rows stand for more than one event). `by_request_source`: the same 5xx grouped by requestSource and status, which separates a Worker subrequest (edgeWorkerFetch) from a visitor request (eyeball). Each read reports its own error (`sampling_error`, `source_error`) instead of failing the other. Built for #1002: the sampled 5xx and the zone's exact totals disagree on count and on code.

Crawler-family enum drift (stored report)

Did the hand-maintained crawler-family enum drift? The plugin's snt_mr_valid_families() is mirrored by hand in the rights-signals worker, and nothing else checks that the two copies agree or that the enum still matches the world. A weekly run diffs the plugin enum against the DEPLOYED worker's (read at its source_commit), and both against two pinned MIT data corpora (monperrus/crawler-user-agents, ai-robots-txt/ai.robots.txt) re-fetched live. Rows: mirror_parity (unequal is CRITICAL), ours_unmatched (families classifying nothing upstream), unobservable (families that CANNOT classify anything by construction and are therefore exempt from ours_unmatched rather than reported as drift — apple-ai, because Applebot-Extended is a robots.txt token that never fetches), upstream_unmapped (upstream tags no family claims; counts, not hits — the ledger has no UA dimension), vendor_gap (AI operators absent from our families), respect_flips and vocabulary changes since the pin. status/summary are the Site Health verdict

Get custom events

Returns top custom events (name → events/visitors) for a window. Read-only; historical Plausible-imported data.

Get analytics summary

Returns range analytics totals (range: 7|14|30|90|365|all, class: human|suspect|bot). Read-only. Denominators, honestly named: `unique_visitor_days` includes visitor-days that fired no pageview (e.g. feed/beacon-only), so it can exceed `views`; `unique_visitor_days` is its honest alias. (The wp-admin Sessions tab is a third unit again: within-day sessions from the live session engine, resetting at UTC midnight: no field here carries it.) `pageview_visits` is the headline visit metric: visitor-days with at least one pageview. `views >= pageview_visits` holds by construction, so this ratio cannot invert (`integrity_violation: true` means a genuine rollup bug upstream, values served unclamped). `viewless_visits` = unique_visitor_days - pageview_visits (visitor-days with zero pageviews). Ratios: `view_visit_ratio` = views/pageview_visits (>=1); `pageviews_per_visitor_day` = views/unique_visitor_days (may be <1). PREFER `view_visit_ratio` when judging engagement: `pageviews_per_visitor_day` is DILUTED BY DESIGN by

Get Cron Firing History

Returns the most recent N firings of a cron hook with elapsed time, success/failure, and any error message. Backed by the snt_cron_history table populated since plugin v3.2.0; retention is a rolling 30 days OR 1000 rows per hook, whichever is shorter.

Get theme + plugin deploy status

Returns current theme version, current plugin version, latest available versions from GitHub, and whether updates are available — plus a `workers` array for the five owned Cloudflare workers (live probe vs latest GitHub tag; unprobeable/unknown rows stay visible). Pass force_refresh=true to clear the GitHub-tag + update_themes/update_plugins + worker probe transients first so the answer is freshly fetched (replaces the removed force-check-updates ability; clears caches only, never user data). Read-only; safe to call anytime.

Get Content-Health Scan Summary

Returns a compact summary of the last cached Content-Health scan: the total finding count, the flagged checks ranked by count (each with its label, count, and fix hint), the passed/total check tally, and every skipped check with the reason it could not run. Returns null when no scan has run yet. Read-only — never triggers a scan (a scan walks all posts and probes links).

Get Machine Readers Crosstab

Crawler reads at the edge over a window (days: 1-90, default 30) as family x purpose x agent cells, hits descending: `cells[]` of {family, purpose, agent, hits, days, surfaces}, where `days` is how many distinct days the cell was seen on and `surfaces` its hits per surface class. Answers "which purpose did each family read for" directly, which the summary's per-family and per-purpose totals cannot: a family whose reads split between `train` and `search` shows as two cells. Purpose `unknown` is an UNMAPPED reader, not a reader with no purpose; `taxonomy_absent: true` means the edge sent no taxonomy at all and every purpose is unknown for that reason. `truncated: true` means the aggregate read hit the edge's row cap and the cells under-count the newest days; `total` sums the cells. User agents are self-reported: observation, never proof of identity. `ok: false` carries the sensor `error` and no cells. Read-only.

Get Rights Reads

Every fetch of the rights surfaces (/.well-known/tdmrep.json, /license.xml, /tdm-policy) over a window (days: 1-90, default 30), newest first, from the edge's full-fidelity stream: `reads[]` of {observed_at, family, vendor, purpose, path, hits}. No user-agent string is carried; the family and vendor are the edge's classification of it. `cadence[]` folds the same reads per (family, path): reads, first, last, `median_interval_s`, `regularity` (coefficient of variation of the gaps between reads, 0 is a metronome, null under two gaps) and `poller` (three reads or more at regularity 0.5 or under: a scheduled fetch rather than a visit). `ai_rights` gives the AI-training families' rights reads counted twice, `aggregate` from the summary's dataset and `detail` from this one; the two are written by different paths at the edge and a gap between them is a sensor finding, not a rounding. `truncated: true` means the stream hit the edge's 500-row cap and the OLDEST reads in the window are missing. `ok: false` carries the s

Get RSS feed activity statistics

Returns the most recent RSS feed request timestamp + 24h / 7d / 30d totals + unique visitor counts. Backed by the sn_rss_tracker module. Use to verify RSS feed traffic before changing feed structure or auditing crawler activity.

Inbound-link pass for new notes (stored report)

Every published note with ZERO inbound links, the older notes already judged ready to link to it, and every scheduled note with its outbound link count. PAST: for each published post with no inbound link in the link graph, however old, the pass takes its top related published notes and runs the pair-suggest judgment (older → new); a link verdict with a valid anchor is listed under notes[].pairs[] as outcome:ready with the anchor — the same verdict the link_opportunities worklist reads, so Apply (ai-link-apply, source=older note, target=the unlinked note) is one call. A per-run pair budget bounds model calls; deferred counts what waits for the next run. PRESENT: a publish schedules a run minutes later. FUTURE: scheduled[] lists future posts with outbound (their note links); a scheduled note with outbound:0 is fixable before it publishes. state:unavailable means the AI provider did not answer — fail-closed, never zero pairs; artifact:unbuilt on a note means the ML related artifact had not indexed it yet.

Jev: the stored lane map

The pairs of published notes Jev read as making the same argument (probability at or above 0.5), from the last lane map. Read-only.

Jev: this cycle's spend, by feature

The site's own priced ledger of Jev use: requests, cached hits, failures, input tokens and USD per feature (notes, collision, lane_map, fit) for the current credit cycle, with the credit, the remaining amount and the days left. Priced from reported tokens at the pinned rate; never projected. Read-only.

Jev over the notes: the stored pass

What TypeSafe's Jev judged about each published and scheduled note in the last daily pass (search title as a query, description as a summary, opening naming the subject), the findings above the confidence floor, the count below it, and the pass's own usage. Read-only; nothing here calls Jev.

Jev: the queries each note is seen for and does not answer

The stored fit pass as two lists. gaps: queries with real impressions the note scores under 1 of 2 on, by impressions; the raw material for the next note. stray: clicks on a query the note scores under 0.5 on; a title chasing the wrong search. Read-only.

Jev: the stored tag-fit pass

The notes the last tag-fit pass flagged: attached tags whose subject the note does not touch, scored under 0.5 of 2 at confidence 0.7 or better, with every attached tag's score beside them; and `by_tag`, the same pass pivoted per tag (notes, mean score, the notes that only touch it), which is what a reader of that tag's archive gets. No proposed tags: what a note carries is the owner's call. Read-only; check 31 and the Tags leaf read the same lines.

Jev: the stored anti-tell pass

The notes the last corpus pass flagged, with Jev's rows per paragraph and the regex counts. Read-only.

Keyring Status

Every credential the plugin holds (Connections › Credentials), one row each: its id and group, where its value comes from (`source`: constant | site | option | empty), whether it is set, whether it derives from the site secret, and the last "Verify all" verdict with its sentence (ok | refused | error | unset | none). NEVER a value. `state: never_verified` means Verify all has not run. A `refused` sensor row names which side differs; a `none` verdict means the row has no probe and the tab that uses it is the witness. Read-only; never probes.

Rank a post's own terms as keyword candidates (TF-IDF)

Deterministic candidate generator, no AI: tokenizes the post's body and ranks its own unigrams plus adjacent bigrams (both members must survive tokenization; a stopword between two words breaks adjacency — bigrams are phrases that literally appear) by TF-IDF weight against corpus statistics built over ALL five non-trash statuses, bigrams boosted 1.25x, weights 4dp, sorted weight-descending. Returns candidates for a human to accept as focus keywords or tags — nothing auto-writes. Empty body returns ok with zero candidates (an empty body is an answer); unknown/trash/non-post IDs are a 404.

List Cron Events

Returns scheduled WP-Cron events with next-run, recurrence, last-fired, args, has_handler flag, and is_sn_owned flag. Pass sn_only=true to filter to the SN-owned hooks (e.g. the RSS subscriber-prune hook). Pass hook (and optionally args_signature, which requires hook) to narrow to a single hook's events — this replaces the removed get-cron-event ability; no match returns an empty array, but args_signature without hook is an input error.

Login defense: IPv6 criterion

Returns the login guard IPv6-share criterion: the measured share, the window it was MEASURED over (not the one the query asked for), and the decision both halves authorise. decision is one of build_ranges | withhold_unfinished_window | below_threshold | unknown. The rule (worker v1.5.2): build 128-bit denylist ranges when the IPv6 share of block-eligible traffic exceeds 5% sustained over 30 days. Read `decision`, never `crossed` alone — a crossed line on an unfinished window authorises nothing. THREE window numbers, and they answer different questions: measured_days is a SPAN (now - first_seen); days_covered is how many days ANY family wrote; v6_days_covered is how many days IPv6 ITSELF appeared on. Only v6_days_covered answers "sustained" — an all-family count cannot see an IPv6 burst, and the observations floor stays all-family on purpose, because it is denominator adequacy for the share, not a presence test. share_pct is null when unmeasured; never-measured is not 0%. Read-only.

Per-note signals (the Posts tab as data)

One row per published note over the dense signals the site already syncs, exactly as the S&N Analytics Posts tab paints them: Search Console impressions/clicks/position for the stored window, URL Inspection coverage with coverage_state verbatim and the last crawl, inbound internal links from the live link graph, the anchored provenance version and block (and whether the followed key signed it), the ML kernel's related-note count and top score, and lifetime human views as a RAW number with no verdict. Every field is {value, why}: a null value is an ABSENT signal with its reason, never a zero. flags carries the three binaries derived in one place (not_indexed, stale_crawl, orphaned); read them rather than re-deriving from search-coverage + inbound-pass. counts are counts of binaries over the rows. strip carries the site-wide context every row is read against, including machine reads, which are site-wide ONLY by the sensor's privacy contract. Read-only over stored syncs; never inspects, syncs or probes. Sample s

Provenance integrity sweep status

Returns the latest server-side provenance integrity sweep: summary counts (fleet, checked, clean, failed, unreachable, ledger-key verdict) plus every Note currently failing a triangle leg, each naming WHICH leg (hash mismatch, twin drift, twin unreachable, ledger missing, ledger contradiction). Returns null before the first sweep. Read-only — never triggers a sweep (the Content-Health scan owns that).

Purge Verification Log

Returns the per-row trail of edge-freshness probes as DATA — the same rows the Cloudflare admin tab renders for a human under 'Post-purge probes', which no machine reader could reach. After each post save the plugin waits SN_CF_PROBE_DELAY seconds, fetches the post URL a reader would get and the same URL cache-busted, and compares the normalized <main> region. Call this when the cache widget shows a rising stale count, when asked whether the edge is serving old renders, or before concluding a purge failed. READ THE WINDOW BEFORE THE COUNTS: the log is a rolling buffer capped at 20 entries, so `counts.total` pins at 20 once full and is NOT a lifetime figure — it is the size of the recent window. A rising `counts.stale` against that fixed denominator therefore means the recent failure RATE is rising, not that a lifetime tally is accumulating; reading it the other way inverts the conclusion. `rows` are newest-first, each carrying `time_iso`, `url`, `result` (fresh|stale), `escalated`, `algo`, and `source`

Machine-reader volume and shape deviations

Runs the analytics signal engine over the crawler ledger instead of over human traffic. Adds no statistics: the same median/MAD anomaly detector, Theil-Sen trajectory and Holt forecaster the analytics maturity ladder already ships, fed a DENSER series (69,833 machine requests in 30 days against roughly 130 human visits, measured 2026-09-02). Per eligible family: anomalies over the last 7 days against the 30-day baseline, PLUS a separate binary silence rule. The z detector is nominally two-sided but on this data its DOWN side is unreachable: these are counts bounded below by zero, so the most negative robust z obtainable is 0.6745 * median / MAD, and measured live 2026-09-02 a day of total silence scored |z| 0.74-2.30 against a 3.5 threshold for EVERY eligible family. No threshold fixes that (the ceiling for openai is 0.80), so silence is reported by its own rule: an eligible family — present on at least 20 of 30 days — recording zero hits on a day emits a `reader_silent` signal. Binary, kept separate from

Rights evidence: the monthly records

The site's ledger of rights-evidence records: per month, per AI-training crawler family the sensor saw, the record's uuid, content hash, status (composed, unanchored, pending, confirmed, conflict), ledger path and the last error. One record per family per month, composed from the edge sensor on the first daily pass after the month closes: the reservation in force (the public ledger's rights-signal versions and hashes), every fetch of the rights files by that family, and its crawling per day with the training share. The worker signs and OpenTimestamps-anchors it under `rights-evidence/<uuid>/v1`; `ledger_base` + ledger_path + `.json` is the record, `.ots` its proof. `ready` says whether the worker, its secret and the sensor are configured. Read-only.

Search Console: index coverage per post (stored)

Which of the site's public URLs Google has actually indexed — posts, Pages AND tag archives (v13.109.0: before that the sweep walked posts only, so every Page including the provenance hub and its essays, plus every tag archive, was absent; their zero-impression readings were unanswerable rather than negative). Entries carry kind (post|term) alongside post_id/term_id. From the URL Inspection API, inspected weekly and STORED — reading this never spends inspection quota. Per post: verdict, Google's coverage_state verbatim, indexing/robots/fetch states, last crawl time, canonical agreement, and indexed (true/false; null when Google gave no coverage state — never a guess). Summary counts indexed / not_indexed / unknown / errors, lists not_indexed_paths and canonical_mismatch. This is the discriminator the disagreement scan's no_impressions reading needs: a page with zero impressions is either NOT INDEXED (crawl or quality) or indexed with no query demand (topic), and Search Analytics cannot tell those apart.

Search Console x crawler ledger: do the instruments agree?

Compares Google's impressions with the crawler ledger's search-engine fetches over roughly the same window and names the verdict (agree | gsc_without_crawler | crawler_without_gsc | both_quiet) with the sentence each earns — they are DIFFERENT problems. grain is always "window": this is agreement in magnitude between instruments whose windows do not line up, never a per-page join (the ledger has no path dimension). ok:false with a reason means an instrument did not answer, which is not "zero". Read-only.

Search Console: position drift

Pages whose average Google position worsened materially across the stored history (positive drift = WORSE; worst first). state:"accruing" means the history cannot answer yet and is NOT "no drift" — it carries `progress` {snapshots, span_days, needed_days} so you can see HOW FAR OFF it is rather than only that it is not ready; state:"measured" with an empty list is the real, good zero. Read-only over stored snapshots.

Search Console: the stored window

What the site earns in Google Search over the last synced window (28 days ending ~3 days back): page rows (clicks, impressions, CTR, position; most-shown first), the top queries, near-ranking opportunities (position 8-20 with real impressions — a filter over stored rows, no new fetch), and totals. totals.capped is TRUE when the page rows hit the sync's 250-row limit — then every total is a FLOOR, not a site figure. synced:false with null totals means the property has never synced: that is not a zero. Read-only over data the daily sync already stores.

Payload Shape Stability

Reports whether a payload's STRUCTURE has held still long enough to be frozen — types and keys, never values. Call this before shipping a remote MCP twin, or before any change that copies a payload shape somewhere it becomes expensive to alter: a twin copies its origin output_schema byte-identically, so shipping one freezes that shape and changing it afterwards costs a contract bump plus a worker release. `state` is the answer, per subject: `settled` (unchanged across at least SN_SHAPE_STABLE_READINGS readings spanning at least SN_SHAPE_STABLE_DAYS days — safe to freeze), `settling` (recording, thresholds not met — `reason` says which one is short), `unknown` (never recorded, which is an ABSENCE OF EVIDENCE and never a pass). `readings` and `days` are the measured span since the last change; `since` is when the current shape first appeared. READ `ever_changed` BEFORE INTERPRETING `since`: false means `since` is when recording BEGAN for this subject, true means it is when the shape last MOVED — a recen

Batch-read readership metrics (consolidated)

One coherent answer to "how is the site being read?" — a sectioned batch over the three readership reads: analytics_summary (range totals with the honest-denominator semantics: prefer view_visit_ratio, engagement times are MILLISECONDS), analytics_events (top custom events for the window), and rss_stats (feed fetches and fetchers; its payload carries its own fixed 7d/30d windows). `range` (default 30) applies to analytics_summary and analytics_events; `class` (default human) applies to analytics_summary only; both are validated by the sources, which own their value sets, and both are ignored by rss_stats. Each entry in the returned map carries its source ability's exact payload shape — this tool never reshapes, so answers match the narrow tools byte-for-byte. If a source is unregistered or refuses, that ONE section degrades to {error:"unavailable"} while the rest still return; the call only fails as a whole on invalid input (empty or unknown sections).

List or fetch corpus posts (consolidated)

Consolidated post query, absorbing list-posts (metadata), get-post-content (bodies) and note-dossier (the per-note dossier) into one record: each is an opt-in FIELD, not a different shape. scope selects the target set: {kind:"all"} (default) walks every non-trash post of scope.post_type (default "post"); {kind:"post_ids", post_ids:[...]} fetches a bounded ID set, unknown/trashed IDs reported in `missing` rather than silently dropped; {kind:"modified_since", modified_since:"<date>"} walks posts modified at/after that date, newest-modified first; {kind:"post_type", post_type:"<type>"} walks one specific registered+public type. include_content:true attaches full post_content per row but is REJECTED (422, never silently truncated) when the resolved scope exceeds 20 posts — narrow the scope instead. status:['future',...] narrows to those post statuses (publish/future/draft/pending/private; default all five) and is applied BEFORE pagination, so count and cursor describe the set actually returned. fields:['post_da

Scan the corpus for actionable candidates (consolidated)

Consolidated read-only scan, absorbing block-migrations-scan, pattern-adoption-scan, duplicate-body-scan, near-duplicate-scan, and link-candidates, plus a sixth source (orphan_media, a pure-SQL detector previously reachable only via the AI-gated ai-orphan-suggest path). scan_type takes exactly ONE value per call — cost profiles differ by an order of magnitude (near_duplicate is O(n^2) pair comparison; block_migrations/pattern_adoption/duplicate_body/orphan_media are O(n) walks; link_candidates is O(n) artifact reads) and a caller should feel that rather than have it hidden behind a convenience flag. scan_type "anchor_violations" applies two BINARY link rules over the corpus (scheduled posts included): anchor_equals_sentence (an <a>'s anchor text is identical to the full sentence containing it, terminal punctuation ignored) and heading_contains_link (any <a> inside an h1–h6; a heading wrapped entirely in a link reports under this rule only, never both). No thresholds and deliberately NO anchor/sentence len

Batch-read site facts (consolidated)

Consolidated read for 14 site facts otherwise requiring sequential calls (get-design-system-summary is retired, not absorbed — its raw counterpart design_tokens supersedes it): theme_version, latest_theme_tag, design_tokens, block_patterns, template_overrides, active_template, llms_txt, seo_route_meta, pillars, reading_time, scan_telemetry, tool_telemetry, configuration_drift, pattern_content. pattern_content (v13.3.0) is plugin-internal: ONE registered block pattern's full record INCLUDING its serialized markup, by exact name via the top-level `pattern` input (REQUIRED when this fact is requested; 400 if missing) — block_patterns lists names/titles/keywords but not markup, which is enough to know a pattern exists and not enough to author against it, so a caller composing blocks for sn-apply block_insert/block_replace had to guess. A name the registry does not hold returns {registered:false, name} in the fact slot — an answer, distinct from {error:"unavailable"} (read path missing). configuration_drift

Batch-read operational status (consolidated)

One coherent answer to "what is the site's operational state?" — a sectioned batch over the ten narrow status reads: uptime (Better Stack readout), deploy (worker/plugin/theme deploy state), health_scan (last cached content-health summary; null when no scan has run), anchor (provenance OTS anchoring state), provenance_integrity (ledger integrity readout), ipv6_criterion (the pre-committed login-defense gauge: share_pct, measured_days, window_complete, and a named decision), ai_cache_probe (whether Anthropic prompt caching would pay, from recorded calls), cadence (publish + cron rhythm deviations), cron_scheduled (currently scheduled cron events), and cron_history (recorded firings of ONE hook — `hook` is REQUIRED input when this section is requested, because the source ability has no all-hooks default; 400 if missing, ignored by every other section). Pass the subset you need in `sections`; each entry in the returned map carries its source ability's exact payload shape — this tool never reshapes, so answ

Validate proposed content before writing (consolidated, deterministic)

Deterministic, model-free validation of proposed content — the verification layer behind the ai-*-suggest tools, not a replacement generator. Every check is either an ERROR (objective rule violation, blocks ready_to_apply), a WARNING (heuristic signal, never blocks), or INFO (evidence for a human judgment call — brand_voice findings are never a score or a verdict). Stateless and side-effect free: call it as many times as needed while iterating on a draft. Zero model calls, ever — every check is a pure read + compute against the corpus (length caps, corpus-wide collision checks, link-graph state, tag vocabulary membership, block-pattern registry). checks:"all" with no proposed content validates the post's currently PUBLISHED surfaces instead of erroring. DRAFTING HARNESS: post_id is required, but proposed content does NOT need to belong to that post — pass any existing corpus post_id with compare_against:"none" and the body/tags/excerpt/meta checks evaluate the proposed content entirely on its own term

Read the corpus topic partition

Deterministic topic map, no AI: the stored partition of published notes into topics — connected components over TF-IDF cosine similarity, computed at artifact-build time (publish transitions + the nightly rebuild), never on demand. Each cluster: {members: [post IDs ascending], label: top shared terms}. Singletons are excluded (a topic needs two notes). Returns a 503 while the ML artifacts are unbuilt; an empty cluster list is a real answer, not an error.

Get Better Stack uptime status

Returns the Better Stack monitor + heartbeat states (name, status, level) from a 90s server-side cache, plus 30d/90d availability and 30d incident counts when the warmer has the caches warm (never fetched on this path). Pass detail=true for the full monitor payload: 30d + 90d availability, incident counts, average response times (24h), and the recent-incidents log (independently cached tiers: 1h/6h/15min/5min). Pass force_refresh=true to bypass the status cache. Read-only; safe to call anytime. configured=false means no API token is saved yet (not an error); null stats mean that summary tier was unavailable (statuses are still authoritative).

Watches Due

Returns the registered watches — decisions deferred to a later date or a later STATE — and which have come due. Call this when asked what is outstanding, before planning work, or when a session resumes and needs to know what the site has been waiting on. `ripe` lists only watches that have come due; an empty `ripe` list means nothing needs attention, which is the normal state and is NOT an error. Each row carries `label`, `note` (the evidence that ripened it, or the date), `read` (the exact call that answers it) and `why` (what acting on it means). `date_only` distinguishes the two kinds and matters: a state-tested watch ripened because something measurable changed, while a date-only watch ripened because a clock passed and NOTHING was measured — those warrant different confidence. A watch that cannot be tested (its module absent, its reader unavailable) is never reported ripe, on the same rule the rest of this plugin keeps: absence of evidence is not a finding. Read-only; evaluates live state and store

Zenodo DOI status

Whether the site's signed documents (notes and pillar essays) carry Zenodo DOIs: the environment (sandbox or production), whether a token is set, every document's state counted (minted, ready, anchor-pending, sandbox, or a failed deposit with its error), and the rows not yet minted. Read-only; deposits run from the anchor confirmation and the hourly pass.

What its catalog declares

From the ARD catalog this host publishes at /.well-known/ai-catalog.json. The operator controls every entry; agenttru.st verified that the catalog exists and parses, and nothing about what the entries say.

Signal & Noise MCP server (read)

mcp-server-card
https://juanlentino.com/.well-known/mcp/server-card.json

API catalog

linkset
https://juanlentino.com/.well-known/api-catalog

llms.txt reading list

text/markdown
https://juanlentino.com/llms.txt

Notes JSON Feed

feed
https://juanlentino.com/feed/json/

Note provenance verification

text/html
https://juanlentino.com/verify/

Text-and-data-mining policy

text/html
https://juanlentino.com/tdm-policy/

Technical agent card

Copied from the agent's card. The operator controls these values; agenttru.st has not verified them.

Provider
Juan Lentino — what this agent says about itself; other agents claiming the same provider are not thereby related
Protocol
a2a
Version
18.6.2
Card completeness
complete all eight fields required by a2a.proto v1.0
View all card details
Capabilities
pushNotifications stateTransitionHistory streaming
Agent card
https://juanlentino.com/.well-known/agent-card.json

Operate this agent and would rather not be listed? Request removal.