日本語 · English

Kairos Language Specification — Appendix B. Supply-Side Profile (the contract for those who publish tables)

Translated from the canonical Japanese appendix spec/61-supply-profile.md. The source_sha above records the source revision; a consistency check flags this page when the Japanese original changes.

This document is an appendix placed in the specification tree; it is not part of the normative text (§1–7). Where Appendix A (the firing layer profile) is the contract for “the side that executes the sequence of instants”, this document is the contract for “the side that publishes tables”. It fixes the resolved value that external (§3.8 · ADR-46) receives at run time, so that whoever builds it, it arrives in the same shape and passes the same checks.

B.0 What this document is

The language owns the shape of a table and the checks on it. It does not ship tables. Data that rots by the year (holidays, solar terms, new moons) is shipped by a supply side whose upstream is the institution that gazettes it. This document tells the supply side: satisfy this, and the language’s checks pass as they are.

The grades of conformance are the same three as in Appendix A.

The stance of this document.

Read in this order: §3.8 → reference/external.md → this document → A.5 of Appendix A.

B.1 The shape of the deliverable (the static bundle)

One file is one bundle. Keyed by binding-name, it holds one table per key.

A holiday table.

{ "holidays": {
    "dates": ["2026-01-01", "2026-01-12", "…", "2027-11-23"],
    "covering": "2026-01-01..2027-12-31",
    "asof": "2026-10-22" } }

A labelled table (solar terms). The declaring side writes sekki = external(kind: dates, labels: [小寒, 大寒, 立春, …], source: "…").

{ "sekki": {
    "dates":  ["2026-01-05", "2026-01-20", "2026-02-04"],
    "labels": ["小寒", "大寒", "立春"],
    "covering": "2026-01-01..2026-02-28",
    "asof": "2026-10-22" } }

B.2 covering = the completeness claim

covering is the claim “this range is complete”. A day absent inside the range is read as “absent”. Outside the range is read as “unknown”, and the consumer sees an annotation.

B.3 asof = the version identifier

asof is the name of a version. Only identity is compared. Neither order nor a date meaning is read from it.

B.4 URLs and versions

Fix the place of delivery, and never delete a version once delivered.

B.5 How to extend

A table grows once a year. Publish the promise to extend, and cut a version when you do.

Sources, for Japan. The authority over a table belongs to the institution that gazettes it. Neither the language nor the supply side replaces it.

Table Source When gazetted
National holidays Cabinet Office, “National holidays” (国民の祝日について) early February of the preceding year
Solar terms and new moons National Astronomical Observatory of Japan, the almanac (暦要項) February 1 of the preceding year (official gazette)

B.6 Acceptance tests

Four tests that pass with the language’s deliverables alone (npx kairos-lang and schema/supply.schema.json). Run them before delivery and at every extension. Below, the new version is s.json (covering 2026–2027, asof 2026-10-22), the old version is old.json (covering 2026 only), and the declaration is check.kairos.

(1) Shape: The bundle validates against schema/supply.schema.json. The CLI checks the shape at evaluation time, so a prior check can use any JSON Schema validator.

(2) Contract: The bundle passes the evaluator’s checks. Pair the declaration with the table and evaluate the whole coverage.

premise JP { calendar-system: Gregorian; tz: "Asia/Tokyo"; wkst: Mon
  holidays = external(kind: dates, source: "https://example.com/supply/jp-holidays.json") }
@JP
holidays
npx -y kairos-lang list --supply s.json --from 2026-01-01 --to 2028-01-01 --tz Asia/Tokyo check.kairos

Expected: exit code 0. The points match the gazette. No ⚠ 範囲外 (out of coverage) appears. The coverage summary at the end reads JP.holidays covering 2026-01-01..2027-12-31 asof 2026-10-22 残走路 0 日 (runway 0 days).

(3) The outside of the table is not silent: Asking outside covering yields an annotation. If none appears, covering is too wide.

npx -y kairos-lang list --supply s.json --from 2028-01-01 --to 2028-02-01 --tz Asia/Tokyo check.kairos

