@cynodia/axiom 0.11.0-alpha.1 → 0.11.2-alpha.1
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 +3 -3
- package/docs/ACTIONS_TRANSACTIONS.md +1 -1
- package/docs/AGENT_API.md +1 -1
- package/docs/AGENT_REFERENCE.md +9 -5
- package/docs/ANTI_PATTERNS.md +2 -2
- package/docs/AUTHORITY.md +4 -2
- package/docs/CONSTRAINTS.md +1 -1
- package/docs/EFFECTS.md +1 -1
- package/docs/EVENTS.md +1 -1
- package/docs/EXPRESSIONS.md +1 -1
- package/docs/GRAPH_MODEL.md +1 -1
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/LOCATIONS.md +1 -1
- package/docs/MIGRATIONS.md +121 -21
- package/docs/PRESENTATION.md +1 -1
- package/docs/QUERIES.md +1 -1
- package/docs/RUNTIME.md +1 -1
- package/docs/SEMANTIC_CONTRACT.md +1 -1
- package/docs/STATE.md +1 -1
- package/docs/STORAGE.md +1 -1
- package/docs/SUBSCRIPTIONS.md +1 -1
- package/docs/TRIGGERS.md +1 -1
- package/docs/UI.md +1 -1
- package/docs/VALIDATION.md +1 -1
- package/llms.txt +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Shorter forms of the same routing: [`AGENTS.md`](AGENTS.md) and [`llms.txt`](llm
|
|
|
33
33
|
at this package's root.
|
|
34
34
|
|
|
35
35
|
**Status: experimental / alpha.** The API may change between alpha releases. The
|
|
36
|
-
documentation in `docs/` describes this exact version, `0.11.
|
|
36
|
+
documentation in `docs/` describes this exact version, `0.11.2-alpha.1`.
|
|
37
37
|
|
|
38
38
|
## Installation
|
|
39
39
|
|
|
@@ -47,7 +47,7 @@ Every release of this project is a pre-release and npm's `latest` tag points at
|
|
|
47
47
|
plain command above installs the current version. **There is no `alpha` dist-tag** — the tag
|
|
48
48
|
was removed once it stopped tracking releases, and `npm install @cynodia/axiom@alpha` now
|
|
49
49
|
fails with a 404. Pin the exact version instead when one is needed:
|
|
50
|
-
`npm install @cynodia/axiom@0.11.
|
|
50
|
+
`npm install @cynodia/axiom@0.11.2-alpha.1`.
|
|
51
51
|
|
|
52
52
|
These are ES modules compiled to ES2022; import them with `import`, not `require`. There is
|
|
53
53
|
no published Axiom CLI. `@cynodia/axiom-server`'s SQLite persistence adapter additionally
|
|
@@ -70,7 +70,7 @@ reports its absence rather than failing at import.
|
|
|
70
70
|
| `Theme` | Translation of presentation intent into visual design. |
|
|
71
71
|
| Renderer | Platform-specific materialization. Not part of the graph. |
|
|
72
72
|
| `StateDef.authority` | Who may commit a value: the client, or the server. The one declaration the split follows from. |
|
|
73
|
-
| `ServerIR` | The half an authority executes. Portable JSON
|
|
73
|
+
| `ServerIR` | The half an authority executes. Portable JSON. `axiom.server.v1` is frozen; the current contract is `axiom.server.v7`, computed from the document's vocabulary. |
|
|
74
74
|
| Semantic protocol | What a client may ask for: named actions with arguments, never mutation programs. |
|
|
75
75
|
| `PersistenceAdapter` | Where a decided value survives. Not part of the semantics. |
|
|
76
76
|
|
package/docs/AGENT_API.md
CHANGED
package/docs/AGENT_REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent reference
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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:
|
|
@@ -65,7 +65,7 @@ One canonical term per concept. These are not interchangeable.
|
|
|
65
65
|
## Graph construction
|
|
66
66
|
|
|
67
67
|
```ts
|
|
68
|
-
const graph = new ApplicationGraph(id, name); // version defaults to '0.11.
|
|
68
|
+
const graph = new ApplicationGraph(id, name); // version defaults to '0.11.2'
|
|
69
69
|
graph.addNode<StateDef>({ id, kind: 'state', ... }); // returns NodeId; throws if id exists
|
|
70
70
|
graph.getNode<StateDef>(id); // deep clone, or undefined
|
|
71
71
|
graph.updateNode(node); // write a modified node back
|
|
@@ -603,7 +603,7 @@ authoring an application that crosses the trust boundary.
|
|
|
603
603
|
10. **FORM SUBMIT** — a declared submit button invokes with its own arguments, clicked or submitted.
|
|
604
604
|
11. **IDEMPOTENCY** — a generated request id is unique across runtime instances; records are scoped by principal.
|
|
605
605
|
12. **CHANGES** — `changes` names every observable state whose value moved, and no others.
|
|
606
|
-
13. **PORTABILITY** — `axiom.server.v1` is frozen and language-independent.
|
|
606
|
+
13. **PORTABILITY** — `axiom.server.v1` is frozen and language-independent. It is not the *current* contract: a document declares the oldest contract that carries its vocabulary; `axiom.server.v7` is current (migrations, schema identity).
|
|
607
607
|
14. **INTEGRATION** — external systems are accessed through typed integration operations.
|
|
608
608
|
15. **QUERY** — an external query is explicit action/trigger execution, never a pure `Expression`.
|
|
609
609
|
16. **EFFECT** — external effects are not rollback-capable state mutations.
|
|
@@ -947,8 +947,12 @@ Providers: `createMemoryRowStore` + `createMemoryMigrationStore` (deterministic
|
|
|
947
947
|
`runMigrationConformanceFixture` over the `axiom.conformance.v5` fixtures in
|
|
948
948
|
`conformance/migrations/`.
|
|
949
949
|
|
|
950
|
-
|
|
951
|
-
|
|
950
|
+
There is **no published Axiom CLI**. Every schema/migration operation is a public library
|
|
951
|
+
function — `inspectSchema`, `diffSchema`, `explainSchemaDiff`, `migrationImpact` (from
|
|
952
|
+
`@cynodia/axiom-agent-api`); `planMigration`, `explainMigration`, `executeMigration`,
|
|
953
|
+
`getMigrationStatus` (from `@cynodia/axiom-server`). A host builds its own command around
|
|
954
|
+
them. (The Axiom repository has a private, unpublished CLI over the same functions for
|
|
955
|
+
maintainer use.)
|
|
952
956
|
|
|
953
957
|
Diagnostics: `SCHEMA_MIGRATION_REQUIRED` `SCHEMA_INCOMPATIBLE` `MIGRATION_IN_PROGRESS`
|
|
954
958
|
`MIGRATION_STATE_CORRUPTED` `MIGRATION_PATH_NOT_FOUND` `MIGRATION_APPROVAL_REQUIRED`
|
package/docs/ANTI_PATTERNS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Anti-patterns
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
|
@@ -631,7 +631,7 @@ is never "the operator approved data loss."
|
|
|
631
631
|
if (pkg.version === persisted.axiomVersion) startNormally();
|
|
632
632
|
```
|
|
633
633
|
|
|
634
|
-
`@cynodia/axiom` `0.11.
|
|
634
|
+
`@cynodia/axiom` `0.11.2`, `axiom.server.v7`, and `graph.schemaVersion` `14` are unrelated.
|
|
635
635
|
Compare `schemaFingerprint(graph)` and `graph.schemaVersion` against what the provider
|
|
636
636
|
durably recorded — which is exactly what the startup gate does.
|
|
637
637
|
|
package/docs/AUTHORITY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Authority
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
|
@@ -509,8 +509,10 @@ does for a local failure.
|
|
|
509
509
|
| `MIGRATION_VALIDATION_FAILED` | Post-migration validation found persisted data that does not satisfy the target semantic schema (spec11 §37). |
|
|
510
510
|
| `MIGRATION_CHECKPOINT_INVALID` | A resume was attempted from a checkpoint that does not match the current plan or schema fingerprint. |
|
|
511
511
|
| `MIGRATION_FINGERPRINT_MISMATCH` | The persisted schema fingerprint does not match the origin of the resolved migration path — the stored data is not the shape the chain expects. |
|
|
512
|
-
| `MIGRATION_NOT_AUTHORIZED` | The caller is not the host-
|
|
512
|
+
| `MIGRATION_NOT_AUTHORIZED` | The caller is not the host-minted migration capability. Naming a migration id over the client protocol does nothing; an object built with the capability's visible fields (or a spread copy of a real one) is rejected — authorization is by provenance, not shape (spec11 §73-74, spec11.1 §15-17). |
|
|
513
513
|
| `MIGRATION_FAILED` | A migration failed for a reason with no more specific code; the target schema version was not committed and the recovery state is defined. |
|
|
514
|
+
| `SCHEMA_IDENTITY_REQUIRED` | The provider's persisted metadata declares a semantic schema version, but the application graph declares none — so compatibility cannot be established. The gate fails closed rather than assuming the unversioned graph is safely compatible with schema 1 (spec11.1 §7). |
|
|
515
|
+
| `SCHEMA_METADATA_REQUIRED` | The application graph declares semantic schema evolution (a `schemaVersion` past 1, or any `MigrationDef`), but `createAxiomServer` was given no `migrationMetadata` store, so the startup gate could not run. Startup is refused rather than silently assuming compatibility (spec11.1 §8). |
|
|
514
516
|
|
|
515
517
|
**Migration execution is host-controlled.** `executeMigration()` is a standalone function,
|
|
516
518
|
not a `ServerRequest` branch — there is no path from a client through the semantic protocol
|
package/docs/CONSTRAINTS.md
CHANGED
package/docs/EFFECTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Effects
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
package/docs/EXPRESSIONS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Expressions
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
|
package/docs/GRAPH_MODEL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Graph model
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
|
package/docs/INTEGRATIONS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Integrations
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
|
package/docs/LOCATIONS.md
CHANGED
package/docs/MIGRATIONS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Schema evolution & semantic migrations
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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,
|
|
@@ -9,15 +9,17 @@ a migration callback, a repository script, or a manual schema-version check.
|
|
|
9
9
|
> The graph owns the meaning of the change. The migration model owns the transition between
|
|
10
10
|
> semantic versions. The provider owns the physical execution.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
The design rationale, the architecture research and the implementation reports are
|
|
13
|
+
maintainer artifacts in the Axiom repository (`reports/`); they are not shipped in the npm
|
|
14
|
+
tarball. This document plus the `.d.ts` declarations, the `axiom.server.v7` schema and the
|
|
15
|
+
`axiom.conformance.v5` fixtures are the complete consumer contract.
|
|
14
16
|
|
|
15
17
|
---
|
|
16
18
|
|
|
17
19
|
## Semantic schema identity
|
|
18
20
|
|
|
19
21
|
An application has a **semantic schema version** — `graph.schemaVersion`, a monotonic
|
|
20
|
-
integer, default `1`. It is a distinct concept from the npm package version (`0.11.
|
|
22
|
+
integer, default `1`. It is a distinct concept from the npm package version (`0.11.2`) and
|
|
21
23
|
from the Server IR contract (`axiom.server.v7`). A `MigrationDef` chain connects consecutive
|
|
22
24
|
integers.
|
|
23
25
|
|
|
@@ -65,7 +67,7 @@ does not silently skip a semantic transition.
|
|
|
65
67
|
| `populate-field` | `entityId`, `fieldId`, `value` (expression) | migration-required |
|
|
66
68
|
| `transform-field` | `entityId`, `fieldId`, `fromType`, `toType`, `expression` | migration-required; narrowing → destructive |
|
|
67
69
|
| `transform-record` | `entityId`, `produce` (an `object` expression), `removesFields?`, `addsFields?` | migration-required; discards info → destructive |
|
|
68
|
-
| `add-relationship` | `relationship` | compatible
|
|
70
|
+
| `add-relationship` | `relationship` | compatible (metadata; no per-row rewrite) |
|
|
69
71
|
| `remove-relationship` | `relationshipId` | compatible (metadata only) |
|
|
70
72
|
|
|
71
73
|
Split and merge are **not** dedicated primitives: both are `transform-record` with
|
|
@@ -117,13 +119,35 @@ The **safe type-change set** is small: an identical type, a widening to `optiona
|
|
|
117
119
|
same inner type, and enum membership growth. Everything else is `migration-required` at
|
|
118
120
|
best and `destructive` if narrowing.
|
|
119
121
|
|
|
120
|
-
`migrationCoversDiff(diff, operations)` proves
|
|
122
|
+
`migrationCoversDiff(diff, operations)` proves a set of operations accounts for exactly the
|
|
121
123
|
data-affecting part of the diff: every `migration-required` / `destructive` entry has a
|
|
122
124
|
matching operation, and no operation describes a change the graphs do not contain.
|
|
123
125
|
|
|
126
|
+
**Coverage is scoped to the semantic transition being evaluated** (spec11.1 §22-24), not to
|
|
127
|
+
the whole chain. `migrationImpact(previous, next)` picks the operations by the version gap:
|
|
128
|
+
|
|
129
|
+
- `next.schemaVersion === previous.schemaVersion + 1` → `coverageMode: 'step'`. Coverage is
|
|
130
|
+
evaluated against exactly the `N → N+1` migration's operations. This is authoritative and
|
|
131
|
+
agrees with `migrationCoversDiff` and `validateGraph`; historical operations from earlier
|
|
132
|
+
migrations in `next` do **not** count as unmatched.
|
|
133
|
+
- more than one version apart → `coverageMode: 'chain'`. A single endpoint diff has no
|
|
134
|
+
ordinary per-step coverage, so `covered` reports only whether a complete migration chain
|
|
135
|
+
connects the two versions; `steps[]` lists the migrations that would run.
|
|
136
|
+
- same version, or a downgrade → `coverageMode: 'none'`.
|
|
137
|
+
|
|
138
|
+
`covered: false` is never an unexplained boolean — the result carries `uncovered`,
|
|
139
|
+
`unmatched` and `steps`.
|
|
140
|
+
|
|
124
141
|
`AgentAPI` surface: `inspectSchema()`, `diffSchema(previous)`, `migrationImpact(previous)`
|
|
125
|
-
(§57 — the diff, coverage
|
|
126
|
-
|
|
142
|
+
(§57 — the diff, coverage + `coverageMode`/`uncovered`/`unmatched`/`steps`,
|
|
143
|
+
`dataLossPossible`, and which queries / actions / read policies / constraints / UI nodes
|
|
144
|
+
reference a changed field), and `explainSchemaDiff(diff)`. These agree with runtime and
|
|
145
|
+
compiler validation on whether a valid migration step covers its semantic diff (spec11.1 §26).
|
|
146
|
+
|
|
147
|
+
**`RelationshipDef.required`.** There is no public relationship-requiredness authoring
|
|
148
|
+
concept in 0.11.x. The fingerprint projection reserves a `required` slot for relationships
|
|
149
|
+
that is **always `false`**, so that adding the capability in a future minor need not bump
|
|
150
|
+
`SCHEMA_FINGERPRINT_VERSION` (an existing graph, unable to set it, fingerprints identically).
|
|
127
151
|
|
|
128
152
|
---
|
|
129
153
|
|
|
@@ -153,8 +177,17 @@ executeMigration({
|
|
|
153
177
|
|
|
154
178
|
- **Migration execution is host-controlled.** `executeMigration` is a standalone function,
|
|
155
179
|
not a `ServerRequest` branch — there is no path from a client through the semantic
|
|
156
|
-
protocol that runs a migration
|
|
157
|
-
`migrationAuthority(grantedBy)`; a
|
|
180
|
+
protocol that runs a migration, and no `migrate` / `execute-migration` request kind. It
|
|
181
|
+
requires a `MigrationPrincipal` minted by the host with `migrationAuthority(grantedBy)`; a
|
|
182
|
+
call without one is `MIGRATION_NOT_AUTHORIZED`.
|
|
183
|
+
- **Migration authority is opaque, and authorization is by provenance, not shape.** The
|
|
184
|
+
object `migrationAuthority()` returns is frozen and registered in a process-private
|
|
185
|
+
registry. Constructing an object with the same visible fields —
|
|
186
|
+
`{ kind: 'axiom.migration-authority', grantedBy: 'operator' }` — or a spread copy of a
|
|
187
|
+
real one — `{ ...migrationAuthority('operator') }` — does **not** recreate authority and
|
|
188
|
+
is rejected. `grantedBy` is a descriptive audit label, not the source of authorization.
|
|
189
|
+
The capability is process-local and is never serialized; durability lives in the
|
|
190
|
+
`MigrationMetadataStore`, the lease and the checkpoints.
|
|
158
191
|
- **"A migration exists" is not "the operator approved data loss."** Every destructive
|
|
159
192
|
operation id MUST appear in `approveDestructive`, or the migration is refused
|
|
160
193
|
(`MIGRATION_APPROVAL_REQUIRED`) with **zero writes** and the schema version unchanged.
|
|
@@ -186,19 +219,44 @@ checkpoint, and an `idle` / `in-progress` / `checkpointed` phase.
|
|
|
186
219
|
|
|
187
220
|
## The startup gate
|
|
188
221
|
|
|
189
|
-
|
|
190
|
-
|
|
222
|
+
**There is no hopeful startup, and `compatible` never means "not checked".** A
|
|
223
|
+
machine-readable `compatible` verdict means compatibility was *actually established* against
|
|
224
|
+
the provider's durable record.
|
|
191
225
|
|
|
192
|
-
|
|
193
|
-
| --- | --- |
|
|
194
|
-
| **compatible** | stored `(version, fingerprint)` match — start normally |
|
|
195
|
-
| **fresh** | no stored metadata — stamp the provider and start |
|
|
196
|
-
| **migration-required** | stored version `<` required, a chain exists — `start()` throws `SCHEMA_MIGRATION_REQUIRED` |
|
|
197
|
-
| **migration-in-progress** | a migration lock is held — `start()` throws `MIGRATION_IN_PROGRESS` |
|
|
198
|
-
| **incompatible** | stored version `>` required (`SCHEMA_INCOMPATIBLE`), or no chain (`MIGRATION_PATH_NOT_FOUND`) — `start()` throws |
|
|
199
|
-
| **corrupted** | same version, different fingerprint (`MIGRATION_FINGERPRINT_MISMATCH`), or data present with no metadata — `start()` throws |
|
|
226
|
+
### What must be configured
|
|
200
227
|
|
|
201
|
-
`
|
|
228
|
+
- A graph that **declares semantic schema evolution** — a `schemaVersion` past `1`, or any
|
|
229
|
+
`MigrationDef` — MUST be given a `migrationMetadata` store. `createAxiomServer({ ir })`
|
|
230
|
+
with no store, for such a graph, refuses `start()` with `SCHEMA_METADATA_REQUIRED`: the
|
|
231
|
+
gate could not run, so serving is not permitted.
|
|
232
|
+
- A graph that declares **no** semantic schema identity does not need a store. If one is
|
|
233
|
+
supplied and it records a versioned schema, the mismatch is still caught (below).
|
|
234
|
+
|
|
235
|
+
### Verdicts
|
|
236
|
+
|
|
237
|
+
`start()` proceeds only on `compatible`, `fresh` or `not-applicable`; every other verdict
|
|
238
|
+
throws with its diagnostic code. `server.schemaGate()` returns the verdict without starting.
|
|
239
|
+
|
|
240
|
+
| Verdict | Meaning | `start()` |
|
|
241
|
+
| --- | --- | --- |
|
|
242
|
+
| **compatible** | stored `(version, fingerprint)` were compared and match | proceeds |
|
|
243
|
+
| **fresh** | the graph declares a schema, the provider has no metadata, and no persisted data exists — the provider is stamped at the graph's version | proceeds |
|
|
244
|
+
| **not-applicable** | the graph declares no schema identity and there is no versioned persistence to protect — the gate genuinely does not apply | proceeds |
|
|
245
|
+
| **migration-required** | stored version `<` required and a complete chain exists — `SCHEMA_MIGRATION_REQUIRED` | refused |
|
|
246
|
+
| **migration-in-progress** | a migration lock is held — `MIGRATION_IN_PROGRESS` | refused |
|
|
247
|
+
| **incompatible** | stored version `>` required (`SCHEMA_INCOMPATIBLE`), or no chain to it (`MIGRATION_PATH_NOT_FOUND`) | refused |
|
|
248
|
+
| **corrupted** | same version, wrong fingerprint (`MIGRATION_FINGERPRINT_MISMATCH`); or persisted data present with no metadata and a schema-evolving graph (`MIGRATION_STATE_CORRUPTED`) | refused |
|
|
249
|
+
| **schema-identity-required** | the provider records a schema version but the graph declares none — compatibility cannot be established (`SCHEMA_IDENTITY_REQUIRED`) | refused |
|
|
250
|
+
| **schema-metadata-required** | the graph declares schema evolution but no metadata store was supplied (`SCHEMA_METADATA_REQUIRED`) | refused |
|
|
251
|
+
|
|
252
|
+
### `fresh` ≠ `compatible` ≠ `not-applicable`
|
|
253
|
+
|
|
254
|
+
`fresh` is a new database for a schema-evolving application — it initializes to the graph's
|
|
255
|
+
declared schema through the documented fresh-start path, with no migration from imaginary
|
|
256
|
+
history. `not-applicable` is an application with no persisted semantic schema to protect —
|
|
257
|
+
often a trivial in-memory program. Neither is `compatible`, which means an actual match was
|
|
258
|
+
verified. An unversioned graph pointed at an existing versioned provider is
|
|
259
|
+
`schema-identity-required`, never any of the three.
|
|
202
260
|
|
|
203
261
|
**Serving during a migration.** While a migration lock is held, the authority refuses every
|
|
204
262
|
request with `MIGRATION_IN_PROGRESS`. Once the lock clears, if the persisted schema still
|
|
@@ -222,6 +280,31 @@ cursor minted under one schema is `QUERY_CURSOR_INVALID` after a migration chang
|
|
|
222
280
|
- A resume against a checkpoint from a different plan is refused
|
|
223
281
|
(`MIGRATION_CHECKPOINT_INVALID`).
|
|
224
282
|
|
|
283
|
+
**Concurrent-migrator outcomes are semantic, not physical.** When two processes run the
|
|
284
|
+
same required migration against the same database — including two independent OS processes
|
|
285
|
+
sharing one SQLite file — each `executeMigration` result MUST be one of:
|
|
286
|
+
|
|
287
|
+
| Result | Meaning |
|
|
288
|
+
| --- | --- |
|
|
289
|
+
| `run.phase === 'completed'`, `alreadyAtTarget === false` | this process performed the transition — exactly one process in a race does |
|
|
290
|
+
| `run.alreadyAtTarget === true` | a competitor completed the whole transition first; nothing to do |
|
|
291
|
+
| `MIGRATION_IN_PROGRESS` | a competitor holds the migration lease |
|
|
292
|
+
|
|
293
|
+
A competing runner never re-executes the transition: the transform runs exactly once, the
|
|
294
|
+
history gains exactly one entry per step, and the schema version advances once. A losing
|
|
295
|
+
process performs no migration data work and does not touch the active owner's checkpoint.
|
|
296
|
+
|
|
297
|
+
**The provider absorbs physical contention.** SQLite's single-writer file lock
|
|
298
|
+
(`SQLITE_BUSY` / `SQLITE_LOCKED`) is reconciled to the outcomes above inside the provider —
|
|
299
|
+
a short bounded busy wait, then an ownership re-check. A consumer does **not** catch
|
|
300
|
+
SQLite-native lock errors around `executeMigration`, `getMigrationStatus`, `schemaGate()`
|
|
301
|
+
or ordinary requests, and does **not** write its own busy-retry loop; that is provider
|
|
302
|
+
responsibility. `createSqliteMigrationStore` / `createSqliteRowStore` accept an optional
|
|
303
|
+
`busyTimeoutMs` (default 2000) that tunes only the physical wait — it is not
|
|
304
|
+
migration-ownership configuration and correctness never depends on it. If contention
|
|
305
|
+
genuinely cannot be explained by a migration owner, the result is `MIGRATION_FAILED` with
|
|
306
|
+
the physical cause retained for the operator, never a masked `MIGRATION_IN_PROGRESS`.
|
|
307
|
+
|
|
225
308
|
---
|
|
226
309
|
|
|
227
310
|
## Providers
|
|
@@ -241,6 +324,23 @@ migration is refused **before any write** (`MIGRATION_PROVIDER_UNSUPPORTED`).
|
|
|
241
324
|
**No application-authored SQL.** The memory and SQLite providers must derive semantically
|
|
242
325
|
equivalent target data from the same fixture.
|
|
243
326
|
|
|
327
|
+
### Where the rows come from
|
|
328
|
+
|
|
329
|
+
A migration operates on persistence the host already has — a production SQLite file, a
|
|
330
|
+
Postgres database. `MigrationRowStore` deliberately has **no insert operation**: seeding
|
|
331
|
+
data is not a migration step. For tests, bootstrap and the conformance runner, the
|
|
332
|
+
reference stores accept pre-existing rows through their own constructors:
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
createMemoryRowStore(dataset) // dataset: Map<entityId, Row[]>
|
|
336
|
+
await createSqliteRowStore({ location, ir, seed }) // seed: Record<entityId, Row[]>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
The `seed` is source-shape data; the SQLite store reconciles it to the columns the seed
|
|
340
|
+
carries so the database genuinely starts at the *source* schema and the migration's own
|
|
341
|
+
`ALTER TABLE`s move it to the target. `seed` is a constructor convenience, not part of the
|
|
342
|
+
migration model.
|
|
343
|
+
|
|
244
344
|
---
|
|
245
345
|
|
|
246
346
|
## Portable conformance — `axiom.conformance.v5`
|
package/docs/PRESENTATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Presentation
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
# Semantic contract
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. Runtime guarantees, stated formally. This file defines behavior; it
|
|
4
4
|
does not teach. Where this file and any specification in `../specs/` disagree, this file
|
|
5
5
|
describes the implementation and is authoritative.
|
|
6
6
|
|
package/docs/STATE.md
CHANGED
package/docs/STORAGE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Storage and blobs
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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
|
|
package/docs/SUBSCRIPTIONS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Subscriptions
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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`:
|
package/docs/VALIDATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Validation
|
|
2
2
|
|
|
3
|
-
Axiom 0.11.
|
|
3
|
+
Axiom 0.11.2-alpha.1. 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/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Axiom
|
|
2
2
|
|
|
3
|
-
> AI-native semantic application framework, version 0.11.
|
|
3
|
+
> AI-native semantic application framework, version 0.11.2-alpha.1. 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.11.
|
|
3
|
+
"version": "0.11.2-alpha.1",
|
|
4
4
|
"description": "AI-native semantic web application framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "AskTech AS",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@cynodia/axiom-core": "0.11.
|
|
38
|
-
"@cynodia/axiom-runtime": "0.11.
|
|
39
|
-
"@cynodia/axiom-compiler": "0.11.
|
|
40
|
-
"@cynodia/axiom-agent-api": "0.11.
|
|
37
|
+
"@cynodia/axiom-core": "0.11.2-alpha.1",
|
|
38
|
+
"@cynodia/axiom-runtime": "0.11.2-alpha.1",
|
|
39
|
+
"@cynodia/axiom-compiler": "0.11.2-alpha.1",
|
|
40
|
+
"@cynodia/axiom-agent-api": "0.11.2-alpha.1"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"build": "tsc -b tsconfig.json"
|