---
name: w3ds-verification-method
description: "Use when a W3DS query returns nothing, when deciding whether something exists in the ecosystem, when a probe or fix appears to work, when reporting a task done, or when about to tell a user a capability is missing. Extends the base skill's 'When you cannot verify' with how to know when you HAVE verified. These rules are generic, but W3DS punishes breaking them unusually hard."
license: Apache 2.0
---

# Knowing when you have actually verified

W3DS makes ordinary sloppiness expensive. Failures here are silent by construction: an unregistered `schemaId` works locally, an ACL cannot be read back, a tenant selection makes correct data invisible, an update overwrites with no history to restore from, and a write lands successfully on a vault nobody will look at. Almost nothing throws.

So the usual habit — try it, see no error, move on — produces confident wrong statements rather than bugs you can find later. These are the rules that caught ours.

## The authority order

**told > declared > measured > inferred.**

- **told** — the owner or user stated it.
- **declared** — the platform's own self-description says so about its own behaviour.
- **measured** — you probed it.
- **inferred** — you worked it out.

Two consequences people get backwards:

- **A platform's declaration outranks your measurement of it.** Where your data contradicts a declaration, *that contradiction is the finding* — and it is almost always about your reader, not about the protocol. Twice, confident wrong answers about protocol mechanics came from querying derived tables when the platform's own declaration was one fetch away.
- **"Measured" is not the strongest word.** A knowledge store that ranks incoming facts by this scale will *discard* a `measured` correction to a `declared` claim and report success. That happened: a correction was re-seeded as `measured` on a note stored as `declared`, thinking measured was stronger; the update vanished and the tool printed "seeded" exactly as if it had worked. **Read the row back after writing a correction.**

Label every derived claim with which of the four it is, and with its provenance. An inference presented as a fact is the defect, even when the value happens to be right.

## An empty result is not a fact

An empty query result is evidence about the **query** until the query itself has been checked.

Never convert it into a claim about the world — *"X does not exist"*, *"we have no Y"* — and never let it justify a decision, before confirming the query can find a **known-present control case**.

When the context already contradicts the emptiness — someone told you the thing exists — the contradiction **outranks** the query.

### A failed probe is re-thought, never re-run

When a probe returns nothing, the emptiness is evidence about the probe. Before running it again: name the probe's assumptions — which vault, which ontology, which date filter, which field, which HTTP method — and **change one**.

Re-running an unchanged failed probe is a decision to fail again. It happened over two hours and roughly twenty identical searches, answering "there is no transcript" while the answer sat in the query's own output, cut off by a date filter nobody questioned.

And when reporting, report the method: *"I searched this way and found nothing"* — never *"it doesn't exist."*

### A paged listing does not prove absence

Reading N pages and not finding something proves nothing when the listing is longer than N pages. That is a limit, not an absence. Verify by addressing the id directly, or with a targeted search.

### The asker's "when" and "what" are hints, not filters

When someone half-remembers what they are looking for, **every parameter in their question is as uncertain as the thing they forgot.** "A couple of weeks ago", "I think in chat X", "something about Y" are things to rank by, never boundaries to cut by. A person who says "we don't remember which one" is telling you their memory is unreliable — and their date came from the same memory.

Search unbounded first, rank by the hint, narrow only after something is found. When a search fails, the **date filter is the first assumption to drop, not the last**.

Corollary: search for the **evidence of the fact**, not for a sentence stating it. A handover of ownership usually leaves no quotable "I hereby take this over"; it shows up as the person already behaving as owner. Looking only for the speech act finds nothing and calls it absence.

## A rule nobody executed is not a rule

A constraint written in a declarative format — a JSON Schema keyword, a check constraint, a validation config — enforces **nothing** until something has been observed rejecting a bad input.

Declarative rules fail **silently** when the validator does not know the keyword: it is ignored, not reported, and the rule reads as active to every human who opens the file.

**Write the negative test before believing the constraint.** In W3DS this is not hypothetical — a registered ontology constrains nothing at write time, so a schema is documentation until something validates against it.

Related: a validator that rejects the *total* failure usually lets the *partial* one through, and the partial one is what real code produces. Test the shrunk case, not just the empty one.

