OpenVehicle is now OpenCar, and scoped to match the name (#214)

Anthony asked for OpenCar twice after I argued for OpenVehicle on the
grounds that it covered boats. His name is the better one: OpenCar is
what a person reaches for, and a site that lists cars lists the
motorcycle and the pickup beside them.

So rather than keep a name that disagrees with its contents, the scope
moves to match the name. `kind` is now car, motorcycle, truck, van,
suv, bus, rv, atv, other -- road vehicles. Boats and heavy equipment are
dropped from it and belong in sibling profiles, which cost nothing to
add because the parent does not change. Keeping them here would have
meant every field being optional and meaningless for half the subjects.

`subject.type` is `car` and the key is `subject.car`, so the axis value
and the profile agree.

Renamed the day it shipped and before anything reads it: no descriptor
exists yet, and nichedb's directory has not been built. Doing it later
would have meant a migration.

50 contract tests pass, spec-discovery included.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Anthony Ettinger 2026-09-25 03:22:36 -07:00 • committed by GitHub
parent 32bbdeda95
commit c434a65272
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 15 additions and 13 deletions

View file

@ -97,7 +97,7 @@ export const FAMILIES: Family[] = [
s("openaffiliate", "OpenAffiliate", "One file a merchant serves about the commission it pays"),
s("openlisting", "OpenListing", "One file a seller serves about one thing it is offering: what it is, what it costs, on what terms and where, with the offer and the subject as separate axes so a house to rent and a car for sale are one format", { landing: undefined }),
s("openproperty", "OpenProperty", "The property subject: houses, apartments, rooms and land, with tenure, area and the floor-versus-floors distinction that property data usually gets wrong", { parent: "openlisting", landing: undefined }),
s("openvehicle", "OpenVehicle", "The vehicle subject: cars, motorcycles, trucks and boats, with the VIN as a claim rather than a proof and odometer units always stated", { parent: "openlisting", landing: undefined }),
s("opencar", "OpenCar", "The motor-vehicle subject: cars, motorcycles, trucks, vans and RVs, with the VIN as a claim rather than a proof and odometer units always stated", { parent: "openlisting", landing: undefined }),
s("openrecipe", "OpenRecipe.md", "One Markdown file that is a recipe, with schema.org derived from it and never the reverse"),
s("opensong", "OpenSong", "One plain-text file that is a song: title, style, exclusions and lyrics as the blocks a generator takes, kept beside the audio"),
s("openemoji", "OpenEmoji", "An emoji set as a folder: one file that states coverage, licence and whether a person or a model drew it, and glyphs named by the codepoints they draw"),

View file

@ -1,22 +1,24 @@
# OpenVehicle
# OpenCar
The vehicle profile of [OpenListing](/docs/openlisting). It adds one key, `subject.vehicle`, describing a car, motorcycle, truck, trailer or boat. Everything else — the offer, the price, the location, the media, the provenance — is the parent specification and is not restated here.
The motor-vehicle profile of [OpenListing](/docs/openlisting). It adds one key, `subject.car`, describing a car, motorcycle, truck, van or RV. Everything else — the offer, the price, the location, the media, the provenance — is the parent specification and is not restated here.
Status: **0.1 draft**, alongside the parent.
Slug: `openvehicle`
Slug: `opencar`
## When this profile applies
When `subject.type` is `"vehicle"`.
When `subject.type` is `"car"`.
## `subject.vehicle`
The name is the one people reach for, and a site that lists cars also lists the motorcycle and the pickup beside them. Boats and heavy equipment are deliberately NOT here: they share almost none of these fields, and squeezing them in would make every one of them optional and meaningless. They belong in sibling profiles, which cost nothing to add because the parent does not change.
## `subject.car`
```json
"subject": {
"type": "vehicle",
"type": "car",
"title": "2021 Jeep Grand Cherokee Overland",
"vehicle": {
"car": {
"kind": "car",
"year": 2021,
"make": "Jeep",
@ -40,7 +42,7 @@ When `subject.type` is `"vehicle"`.
### `kind`
`car`, `motorcycle`, `truck`, `van`, `bus`, `trailer`, `rv`, `boat`, `atv`, `equipment`, `other`.
`car`, `motorcycle`, `truck`, `van`, `suv`, `bus`, `rv`, `atv`, `other`.
### Fields

View file

@ -2,7 +2,7 @@
OpenListing is one file a seller serves about one thing it is offering: what the thing is, what it costs, on what terms, and where it is. A house for sale, an apartment to rent, a car, a piece of equipment. The seller stays the author of its own listing, and a directory reads the seller's file instead of licensing somebody else's database or scraping a marketplace that forbids it. It is maintained by Profullstack, Inc. as part of the LogicSRC open-standards surface.
Status: **0.1 draft**. The parent specification; subject profiles for [OpenProperty](/docs/openproperty) and [OpenVehicle](/docs/openvehicle) bind it to the two kinds of thing it was first written for.
Status: **0.1 draft**. The parent specification; subject profiles for [OpenProperty](/docs/openproperty) and [OpenCar](/docs/opencar) bind it to the two kinds of thing it was first written for.
Slug: `openlisting`
@ -22,7 +22,7 @@ What is missing is small: one file, on the seller's own origin, saying what is o
- A **seller** is whoever is offering the thing: an owner, a landlord, a dealer, an agent acting for one. Its **descriptor** is the file it serves.
- A **listing** is one thing on offer. One descriptor describes one listing.
- The **subject** is the thing itself — a property, a vehicle.
- The **subject** is the thing itself — a property, a car.
- The **offer** is the deal on it — for sale, to rent, at auction.
- A **directory** is anything that reads descriptors and lists across sellers.
- A **reader** is anything that reads a descriptor.
@ -34,7 +34,7 @@ A house for sale and a house to rent are the same house described the same way;
So OpenListing separates them:
- **`offer.type`** says what the deal is: `sale`, `rent`, `lease`, `auction`, `free`, `wanted`.
- **`subject.type`** says what the thing is: `property`, `vehicle`, and whatever later profiles add.
- **`subject.type`** says what the thing is: `property`, `car`, and whatever later profiles add.
A subject profile adds the fields that only make sense for its subject — bedrooms for a property, mileage for a vehicle — and changes nothing else. A reader that understands OpenListing but not a given profile still reads the price, the location, the offer and the dates correctly, and can say so rather than failing.
@ -186,6 +186,6 @@ A directory MUST retain the seller's `id` as canonical and MUST NOT present a re
## Subject profiles
- [OpenProperty](/docs/openproperty) — houses, apartments, rooms, land
- [OpenVehicle](/docs/openvehicle) — cars, motorcycles, trucks, boats
- [OpenCar](/docs/opencar) — cars, motorcycles, trucks, vans, RVs
A profile adds a key under `subject` named for the subject type and nothing else. New profiles do not change this document.