almanac

Axioma-XKS — a capsule format for knowledge that can be audited

Machine-readable half: data/axioma-xks-spine-v1.json. This document explains; that file decides. Where they disagree, the file is right and this document is a bug.

The problem it exists for

Knowledge written down for machines rots in a way that is hard to see. A sentence that was true when written stays legible, stays confident, and stays wrong. Nothing about its appearance changes when the world moves underneath it. The failure mode is not a broken link or a parse error — those are loud. It is a document that continues to teach, fluently, something that stopped being so.

Retrieval systems make this worse rather than better: they select for text that looks authoritative and carries no way to ask how old it is, who asserted it, or what would have to happen for it to stop being true.

Axioma-XKS is a small answer to that. A capsule is a unit of knowledge that carries, in the same file as the claim:

None of that is novel on its own. What the format insists on is that all of it lives in the capsule, not in a wiki page beside it, not in the author’s memory, and not in a second file that will drift.

The spine

Seven fields are required in every capsule of every profile:

Field What it carries Why it is mandatory
xks_version version of this format so a reader can refuse what it does not understand instead of guessing. Not the version of the thing described — see module-passport.version
id stable identifier never reused for a different subject; a citation must stay pointed at one thing
profile which profile’s rules apply a reader must not have to infer this from which optional fields happen to be present
claim one assertion one per capsule — a capsule asserting two things cannot be retracted by halves
provenance author and date an assertion without an author can only be believed, not audited
confidence number, 0..1 declared, never inferred by the reader from fluency. The author’s stated belief, not a calibrated probability, and it must not be read as one
decay expiry and trigger a claim with no expiry silently becomes a claim about the past

provenance and decay are objects, not strings, and their required sub-fields are declared in the schema: provenance.claim.source and .timestamp, decay.check_after and .trigger. A file missing any of this is not an Axioma-XKS capsule, whatever else it contains.

Profiles

The spine is shared; what sits on top of it depends on what is being described. Which profile applies is stated by the capsule, in profile — never guessed by the reader.

knowledge-object — a claim about the world, published for people and machines at once. Requires a domain and a layers object containing six layers, all mandatory: an answer a person can read, evidence an auditor can follow, a model that can be reasoned with, a play scene a learner can act in, a quiz that tests understanding, and a machine layer carrying a runnable criterion. The six are keys inside layers, not top-level fields.

Two rules do the real work here. evidence must carry a reference that resolves and a quote that is verbatim present at it — the presence of a non-empty string is not evidence, and this project shipped a green test for a month on exactly that confusion. machine must carry local_check, a command satisfying the execution contract the schema now declares (machine_execution_contract in data/axioma-xks-spine-v1.json, added in 1.2.0): a node command, run from the repository root, no dependency, no network, exit 0 means the claim still holds. What that contract does not yet cover is set out under Known gaps — it closes the gap for node commands inside this repository, not for an execution environment in general.

module-passport — a capsule describing a living software module. Requires title, version, lifecycle, and kind; components and tests are optional manifests of the files it is made of and the verifiers that check it. Its version must equal the version the module reports to its users — two version numbers for one module is the same defect as two contracts — and it is a different field from xks_version, which versions the capsule format.

Closed vocabularies, declared extensions

Vocabularies belong to a profile, not to the format. A profile declares which vocabularies it closes and what values they admit; a validator rejects a value outside the vocabulary of the capsule’s declared profile. lifecycle is shared across profiles. kind and layer belong to module-passport; knowledge-corpus has its own layer.

That scoping is a fix, not a refinement, and it was paid for. The first published version of this document named two closed vocabularies while the private contract it was derived from names three — layer, with the values core / face / vault, was dropped in publication and nobody noticed for a day. Meanwhile an adjacent corpus by the same author had been blocked since 2026-08-02 for exactly that reason: it is a body of knowledge, it has no code modules, it has nothing to put in that enum, and the published spec gave it no way to say so. A format that forces a corpus to describe itself in the vocabulary of a codebase is telling it to lie or to fork.

This is not strictness for its own sake. An open vocabulary makes conformance a matter of taste, and two independent readers of the same corpus stop being comparable — which destroys the only property that made the format worth having.

