@cynodia/axiom 0.17.0-alpha.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,8 +32,10 @@ documentation above was missed.
32
32
  Shorter forms of the same routing: [`AGENTS.md`](AGENTS.md) and [`llms.txt`](llms.txt), both
33
33
  at this package's root.
34
34
 
35
- **Status: experimental / alpha.** The API may change between alpha releases. The
36
- documentation in `docs/` describes this exact version, `0.17.0-alpha.1`.
35
+ **Status: stable 1.0.0.** The portable semantic contract is frozen (Axiom 0.17) and the
36
+ public API follows the `1.x` compatibility policy in
37
+ [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md). The documentation in `docs/` describes
38
+ this exact version, `1.0.0`.
37
39
 
38
40
  ## Installation
39
41
 
@@ -43,11 +45,10 @@ npm install @cynodia/axiom-ui # semantic UI authoring patterns (build ti
43
45
  npm install @cynodia/axiom-server # only if the application has an authority
44
46
  ```
45
47
 
46
- Every release of this project is a pre-release and npm's `latest` tag points at it, so the
47
- plain command above installs the current version. **There is no `alpha` dist-tag** — the tag
48
- was removed once it stopped tracking releases, and `npm install @cynodia/axiom@alpha` now
49
- fails with a 404. Pin the exact version instead when one is needed:
50
- `npm install @cynodia/axiom@0.17.0-alpha.1`.
48
+ npm's `latest` tag points at the current release, so the plain command above installs it.
49
+ **There is no `alpha` dist-tag** — the tag was removed once it stopped tracking releases,
50
+ and `npm install @cynodia/axiom@alpha` now fails with a 404. Pin the exact version instead
51
+ when one is needed: `npm install @cynodia/axiom@1.0.0`.
51
52
 
52
53
  These are ES modules compiled to ES2022; import them with `import`, not `require`.
53
54
  `@cynodia/axiom-cli` (`npm install -g @cynodia/axiom-cli`) publishes the `axiom` executable
@@ -173,6 +174,7 @@ focused document when the reference is not specific enough for the question at h
173
174
  | --- | --- |
174
175
  | **Compressed contract for authoring or modifying an app — start here** | [`docs/AGENT_REFERENCE.md`](docs/AGENT_REFERENCE.md) |
175
176
  | Exact runtime guarantees, stated formally | [`docs/SEMANTIC_CONTRACT.md`](docs/SEMANTIC_CONTRACT.md) |
177
+ | What 1.0 guarantees, the SemVer policy, upgrading from 0.17 | [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) |
176
178
  | Mistakes that compile but are wrong | [`docs/ANTI_PATTERNS.md`](docs/ANTI_PATTERNS.md) |
177
179
  | Graph, node kinds, ids, types, entity value representation | [`docs/GRAPH_MODEL.md`](docs/GRAPH_MODEL.md) |
178
180
  | Every expression kind, builtin, scope, presence and null rule | [`docs/EXPRESSIONS.md`](docs/EXPRESSIONS.md) |
@@ -1,6 +1,6 @@
1
1
  # Actions and transactions
2
2
 
3
- Axiom 0.17.0-alpha.1. An action is behavior expressed as data, executed as a transaction.
3
+ Axiom 1.0.0. An action is behavior expressed as data, executed as a transaction.
4
4
 
5
5
  ```ts
6
6
  {
@@ -190,6 +190,15 @@ The controlled boundary for behavior the operation vocabulary cannot express.
190
190
  **Use it only where no semantic primitive exists.** A native operation is opaque to every
191
191
  analysis Axiom offers.
192
192
 
193
+ **`NativeOperation` is not portable semantics.** It is a host-language extension point, not
194
+ part of the portable semantic profile. A conforming runtime that has no compatible
195
+ registered implementation for an encountered `NativeOperation` MUST report it as
196
+ **unsupported / opaque** and refuse — it MUST NOT ignore the operation, skip it, substitute
197
+ a no-op, or invent host behavior. A graph that *requires* a `NativeOperation` is outside the
198
+ portable profile unless an explicitly declared runtime-specific extension defines it. That
199
+ the reference full-stack host *can* run registered native operations does not make the
200
+ construct portable, and does not change this requirement for any other runtime.
201
+
193
202
  ### `integration-query`
194
203
 
195
204
  ```ts
package/docs/AGENT_API.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agent API
2
2
 
3
- Axiom 0.17.0-alpha.1. The machine-facing interface. Agents query semantics and apply
3
+ Axiom 1.0.0. The machine-facing interface. Agents query semantics and apply
4
4
  structural transformations; they never edit generated code.
5
5
 
6
6
  ```ts
@@ -1,6 +1,6 @@
1
1
  # Agent reference
2
2
 
3
- Axiom 0.17.0-alpha.1. Compressed operational contract. Read this plus the `.d.ts`
3
+ Axiom 1.0.0. Compressed operational contract. Read this plus the `.d.ts`
4
4
  declarations before authoring or modifying an Axiom application.
5
5
 
6
6
  Formal guarantees: [`SEMANTIC_CONTRACT.md`](SEMANTIC_CONTRACT.md). Mistakes that compile:
@@ -1,6 +1,6 @@
1
1
  # Anti-patterns
2
2
 
3
- Axiom 0.17.0-alpha.1. Each of these compiles. Each is wrong. Each is followed by the correct
3
+ Axiom 1.0.0. Each of these compiles. Each is wrong. Each is followed by the correct
4
4
  alternative.
5
5
 
6
6
  ## 1. Field names as entity runtime keys
package/docs/AUTHORITY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Authority
2
2
 
3
- Axiom 0.17.0-alpha.1. How an application crosses the trust boundary.
3
+ Axiom 1.0.0. How an application crosses the trust boundary.
4
4
 
5
5
  Until 0.5.x an Axiom application executed locally. 0.6 adds an **authority**: a generic
6
6
  runtime that owns state, decides mutations and persists them. The same semantic graph
@@ -695,7 +695,7 @@ do not conflate them under one "contract" name):
695
695
  | --- | --- |