Expected: exit code 0. # 0 点 (0 points), # ⚠ 範囲外 2028-01-01..2028-02-01(JP.holidays covering 2026-01-01..2027-12-31, asof 2026-10-22), and a runway of -31 日 (−31 days).

(4) An extension is additions only: The TSV diff between the old and the new version contains additions only, with zero deletions.

npx -y kairos-lang list --supply old.json --from 2026-01-01 --to 2028-01-01 --tz Asia/Tokyo --tsv check.kairos > old.tsv
npx -y kairos-lang list --supply s.json   --from 2026-01-01 --to 2028-01-01 --tz Asia/Tokyo --tsv check.kairos > new.tsv
diff old.tsv new.tsv | grep -c '^<'      # expected: 0

Examples of contract violations (each exits with code 1). The diagnostics are the reference implementation’s canonical output, which is Japanese.

Violation Diagnostic (beginning)
Out of order or duplicated 契約違反: 解決値は昇順・重複なし (ascending, no duplicates)
A point outside covering 契約違反: 解決値の点が covering の外
A date that does not exist 契約違反: 実在しない日付
kind mismatch 契約違反: kind: dates の解決値は dates("YYYY-MM-DD" の列)を運ぶ
A label outside the declared range 契約違反: 宣言値域の外のラベル
Label count differs from the points 契約違反: labels は時点列と同長
Labels sent to a binding that declares none 契約違反: labels 無宣言の external にラベルが来た
covering or asof missing --supply s.json の "holidays": covering(文字列)が必須 (covering, a string, is required)

B.7 What the language ships and what it does not

The language ships The language does not ship
The canonical shape (the schema) and the evaluator’s checks The tables themselves (data that rots by the year)
This document and the acceptance-test procedure Delivery infrastructure, URLs, caches
The bundled examples (impl/examples/) as sequences to compare against Extension promises, notifications, billing, subscriber management

What cannot be checked is the supply side’s responsibility.

B.8 Self-declaration of conformance (checklist)

The list a supply side attaches when it says “conforms to the Kairos supply contract”. Tick every MUST; for each SHOULD you skip, write which and why.

MUST (shape)

  1. The bundle has the shape {binding-name: {dates|instants, covering, asof [, labels]}} and validates against the schema (B.1)
  2. dates are civil days in the premise’s tz, ascending, no duplicates, every date exists; instants are epoch ms, ascending (B.1)
  3. labels are strings, as many as the points, within the declared range; none are sent to a binding that declares none (B.1)
  4. Every point lies inside covering (B.2)

MUST (operation)

  1. covering holds only gazetted ranges; no year that has not been gazetted (B.2)
  2. asof is a non-empty string and changes only when the content changes (B.3)
  3. A fixed URL for the latest version, and version URLs that never disappear (B.4)
  4. The extension promise (how many days after the gazette) is published, and an extension updates covering and asof in the same version (B.5)
  5. Acceptance tests (1)–(4) run before delivery and at every extension, with the record kept (B.6)

SHOULD

B.9 Terms

Term Definition See
supply side The side that builds and publishes the resolved value (the table) of external. It copies the values of the gazetting institution B.0
static bundle The JSON that carries dates/instants, covering, asof, and labels per binding-name. Resolved once per evaluation B.1 · A.5
covering The completeness claim. A point absent inside the range is “absent”; outside the range is “unknown” B.2 · §3.8
asof The version identifier. Compared by identity only B.3 · §3.8
runway The number of days from the evaluation’s to to the end of covering. Negative means the coverage has run out B.2 · §4.10
out-of-coverage annotation The annotation that runs alongside the result when the evaluation reaches outside covering B.2 · §4.10
contract violation The state in which a resolved value fails the checks on shape, ordering, containment, existence, or labels. Exit code 1; error.kind is supply B.6 · ADR-46
supply error A failure of resolution itself (no resolver, nothing fetched). The same error.kind as a contract violation, supply A.4 · ADR-46
legitimate empty dates: [] plus covering. Evaluation succeeds with zero points B.2 · ADR-45