Skip to content
Console
Browse documentation
Guide

Compare declared coverage with observations

Ask your agent to declare the services, route templates and screens read from code, then compare them with an exact window.

On this page

A coverage declaration says what your application should report. Your agent reads the code and writes the inventory. Anectico compares it with what was observed for one project, environment, application release and exact window. A result says declared but not observed in this window. It cannot say why nothing arrived.

Ask your agent

"Read this application's routes, screens and service names. Show me a declaration for release v1.2.0 in production. Validate it first. After I approve it, save it and compare it with yesterday's traffic. What should be reporting and was not observed?"

Your agent uses validate_coverage_declaration, get_coverage_declaration, list_coverage_revisions, get_observed_coverage and compare_coverage through execute_read_action. The writes declare_coverage and withdraw_coverage go through execute_internal_action: preview first, then repeat identical arguments with the confirmation token. The CLI commands are anectico coverage declare, show, revisions, observed, compare and withdraw. The CLI reads the file as data. It never parses or runs source code.

The declaration file

Use JSON with exactly these three arrays. Each service or screen carries a name; each route carries a service, method and route_template. A short note is optional on every entry. Environment and release are command arguments, not fields in the file.

{
  "services": [{"name": "shop-api", "note": "Public shop requests"}],
  "routes": [
    {"service": "shop-api", "method": "GET", "route_template": "/orders/{id}"},
    {"service": "shop-api", "method": "POST", "route_template": "/checkout"}
  ],
  "screens": [{"name": "Checkout"}, {"name": "/orders/{id}"}]
}

Read service names from the configuration that reports service.name. Read HTTP templates from the router: /orders/{id}, /orders/:id and /orders/<id> describe a parameter. Never copy an actual customer URL. Read mobile screen names from navigation, and web page templates from the page router. A named mobile screen does not start with /.

There are at most 5,000 entries in a 2 MiB document and 10,000 revisions per project. Names, environment, release and templates have at most 512 ASCII bytes; notes have at most 200 ASCII bytes. Operational names start with a letter or number and use letters, numbers, _, ., + or -. Release also accepts a bare 40- or 64-character hexadecimal software revision. Notes use ordinary letters, numbers, spaces and limited punctuation: . , _ : / ( ) -.

Paths start with /. Static segments use letters, numbers, _, . or -; parameter names use letters, numbers and _, starting with a letter or _. Empty or dot segments, query strings, fragments, percent escapes, email addresses, UUIDs, long numbers (six or more consecutive digits) and long hexadecimal identifiers are refused. Use a template instead. Invisible characters and instruction sentences are refused as names. Duplicate entries, including equivalent parameter spellings, are refused. Anectico reports the refusals and does not repair the file.

anectico coverage declare --file coverage.json --environment production --release v1.2.0 --dry-run
# Read the preview with the person. Their approval authorizes the next command.
anectico coverage declare --file coverage.json --environment production --release v1.2.0 --yes
anectico coverage show --environment production --release v1.2.0
anectico coverage compare --environment production --release v1.2.0 \
  --start 2026-10-09T00:00:00Z --end 2026-10-10T00:00:00Z
anectico coverage observed --environment production --release v1.2.0 \
  --start 2026-10-09T00:00:00Z --end 2026-10-10T00:00:00Z

The dry run saves no declaration and reserves no revision. It returns the proposed content and verified principal; the declaration time is the server's commit clock. A save creates a revision. Its content stays fixed except for person erasure. The latest is current; show --revision 1 reads retained history and revisions lists metadata newest first. A withdrawal creates an empty withdrawal revision and retains earlier revisions. Project or workspace deletion removes the entire history.

The CLI prints --idempotency-key and --expected-revision before writing. Keep both, the same file and all the same arguments after an uncertain response; the server replays the original receipt without a second save. A different request with that key is refused. A stale revision requires a new preview and approval.

Supported methods are GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, CONNECT and TRACE. They may be supplied in either case. Release strings also accept a bare 40- or 64-character software revision hash; identifiers in service/screen names and concrete paths remain refused.