Extension is still allowed, and is expected. The rule is that an extension is declared in the capsule, never adopted silently: lifecycle_profile names the profile whose vocabulary the capsule uses, and its absence means the base one. A reader that meets a profile it does not know must say “unknown vocabulary” — not “invalid capsule”. Otherwise an extension is indistinguishable from corruption, and the format punishes precisely the users who grow.

That obligation is empty unless it says what the capsule’s status then is, so: the capsule is conformant to the spine and to its profile’s structural rules, and exactly one field — the one governed by the unknown vocabulary — is unverified. A validator reports this as a third outcome, distinct from both pass and fail, and must not let the capsule reach “fully verified” while it stands. Two outcomes cannot carry three states: collapse it into failure and extension dies, collapse it into success and a hallucinated profile name walks straight through validation.

The mechanism covers any profile-scoped vocabulary, named <vocabulary>_profile — lifecycle_profile, layer_profile, and so on. Until 1.3.0 only lifecycle could be extended, which left a corpus needing a different layer with no path but a fork.

The worked example is real, not hypothetical. An adjacent corpus by the same author keeps a seventh lifecycle value, historical, because a withdrawn topic in a knowledge map has to read differently from a deprecated software module: knowledge does not die the way code does. A format that cannot express that fork hands an outside reader a contradiction as the first thing they see.

Retraction

A published capsule is never edited to hide an error, and never deleted. It is marked withdrawn, with the reason and a pointer to what replaces it.

Concretely: evidence_status becomes withdrawn and a withdrawn object carries date, reason, and superseded_by. The claim, the evidence, and the original identifier stay exactly as published — a retraction that edits the claim is not a retraction.

A corpus that quietly revises itself cannot be cited, because the citation would point at whatever the text happens to say today. Retraction is what makes a record load-bearing, and it is cheap to promise and expensive to keep.

What this format did not catch in its own author

The first version of this section said the errors below were things “the format caught”. The first external reviewer — a model from another vendor, reading this cold — called that self-congratulation wearing the clothes of honesty, and was right. The correction stands here rather than being quietly swapped in, because that is the behaviour the rest of this document demands.

Here is the accurate account. Four errors, all public, all in this repository’s history, and not one of them was caught by the capsule format.

A benchmark answer key wrong in half its fixtures. Six of twelve chess fixtures asserted the wrong answer, because none of the positions contained a king and hand-written move logic stood in for an engine, reproducing its author’s misunderstanding of two rules. Caught by: a second model, from another vendor, disagreeing with the key twice in a row. The format played no part. See the retirement notice and the finding.

A published result that understated another vendor’s model by half. The prompt given to an evaluated model specified one response shape; the evaluator read another. Caught by: a person opening both files and comparing them. The format played no part. See RESULTS.md.

One chess position recorded three times, three different ways. Caught by: the same manual investigation. If anything, this is an error the format’s own one-claim-one-place principle would have prevented had it been applied — its absence caused the error rather than its presence catching it.

A citation stitched from three editions — a quote from the 2023 rules, an article number from 2009, a link to the 2009 PDF. Caught by: a test that fetches the reference and looks for the quote in the response body. That test is the closest thing here to a win, and it is a test, not a format.

So what does the format actually contribute? One thing, and it is smaller than the earlier version claimed but not nothing: it makes the fields exist so a check can be written against them. A capsule with no evidence.ref gives a test nothing to fetch; a claim with no decay.check_after gives a scheduler no date to fire on; a corpus with no declared confidence leaves a reader inferring certainty from fluency. The format does not do the checking. It removes the excuse that there was nothing to check.

Two of these errors were found only because a different model disagreed, which is worth more than any field in the schema — and is exactly how this section came to be rewritten.

