com.airplaneian.contrail.temp.flight

airplaneian.com

Schema Diff

+14 -14

From

CID
bafyreid4vdci6gd...
Indexed At
2026-07-25 18:31 UTC
View this version

To

CID
bafyreigymqxm2p7...
Indexed At
2026-07-25 18:50 UTC
View this version

Compatibility Analysis

Backward Compatible

No changes detected.

1 1
{
2 2
  "id": "com.airplaneian.contrail.temp.flight",
3 3
  "defs": {
4 4
    "main": {
5 5
      "key": "tid",
6 6
      "type": "record",
7 7
      "record": {
8 8
        "type": "object",
9 9
        "required": [
10 10
          "createdAt"
11 11
        ],
12 12
        "properties": {
13 13
          "date": {
14 14
            "type": "string",
15 15
            "maxLength": 10,
16 -
            "description": "Calendar date of departure at the origin, as 'YYYY-MM-DD'. Present as its own field rather than derived from the timestamps because it is one third of the commercial identity key -- date plus 'operator' plus 'flightNumber' -- and because deriving it from an instant requires knowing the origin's local offset, which a reader may not have. Where both this and a departure timestamp are written they must agree. Write it consistently, since cross-repository matching depends on it."
16 +
            "description": "Calendar date of departure at the origin, as 'YYYY-MM-DD'. Present as its own field rather than derived from the timestamps because it forms one third of the commercial identity key, alongside 'operator' and 'flightNumber', and because deriving it from an instant requires knowing the origin's local offset, which a reader may not have. Where both this and a departure timestamp are written they must agree. Write it consistently, since cross-repository matching depends on it."
17 17
          },
18 18
          "seat": {
19 19
            "type": "string",
20 20
            "maxLength": 16,
21 -
            "description": "Seat occupied, as a string, for example '14C' -- row and position together, since the letter is not optional and the whole thing is not a number. Only meaningful when 'relationship' indicates the author was aboard."
21 +
            "description": "Seat occupied, as a string, for example '14C', with row and position together, since the letter is not optional and the whole value is not a number. Only meaningful when 'relationship' indicates the author was aboard."
22 22
          },
23 23
          "cabin": {
24 24
            "type": "string",
25 25
            "maxLength": 64,
26 26
            "description": "Cabin or class of service. An open string rather than an enumeration because carriers invent and rename cabins continually and any closed set would be obsolete within a year. Write lower camel case, matching the known values below, so that records from different tools compare equal; readers must tolerate values outside the list.",
27 27
            "knownValues": [
28 28
              "economy",
29 29
              "premiumEconomy",
30 30
              "business",
31 31
              "first"
32 32
            ]
33 33
          },
34 34
          "notes": {
35 35
            "type": "string",
36 36
            "maxLength": 10000,
37 37
            "description": "Free-text note about the flight. Everything written here is public and permanent once the record is published, and unlike the structured fields its contents cannot be reviewed by a tool for anything the author did not mean to disclose. Tools writing records on a user's behalf should show note contents prominently before publishing. Do not use this field to carry structured data that belongs in a dedicated field, and do not use it for booking references or other credentials.",
38 38
            "maxGraphemes": 1000
39 39
          },
40 40
          "icao24": {
41 41
            "type": "string",
42 42
            "maxLength": 8,
43 43
            "description": "The airframe's 24-bit ICAO address as six lowercase hexadecimal characters, for example 'a1b2c3'. Stable per airframe and the primary identity field for general aviation, where there is no flight number to match on. Together with an actual departure time it forms the general aviation identity key; write both consistently, since cross-repository matching depends on them."
44 44
          },
45 45
          "origin": {
46 46
            "ref": "com.airplaneian.contrail.temp.defs#place",
47 47
            "type": "ref",
48 48
            "description": "Where the flight departed. May equal 'destination': local flights that return to their departure point, such as circuits, sightseeing, or training sorties, are ordinary and must not be treated as an error."
49 49
          },
50 50
          "source": {
51 51
            "type": "string",
52 52
            "maxLength": 64,
53 53
            "description": "Short identifier for the tool or dataset that produced this record, for example 'flighty', 'manual', or 'adsb'. Together with 'sourceId' this lets a tool find the records it wrote previously and update them in place instead of creating duplicates on a re-import. It also records provenance: the same record shape carries a first-hand passenger entry and a machine-harvested observation, and 'source' is what distinguishes them."
54 54
          },
55 55
          "status": {
56 56
            "type": "string",
57 57
            "maxLength": 32,
58 58
            "description": "How the flight concluded. Absent means unknown rather than normal, so write 'normal' explicitly when it is known that the flight operated as planned. An open string for consistency with the other classification fields here; readers must tolerate values outside the list.",
59 59
            "knownValues": [
60 60
              "normal",
61 61
              "cancelled",
62 62
              "diverted"
63 63
            ]
64 64
          },
65 65
          "callsign": {
66 66
            "type": "string",
67 67
            "maxLength": 16,
68 68
            "description": "The flight identification the aircraft transmitted, written exactly as received, uppercase with no padding or spaces. This is the primary flight identifier available from ADS-B and other surveillance sources, and it must not be decomposed on the way in: 'UAL38' splits cleanly into an operator and a flight number, but a general aviation aircraft transmits its registration, and state or military aircraft commonly transmit something with no civil structure at all, such as 'LEGACY' or 'KLH71'. Write this field verbatim and populate 'operator' and 'flightNumber' as well only when the split is unambiguous. Absent for sources that never see a callsign, such as a passenger's own booking history."
69 69
          },
70 70
          "operator": {
71 71
            "type": "string",
72 72
            "maxLength": 8,
73 73
            "description": "ICAO designator of the agency that actually operated the flight, three letters, uppercase. Not restricted to airlines: 'UAL' for an airline, 'FDX' for a cargo carrier, 'RCH' for a military air mobility flight. ICAO rather than IATA because IATA codes are recycled between carriers, so a historical record tagged with one is ambiguous. Absent for most general aviation, where no designator exists; use 'operatorName' in that case. Part of the commercial identity key alongside 'date' and 'flightNumber', so write it consistently where it is known, since cross-repository matching depends on it."
74 74
          },
75 75
          "sourceId": {
76 76
            "type": "string",
77 77
            "maxLength": 512,
78 -
            "description": "The identifier the tool named in 'source' uses for this flight, in that tool's own namespace -- typically an opaque key from an export. Deliberately stored in the record body rather than encoded into the record key, so that a record can be corrected without changing its identity: deriving keys from content would turn a fixed flight number into a new record instead of an update. Meaningful only in combination with 'source', and carries no meaning to readers who do not know that tool."
78 +
            "description": "The identifier the tool named in 'source' uses for this flight, in that tool's own namespace, typically an opaque key from an export. Deliberately stored in the record body rather than encoded into the record key, so that a record can be corrected without changing its identity: deriving keys from content would turn a corrected flight number into a new record instead of an update. Meaningful only in combination with 'source', and carries no meaning to readers who do not know that tool."
79 79
          },
80 80
          "createdAt": {
81 81
            "type": "string",
82 82
            "format": "datetime",
83 83
            "description": "When this record was written, as distinct from when the flight happened. The only required field. Write it with an explicit UTC offset and no fractional seconds, for example '2026-07-24T18:22:05-07:00' or '2026-07-25T01:22:05Z'. Fractional seconds are omitted throughout this schema because trailing zeroes in a fractional part round-trip ambiguously and lose precision inconsistently between implementations; a fixed convention avoids both problems."
84 84
          },
85 85
          "destination": {
86 86
            "ref": "com.airplaneian.contrail.temp.defs#place",
87 87
            "type": "ref",
88 88
            "description": "Where the flight arrived, or where it was intended to arrive if it was cancelled. If the flight diverted, this remains the intended destination and the actual landing place goes in 'diversionAirport'."
89 89
          },
90 90
          "aircraftType": {
91 91
            "type": "string",
92 92
            "maxLength": 128,
93 -
            "description": "Free-text description of the aircraft type as the source expressed it, for example 'Boeing 737-800' or 'Piper PA-18 Super Cub'. Present because most sources supply a name rather than a designator, and discarding it in favour of an empty 'icaoTypeDesignator' would lose real information. Not normalised and not reliable for matching -- use 'icaoTypeDesignator' for that. Do not derive one field from the other: a guessed designator is worse than an absent one, since several distinct designators share a single marketing name."
93 +
            "description": "Free-text description of the aircraft type as the source expressed it, for example 'Boeing 737-800' or 'Piper PA-18 Super Cub'. Present because most sources supply a name rather than a designator, and discarding it in favour of an empty 'icaoTypeDesignator' would lose real information. Not normalised and not reliable for matching, so use 'icaoTypeDesignator' for that. Do not derive one field from the other, because a guessed designator is worse than an absent one and several distinct designators share a single marketing name."
94 94
          },
95 95
          "flightNumber": {
96 96
            "type": "string",
97 97
            "maxLength": 16,
98 98
            "description": "The operating agency's flight number, as a string rather than an integer. Alphabetic suffixes are in real use, some sources emit malformed values, and a numeric type could never be loosened later without breaking every existing record. Write the digits alone without the operator designator prefix. Part of the commercial identity key, so write it consistently, since cross-repository matching depends on it. Absent for flights that have no flight number, which is most of general aviation and much state and military flying."
99 99
          },
100 100
          "operatorName": {
101 101
            "type": "string",
102 102
            "maxLength": 128,
103 103
            "description": "Free-text name of the agency that operated the flight, for operators that have no ICAO designator: flight schools, charter and air taxi businesses, law enforcement and government units, private owners flying their own aircraft. Not normalised and not reliable for matching, in the same way that 'aircraftType' complements 'icaoTypeDesignator'. Do not restate here the name of an operator whose designator is already in 'operator'. Note that this is who flew the aircraft, which is frequently not who owns it."
104 104
          },
105 105
          "registration": {
106 106
            "type": "string",
107 107
            "maxLength": 16,
108 108
            "description": "Registration or tail number of the airframe, for example 'N12345' or 'GVBOW'. Write it uppercase with no hyphens, spaces, or other separators, so that 'G-VBOW' and 'GVBOW' do not become two different aircraft to a reader. This normalisation matters because registration is one of the few fields by which general aviation records can be matched across repositories. Military and state aircraft carry identifiers in this field too, in whatever form their operator uses, such as 'MM62209' or 'FAC1215'. Note that registrations are reassigned to different airframes over time, so 'icao24' is the more durable airframe identifier where it is known."
109 109
          },
110 110
          "relationship": {
111 111
            "type": "string",
112 112
            "maxLength": 64,
113 -
            "description": "The author's connection to this flight. Unlike every other field in this record, absent here does not mean unknown: it means no claim of any relationship is being made. A record written from ADS-B data about someone else's flight simply omits it. An open string rather than a closed set, so that relationships nobody anticipated can be expressed without a schema change; readers must tolerate values outside the known list. Note that omitting this field does not make a record private -- the presence of flight records in a repository discloses the author's connection to those flights regardless of what the records claim.",
113 +
            "description": "The author's connection to this flight. Unlike every other field in this record, absent here does not mean unknown: it means no claim of any relationship is being made. A record written from ADS-B data about someone else's flight simply omits it. An open string rather than a closed set, so that relationships nobody anticipated can be expressed without a schema change, and readers must tolerate values outside the known list. Note that omitting this field does not make a record private, because the presence of flight records in a repository discloses the author's connection to those flights regardless of what the records claim.",
114 114
            "knownValues": [
115 115
              "passenger",
116 116
              "pic",
117 117
              "sic",
118 118
              "student",
119 119
              "instructor",
120 120
              "crew",
121 121
              "observer"
122 122
            ]
123 123
          },
124 124
          "actualLanding": {
125 125
            "type": "string",
126 126
            "format": "datetime",
127 -
            "description": "Actual wheels-on time -- the 'on' time. Explicit UTC offset, no fractional seconds. The interval between this and 'actualTakeoff' is flight time; do not store that interval, as it is derivable."
127 +
            "description": "Actual wheels-on time, the 'on' time. Explicit UTC offset, no fractional seconds. The interval between this and 'actualTakeoff' is flight time, which is not stored because it is derivable."
128 128
          },
129 129
          "actualTakeoff": {
130 130
            "type": "string",
131 131
            "format": "datetime",
132 -
            "description": "Actual wheels-off time -- the 'off' time. Explicit UTC offset, no fractional seconds. Together with 'icao24' this forms the general aviation identity key, and it is usually the most reliably known time for a flight with no gate operations."
132 +
            "description": "Actual wheels-off time, the 'off' time. Explicit UTC offset, no fractional seconds. Together with 'icao24' this forms the general aviation identity key, and it is usually the most reliably known time for a flight with no gate operations."
133 133
          },
134 134
          "registeredOwner": {
135 135
            "type": "string",
136 136
            "maxLength": 128,
137 137
            "description": "Free-text name of the party the airframe is registered to, as the civil registry records it. This is deliberately separate from 'operator' and 'operatorName', because the registrant is frequently not the operator: a large share of the fleet is registered to trusts, banks, or single-purpose holding companies, such as 'WILMINGTON TRUST CO TRUSTEE' or a limited company named after the tail number. Surveillance datasets usually expose a single combined owner-or-operator field, and its contents are the registrant, so it belongs here rather than in 'operator'. Absent for aircraft with no public registry entry, which includes most military aircraft."
138 138
          },
139 139
          "diversionAirport": {
140 140
            "ref": "com.airplaneian.contrail.temp.defs#place",
141 141
            "type": "ref",
142 142
            "description": "Where the flight actually landed, when it did not land at 'destination'. Present only when 'status' is 'diverted'. 'destination' continues to hold the intended arrival point."
143 143
          },
144 144
          "marketingAirline": {
145 145
            "type": "string",
146 146
            "maxLength": 8,
147 147
            "description": "ICAO designator of the airline that sold the flight, when it differs from 'operator'. This one is deliberately named for airlines, because codeshare marketing is an airline arrangement and has no counterpart in other kinds of operation. Absent means either that there was no codeshare or that it is unknown. Do not put the marketing carrier in 'operator'; the distinction is what lets two records describing one physical flight be recognised as such."
148 148
          },
149 149
          "scheduledLanding": {
150 150
            "type": "string",
151 151
            "format": "datetime",
152 -
            "description": "Scheduled wheels-on time -- the 'on' time. Explicit UTC offset, no fractional seconds."
152 +
            "description": "Scheduled wheels-on time, the 'on' time. Explicit UTC offset, no fractional seconds."
153 153
          },
154 154
          "scheduledTakeoff": {
155 155
            "type": "string",
156 156
            "format": "datetime",
157 -
            "description": "Scheduled wheels-off time -- the 'off' time. Explicit UTC offset, no fractional seconds."
157 +
            "description": "Scheduled wheels-off time, the 'off' time. Explicit UTC offset, no fractional seconds."
158 158
          },
159 159
          "actualGateArrival": {
160 160
            "type": "string",
161 161
            "format": "datetime",
162 -
            "description": "Actual time the aircraft reached the gate or parking position -- the 'in' time. Explicit UTC offset, no fractional seconds."
162 +
            "description": "Actual time the aircraft reached the gate or parking position, the 'in' time. Explicit UTC offset, no fractional seconds."
163 163
          },
164 164
          "icaoTypeDesignator": {
165 165
            "type": "string",
166 166
            "maxLength": 8,
167 167
            "description": "ICAO aircraft type designator, for example 'B77W' or 'C172'. Write it only when the source actually supplies a designator, not when it has been inferred from a marketing name."
168 168
          },
169 169
          "actualGateDeparture": {
170 170
            "type": "string",
171 171
            "format": "datetime",
172 -
            "description": "Actual time the aircraft left the gate or parking position -- the 'out' time. Explicit UTC offset, no fractional seconds. The interval between this and 'actualGateArrival' is block time; do not store that interval, as it is derivable."
172 +
            "description": "Actual time the aircraft left the gate or parking position, the 'out' time. Explicit UTC offset, no fractional seconds. The interval between this and 'actualGateArrival' is block time, which is not stored because it is derivable."
173 173
          },
174 174
          "scheduledGateArrival": {
175 175
            "type": "string",
176 176
            "format": "datetime",
177 -
            "description": "Scheduled time the aircraft reached the gate or parking position -- the 'in' time. Explicit UTC offset, no fractional seconds."
177 +
            "description": "Scheduled time the aircraft reached the gate or parking position, the 'in' time. Explicit UTC offset, no fractional seconds."
178 178
          },
179 179
          "marketingFlightNumber": {
180 180
            "type": "string",
181 181
            "maxLength": 16,
182 182
            "description": "Flight number under which the flight was sold, when it differs from 'flightNumber'. A string, for the same reasons."
183 183
          },
184 184
          "scheduledGateDeparture": {
185 185
            "type": "string",
186 186
            "format": "datetime",
187 -
            "description": "Scheduled time the aircraft left the gate or parking position -- the 'out' time. Write it with an explicit UTC offset and no fractional seconds. The eight time fields form the standard out/off/on/in set; all are optional, so a record knowing only a takeoff time is perfectly valid, and general aviation records will usually omit the gate times entirely."
187 +
            "description": "Scheduled time the aircraft left the gate or parking position, the 'out' time. Write it with an explicit UTC offset and no fractional seconds. The eight time fields form the standard out, off, on and in set. All of them are optional, so a record knowing only a takeoff time is valid, and general aviation records will usually omit the gate times entirely."
188 188
          }
189 189
        }
190 190
      },
191 -
      "description": "An assertion that a particular flight existed. This is not a first-person log entry: the record describes the flight itself, and the author's connection to it -- passenger, pilot, observer -- is an optional annotation via 'relationship' rather than the point of the record. A record written from ADS-B data about a stranger's flight and a record written from the author's own boarding pass are the same kind of assertion with different provenance, distinguished by 'source' and by whether 'relationship' is present. Because the record is about the flight rather than about the author, several people will write records describing the same flight, and none of them is canonical. That duplication is expected and by design. It does mean readers need to recognise two repositories describing one flight, so the identity fields matter more here than they would in a personal-log model: for scheduled flights write 'date', 'operator', and 'flightNumber' consistently; for general aviation, state and military flying write 'icao24' and an actual departure time, and write 'callsign' verbatim wherever a source supplies one. There is deliberately no global flight identifier, because no authority exists to issue one. The record is intended to describe any kind of flying, and accommodates scheduled airline service, cargo, charter, business aviation, air ambulance, law enforcement, government, military and flight training operations alongside general aviation -- a widebody on a transpacific sector and a light aircraft flying circuits at an unlicensed strip are both valid, and origin may equal destination. Only 'createdAt' is required. Every other field being optional is the single most important property of this schema: absent means unknown or not applicable, and there are no sentinel values for unknowns. A tool that wants complete data should reject incomplete input itself rather than expect the schema to enforce it. Values derivable from other fields are excluded on purpose -- duration, distance, and great-circle miles are all computable from times and places, and storing them guarantees that records written by different tools disagree. Reference data about the world, such as airport names, coordinates looked up from a code, or aircraft specifications, likewise does not belong in a user's repository. Note that a collection of these records is a movement history: it discloses home airport, travel cadence, and periods away from home. That disclosure follows from the records being present in a repository at all, and is not affected by whether 'relationship' claims the author was aboard."
191 +
      "description": "An assertion that a particular flight existed. The record describes the flight itself rather than the author's experience of it, so it is not a personal log entry. The author's connection to the flight is an optional annotation in 'relationship', and when that field is absent no claim is being made either way. Only 'createdAt' is required. Every other field is optional, and an absent field means the value is unknown or does not apply, never that it is empty or zero. Several people may write records describing the same flight and none of them is canonical, so write the identifying fields consistently wherever they are known: 'date', 'operator' and 'flightNumber' for scheduled service, 'icao24' with an actual departure time otherwise, and 'callsign' verbatim wherever a source supplies one. There is no global flight identifier, because no authority exists to issue one. Any kind of flying is in scope, from scheduled airline service through cargo, charter, state and military operations to general aviation, and origin may equal destination. Values derivable from other fields, such as duration and distance, are excluded on purpose, because tools computing them separately will disagree. Reference data about the world, such as airport names or coordinates looked up from a code, does not belong in a personal repository either. Note that a collection of these records is a movement history, and discloses the author's travel patterns regardless of what any individual record claims."
192 192
    }
193 193
  },
194 194
  "$type": "com.atproto.lexicon.schema",
195 195
  "lexicon": 1
196 196
}

Compare Other Versions

Lexicon Garden

@