Category: Agent workflows

Recall, verify, monitor: one backlink pipeline for your agent

Walk a backlink candidate from an import or the owned corpus through one bounded verification batch and into a monitored placement, command by command.

By AgentLinkOps editorial team · · 9 min read

Recall, verify, monitor: one backlink pipeline for your agent: three sequential stages in a backlink workflow.

A backlink candidate moves through three stages in AgentLinkOps: recall it from an import or the owned corpus, verify it in one bounded batch, then convert the present result into a monitored placement. Each stage runs through documented commands with their own records, and the record from one stage travels into the next. Nothing skips ahead: recall never checks a page, a check never starts monitoring, and monitoring keeps the candidate lineage it came from.

This article walks the three stages with the command names an MCP client or REST caller uses. The single-candidate path described in the backlink MCP workflow still exists and is unchanged. The batch path adds a way to verify up to fifty stored candidates under one budget reservation and to enroll monitoring as an explicit step. The discovery use cases explain which placement job a candidate serves; this page explains what happens to the candidate once you have chosen one.

Why the three stages are one pipeline

Three separate features leave three gaps. A candidate list with no check invites a reader to treat rows as placements. A check with no path into monitoring makes the agent re-register a URL by hand and lose the reason it was checked. A watch with no lineage cannot say which import, which run and which observation justified it.

The pipeline closes those gaps with records. Every candidate carries its run and provider. Every verification job carries its candidate and an immutable observation. Every converted watch carries the run, candidate, job and observation that produced it. Your agent can read any point in the chain and explain how the record got there. The discovery versus monitoring guide covers why the two ends of that chain need different vocabulary.

Recall: candidates from an import or the owned corpus

Recall answers one question: which source and target pairs might be worth a check? Two commands supply candidates today.

import_backlinks stores a supplier export you already own as discovery candidates. Every row needs a source URL and a target URL. Invalid rows are returned with their positions while valid neighbors continue, the supplier name stays in provenance, and an omitted supplier date stays null rather than borrowing the import date. Re-importing the same scope, supplier and rows reuses the run. The CSV import walkthrough shows the column map and the rejected-row output.

discover_backlinks queries a configured owned corpus for bounded candidates with dated evidence. Its request requires explicit choices for subdomains, backlink status, internal backlinks, page limit and row limit. Where owned discovery is not configured, the error names the operator change required, and import_backlinks remains available. Live supplier discovery is disabled in this build and stops with PROVIDER_NOT_CONFIGURED before anything is saved.

Either way, list_discovery_candidates reads up to 100 candidates from the saved run with their provider provenance and a separate verification status. The first page freezes a stored snapshot; restart without a cursor for newer results. Each candidate starts as not_checked, with no observation behind it. Registration is not verification, and the walkthrough shows a real candidate record in that state.

Your agent's judgement belongs between recall and verify. Reading the page, deciding whether the publisher covers your subject and choosing which rows deserve a metered check is the work the candidate evaluation guide describes. A batch verifies the candidates you selected; it never selects for you.

Verify: one bounded batch, one reservation, every outcome visible

verify_discovery_candidates queues checks for 1 to 50 selected stored candidates from one run, under one workspace budget reservation, and requires an idempotencyKey. The response returns every item outcome, including budget rejections. Verification is asynchronous and does not enroll monitoring. Here is what the admission decides, in input order:

Item outcomeWhat it means
queuedThe candidate was admitted, a job exists and one check unit is reserved for it
DISCOVERY_CANDIDATE_NOT_FOUNDThe ID does not resolve inside the authorized run; foreign records are never revealed
NONCANONICAL_CANDIDATE_URLThe stored URL does not match its canonical form, so no fetch is attempted
DUPLICATE_PLACEMENTAn earlier item in the same batch resolves to the same source and target, so this one is not scheduled twice
CHECK_QUOTA_EXCEEDEDWorkspace headroom ran out before this item; earlier admitted items keep their units

That last row is how exhaustion stays honest. If the workspace has headroom for twelve checks and you submit twenty eligible items, the first twelve are admitted and the remaining eight are marked CHECK_QUOTA_EXCEEDED in the same durable batch. Zero headroom produces a batch with every eligible item rejected, no jobs and no reservation. The batch never reports completion from the admitted prefix alone, and a rejected batch does not become new work when replayed after headroom changes.

Replaying the same idempotencyKey returns the same batch, the same item decisions and the same job IDs without a second reservation. Use it after a network failure. A different payload under the same idempotencyKey is refused with IDEMPOTENCY_CONFLICT.

get_candidate_verification_batch reads the batch by its identifier: per-item state, each job's own observation, and the reserved, consumed and released check units. The batch is pending while any admitted job is still running, then completed if every requested item succeeded, partial if some did, or failed if none did. Inspect the items even when the aggregate says completed, because job success is separate from link state.