696
696
  | `manifest.conformance` | The **fixture-format** version (`axiom.conformance.v1`/`v2`) — the shape of the JSON documents themselves: what top-level keys a fixture may have (`invocations` vs `steps`/`externalAdapters`, and so on). |
697
697
  | `manifest.baseContract` | The **oldest** Server IR contract any fixture in this manifest may use — `axiom.server.v1`, always, since new fixtures are added without ever raising this floor. It does **not** describe what the newest fixture needs. |
698
- | `manifest.fixtures[].contract` | The Server IR contract **that specific fixture** requires — this is what is authoritative for what running it needs. The suite ships fixtures spanning `v1` through `v4` simultaneously, each correctly labelled. |
698
+ | `manifest.fixtures[].contract` | The Server IR contract **that specific fixture** requires — this is what is authoritative for what running it needs. The root suite ships fixtures spanning `v1` through `v5` simultaneously (and the sub-tiers reach `v9`), each correctly labelled. |
699
699
  | `manifest.release` | The `@cynodia/axiom` package version this snapshot of the suite shipped with — unrelated to either version above. |
700
700
 
701
701
  Before 8.2 the manifest's top-level field was named `contract` and fixed at
@@ -734,10 +734,15 @@ are tested against the same expectation.
734
734
  ## Machine-readable contracts
735
735
 
736
736
  ```
737
- @cynodia/axiom-server/schema/server-ir.v1.schema.json
737
+ @cynodia/axiom-server/schema/server-ir.v1.schema.json ← frozen, byte-stable
738
738
  @cynodia/axiom-server/schema/server-ir.v2.schema.json
739
739
  @cynodia/axiom-server/schema/server-ir.v3.schema.json
740
740
  @cynodia/axiom-server/schema/server-ir.v4.schema.json
741
+ @cynodia/axiom-server/schema/server-ir.v5.schema.json
742
+ @cynodia/axiom-server/schema/server-ir.v6.schema.json
743
+ @cynodia/axiom-server/schema/server-ir.v7.schema.json
744
+ @cynodia/axiom-server/schema/server-ir.v8.schema.json
745
+ @cynodia/axiom-server/schema/server-ir.v9.schema.json ← current
741
746
  @cynodia/axiom-server/schema/protocol.v1.schema.json
742
747
  ```
743
748
 
@@ -1,6 +1,6 @@
1
1
  # Authorization
2
2
 
3
- Axiom 0.17.0-alpha.1. The operational contract for **authorization completeness** — the 0.15
3
+ Axiom 1.0.0. The operational contract for **authorization completeness** — the 0.15
4
4
  milestone (spec15). Whether a principal may perform a semantic operation is part of the
5
5
  graph's executable meaning — not a runtime concern, not UI visibility, not something that
6
6
  varies by transport, provider, process, retry path or authority topology. `axiom.server.v9`
