Stable IRI: https://taprun.dev/ns/tap-v1
JSON-LD context: index.jsonld
Version: tap-v1
Issued: 2026-04-15
Modified: 2026-04-23
License: CC0 1.0 Universal
tap-v1 is the namespace for Tap-specific extensions to the
W3C Web Annotation Data Model.
Scope rule: the namespace defines only terms that ship across a
consumer boundary in a stored .tap.json envelope — internal
implementation types (forge-time fingerprints, intermediate selector
candidates) are TypeScript-only and intentionally excluded. Two on-disk
surfaces carry tap:* terms:
.tap.json W3C Annotation with
motivation tap:executing and a tap:ExecutionPlan body.assessing
(W3C-standard) whose body carries tap:verdict and related diagnostic
properties.The W3C Web Annotation context (http://www.w3.org/ns/anno.jsonld) does
not define tokens for execution plans or doctor diagnostics. Without a
published tap-v1 context, every tap:* CURIE in a Tap annotation
would fail strict JSON-LD validation. This document is what lets
external tooling (annotation stores, validators, agent platforms)
consume Tap annotations without a custom profile.
Tap itself parses tap:* fields by literal key and does not require
runtime context resolution, so the runtime cost of this document is zero
— it exists purely as a stable identifier and as documentation for
external consumers.
.tap.json| Term | Kind | Role |
|---|---|---|
tap:executing |
oa:Motivation |
Motivation of a compiled Tap program |
tap:ExecutionPlan |
rdfs:Class |
Body type of a compiled Tap program |
tap:site, tap:name, tap:intent |
properties | Tap identity/direction (bare keys inside tap:ExecutionPlan) |
tap:health, tap:args |
properties | Tap contract + argument schema (bare keys inside tap:ExecutionPlan) |
assessing annotation| Term | Kind | Role |
|---|---|---|
tap:verdict |
property | healthy · broken · stale · layer-mismatch · unreachable · unverified |
tap:compiledFromLayer |
property | Trust layer 1–4 the tap was compiled from |
tap:recommendedLayer |
property | Layer doctor recommends re-forging from |
tap:crossValidation |
property | Layer-1 vs. observed-value disagreement record ({layer1Value, observedValue, disagreement}) |
tap:suggestions |
property | Ordered diagnostic suggestions (free-text) |
tap:suggestAuthoritative |
property | Optional ready-to-embed AuthoritativeSpec shown only when verdict is unverified AND a known-shape source exists for the target. Lets agents close the verification gap without hand-writing the V config. |
See index.jsonld for the full context document and
normative definitions. CI guards (packages.yml :: ns-cross-consumer-only)
keep the term set in this README equal to the term set in the JSON-LD
context so the two never drift.
{
"@context": [
"http://www.w3.org/ns/anno.jsonld",
"https://taprun.dev/ns/tap-v1"
],
"id": "https://taprun.dev/taps/github/trending",
"type": "Annotation",
"motivation": "tap:executing",
"target": "https://taprun.dev/taps/github/trending",
"body": {
"type": "tap:ExecutionPlan",
"site": "github",
"name": "trending",
"intent": "read",
"description": "Trending GitHub repositories",
"health": { "min_rows": 5, "non_empty": ["repo"] },
"args": { "limit": { "type": "int", "default": 20 } },
"ops": [
{ "op": "nav", "url": "https://github.com/trending" },
{ "op": "wait", "selector": "article.Box-row" },
{
"op": "exec",
"fn": "async (handle) => handle.eval(() => Array.from(document.querySelectorAll('article.Box-row')).map(el => ({ repo: el.querySelector('h2 a')?.textContent?.trim() })))"
}
]
},
"generator": {
"id": "https://taprun.dev/migrate",
"type": "SoftwareAgent",
"version": "1"
},
"created": "2026-04-23T00:00:00Z"
}
A consumer that only understands W3C Web Annotation sees a valid
Annotation with a motivation, a target IRI, and a body. A Tap-aware
consumer additionally reads the tap:ExecutionPlan body and can replay
the program against the declared target.
{
"@context": [
"http://www.w3.org/ns/anno.jsonld",
"https://taprun.dev/ns/tap-v1"
],
"type": "Annotation",
"motivation": "assessing",
"target": "tap:github/trending",
"body": {
"tap:verdict": "layer-mismatch",
"tap:compiledFromLayer": 4,
"tap:recommendedLayer": 1,
"tap:crossValidation": {
"layer1Value": 25,
"observedValue": 18,
"disagreement": "ItemList.numberOfItems differs from extracted row count"
},
"tap:suggestions": [
"Re-forge from Layer 1 (JSON-LD ItemList present on this page)",
"Current selector targets Layer 4 (CSS classes); higher-trust source available"
]
},
"generator": { "id": "https://taprun.dev/doctor", "type": "SoftwareAgent" },
"created": "2026-04-23T00:00:00Z"
}
Terms follow JSON-LD / RDF convention:
tap:ExecutionPlan)tap:compiledFromLayer, tap:suggestAuthoritative)tap:executing), matching the W3C anno style (oa:assessing, oa:describing)https://taprun.dev/ns/tap-v1 is stable
forever. Once tap:ExecutionPlan means what it means in this
document, it means that permanently.tap-v2/).tap-v1.owl:deprecated: true) rather than removed, so external data that
referenced them remains valid.packages.yml :: ns-cross-consumer-only) enforces the
scope rule mechanically — terms that appear in this document but are
not actually emitted in a stored .tap.json or doctor assessment
fail the build, and vice versa.This namespace document is released under CC0 1.0 Universal — vocabulary infrastructure should never carry usage restrictions. You can freely reference, mirror, or redistribute this document.
The file at ./index.jsonld should be served with
Content-Type: application/ld+json when dereferenced. GitHub Pages’
default MIME for .jsonld is application/octet-stream, which most
strict JSON-LD processors accept as long as they can parse the body —
Tap’s own consumers never fetch this context — but external validators
may warn. A future move to a host with configurable MIME types (or a
Cloudflare Worker in front of Pages) can fix this without changing the
URI. See ./SERVING.md if present.
/ns/ root namespace — Schema.org-layered vocabulary (separate from tap-v1, used by pre-migration .jsonld manifests)