Three observation states matter here. present means a complete page read found a link matching the target scope. absent means a complete page read found none. unknown means the check could not establish either, with a named reason: a timeout, a rate limit, a robots refusal, a login wall or a page a plain fetch cannot read. Under RFC 9309, a robots file that is unreachable because of a server error means the crawler "MUST assume complete disallow", so the verifier reports that refusal as an unknown rather than guessing. An unknown observation consumes one check unit, because a fetch happened. The product documentation states the rule the pipeline is built on: "An unknown result is never a removal finding." Unknown never means the link was removed, and it never counts as absence.

A synthetic six-item batch, for illustration only:

OrdinalCandidateAdmissionJob resultObservation
1Community resource listqueuedsucceededpresent, anchor and rel tokens recorded
2Archived handbook PDF pagequeuedsucceededabsent, complete read
3Publisher behind a login wallqueuedsucceededunknown, reason possible_login_wall
4Same page as item 1, different rowDUPLICATE_PLACEMENTnonenone
5Row whose ID was mistypedDISCOVERY_CANDIDATE_NOT_FOUNDnonenone
6Tutorial page, headroom exhaustedCHECK_QUOTA_EXCEEDEDnonenone

The batch is partial. Three units were consumed, none are outstanding, and items 4 to 6 explain themselves. Only item 1 can move to the next stage. Item 3 is a candidate for a retry or a browser visit, and its unknown is not evidence that the page dropped anything.

Monitor: convert a present verification into a watch with provenance

monitor_discovery_candidate explicitly enrolls the watch from a completed present candidate verification. It takes the verification job ID, an idempotencyKey and an optional cadence, defaulting to one check a day within the same 3,600 to 2,592,000 second range every hosted watch uses. Only a succeeded job with a present observation qualifies; an absent or unknown result is refused with CANDIDATE_NOT_VERIFIED_PRESENT. Active-watch limits apply, and a quota failure rolls back the conversion receipt and the activation together.

Provenance travels with the watch. Reading it with get_link_watch returns a discovery_provenance field carrying the run ID, candidate ID, verification job ID, observation ID, your local reference and the conversion time. One read answers why this page is being monitored, months after the decision.

Replay is deliberately conservative. Sending the same conversion idempotencyKey again returns the watch's current status and never reactivates a watch you paused after the conversion. Verification alone never activates anything either: the paused watch created at verification time stays paused until this command, or a plain monitor_link call, activates it.

From here the placement is an ordinary monitored watch. The last verified state and the latest attempt stay separate fields. Confirmed loss needs two complete absent observations at least 30 minutes apart, and an unknown between them does not advance that clock. The methodology page walks the state transitions, and the monitoring hub covers how to read a missing-link result before acting on it.

A request your agent can run

Here is a bounded brief for the whole pipeline, written for a fictional outdoor publisher. It names the run, the ceiling and the stopping points.

Read run dr_example with list_discovery_candidates. Shortlist the rows
whose source page covers trail access and explain each choice.
Verify at most 15 of them in one batch with verify_discovery_candidates,
using idempotencyKey trail-access-batch-1. Poll get_candidate_verification_batch
until it is no longer pending. For each item, report its admission
outcome, job result and observation state with its reason.
Do not enroll monitoring. List the present items so I can choose
which ones to convert with monitor_discovery_candidate.

The brief keeps monitoring behind a human decision, keeps the check budget explicit and asks for every outcome rather than a summary. The MCP tools specification describes how a client lists the connected catalog, so the agent can confirm the three commands are present on its connection before it plans around them. Submitting a batch needs the discovery read and watch write scopes; reading one needs only the read scopes. The permissions guide explains why a read grant does not include a check, and the access and data page lists every scope.

What is live today

The three batch commands are registered in the tool registry, exercised by the repository's Workerd test suite and included in the production release recorded on September 16, 2026, which serves 88 authenticated commands. No authenticated batch run against that deployment has been recorded yet, so this page describes the documented contract rather than a measured production run. The tool catalog shows each command's state, and the what your agent can prove page keeps the verifier's own limits beside its results.

Live supplier discovery stays disabled. Imports and the owned corpus are how candidates arrive. The service sends no outreach and creates no watch on its own. Your agent reads, judges and asks; you decide which present results deserve a schedule.

Sources

  1. Read evidence without turning uncertainty into loss · AgentLinkOps documentation · Not dated; accessed September 16, 2026
  2. RFC 9309: Robots Exclusion Protocol · Internet Engineering Task Force · September 2022
  3. Tools · Model Context Protocol · 2025-11-25