## A fix to the reading is not a fix until something runs it

Repairing how something is **read** changes nothing until something **triggers** the read.

A repair that only ever runs when a person invokes it by hand is not deployed — it is demonstrated. And invoking it by hand and calling that a verification hides the gap from the one person who could have seen it.

Ask, explicitly: what will run this, and when, without me?

## Finish with an observation, not an argument

A change is finished when its **effect has been seen** — the rendered page, the row in the database, the plan the query actually got, the record that displays. Until then, say what was changed and what remains unverified.

Two real reports that were wrong in exactly this shape: *"the join is hashable now"* without reading the plan, and *"avatar set, refresh the chat"* without checking a record that renders.

And never report an intention in the past tense. A description of what you meant to do, delivered as a result, is a false report — `grep` your own claim before writing it down.

Related trap when the measurement runs with elevated rights: an `EXPLAIN` run as superuser bypasses row-level security and produces a plan the application will never get. Reproduce the application's role and search path before trusting anything you measure.

## Before saying a capability is missing

Never answer "I have no such feature" to a do-this request until you have checked, in order:

1. **Does an ontology for it exist?** Across all the circles — registry, platform self-descriptions, live data. Not the registry alone.
2. **Does the target vault already hold records of that type?** If so the field shape is settled: copy it, field for field. Existing data is the specification.
3. **Can it be written?** Owner's own vault, owner-only ACL, the sanctioned write path.
4. **Only then** say no — and say what you looked at.

**An unchecked "no" is as false as an unchecked "yes", and worse, because it sounds careful.** This rule exists because "I have no timer, saying I'd set one would be a lie" was answered to a request for a reminder while the vault already held eighteen of them with the exact fields ready to copy.

### And when there is a clock, act first

A capability question can wait; a deadline cannot. If the request has a time on it, do it, then discuss. The reminder above was for 21:30; by the time the wrong answer and a detour through the wrong data source were finished, it was 21:37.

## Copy the working instance

When something already works somewhere and you are making another thing work the same way: **find the working instance and copy it**, rather than reconstructing it from how it ought to be built.

The trigger is not "a question about the protocol." It is "this already works for someone." In one day this was missed four times, and each answer was one query away: the platform's own declaration, the list of real names, the query plan, the record whose avatar actually renders.

## When something sits unhandled, read the log of the thing that handled it

A pipeline that reads, understands, matches and writes has four places to stop, and they look identical from the outside. The queue row shows the outcome; only the log shows which step produced it. Read it before theorising.

## Decide by self-correction, not by importance

When the same defect appears twice, what separates "fix now" from "record and move on" is **not** how much it matters — it is whether the system has a path that repairs the wrong value on its own.

A failure that writes a value once and is never revisited is terminal, however small it looks. And the self-healing path is itself a **dependency**: name it in the code, because a refactor that removes it turns a wasted retry into a permanent falsehood without touching anything that looks buggy.

## Keep what was wrong

A belief proven false is **refuted, never deleted**. "We believed this and it was false" is what stops the same theory being rebuilt from the same data next month.

Keep the refuted claim, the evidence against it, and the date. A knowledge base of only true things loses the reason each one is phrased the way it is.

## Attribute the verb to whoever performed the action

In anything written for a person, the verb must belong to its actor. Attributing your own aggregation to the source — *"they named four"* when they named two and you assembled the rest — is a defect even when every item is correct: value right, origin right, action borrowed.

It cannot be caught by reading the code that produced the text, or by re-reading the diff. It is caught by printing the finished output and reading it as its reader, who has no way to check.

## Checklist before reporting done

- [ ] Every claim is labelled told / declared / measured / inferred, with provenance.
- [ ] No "does not exist" rests on a query that was not tested against a known-present control.
- [ ] Any probe that returned nothing was re-thought with one assumption changed, and the search method is reported.
- [ ] Every constraint relied on has been seen rejecting a bad input.
- [ ] Something other than a human hand will trigger the code path that was fixed.
- [ ] The effect was **seen** — not inferred from the diff — and whatever remains unverified is named as such.
- [ ] Nothing declines a request before the four capability checks were run.
