Capability Schema
A shared language for what the world can do.
Published concept artefact · describes a design, not a running system
A capability declaration states what a resource can do, where it can do it, how soon, and who must consent — precisely enough to be found, compared and booked. This is v0.1, published 13 August 2026: not a described vocabulary but a schema you can write in — a validatable JSON Schema with this site’s entire 32-resource catalogue embedded as conformant example declarations.
One box of five — on purpose.
Saying what a schema does not define is the honest half of defining it. A declaration describes the resource; everything that happens to one — discovery, booking, planning, evidence — has its own record, and cost lives in the booking, never here.
01
Capability declaration
What a resource can do, where, how soon, who consents
This schema — the only box it defines
02
Discovery & comparison
Finding candidates and comparing them on the declared attributes
Consumes declarations
03
Booking
One resource, one mission, one window — where cost lives
Out of schema, by decision
04
Governed mission plan
The approvals gathered, the constraints checked
Out of schema
05
Evidence record
What actually happened, with provenance
Out of schema
Seven classes every mission resolves into.
Missions do not ask for devices — they ask for these. Each class is answered by many resource classes with different trade-offs; the platform page carries 32 worked examples, and every one of them ships in the schema’s example set.
Observe
6 resource classes
Acquire imagery or signals of a target or area.
Measure
5 resource classes
Quantify a physical property to a defined quality.
Track
4 resource classes
Follow an object or signal across time and space.
Inspect
4 resource classes
Examine an asset for condition, defects, or anomalies.
Retrieve
5 resource classes
Access existing records, archives, or reference data.
Analyse
4 resource classes
Turn raw data into validated findings.
Report
4 resource classes
Produce a verifiable, provenance-rich output.
See the classes with their resource classes and attributes: the capability graph
The declaration, field by field.
Five required fields, four optional ones. The required core is deliberately the set every class — from a satellite payload to a human reviewer — can answer; everything domain-specific lives in extensions.
| Field | Type | Declares | Example |
|---|---|---|---|
| capabilityClassrequired | string (enum of 7) | Which of the seven capability classes the resource answers. The class set is closed in v0.1 — the extensibility note carries that argument. | "inspect" |
| resourceClassrequired | string | What kind of thing provides the capability — a class of resource, never a make, model or company name (write “drone-mounted thermal camera”, not a product name). The specific unit binds at booking, not here. | "Drone + thermal camera" |
| reachrequired | string | Coverage geometry: which part of a target it can actually get to. Reach is why two resources answering the same capability are not interchangeable. | "Roof and façade, close range" |
| leadTimerequired | string | How soon it can deliver once booked — from “immediate” (an archive) to “weeks, by availability” (a certified inspector). A mission with a season boundary selects on this before anything else. | "Hours, weather permitting" |
| approvalrequired | array of strings, min 1 | Consents, clearances and standing authorisations, roughly in the order obtained. An element may name a compound consent granted as one unit; a conditional clearance states its condition. Declaring this up front is what lets a plan carry its permissions instead of discovering them mid-mission. | ["Aviation authority", "Site owner"] |
| status | string (enum of 6) | Where the resource stands on the onboarding path. Defaults to “described” — which is also the honest value of every example on this site: nothing is cleared. | "described" |
| conditions | array of strings | Operating constraints the declaration owns up to — weather windows, daylight, co-registration, staffing. A constraint declared here is one a mission plan can check instead of trip over. | ["Daylight or a stated thermal window"] |
| extensions | object (namespaced) | Per-domain attributes under a lowercase namespace key, carrying your real measured values, with units. Domain measures never enter the required core. | { "sensing": { "resolution": "…" } } |
| declaredBy | object | Who is declaring — operator name, contact, date. Optional because the comparison works anonymously; named, the declaration becomes yours to send, and to be credited for. | { "operator": "…", "date": "…" } |
A declaration may also carry "$schema" pointing at this schema, for editor tooling — meta, not vocabulary.
Three declarations, written out.
Copy one, replace the values with an asset you actually operate, and validate it — that is the whole experiment. Every example declares "status": "described", because that is the truth: nothing on this site has passed a single onboarding gate. Add the optional declaredBy block and send it — real declarations enter the v0.2 changelog, with credit.
Drone + thermal camera · inspect
{
"capabilityClass": "inspect",
"resourceClass": "Drone + thermal camera",
"reach": "Roof and façade, close range",
"leadTime": "Hours, weather permitting",
"approval": [
"Aviation authority",
"Site owner"
],
"status": "described",
"conditions": [
"Daylight or a stated thermal window",
"Wind below the platform’s operating limit"
],
"extensions": {
"sensing": {
"resolution": "Thermal ground resolution at survey distance",
"threshold": "Declared against the mission’s stated defect size"
}
}
}Satellite imagery archive · retrieve
{
"capabilityClass": "retrieve",
"resourceClass": "Satellite imagery archive",
"reach": "Only past acquisitions",
"leadTime": "Immediate",
"approval": [
"Licence terms"
],
"status": "described"
}Change-detection model · analyse
{
"capabilityClass": "analyse",
"resourceClass": "Change-detection model",
"reach": "Comparable image pairs",
"leadTime": "Minutes",
"approval": [
"Model licence"
],
"status": "described",
"conditions": [
"Input imagery co-registered"
]
}Validate yours against the published schema, no platform required:
curl -sO https://tilfang.com/schema/v0.1.json
npx ajv-cli validate --spec=draft2020 --strict=false -s v0.1.json -d your-declaration.json--strict=false because the schema carries x- meta keys (version, changelog, pressure points) that validators ignore but strict mode refuses.
The artefact itself — nothing behind a download.
The complete published schema, browsable in place — the very object the endpoint serves, rendered from the same source. Expand what interests you; the example catalogue is the long part.
v0.1{ 18 }
properties{ 10 }
$schema{ 2 }
capabilityClass{ 2 }
enum[ 7 ]
resourceClass{ 3 }
reach{ 3 }
leadTime{ 3 }
approval{ 4 }
items{ 2 }
status{ 3 }
enum[ 6 ]
conditions{ 3 }
items{ 2 }
extensions{ 4 }
patternProperties{ 1 }
^[a-z][a-z0-9-]*${ 1 }
declaredBy{ 4 }
properties{ 3 }
operator{ 2 }
contact{ 1 }
date{ 1 }
required[ 5 ]
examples[ 32 ]
0{ 8 }
approval[ 2 ]
conditions[ 2 ]
extensions{ 1 }
sensing{ 2 }
1{ 6 }
approval[ 1 ]
2{ 7 }
approval[ 1 ]
conditions[ 1 ]
3{ 6 }
approval[ 1 ]
4{ 6 }
approval[ 1 ]
5{ 6 }
approval[ 1 ]
6{ 6 }
approval[ 1 ]
7{ 6 }
approval[ 1 ]
8{ 6 }
approval[ 1 ]
9{ 6 }
approval[ 1 ]
10{ 6 }
approval[ 1 ]
11{ 6 }
approval[ 1 ]
12{ 6 }
approval[ 1 ]
13{ 6 }
approval[ 1 ]
14{ 6 }
approval[ 1 ]
15{ 6 }
approval[ 1 ]
16{ 6 }
approval[ 1 ]
17{ 6 }
approval[ 1 ]
18{ 6 }
approval[ 1 ]
19{ 6 }
approval[ 1 ]
20{ 6 }
approval[ 1 ]
21{ 6 }
approval[ 1 ]
22{ 6 }
approval[ 1 ]
23{ 6 }
approval[ 1 ]
24{ 6 }
approval[ 1 ]
25{ 6 }
approval[ 1 ]
26{ 6 }
approval[ 1 ]
27{ 6 }
approval[ 1 ]
28{ 6 }
approval[ 1 ]
29{ 6 }
approval[ 1 ]
30{ 6 }
approval[ 1 ]
31{ 6 }
approval[ 1 ]
x-capability-classes[ 7 ]
0{ 3 }
1{ 3 }
2{ 3 }
3{ 3 }
4{ 3 }
5{ 3 }
6{ 3 }
x-exclusions{ 1 }
x-changelog[ 1 ]
0{ 3 }
x-pressure-points[ 3 ]
Status is part of the language.
The declaration carries where a resource stands on the onboarding path — the four gates the platform page describes, as six states a plan can check. They are definitions, not achievements: nothing on this site has passed the first gate. And certification is a lease — the last state exists so it can be used.
described
Gate 1 · Describe
Written down as inputs, outputs and conditions — this schema’s job. Every example on this site stops here.
constrained
Gate 2 · Constrain
Authentication, policy, cost and safety constraints recorded — before any adapter exists.
sandboxed
Gate 2 · Sandbox
A candidate adapter has run against simulation or non-production endpoints. Nothing real touched.
cleared
Gate 3 · Clear
A person signed one named capability scope. Anything outside it is a new onboarding.
monitored
Gate 4 · Watch
Measured performance is compared with what was declared, continuously.
revoked
Gate 4 · Revoke
Clearance withdrawn — certification is a lease, not a property right.
Extensible by domain, from v0.1
Some attributes are meaningful only for some classes: resolution against a stated threshold decides between a drone survey and an archive scene, and means nothing for Report. Such measures live in per-domain extension namespaces a declaration may add — never in the core, which stays the set every class can answer. The class set itself is deliberately closed at seven until an operator argues for an eighth: classes are a v0.2 argument, attributes are a per-domain extension.
"extensions": {
"sensing": {
"resolution": "Thermal ground resolution at survey distance",
"threshold": "Declared against the mission’s stated defect size"
}
}What it deliberately leaves out
Cost. Writing the worked examples showed cost is not a property of the resource at all: the same drone costs differently on a scheduled sweep and a call-out. Cost attaches to a booking — the (resource, mission, window) triple — so a price never appears in a capability declaration, and at concept stage a price would be a guess wearing a decimal point anyway.
The ledger it keeps of itself.
- v0.1.0 · 2026-08-13 — Initial publication: seven classes, five required fields (class, resource class, reach, lead time, approval), lifecycle states mirroring the onboarding gates, namespaced domain extensions, cost excluded as a booking attribute. Published as a validatable JSON Schema with the site’s full resource catalogue embedded as conformant examples.
Known v0.2 pressure points, named before anyone argues them:
- A structured lead time — free text cannot be machine-compared, and the comparison claim leans on this field hardest.
- Jurisdiction and operating territory — reach today is geometry, not law, and a drone operator’s reality is both.
- Whether approval needs typed entries — a standing credential, a per-mission consent and a conditional clearance are different things an array of strings flattens.
The three answers worth more than praise.
This schema is published ahead of any product, deliberately. The test it runs is simple: an operator either describes a real asset in it — or tells us where it breaks. Any of those answers moves the concept further than a private draft ever could.
Describe one real asset you operate in this schema. Where did a required field refuse your reality?
Which attribute does your domain compare on that neither the core nor an extension namespace can carry?
Which consent in your actual approval chain has no place in the approval array as defined?