diff --git a/docs/architecture/14-api-contract/openapi.yaml b/docs/architecture/14-api-contract/openapi.yaml index c0ce041b..ff70302a 100644 --- a/docs/architecture/14-api-contract/openapi.yaml +++ b/docs/architecture/14-api-contract/openapi.yaml @@ -1748,10 +1748,33 @@ components: - type: string - type: 'null' description: | - Where this book's chapter boundaries came from, passed through from the engine's - manifest; `null` while the book is still arriving. ⚠ **Added by the order-form minor - (0.11.0)** so a client can tell an order in chapters from an order it must phrase in - characters. + Where this book's chapter boundaries came from, in the engine's own word, passed through + untouched — or `null` when NO MANIFEST HAS BEEN READ FOR THIS BOOK. ⚠ **Added by the + order-form minor (0.11.0)** so a client can tell an order in chapters from an order it + must phrase in characters. + + ⛔ **`null` IS NOT A VALUE OF THE VOCABULARY AND IT IS NOT `none`.** `none` is a book the + engine LOOKED at and found one chapter in — a statement about the book. `null` is the + absence of any statement: nobody has asked. The difference is the whole reason a client + can tell «there is no provenance» from «there is one, and it is poor», and only the + second is a fact about the text. + + ⚠ **And `null` does NOT mean «still arriving».** An earlier edition of this line said so, + and it is narrower than the truth. A book reaches `not_started` the moment its parse + finishes — and that same transaction leaves it OWING a reading surface, which is what + later brings the provenance. So the ordinary state of a freshly parsed book is `cut, and + no provenance yet`, and a client that waits for arrival waits for a thing that already + happened. Held by `pgstore.TestAParsedBookIsNotStartedBeforeItHasAnyProvenance`. + + ⚠ Two further roads reach the same `null`, and neither is a book in flight: a manifest + older than this field leaves the column empty for good, and a book registered from a file + already on disk has no manifest at all yet. ⇒ `not_started` says the SOURCE was cut; it + does not say a manifest has been read. + + The rendering half — that an absent provenance reaches the client as an explicit `null` + rather than a missing member or an invented word, and that a word this build does not + know travels VERBATIM — is held separately by + `httpapi.TestABooksCutProvenanceIsTheEnginesOwnWordOrAnExplicitNull`. ⚠ **An OPEN vocabulary that grows additively** — today `declared`, `delimited`, `detected`, `none` (⚠ `delimited` added by the engine 06.09: the file drew a separator — an EPUB spine, a form feed — but calling it a CHAPTER is the engine's assumption, not the format's word). A value this build does not know is read as "not recognised" and is never promoted into @@ -2745,7 +2768,11 @@ components: about the book. Held by `httpapi.TestABookWhoseCutCannotBeSoldAgainstOffersCharactersAndSaysSo`, which asserts an explicit `null` rather than an invented word. ⚠ The sibling `Book.structure` carries the - same fact and says the same in its own words; the two cannot disagree. + same fact and now says the same in its own words — until 06.09 it did NOT: it called + `null` «still arriving» and drew no line between `null` and `none` at all, so the rule + lived in the ORDER schema while the field a client reads on the book card was silent + about it. «The two cannot disagree» was a statement of intent then; it is a statement + about the text now. ⚠ **An open vocabulary that GROWS additively** — today `declared`, `delimited`, `detected`, `none` (⚠ `delimited` added by the engine 06.09: the file drew a separator — an EPUB spine, a form feed — but calling it a CHAPTER is the engine's assumption, not the format's word). A value this build does not know is read as "not recognised" and never promoted into