@@ -0,0 +1,166 @@
1
+ # Compatibility and the 1.0 contract
2
+
3
+ Axiom 1.0.0. **Normative.** This document states what Axiom 1.0 guarantees across the
4
+ `1.x` line and how those guarantees are allowed to change.
5
+
6
+ ## Axiom 1.0 portable semantics ARE the frozen 0.17 semantic contract
7
+
8
+ Axiom 1.0 is not a new semantic milestone. It is the stable publication of the semantic
9
+ contract that was frozen at Axiom 0.17:
10
+
11
+ ```
12
+ AXIOM 0.17 SEMANTIC CONTRACT: FROZEN
13
+ ```
14
+
15
+ For every graph inside the portable semantic profile:
16
+
17
+ ```
18
+ portableMeaning(Axiom 1.0) == portableMeaning(Axiom 0.17 frozen contract)
19
+ ```
20
+
21
+ The 0.17 validation history (Track A — an independent Python runtime executes the portable
22
+ contract equivalently; Track B — a fresh evaluator reconstructed the model from public
23
+ artifacts alone; the pre-freeze correction pass) is retained as **architecture and
24
+ conformance evidence** in `reports/` (a maintainer directory, never shipped in a tarball).
25
+ **You do not need to read it to use Axiom 1.0.** What Axiom *means* lives in the documents
26
+ below; how that meaning was *proven* lives in `reports/`.
27
+
28
+ ## Where authoritative information lives
29
+
30
+ | Layer | Role | Class |
31
+ | --- | --- | --- |
32
+ | `specs/spec*.md` | The design record for each milestone. History; not rewritten. | INFORMATIVE (except where a rule is stated nowhere else) |
33
+ | `docs/SEMANTIC_CONTRACT.md` | The consolidated formal statement of portable runtime behavior, incl. [Normative precedence](SEMANTIC_CONTRACT.md#normative-precedence). | **NORMATIVE** |
34
+ | `docs/AUTHORITY.md` | Server IR, the trust boundary, the protocol, Server IR admission, conformance. | **NORMATIVE** |
35
+ | `docs/EXPRESSIONS.md`, `LOCATIONS.md`, `STATE.md`, `ACTIONS_TRANSACTIONS.md`, `CONSTRAINTS.md`, `QUERIES.md`, `AUTHORIZATION.md`, `WORKFLOWS.md`, `EFFECTS.md`, `EVENTS.md`, `SUBSCRIPTIONS.md`, `LIVE_QUERIES.md`, `MIGRATIONS.md`, `DISTRIBUTED_AUTHORITY.md`, `STORAGE.md`, `VALIDATION.md` | The full contract for each semantic area. | **NORMATIVE** |
36
+ | `docs/AGENT_REFERENCE.md` | The compressed reference, including truth tables. | NORMATIVE (compressed; the topic doc wins on any conflict) |
37
+ | `@cynodia/axiom-server/schema/*.json` | Structural validity and discriminators for Server IR and the protocol. | NORMATIVE for **structure only** — never overrides prose meaning |
38
+ | `*.d.ts` | The local contract of each public type. | NORMATIVE for **structure only** |
39
+ | `@cynodia/axiom-server/conformance/**` | Runtime-neutral fixtures. | NORMATIVE **evidence** — tests specified semantics, does not invent them |
40
+ | `docs/RUNTIME.md`, `docs/INTEGRATIONS.md` adapter sections, package READMEs | Reference-implementation and operational guidance. | OPERATIONAL / INFORMATIVE |
41
+ | `README.md` examples, `packages/demo` | Illustrations. | EXAMPLE — illustrate normative rules, never define them |
42
+
43
+ **The reference TypeScript runtime is one conforming implementation of this contract, not
44
+ its definition.** Where the reference runtime disagrees with the normative documents above,
45
+ the reference runtime is defective (see
46
+ [Normative precedence](SEMANTIC_CONTRACT.md#normative-precedence)).
47
+
48
+ ## The portable semantic profile
49
+
50
+ Everything defined by the normative documents is portable **except** where a document marks
51
+ it otherwise. The two explicit non-portable boundaries in 1.0:
52
+
53
+ - **`NativeOperation`** — a host-language extension point. A runtime with no compatible
54
+ registered implementation MUST report it unsupported/opaque and refuse; a graph that
55
+ requires one is outside the portable profile unless an explicit runtime-specific extension
56
+ defines it. See [`ACTIONS_TRANSACTIONS.md`](ACTIONS_TRANSACTIONS.md#native).
57
+ - **Structured value → text coercion** — a graph MUST NOT depend on the text form of a
58
+ record or collection. See [`EXPRESSIONS.md`](EXPRESSIONS.md#text-form).
59
+
60
+ Non-semantic differences a conforming runtime MAY exhibit: human-readable diagnostic wording;
61
+ the exact diagnostic **code** where the contract says it is implementation-defined (e.g. an
62
+ unknown `EventRequest` `eventId`); physical retry/attempt counts where the contract calls
63
+ them non-semantic; storage layout, thread/process model, private logging, performance.
64
+
65
+ ## Conformance baseline
66
+
67
+ `@cynodia/axiom-server` ships the runtime-neutral fixture corpus and its manifests. The
68
+ Axiom 1.0 semantic baseline is the corpus as published with `1.0.0`:
69
+
70
+ ```
71
+ axiom.conformance.1.0 ← the named, permanent reference to the 1.0 fixture corpus
72
+ ```
73
+
74
+ The corpus is organised as a root tier plus per-area sub-tiers, each with its own
75
+ fixture-format version (`manifest.conformance`) and reference runner; see
76
+ [`AUTHORITY.md`](AUTHORITY.md#conformance). Those internal generation numbers
77
+ (`axiom.conformance.v1` … `v11`) are **not renamed** for 1.0 — `axiom.conformance.1.0` is a
78
+ permanent *pointer* to the whole corpus at the 1.0 release, so a runtime can cite exactly
79
+ which baseline it passed.
80
+
81
+ ## `1.x` compatibility policy (SemVer)
82
+
83
+ ### Patch (`1.0.x`)
84
+
85
+ MAY include: bug fixes, performance fixes, security fixes, diagnostic improvements
86
+ compatible with the stability class of the diagnostic (below), documentation corrections,
87
+ and **new conformance fixtures that test already-defined behavior** (including
88
+ bug-regression fixtures). MUST NOT intentionally change portable semantic meaning. MUST NOT
89
+ add a fixture that imposes a *new* semantic requirement.
90
+
91
+ ### Minor (`1.x.0`)
92
+
93
+ MAY add backward-compatible public API and capability surface (new exports, new provider
94
+ capabilities behind explicit declaration, new tooling). Any semantic **expansion** MUST be
95
+ explicitly versioned (a new Server IR contract, a new capability a graph opts into) and MUST
96
+ NOT reinterpret an existing graph. A graph valid under `1.0` stays valid and keeps its
97
+ meaning under every `1.x`.
98
+
99
+ ### Major (`2.0.0`)
100
+
101
+ Required for any intentionally incompatible change to an established `1.x` contract.
102
+
103
+ ### Semantic bugs found after 1.0
104
+
105
+ - **Reference runtime violates the normative contract** → fix the runtime to the contract;
106
+ keep the reproducer permanently. Not a contract change.
107
+ - **The normative contract itself contains a genuine contradiction or an unsafe defect** →
108
+ explicit compatibility / security adjudication, documented: what changes, why, blast
109
+ radius, whether it is patch/minor/major, and whether prior conformance evidence is
110
+ affected. Never a silent reinterpretation.
111
+
112
+ "All existing reference-runtime behavior is frozen forever" is **not** the rule. The
113
+ *contract* is frozen; the implementation is corrected toward it.
114
+
115
+ ## Semantic identity and mixed-version deployment
116
+
117
+ `semanticFingerprint(graph)` moves only for an **execution-affecting** change (an
118
+ `ActionDef` semantic change, an `AuthorizationPolicyDef` edit, a `WorkflowDef` control-flow
119
+ or step change, a `QueryDef` clause change, a `ReadPolicyDef` predicate change, …). A
120
+ presentation-only or metadata-only edit does not move it. Two authorities with the same
121
+ `semanticFingerprint` and compatible `AuthorityCompatibilityKey` (Server IR contract +
122
+ `schemaFingerprint` + `semanticFingerprint` + authorization runtime marker) may run the same
123
+ durable work; an incompatible pair fails closed (`INCOMPATIBLE_AUTHORITY`). See
124
+ [`DISTRIBUTED_AUTHORITY.md`](DISTRIBUTED_AUTHORITY.md).
125
+
126
+ Current markers at 1.0: Server IR `axiom.server.v9`, authorization runtime `axiom.authz.v3`.
127
+ 1.0 adds **no** new Server IR vocabulary and does not move `SEMANTIC_FINGERPRINT_VERSION`.
128
+
129
+ ## Diagnostic stability classes
130
+
131
+ | Class | Meaning |
132
+ | --- | --- |
133
+ | STABLE_MACHINE_CODE | The exact `code` string is contractual (e.g. `AUTHORIZATION_DENIED`, `CONCURRENCY_CONFLICT`, `SERVER_IR_NOT_NORMALIZED`, the `VALIDATION_CODES` set). |
134
+ | STABLE_CATEGORY | The semantic category is contractual; the exact code is not (e.g. "a refusal, not a mutation"). |
135
+ | IMPLEMENTATION_DEFINED | Neither code nor wording is contractual — only the observable effect (e.g. the code for an unknown `eventId`). |
136
+ | DEBUG_ONLY | Present for humans; never part of a machine contract. Free-form `message`, stack traces. |
137
+
138
+ `VALIDATION_CODES` and `RUNTIME_DIAGNOSTIC_CODES` members, and the `SERVER_IR_*` /
139
+ `AUTHORIZATION_DENIED` / `CONCURRENCY_CONFLICT` / migration / coordination codes, are
140
+ STABLE_MACHINE_CODE. A native host-language exception is **never** the machine contract at a
141
+ boundary that accepts untrusted serialized input — such input yields a structured Axiom
142
+ diagnostic.
143
+
144
+ ## Upgrading from 0.17
145
+
146
+ Moving from the final 0.17 package set to 1.0 is a **publication**, not a semantic migration:
147
+
148
+ - Every graph that admitted under 0.17 admits under 1.0 unchanged.
149
+ - `semanticFingerprint`, `schemaFingerprint`, Server IR contract labels and
150
+ `AuthorityCompatibilityKey` are unchanged for every graph.
151
+ - Persisted state, durable workflow records, migration metadata and live-query cursors
152
+ minted under 0.17 remain valid.
153
+ - No graph edit is required because the version number became `1.0`.
154
+
155
+ ## Known 1.0 limitations
156
+
157
+ - `NativeOperation` is non-portable (above).
158
+ - Physical exactly-once **effect delivery** is only as strong as the adapter's own
159
+ idempotency; Axiom guarantees exactly-once *logical* effect creation and documented
160
+ physical retry. See [`EFFECTS.md`](EFFECTS.md).
161
+ - Provider-internal behavior (locking, DDL, storage layout, cleanup scheduling) is
162
+ operational, not portable semantics.
163
+ - Retention/cleanup of workflow history, effect records, event-dedup records, subscription
164
+ cursors, blob intents and coordination leases is a host/provider responsibility, not a
165
+ portable guarantee. See each area's document.
166
+ - Unsupported capabilities on a partial-conformance runtime are refused, never approximated.
@@ -1,6 +1,6 @@
1
1
  # Constraints
2
2
 
3
- Axiom 0.17.0-alpha.1. Two constructs, answering different questions. They are not
3
+ Axiom 1.0.0. Two constructs, answering different questions. They are not
4
4
  interchangeable.
5
5
 
6
6
  | | Question | Sees |
@@ -1,6 +1,6 @@
1
1
  # Distributed authority
2
2
 
3
- *This document describes Axiom `0.17.0-alpha.1`.*
3
+ *This document describes Axiom `1.0.0`.*
4
4
 
5
5
  The authoritative runtime (`docs/AUTHORITY.md`) may run as **more than one process at the
6
6
  same time**, over one shared persistence provider, without any change to the
@@ -201,6 +201,22 @@ A stable id is **never synthesised** from a receive timestamp, an authority inst
201
201
  random UUID. The window per source is bounded; an id that has fallen out of the window is
202
202
  treated as new (bounded, not exactly-once).
203
203
 
204
+ **Ownership and scope.** External-event deduplication is owned by the **ingestion boundary** —
205
+ it runs before any `Event` is constructed and therefore before any trigger, action or
206
+ workflow. Neither the trigger dispatcher nor the action runtime deduplicates: by the time a
207
+ delivery reaches a trigger it is already a single accepted occurrence. The **identity** is
208
+ always an external one the provider supplies (`source + externalEventId`); Axiom never
209
+ invents it. The **scope** is whatever backs the check:
210
+
211
+ | Mechanism | Layer | Identity | Durable? | Scope |
212
+ | --- | --- | --- | --- | --- |
213
+ | Webhook `deliveryId` window (`docs/EVENTS.md`) | HTTP webhook decode | `decode`'s `deliveryId` | no (bounded in-memory, per route) | one process |
214
+ | `ExternalEventDedupStore` | event ingestion | `source + externalEventId` + payload fingerprint | yes | cluster-wide when the store is shared; per-authority otherwise |
215
+ | `SubscriptionDef.delivery.deduplicateBy` (`docs/SUBSCRIPTIONS.md`) | subscription delivery | a named payload field | restart-durable when the adapter implements `hasDelivery` | per subscription |
216
+
217
+ A runtime that does not implement a durable store gets the bounded, in-process window and
218
+ MUST say so — it MUST NOT claim exactly-once.
219
+
204
220
  ## 12. Subscriptions
205
221
 
206
222
  A `SubscriptionDef` separates three things: the semantic subscription (durable), the
package/docs/EFFECTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Effects
2
2
 
3
- Axiom 0.17.0-alpha.1. External effects are not rollback-capable state mutations. This file
3
+ Axiom 1.0.0. External effects are not rollback-capable state mutations. This file
4
4
  is the delivery model; [`AUTHORITY.md`](AUTHORITY.md#external-effects) is the load-bearing
5
5
  statement of why, and [`INTEGRATIONS.md`](INTEGRATIONS.md) is the operation vocabulary this
6
6
  builds on.
package/docs/EVENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Events
2
2
 
3
- Axiom 0.17.0-alpha.1. An event is a typed fact — something that happened — never work
3
+ Axiom 1.0.0. An event is a typed fact — something that happened — never work
4
4
  itself. [`AUTHORITY.md`](AUTHORITY.md#external-events) is the load-bearing statement;
5
5
  this file is the vocabulary and the webhook delivery mechanism. A **subscription** is the
6
6
  other way an external fact becomes an `EventDef` payload — see
@@ -44,12 +44,28 @@ An event reaches the semantic layer three ways, and all three funnel through the
44
44
  3. **The semantic protocol directly** — `EventRequest{ kind: 'event', eventId, payload }`,
45
45
  for a host that already trusts its own caller (an internal service, a test).
46
46
 
47
+ ## Unknown event id
48
+
49
+ An `EventRequest` (or a webhook `decode` result, or a subscription delivery) whose `eventId`
50
+ is **not an `EventDef` in the admitted application graph** MUST be **refused**. No `Event` is
51
+ constructed, no trigger is dispatched, no `ActionDef` is invoked, no `WorkflowDef` is
52
+ started, no application-state or provider mutation occurs, and no logical effect is created.
53
+ The request is answered `ok: false`.
54
+
55
+ The **exact diagnostic code** for an unknown `eventId` is **implementation-defined** unless
56
+ a more specific public diagnostic contract applies: portable conformance compares the
57
+ refusal and its zero side effects, not the code string. The reference runtime reuses
58
+ `EVENT_PAYLOAD_INVALID` (an unknown event cannot have a conforming payload); another
59
+ conforming runtime MAY report a distinct code such as `UNKNOWN_EVENT`. That difference is a
60
+ non-semantic diagnostic-representation difference, not a behavioral disagreement.
61
+
47
62
  ## Payload validation
48
63
 
49
64
  Every event's payload is checked against its declared `EventDef.payloadType` — the same
50
65
  `validateValueAgainstType` walk that checks action arguments and seed data — **before any
51
66
  trigger's action runs**. A malformed payload never reaches trusted code:
52
- `EVENT_PAYLOAD_INVALID`, and no action is invoked.
67
+ `EVENT_PAYLOAD_INVALID`, and no action is invoked, no state or provider mutates, and no
68
+ effect is created.
53
69
 
54
70
  ## Webhooks
55
71
 
@@ -1,6 +1,6 @@
1
1
  # Expressions
2
2
 
3
- Axiom 0.17.0-alpha.1. An expression describes **what value is computed**. It is a tree of
3
+ Axiom 1.0.0. An expression describes **what value is computed**. It is a tree of
4
4
  plain data, never source text and never a callback. Evaluation is pure: an expression MUST
5
5
  NOT change state.
6
6
 
@@ -14,9 +14,24 @@ To describe *where* a value is written, see [`LOCATIONS.md`](LOCATIONS.md).
14
14
 
15
15
  ## Conversions
16
16
 
17
- Three coercions decide most edge cases. They are shared by every kind.
17
+ Four coercions decide most edge cases. They are shared by every kind, and are defined here
18
+ in **language-neutral** terms: a conforming runtime MUST implement these rules directly, not
19
+ by delegating to a host language's `Number()`, `String()` or JSON serializer. Two runtimes
20
+ in different languages must produce the same result for every input below.
18
21
 
19
- **Truthiness** (`and`, `or`, `not`, `conditional`, predicates, `visibleWhen`):
22
+ ### Number model
23
+
24
+ Every Axiom number is an IEEE-754 64-bit binary floating-point value (binary64). `NaN` and
25
+ the two infinities are numbers to the arithmetic below, but they are **not domain values**:
26
+ a stored field, an `initialValue` or a query row that is non-finite is a schema-conformance
27
+ failure (`INITIAL_VALUE_TYPE_MISMATCH` at authoring time; a mutation that would store one is
28
+ rejected). `divide` by zero is `null`, never an infinity. An ordered comparison (`gt`,
29
+ `gte`, `lt`, `lte`) in which either side is a non-finite number is **`false`**. Negative
30
+ zero is not observably distinct from zero.
31
+
32
+ ### Truthiness
33
+
34
+ `and`, `or`, `not`, `conditional`, predicates, `visibleWhen`.
20
35
 
21
36
  | Value | Truthy |
22
37
  | --- | --- |
@@ -24,24 +39,108 @@ Three coercions decide most edge cases. They are shared by every kind.
24
39
  | `[x]` | `true` |
25
40
  | `''` | `false` |
26
41
  | `'x'` | `true` |
27
- | `0` | `false` |
28
- | `null` / `undefined` | `false` |
29
- | `{}` | `true` |
42
+ | `0` / negative zero | `false` |
43
+ | `NaN` | `false` |
44
+ | `null` / absent | `false` |
45
+ | any other number | `true` |
46
+ | `{}` (a record) | `true` |
30
47
 
31
48
  A collection is truthy only when non-empty. This is the one coercion most likely to
32
49
  surprise: use `count(...) > 0` when you mean "has members" and want it to read that way.
33
50
 
34
- **Text** (`concat`, `to-string`, `lowercase`, `trim`, `substring-before`, `substring-after`, comparison of non-numbers, rendering):
35
- `null`/`undefined` → `''`; string → itself; number/boolean → `String(v)`; anything else →
36
- `JSON.stringify(v)`.
51
+ ### Text form
37
52
 
38
- **Number** (`add`, `subtract`, `multiply`, `divide`, `negate`): `Number(value ?? 0)`. A
39
- non-numeric string therefore yields `NaN` rather than an error, and comparisons against
40
- `NaN` are false — a guard fails closed rather than passing on a value it could not compute.
53
+ `concat`, `to-string`, `lowercase`, `trim`, `substring-before`, `substring-after`, `length`
54
+ of a non-collection, the text side of a mixed-type `gt`/`lt` comparison, `contains` on
55
+ text, and rendering.
41
56
 
42
- **Equality** (`eq`, `neq`, `contains`, `one-of`, identity selectors, transition-constraint
43
- change detection) is structural and key-order independent. `null` and `undefined` are
44
- equal to each other and to nothing else.
57
+ | Value | Text form |
58
+ | --- | --- |
59
+ | `null` / absent | `""` |
60
+ | a string | itself, unchanged |
61
+ | `true` / `false` | `"true"` / `"false"` |
62
+ | a number | its **canonical decimal string** (below) |
63
+ | a record or collection | a JSON rendering — **outside the portable conversion grammar** (below) |
64
+
65
+ **Canonical decimal string of a number** — the ECMAScript `Number::toString` radix-10
66
+ algorithm, restated so any language reproduces it:
67
+
68
+ - `0` and negative zero → `"0"`.
69
+ - A negative finite number → `"-"` then the text form of its magnitude.
70
+ - Choose the **shortest** decimal digit sequence that round-trips to the same binary64
71
+ value.
72
+ - Use **fixed** notation when `1e-6 ≤ |value| < 1e21` (and for `0`): the integer digits,
73
+ then — only if a fractional part remains — `.` (U+002E) and the fraction digits. No
74
+ trailing zeros, no leading `+`, no exponent.
75
+ - Otherwise use **exponential** notation: one mantissa digit, then (if more significant
76
+ digits remain) `.` and those digits with no trailing zeros, then `e`, then the exponent
77
+ sign (`+` or `-`), then the exponent digits with no leading zero. `1e21` → `"1e+21"`;
78
+ `1e-7` → `"1e-7"`; `1.5e300` → `"1.5e+300"`.
79
+ - `NaN` → `"NaN"`; positive infinity → `"Infinity"`; negative infinity → `"-Infinity"`.
80
+
81
+ **Structured value → text is not portable.** A record or collection has a text form only as
82
+ a last resort (`to-string` of an object, comparing two records with `lt`). The reference
83
+ runtime renders JSON with object members in **definition order** and no whitespace; a
84
+ conforming runtime MAY differ, and a graph that depends on it is outside the portable
85
+ profile. Where structural text genuinely matters — identity selectors, `group` keys,
86
+ structural equality, `semanticFingerprint` — the runtime uses **canonical JSON** instead
87
+ (object keys sorted by Unicode code point, recursively; no whitespace; `null` kept; absent
88
+ members omitted; numbers in canonical decimal form), which every conforming runtime MUST
89
+ reproduce byte-for-byte.
90
+
91
+ ### Numeric form
92
+
93
+ `add`, `subtract`, `multiply`, `divide`, `negate`. (`sum` does **not** coerce — a
94
+ non-numeric member fails the evaluation.)
95
+
96
+ | Operand | Numeric form |
97
+ | --- | --- |
98
+ | `null` / absent | `0` |
99
+ | a number | itself |
100
+ | `true` / `false` | `1` / `0` |
101
+ | `[]` | `0` |
102
+ | `[x]` | the numeric form of `x` |
103
+ | a collection of two or more | `NaN` |
104
+ | a record | `NaN` |
105
+ | a string | **portable numeric text** (below), else `NaN` |
106
+
107
+ A `NaN` operand propagates: the result is `NaN`, which then fails every ordered comparison
108
+ and cannot be stored — a guard fails closed rather than passing on a value it could not
109
+ compute.
110
+
111
+ **Portable numeric text.** The string is first stripped of leading and trailing whitespace
112
+ (U+0009, U+000A, U+000B, U+000C, U+000D, U+0020, and the Unicode space separators), then:
113
+
114
+ | Trimmed string | Result |
115
+ | --- | --- |
116
+ | empty (originally empty or all whitespace) | `0` |
117
+ | `Infinity` or `+Infinity` | positive infinity |
118
+ | `-Infinity` | negative infinity |
119
+ | a **canonical decimal literal** (below) | that value |
120
+ | a radix-prefixed integer — `0x`/`0X`, `0o`/`0O`, `0b`/`0B` then digits of that radix | that integer |
121
+ | anything else — `"NaN"`, `"1_000"`, `"1,5"`, `"abc"`, `"1abc"`, a lone `.`, `"1e"`, `"5%"` | `NaN` |
122
+
123
+ A **canonical decimal literal** is an optional sign (`+` / `-`), then digits with an
124
+ optional single `.` (at least one digit on one side — `.5` and `1.` are both accepted),
125
+ then an optional exponent: `e` / `E`, an optional sign, one or more digits.
126
+
127
+ > **The radix-prefixed and `Infinity` forms are accepted for host-behaviour compatibility
128
+ > but are discouraged.** A portable graph should coerce only **canonical decimal** text. A
129
+ > future contract version MAY narrow the accepted grammar to canonical decimal; it will not
130
+ > silently widen it. Coercion never yields "implementation-defined" — every string maps to a
131
+ > number, `NaN`, or an infinity by the table above.
132
+
133
+ ### Equality and ordering
134
+
135
+ **Equality** (`eq`, `neq`, `contains` on a collection, `one-of`, identity selectors,
136
+ transition-constraint change detection) is **structural** and key-order independent. `null`
137
+ and absent are equal to each other and to nothing else. Two numbers are equal when they are
138
+ the same binary64 value (so `-0` equals `0`; `NaN` equals nothing, including itself).
139
+
140
+ **Ordering** (`gt`, `gte`, `lt`, `lte`, `sort`): **numeric** when both sides are numbers,
141
+ otherwise by the **Unicode code point** sequence of the two text forms (not the host
142
+ language's string comparison, not locale collation). A comparison with a non-finite number
143
+ on either side is `false`.
45
144
 
46
145
  ## Expression kinds
47
146
 
@@ -93,15 +192,15 @@ object([
93
192
  | Operator | Semantics |
94
193
  | --- | --- |
95
194
  | `eq` / `neq` | Structural equality, key-order independent. |
96
- | `gt` `gte` `lt` `lte` | Numeric when **both** sides are numbers; otherwise lexicographic on their text form. |
195
+ | `gt` `gte` `lt` `lte` | Numeric when **both** sides are numbers; otherwise by Unicode code point of their [text form](#text-form). A non-finite number on either side → `false`. |
97
196
  | `and` / `or` | Truthiness, short-circuiting. Output is a boolean. |
98
- | `add` `subtract` `multiply` | `Number(x ?? 0)` arithmetic. |
99
- | `divide` | Division by zero yields **`null`**, not an error and not `Infinity`. |
197
+ | `add` `subtract` `multiply` | Binary64 arithmetic on the [numeric form](#numeric-form) of each side (absent → `0`). |
198
+ | `divide` | As above; division by zero yields **`null`**, not an error and not `Infinity`. |
100
199
 
101
200
  ### `unary(operator, operand)`
102
201
 
103
- - `not` → `!truthy(operand)`.
104
- - `negate` → `-Number(operand ?? 0)`.
202
+ - `not` → the boolean negation of the operand's [truthiness](#truthiness).
203
+ - `negate` → the arithmetic negation of the operand's [numeric form](#numeric-form) (absent → `0`).
105
204
 
106
205
  > **An expression evaluated as an authorization decision evaluates differently for a
107
206
  > missing security field.** Both `AuthorizationPolicyDef.allow` **and** the legacy
@@ -1,6 +1,6 @@
1
1
  # Graph model
2
2
 
3
- Axiom 0.17.0-alpha.1. The `ApplicationGraph` is the authoritative representation of an
3
+ Axiom 1.0.0. The `ApplicationGraph` is the authoritative representation of an
4
4
  application. Everything else — the IR, the page, the DOM — is derived from it and is never
5
5
  edited.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Integrations
2
2
 
3
- Axiom 0.17.0-alpha.1. How an application declares and calls an external system, without
3
+ Axiom 1.0.0. How an application declares and calls an external system, without
4
4
  embedding a transport, an SDK or a secret in the graph. The authority boundary this
5
5
  depends on is [`AUTHORITY.md`](AUTHORITY.md#external-systems); this file is the vocabulary.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Realtime — live canonical queries
2
2
 
3
- Axiom 0.17.0-alpha.1. The operational contract for **observing a `QueryDef` result over
3
+ Axiom 1.0.0. The operational contract for **observing a `QueryDef` result over
4
4
  time**: subscribe once, receive an initial coherent result, then receive canonical changes
5
5
  as authoritative committed state moves — through any compatible authority, across
6
6
  reconnects. 0.13 adds no Server IR vocabulary of its own — current is `axiom.server.v9`.
package/docs/LOCATIONS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Locations
2
2
 
3
- Axiom 0.17.0-alpha.1.
3
+ Axiom 1.0.0.
4
4
 
5
5
  ```text
6
6
  Expression = a value
@@ -1,6 +1,6 @@
1
1
  # Schema evolution & semantic migrations
2
2
 
3
- Axiom 0.17.0-alpha.1. The operational contract for evolving a deployed application's
3
+ Axiom 1.0.0. The operational contract for evolving a deployed application's
4
4
  semantic model and its persisted canonical data over time — adding a required field,
5
5
  splitting one field into two, removing an obsolete one, migrating millions of
6
6
  provider-backed rows — **without** an application-authored SQL migration, an ORM migration,
@@ -1,6 +1,6 @@
1
1
  # Presentation
2
2
 
3
- Axiom 0.17.0-alpha.1. Presentation is **semantic UX intent**, expressed as data on a UI
3
+ Axiom 1.0.0. Presentation is **semantic UX intent**, expressed as data on a UI
4
4
  node. It names roles, tokens and device classes. It never names a colour, a length, a media
5
5
  query or a CSS property.
6
6
 
package/docs/QUERIES.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Semantic data access & the query layer
2
2
 
3
- Axiom 0.17.0-alpha.1. The operational contract for demand-driven reads over authoritative
3
+ Axiom 1.0.0. The operational contract for demand-driven reads over authoritative
4
4
  data that is too large to materialize as a `StateDef` — 500,000 orders, 5,000,000 order
5
5
  lines, years of audit rows. `axiom.server.v6`.
6
6
 
package/docs/RUNTIME.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Runtime
2
2
 
3
- Axiom 0.17.0-alpha.1. The runtime executes an `ApplicationIR`. It is domain-independent: it
3
+ Axiom 1.0.0. The runtime executes an `ApplicationIR`. It is domain-independent: it
4
4
  contains no knowledge of any application.
5
5
 
6
6
  ## Constructing
@@ -1,11 +1,41 @@
1
1
  # Semantic contract
2
2
 
3
- Axiom 0.17.0-alpha.1. Runtime guarantees, stated formally. This file defines behavior; it
4
- does not teach. Where this file and any specification in `../specs/` disagree, this file
5
- describes the implementation and is authoritative.
3
+ Axiom 1.0.0. Runtime guarantees, stated formally. This file defines behavior; it
4
+ does not teach.
6
5
 
7
6
  `MUST` / `MUST NOT` describe guaranteed behavior. `MAY` describes a documented option.
8
7
 
8
+ ## Normative precedence
9
+
10
+ For a **portable semantic rule** — one whose result can change what an application means to
11
+ an observer — the order of authority is:
12
+
13
+ 1. The formal specification (`specs/spec*.md`) for a rule it states explicitly.
14
+ 2. This semantic contract and the topic documents under `docs/` — the consolidated
15
+ normative statement of portable runtime behavior.
16
+ 3. The public JSON Schemas (`@cynodia/axiom-server/schema/*`) — structural validity and
17
+ discriminators only.
18
+ 4. The public type declarations (`*.d.ts`) — structural shape only; they never override
19
+ prose meaning.
20
+ 5. The runtime-neutral conformance fixtures — normative **evidence** of the rules above.
21
+ They test specified semantics; they do not invent them. A fixture that exercises a
22
+ behavior no normative artifact describes is a **specification gap**, not a new rule.
23
+
24
+ **Reference-runtime behavior is evidence, not authority.** Where the reference runtime
25
+ disagrees with 1–5, the reference runtime is **defective** and is corrected to the
26
+ contract — never the contract to the runtime. Where two of 1–5 disagree, that is a
27
+ specification defect resolved explicitly, not silently by convention or by observing a
28
+ runtime. Where the contract is **silent** on a portable behavior, it is filled by an
29
+ explicit contract change.
30
+
31
+ This inverts the pre-0.17 "the implementation is authoritative" rule, which held only while
32
+ the portable contract was still incomplete. That rule survives **only** for
33
+ **non-portable implementation detail** — rendering internals, storage layout,
34
+ process/thread model, private diagnostics, performance, physical retry counts — none of
35
+ which is portable semantics and none of which cross-runtime conformance compares. For those,
36
+ `docs/` describes the reference implementation and the reference implementation is
37
+ authoritative.
38
+
9
39
  ## State
10
40
 
11
41
  ### Stored state
@@ -177,9 +207,10 @@ location.
177
207
  - Nothing returns a plausible value alongside a failure diagnostic.
178
208
  - Collection operators are strict about their source: `null` fails, `[]` behaves normally.
179
209
  - `sum` fails if any member is not a finite number.
180
- - Values are cloned with `structuredClone`, never a JSON round trip, so `NaN` is not disguised as `null`.
210
+ - Values are cloned structurally, never via a JSON round trip, so `NaN` is not disguised as `null`.
211
+ - Truthiness, text form, numeric form, equality and ordering are defined **language-neutrally** and MUST NOT be delegated to a host language's conversion functions. Axiom numbers are IEEE-754 binary64; `divide` by zero is `null`; an ordered comparison with a non-finite operand is `false`; `NaN` and the infinities are not storable domain values. Number → text is the canonical decimal string (ECMAScript `Number::toString` radix 10, restated); text → number accepts trimmed canonical decimal literals (empty → `0`, unparseable → `NaN`), with radix-prefixed and `Infinity` forms accepted for compatibility but discouraged. Text coercion of a **structured** value is outside the portable grammar; structural identity/keys/fingerprints use canonical (code-point-sorted) JSON.
181
212
 
182
- Full per-kind semantics: [`EXPRESSIONS.md`](EXPRESSIONS.md).
213
+ Full per-kind semantics and the full conversion tables: [`EXPRESSIONS.md`](EXPRESSIONS.md#conversions).
183
214
 
184
215
  ## Authority
185
216
 
package/docs/STATE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # State
2
2
 
3
- Axiom 0.17.0-alpha.1. A `StateDef` is a named application value: stored, or computed from
3
+ Axiom 1.0.0. A `StateDef` is a named application value: stored, or computed from
4
4
  other state.
5
5
 
6
6
  ```ts
package/docs/STORAGE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Storage and blobs
2
2
 
3
- Axiom 0.17.0-alpha.1. How an application stores, references, serves and deletes binary data —
3
+ Axiom 1.0.0. How an application stores, references, serves and deletes binary data —
4
4
  an attachment, a document, a photograph, a diagnostic log — with no filesystem path, no
5
5
  upload route and no download route anywhere in it.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Subscriptions
2
2
 
3
- Axiom 0.17.0-alpha.1. How an application receives a stream of external events — an MQTT
3
+ Axiom 1.0.0. How an application receives a stream of external events — an MQTT
4
4
  topic, a WebSocket feed, a queue consumer, a filesystem watcher, a serial port — without a
5
5
  client, a socket or a callback anywhere in the graph.
6
6
 
package/docs/TRIGGERS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Triggers
2
2
 
3
- Axiom 0.17.0-alpha.1. A `TriggerDef` says **when** an action should be invoked, without
3
+ Axiom 1.0.0. A `TriggerDef` says **when** an action should be invoked, without
4
4
  embedding callback code. `docs/AUTHORITY.md`
5
5
  [§ Triggers](AUTHORITY.md#triggers) is the load-bearing statement of the execution model;
6
6
  this file is the vocabulary.
package/docs/UI.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # UI
2
2
 
3
- Axiom 0.17.0-alpha.1. Eleven semantic UI node kinds describe **what exists and what it does**.
3
+ Axiom 1.0.0. Eleven semantic UI node kinds describe **what exists and what it does**.
4
4
  How it looks is [presentation](PRESENTATION.md).
5
5
 
6
6
  All eleven share `UIBase`:
@@ -1,6 +1,6 @@
1
1
  # Validation
2
2
 
3
- Axiom 0.17.0-alpha.1. Validation is authoring-time structural checking. It is not the same
3
+ Axiom 1.0.0. Validation is authoring-time structural checking. It is not the same
4
4
  as runtime constraint evaluation — see [`CONSTRAINTS.md`](CONSTRAINTS.md) for the four
5
5
  layers of correctness.
6
6
 
package/docs/WORKFLOWS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Durable workflows
2
2
 
3
- Axiom 0.17.0-alpha.1. The operational contract for **long-running semantic computations with
3
+ Axiom 1.0.0. The operational contract for **long-running semantic computations with
4
4
  a durable control position** — orchestration that survives process death, authority
5
5
  failover, retries, timer delivery, event delivery and ordinary distributed contention
6
6
  without application-owned infrastructure. `axiom.server.v8`.
@@ -255,7 +255,7 @@ step's argument expressions / `retry` policy, a `wait-event` step's `where` / `b
255
255
  or binding migration, and none is inferred ("closest step" recovery never happens).
256
256
  - A graph with **no** `WorkflowDef` compiles to the byte-identical `axiom.server.v1`–`v7`
257
257
  document it always did, and its `semanticFingerprint` / `schemaFingerprint` are unchanged.
258
- - Pre-`0.17.0-alpha.1` instances carry a compatibility key computed before `WorkflowDef`
258
+ - Pre-`1.0.0` instances carry a compatibility key computed before `WorkflowDef`
259
259
  participated; a corrected authority treats them as incompatible and fails closed (these
260
260
  are pre-freeze alpha releases — silent reinterpretation is the only unacceptable
261
261
  outcome).
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # Axiom
2
2
 
3
- > AI-native semantic application framework, version 0.17.0-alpha.1. An Axiom application is a
3
+ > AI-native semantic application framework, version 1.0.0. An Axiom application is a
4
4
  > typed semantic graph — state, behavior, constraints, UI structure, presentation and
5
5
  > authority as structured data — executed by generic runtimes. The JavaScript, HTML and CSS
6
6
  > that reach a browser are compiler output and are never authored or edited. The primary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cynodia/axiom",
3
- "version": "0.17.0-alpha.1",
3
+ "version": "1.0.0",
4
4
  "description": "AI-native semantic web application framework.",
5
5
  "license": "MIT",
6
6
  "author": "AskTech AS",
@@ -34,12 +34,15 @@
34
34
  }
35
35
  },
36
36
  "dependencies": {
37
- "@cynodia/axiom-core": "0.17.0-alpha.1",
38
- "@cynodia/axiom-runtime": "0.17.0-alpha.1",
39
- "@cynodia/axiom-compiler": "0.17.0-alpha.1",
40
- "@cynodia/axiom-agent-api": "0.17.0-alpha.1"
37
+ "@cynodia/axiom-core": "1.0.0",
38
+ "@cynodia/axiom-runtime": "1.0.0",
39
+ "@cynodia/axiom-compiler": "1.0.0",
40
+ "@cynodia/axiom-agent-api": "1.0.0"
41
41
  },
42
42
  "scripts": {
43
43
  "build": "tsc -b tsconfig.json"
44
+ },
45
+ "engines": {
46
+ "node": ">=22.0.0"
44
47
  }
45
48
  }