A note on this section’s own history, left here on purpose. For a day, this document carried the rewrite above and the superseded version below it, both intact — the honest account and the flattering one, in the same section, contradicting each other. One said not one error was caught by the format; the other closed with “it made them findable.” A reader got two answers to one question and no way to tell which was current. Nobody noticed while reading the file, because nobody had both halves on screen at once — the same failure mode documented four times over elsewhere in this repository, occurring in the paragraph that documents it. It was found on 2026-08-15 by an agent asked to inventory this corpus, not by a person reading the prose and not by any check in selftest.mjs. The duplicate is deleted rather than reconciled: a superseded statement kept “for context” is just a second statement, and this document’s whole argument is that a second statement nothing compares is how corpora go quietly wrong.

Known gaps

Named here rather than left for a reader to find. A specification that hides its own holes is the thing this project keeps catching in other people’s work and in its own. All six were raised by the first external review. None is closed in general; the first is closed narrowly, for this repository’s own capsules only, by schema 1.2.0 — and its entry says where that narrowness begins and ends rather than counting it as fixed.

The machine layer’s execution environment is only partly specified. Schema 1.2.0 adds machine_execution_contract: local_check is a node command, run from the repository root, with no dependency and no network, where exit 0 means the claim holds and nonzero means it does not — and selftest.mjs (C-08) now runs it for every capsule instead of checking that the field exists. That closes the gap for this repository’s own capsules, read by someone willing to run node in this checkout. It does not specify a runtime for any other environment (shell, Python, a container, a remote endpoint), resource or time limits, a parameter-passing convention for criteria that need input, or how a reader who does not trust running an arbitrary script from a corpus it is auditing is supposed to get the same answer without executing untrusted code. The claim that this format makes “still true” automatically answerable is earned narrowly, not as a property of the format in general.

evidence.ref has no resolution protocol. The spec does not say whether ref is a URL, a DOI, a git object, or a path, nor how to handle redirects, auth, paywalls, client-rendered pages, or a source that moves. The reference implementation handles HTTP(S) and reports an unreachable source as unverified rather than broken; that is one implementation’s choice, not a rule of the format.

No integrity binding. A capsule carries no digest or signature over its own content. A reader cannot distinguish a capsule altered after publication from one that was not. Provenance names an author; it does not bind the bytes.

Nobody is named as the authority over profiles. Nothing says who may declare a new profile or where the declaration is published. Two corpora that each invent a knowledge-corpus profile with different vocabularies would both be conformant and mutually unreadable — which is the exact incomparability that closed vocabularies exist to prevent, displaced one level up rather than solved.

This schema is not a schema. axioma-xks-spine-v1.json is a description with normative prose inside it, not JSON Schema. It cannot be handed to an off-the-shelf validator, so every implementation writes its own reader — which is precisely the situation that lets two readers drift apart.

knowledge-object is coupled to teaching. Making play and quiz mandatory suits knowledge somebody practises and fits badly around a dataset or an operational fact. Filling those layers with placeholders to satisfy the schema would be a stub, and stubs are what this project calls lying about readiness.

Conformance

node selftest.mjs checks, among other things, that every capsule published here satisfies the spine and its declared profile, that every evidence.ref resolves and its quote is verbatim present at the source, and that no generated artifact has been hand-edited. Network checks that cannot run report SKIPPED — a run with a skipped check is incomplete, not green.

Review history

2026-08-12 — first external review. Gemini 3.6 Flash, cold read, no access to this project beyond the two published files. Seven questions, seven answers, all critical. It found the prose and the schema disagreeing in three places, an unhandled ambiguity in the extension rule, six unstated gaps, and a section that flattered its author. Schema v1.1 and this revision of the prose are the response; the review itself is preserved unedited at reviews/2026-08-12-gemini-3-6-flash.md, alongside the prompt it answered — a review without its prompt cannot be told apart from a review that was steered.

Two findings deserve naming, because they land on this document’s own principle. The spine had no field declaring which profile applied — so this project’s validator guessed knowledge-object for every capsule, which is a reader inferring what the author should have stated. And that validator was enforcing sub-fields of decay the schema never declared: the test knew more about the format than the specification did. That is the two-statements defect this document exists to prevent, found inside the document itself, by a stranger, within hours of publication.

Status and citation

This specification is draft. It describes a format in use, not a proposal: the capsules in this repository are its worked examples and are validated against it on every run.

Cite the repository via CITATION.cff. Retracted results keep their identifiers.