01Safety
0.0 / 30
What changed in the harness
Selection accuracy 98→96, token cost up 1%, unconfirmed writes 0%→0%.
Category breakdown
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
0.0 / 30
27.6 / 30
13.3 / 20
13.8 / 20
Highest-impact fix
Estimated gain +30 pointsExpose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
3 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
read_llm_discovery |
no_return_description |
Fetch the contents of an IntoDNS.ai LLM/agent discovery file for IntoDNS.ai itself. `file` selects which file to retrieve: llms.txt (canonical agent index, default), llms-full.txt (full prompt-ready context), llms.json (structured prompt routing), llm/api.md (Markdown API guide), openapi.json (OpenAPI 3.1 spec), or postman.json (Postman collection). Returns the selected file's raw content as text (or JSON as appropriate) so an agent can read the canonical citation URLs, the machine-readable API surface, or prompt-routing hints for IntoDNS.ai. Pure HTTPS GET, no auth, no side effects. Use read_llm_discovery when you need raw discovery data; use get_citation_guidance for a topic-narrowed citation list. |
explain_issue |
params_unexplained |
Ask the IntoDNS.ai AI service for a plain-language explanation of one specific scan finding, identified by the `issue` parameter — one of the enum issue codes (e.g. `spf_missing` or `no_dnssec`) typically taken from scan_domain or get_everything_report output. Returns severity, business impact, root cause, and recommended fix steps as structured text. Read-only POST to /ai/explain — never mutates DNS or domain state. Provide `domain` and `issue`; optionally pass `context` from prior scan output (e.g. scan_domain result) for higher-quality answers. Use after scan_domain when an agent needs to walk a user through why a finding matters; use generate_dns_fix for the actual DNS record snippet that resolves it. |
generate_dns_fix |
params_unexplained |
Generate copy-pasteable DNS record snippets that fix one specific scan finding, identified by the `issue` parameter — one of the enum issue codes (e.g. `spf_missing`, yielding a suggested SPF record) typically taken from scan_domain or explain_issue output. Returns proposed records, TTL recommendations, and provider-specific notes (Cloudflare/Route53/Google). Read-only POST to /ai/fix — the API only suggests; it never modifies the user's zone. Provide `domain` and `issue`; optionally pass `context` from prior scan output for tailored output. Use after explain_issue or scan_domain identifies a problem; use lookup_dns afterwards to verify the user has applied the suggested record. |
Selection evidence
6 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
analyze_security_headers |
generate_security_headers |
medium | Both concern the same security-header domain and both return recommended configs plus ready-to-paste snippets, so a task like 'set up / add / fix security headers for example.com' could make the agent pick the generator (no domain needed, no scan) or the analyzer (domain-scanning, returns the same copy-paste fixes). The intended workflow (analyze first, then generate) is cross-referenced inside the descriptions, but a single-shot request does not force that order. |
create_report_snapshot |
get_report_snapshot |
medium | Near-identical names and identical JSON/Markdown report payloads with heavy shared tokens (report, snapshot). A task phrased as 'get me a snapshot of the current report for the audit' is ambiguous: create_report_snapshot needs only a domain and creates the immutable evidence, while get_report_snapshot requires a snapshotId that exists only after a create. An agent may select the read variant and then fail on the required snapshotId, or pick create for what was meant as a retrieval. |
get_email_test |
poll_email_test |
medium | Both operate on the same testId and both return the pending/finished status plus full SPF/DKIM/DMARC results. A natural task like 'get / fetch / check the results of my email test' could map to either the passive read (get_email_test) or the processing variant (poll_email_test); the descriptions distinguish only by whether parsing is actively triggered, which is rarely stated in the user request. |
lookup_dns |
whois_lookup |
medium | Both are free-form read-only 'lookup a domain' tools, and a terse task such as 'look up example.com' or 'tell me about this domain' is genuinely ambiguous between DNS record lookup and WHOIS ownership/registration lookup. Since neither description names the other, the agent must guess intent from the word 'lookup' alone. |
check_spf |
flatten_spf |
low | Both accept only a domain and both address the same RFC-7208 10-lookup problem: check_spf returns the lookup graph with flattening guidance when near the limit, while flatten_spf returns the flattened record itself. A task phrased as 'my SPF is failing / our SPF has too many DNS lookups' could plausibly route to either the diagnostic or the fix tool, though explicit 'check' vs 'flatten' phrasing usually disambiguates. |
get_pdf_report_link |
get_badge_link |
low | Both are pure URL-construction tools with identical signatures (domain only, no scan, no auth) and both return a link for the domain's score/report. A vague request like 'give me a link for example.com' is ambiguous between a downloadable PDF report URL and an embeddable score badge, though mentioning PDF vs badge clearly picks one. |
Compare the field