Read the comparison lists

List Meaning
declared_and_observed A declared entry matched observations. Each match names its rule, count and first/last times.
declared_not_observed No matching observation in a fully measured kind in this window.
observed_not_declared An observed key matched no entry in this declaration.
not_determined A kind could not be checked, or a declared comparison key was withheld by erasure.
observed_not_determined Erased declaration keys prevent deciding whether these observations were declared.

Declared entries partition into matched, not observed and not determined. Measured observed keys partition into matched, not declared and not determined. Several equivalent observed template spellings can match one declaration; matched_observed_count counts those keys separately. Unknown counts are absent, never a synthetic zero. not_determined_count counts the declaration entries in unavailable kinds.

Service names match exactly. HTTP methods are compared in uppercase. A whole {name}, :name or <name> segment becomes the same placeholder, and one trailing slash is removed. Web page templates follow that path rule; mobile screen names match exactly. Nothing fuzzier is inferred. Every match says exact or normalized_method_parameters_trailing_slash.

The window has an absolute inclusive start and exclusive end, at most seven days, ending no later than now. A kind outside retained history is unavailable; the window is never silently shortened. Each kind has a 10,000,000-row scan budget, a ten-second read budget and at most 5,000 distinct keys. A bound cut makes the whole kind scan_limit; it returns no partial list or count.

Routes come only from reported http.route. Spans that report only raw URLs, or unsafe concrete route values, contribute to no_route_template and are never listed as paths. Screens come from $screen / $screen_name or $pageview / $pathname. Sender names are bounded untrusted data. An altered label has no exact matching entry; its separate digest key prevents truncated labels from being merged or reused as lookup arguments.

Permissions

Declaration reads need tracking_plans:read and projects:read to check the current project. A complete comparison also needs query:read, traces:read for services and routes, and analytics:read for screens and sampling declarations. Observed-only reads start with query:read. MCP reads also need mcp:read. A kind that lacks permission names the missing scope and withholds its observations and counts.

Declaring needs an owner-created API key with tracking_plans:write, tracking_plans:read, projects:read, mcp:read and mcp:write. Withdrawal needs tracking_plans:delete instead of the write scope. An OAuth connection can use the read-only part. A declaration changes expected instrumentation configuration; it does not grant telemetry access or change capture.

Limits of the answer

Server-side capture completeness is unknown. A declaration does not prove that the code was deployed or received traffic. Little traffic makes "not observed" weak evidence. The answer gives the total stored spans plus screen/page events beside it when both counts are available; route counts overlap the spans and are not added twice.

If an observation has no release, it is compared by this window alone and counted in no_release. Versioned telemetry is filtered to the requested release. Reported sampling declarations are named with their rates; they cover coarse hour overlaps and are sender claims. The current project sampling rate is named separately when projects:read is present; it does not reconstruct the historical window. An unavailable sampling read is not proof that sampling was absent. The conclusion counts observations under these rules; withheld, failed or cut kinds make its certainty estimated.

There is no comparison proof page and no returned link. Read the exact window, comparison lists and limits to the person. Say declared but not observed in this window, never infer a broken application or missing instrumentation from silence.

Screen content permissions

Observed screen names and page paths need analytics:read plus agents:content:read, with permission from the project content policy. A valid path shape can still contain a person's name. When either content control refuses the read, the entire screen kind is withheld, with no entries or derived counts. Comparison puts its declared screens in not_determined; it never concludes that a screen was absent. The result names a missing content scope, or a policy refusal when a broader key would not help. Your declared names and notes remain your configuration, returned as untrusted text.

Person erasure replaces matching entry names, services, paths and notes in every revision with [withheld by erasure]. Reads show erasure_changed and redacted_fields. A redacted name or other comparison key is withheld by erasure, never declared but not observed. A redacted note does not change the comparison. A later save that restores matched erased text is refused. Shared declaration text stays out of a person's export. Matching uses held names and identifiers with at least four letters or digits. Nicknames, descriptions and unknown names may not match. Release and environment names identify your software and are not searched as prose.