@hraness/oh 0.2.3

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.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +598 -0
  3. package/dist/canonical.d.ts +32 -0
  4. package/dist/canonical.d.ts.map +1 -0
  5. package/dist/cli.d.ts +4 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +3419 -0
  8. package/dist/contract.d.ts +33 -0
  9. package/dist/contract.d.ts.map +1 -0
  10. package/dist/graph.d.ts +67 -0
  11. package/dist/graph.d.ts.map +1 -0
  12. package/dist/index.d.ts +9 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +1988 -0
  15. package/dist/libsql.d.ts +57 -0
  16. package/dist/libsql.d.ts.map +1 -0
  17. package/dist/libsql.js +2662 -0
  18. package/dist/memory.d.ts +366 -0
  19. package/dist/memory.d.ts.map +1 -0
  20. package/dist/memory.js +3650 -0
  21. package/dist/ontology.d.ts +242 -0
  22. package/dist/ontology.d.ts.map +1 -0
  23. package/dist/operation.d.ts +24 -0
  24. package/dist/operation.d.ts.map +1 -0
  25. package/dist/projection-public.d.ts +59 -0
  26. package/dist/projection-public.d.ts.map +1 -0
  27. package/dist/projection-public.js +1682 -0
  28. package/dist/projection-suss.d.ts +17 -0
  29. package/dist/projection-suss.d.ts.map +1 -0
  30. package/dist/projection-suss.js +1721 -0
  31. package/dist/projection.d.ts +315 -0
  32. package/dist/projection.d.ts.map +1 -0
  33. package/dist/schema.d.ts +45 -0
  34. package/dist/schema.d.ts.map +1 -0
  35. package/dist/sdk.d.ts +51 -0
  36. package/dist/sdk.d.ts.map +1 -0
  37. package/dist/sdk.js +3072 -0
  38. package/dist/search.d.ts +34 -0
  39. package/dist/search.d.ts.map +1 -0
  40. package/dist/semantic.d.ts +83 -0
  41. package/dist/semantic.d.ts.map +1 -0
  42. package/dist/semantic.js +706 -0
  43. package/dist/sqlite/driver.d.ts +6 -0
  44. package/dist/sqlite/driver.d.ts.map +1 -0
  45. package/dist/sqlite/index.d.ts +5 -0
  46. package/dist/sqlite/index.d.ts.map +1 -0
  47. package/dist/sqlite/index.js +2840 -0
  48. package/dist/sqlite/migrations.d.ts +10 -0
  49. package/dist/sqlite/migrations.d.ts.map +1 -0
  50. package/dist/sqlite/port.d.ts +40 -0
  51. package/dist/sqlite/port.d.ts.map +1 -0
  52. package/dist/sqlite/runtime.d.ts +23 -0
  53. package/dist/sqlite/runtime.d.ts.map +1 -0
  54. package/dist/sqlite/store.d.ts +85 -0
  55. package/dist/sqlite/store.d.ts.map +1 -0
  56. package/dist/store.d.ts +236 -0
  57. package/dist/store.d.ts.map +1 -0
  58. package/dist/store.js +996 -0
  59. package/dist/sync.d.ts +57 -0
  60. package/dist/sync.d.ts.map +1 -0
  61. package/dist/sync.js +1328 -0
  62. package/package.json +121 -0
  63. package/skills/oh/SKILL.md +206 -0
  64. package/skills/oh/agents/openai.yaml +4 -0
  65. package/spec/README.md +74 -0
  66. package/spec/manifest.json +41 -0
  67. package/spec/v1/canonical-json.md +59 -0
  68. package/spec/v1/contract.json +28 -0
  69. package/spec/v1/contract.schema.json +58 -0
  70. package/spec/v1/embedding-profile.json +11 -0
  71. package/spec/v1/embedding.md +56 -0
  72. package/spec/v1/graph.md +87 -0
  73. package/spec/v1/memory.md +193 -0
  74. package/spec/v1/migration.md +92 -0
  75. package/spec/v1/ontology.json +55 -0
  76. package/spec/v1/ontology.md +80 -0
  77. package/spec/v1/operation.schema.json +138 -0
  78. package/spec/v1/projection-identity.schema.json +58 -0
  79. package/spec/v1/projection-query.schema.json +60 -0
  80. package/spec/v1/projection-result.schema.json +452 -0
  81. package/spec/v1/projection-rule-pack.schema.json +182 -0
  82. package/spec/v1/projection.md +165 -0
  83. package/spec/v1/record.schema.json +95 -0
  84. package/spec/v1/schema-evolution.md +51 -0
  85. package/spec/v1/schema-revision.schema.json +178 -0
  86. package/spec/v1/storage.md +88 -0
  87. package/spec/v1/store.md +131 -0
  88. package/spec/v1/sync-bundle.schema.json +51 -0
  89. package/spec/v1/sync.md +67 -0
  90. package/src/canonical.test.ts +46 -0
  91. package/src/canonical.ts +203 -0
  92. package/src/cli.test.ts +103 -0
  93. package/src/cli.ts +308 -0
  94. package/src/contract.ts +87 -0
  95. package/src/contracts.test.ts +147 -0
  96. package/src/graph.ts +248 -0
  97. package/src/index.ts +8 -0
  98. package/src/libsql.test.ts +657 -0
  99. package/src/libsql.ts +1687 -0
  100. package/src/memory.test.ts +783 -0
  101. package/src/memory.ts +1684 -0
  102. package/src/ontology.ts +573 -0
  103. package/src/operation.ts +80 -0
  104. package/src/projection-public.ts +53 -0
  105. package/src/projection-suss.ts +129 -0
  106. package/src/projection.test.ts +418 -0
  107. package/src/projection.ts +1457 -0
  108. package/src/schema.ts +156 -0
  109. package/src/sdk.ts +96 -0
  110. package/src/search.ts +66 -0
  111. package/src/semantic.test.ts +480 -0
  112. package/src/semantic.ts +333 -0
  113. package/src/sqlite/driver.ts +47 -0
  114. package/src/sqlite/index.ts +4 -0
  115. package/src/sqlite/migrations.test.ts +44 -0
  116. package/src/sqlite/migrations.ts +178 -0
  117. package/src/sqlite/port.test.ts +127 -0
  118. package/src/sqlite/port.ts +120 -0
  119. package/src/sqlite/runtime.test.ts +68 -0
  120. package/src/sqlite/runtime.ts +53 -0
  121. package/src/sqlite/store.test.ts +295 -0
  122. package/src/sqlite/store.ts +988 -0
  123. package/src/store.test.ts +121 -0
  124. package/src/store.ts +701 -0
  125. package/src/sync.test.ts +117 -0
  126. package/src/sync.ts +227 -0
@@ -0,0 +1,87 @@
1
+ # Graph and operation contract V1
2
+
3
+ The graph format version is `1`. It stores canonical JSON records behind stable
4
+ logical keys and records every change in a content-addressed operation chain.
5
+
6
+ ## Record envelope
7
+
8
+ ```json
9
+ {
10
+ "dependencies": [],
11
+ "key": "entity:ada-lovelace",
12
+ "kind": "entity",
13
+ "recordSha256": "<64 lowercase hex characters>",
14
+ "v": 1,
15
+ "value": { "name": "Ada Lovelace" }
16
+ }
17
+ ```
18
+
19
+ A logical key begins with a lowercase letter, contains at most 512 characters,
20
+ and uses lowercase alphanumeric segments separated by `.`, `_`, `:`, `/`, or
21
+ `-`. Dependencies use the same grammar. They MUST be strictly ordered, unique,
22
+ non-reflexive, and present after the operation settles.
23
+
24
+ V1 record kinds are:
25
+
26
+ ```text
27
+ activity assertion context dependency-manifest edition entity evidence
28
+ identity-operation inquiry inquiry-event review-decision rights-decision
29
+ schema shape statement type-membership view vocabulary
30
+ ```
31
+
32
+ The `value` is arbitrary canonical JSON. A registered codec MAY impose a
33
+ stricter value contract for a kind. The generic envelope parser remains the
34
+ wire boundary.
35
+
36
+ ## Changes
37
+
38
+ A put change contains `{ "kind": "put", "record": ..., "v": 1 }`. A
39
+ tombstone contains the logical key and exact prior record digest. Changes in an
40
+ operation MUST be sorted by logical key and unique. A tombstone fails if its
41
+ prior digest does not match the current record.
42
+
43
+ One operation contains 1 through 8,192 changes. Each record has no more than
44
+ 4,096 dependencies and a value no larger than 1,048,576 canonical UTF-8 bytes.
45
+ A bounded snapshot contains no more than 65,536 records under the V1 graph
46
+ limit.
47
+
48
+ ## Graph revisions
49
+
50
+ A graph revision binds the canonical changes, stable operation ID, parent graph
51
+ revision digest, sorted complete record references, complete record-set digest,
52
+ positive revision, and revision digest. Replaying a revision chain MUST reject
53
+ gaps, forks, duplicate operation IDs, false record snapshots, missing
54
+ dependencies, and digest mismatches.
55
+
56
+ Each record reference contains `dependencies`, `key`, `kind`, `sha256`, and
57
+ `v`. Dependencies are ordered, unique, non-reflexive keys. The complete
58
+ reference set therefore carries enough information to reject a tombstone that
59
+ would strand an unchanged record. `recordsSha256` hashes the ordered complete
60
+ reference array. `graphRevisionSha256` hashes the canonical transition fields
61
+ listed in [`canonical-json.md`](canonical-json.md); `recordRefs` are bound
62
+ through `recordsSha256` and are not duplicated in that digest preimage.
63
+
64
+ Creators, parsers, reducers, and stores MUST reject a resulting snapshot above
65
+ 65,536 records, including growth accumulated across multiple operations.
66
+
67
+ ## Operations
68
+
69
+ An operation adds the actor ID, contract ID, canonical UTC instant, operation
70
+ chain, space ID, and sequence to the graph transition. Sequence starts at one
71
+ with a null parent operation digest. Every later operation increments sequence
72
+ by one and binds the prior operation digest.
73
+
74
+ `operationId` gives a writer idempotency. Reusing it with the same actor and
75
+ changes returns the existing operation. Reusing it for different content is a
76
+ conflict.
77
+
78
+ The complete operation is at most 67,108,864 bytes. Its `operationSha256`
79
+ hashes the payload without that field.
80
+
81
+ ## Concurrency
82
+
83
+ A commit supplies the expected generation and operation digest. The store
84
+ acquires an immediate transaction, reads the current head, computes the full
85
+ transition, appends the operation, materializes records and dependencies, and
86
+ moves the head with compare-and-swap. A stale expected head fails without a
87
+ partial mutation.
@@ -0,0 +1,193 @@
1
+ # Experimental composite agent memory
2
+
3
+ `@hraness/oh/experimental/memory` is the first consumer-facing composition of
4
+ the stable store and projection contracts. It is experimental API, not a new
5
+ ontology or a third storage authority.
6
+
7
+ ## One kernel, two authorities
8
+
9
+ A host MUST bind two distinct physical authorities before it creates the
10
+ facade:
11
+
12
+ - a working-profile store, writable only through codec-enforced semantic
13
+ bundles; and
14
+ - a canonical-profile store pinned at one exact host-selected head and never
15
+ writable through the returned agent object.
16
+
17
+ The host supplies opaque authority IDs plus the exact expected binding digests.
18
+ The factory rejects equal authority IDs, a binding mismatch, or the wrong
19
+ profile. Authority IDs identify custody in results without revealing a database
20
+ path, URL, credential, or purge handle. An Oh space, a semantic context, a
21
+ runtime tenant/session, and a physical authority remain different boundaries.
22
+ The host also binds the working actor, every named program's purpose, and every
23
+ named nomination route. None of those authority-bearing labels comes from
24
+ agent input.
25
+
26
+ The returned object exposes only `remember`, `query`, `explain`, and
27
+ `nominate`. It has no generic commit, store selection, path, sync, rule
28
+ registration, canonical write, or purge operation.
29
+
30
+ `remember` accepts only an expected working head, semantic puts and tombstones,
31
+ and an idempotency request ID. The facade supplies its host-bound actor, uses
32
+ its non-regressing host clock, derives the operation ID, and returns an
33
+ immutable, locator-free receipt with the working authority ID, binding digest,
34
+ resulting complete head, operation digest, actor, and actual instant. It never
35
+ returns raw operation changes or accepts a caller-asserted actor or timestamp.
36
+
37
+ ## Composite projection
38
+
39
+ Every query reads the current working head and the factory-pinned canonical
40
+ head. It builds a disposable composite dataset with lane-tagged
41
+ `memory.record` and `memory.dependency` facts. Equal logical keys with different
42
+ record digests produce an explicit `memory.conflict` fact and result entry;
43
+ working data never shadows canonical data by recency. Equal digests produce
44
+ `memory.agreement`.
45
+
46
+ Trusted host code may register digest-identified domain fact extractors. Each
47
+ extractor declares a disjoint set of relations it owns. The facade supplies a
48
+ deeply immutable record and its exact physical source, bounds invocation and
49
+ output counts, and forbids custom ownership of reserved `memory.*` or `oh.*`
50
+ relations. Every fact proof identifies the built-in fact pack or exact domain
51
+ extractor ID and digest that emitted it. Trusted host code also registers a
52
+ bounded set of parsed rule-pack/query pairs and their fixed purposes under
53
+ names. Agent input selects a name; it cannot submit a purpose, rule, query AST,
54
+ or inert validity label.
55
+
56
+ The composite identity binds:
57
+
58
+ - both opaque authority IDs, binding digests, complete heads, projection
59
+ snapshots, and lane dataset digests;
60
+ - the composite fact dataset;
61
+ - the named program, exact rule pack and query;
62
+ - evaluation and engine identity inherited from the projection result;
63
+ - the host-bound program purpose and fixed visible-conflict policy.
64
+
65
+ Changing any of these values produces a different memory digest and a full
66
+ rebuild. Results and proofs remain `derived`. A rule cannot upgrade the
67
+ authority of its premises. Each public row is labeled from its visible physical
68
+ premise lanes; a truncated or missing witness is `unknown` rather than
69
+ silently canonical. Returned result, row, value, proof, source, and receipt
70
+ graphs are detached and deeply immutable, so a caller cannot mutate bytes after
71
+ their digest or explanation capability is issued.
72
+
73
+ ## Additive parameterized pagination (V2 experimental API)
74
+
75
+ `createOhMemoryAgentV2` is an additive experimental query surface. It does not
76
+ change a V1 request, result, digest preimage, factory, or type. Its `remember`
77
+ and `nominate` methods continue to use the V1 semantic-bundle and nomination
78
+ contracts. Only its `query` and `explain` envelopes use V2.
79
+
80
+ A V2 named program is still entirely host-owned. In addition to the fixed
81
+ purpose, rule pack, query, and extractor registry, the host declares:
82
+
83
+ - the exact query-body variables that may receive parameters;
84
+ - every projection evaluation limit;
85
+ - the maximum complete result row count;
86
+ - a page size of at most 256 rows; and
87
+ - a canonical byte ceiling for each outward page.
88
+
89
+ The host query limit MUST equal the declared maximum row count. A parameter
90
+ variable MUST occur in the query body and MUST NOT be a projected output
91
+ variable. Agent input supplies one exact object of bounded JSON primitive
92
+ values for those names plus a program ID and either `null` or a continuation.
93
+ It cannot supply a purpose, rule, query AST, evaluator option, page size, or
94
+ source selector. Binding substitutes constants only into the fixed query body;
95
+ the rules and projected output remain the registered program.
96
+
97
+ The V2 identity includes the canonical bindings and their digest, the template
98
+ and bound query digests, the complete program digest, and the same physical
99
+ source and projection identities as V1. Thus a parameter value is part of both
100
+ the projection identity and the memory identity, not an unrecorded filter.
101
+ This supports a host extractor that emits bounded primitive value chunks while
102
+ a named program binds `lane` and `key` and projects only chunk position and
103
+ chunk content. Each chunk remains subject to the V1 16 KiB atom limit and the
104
+ extractor's existing count and source rules.
105
+
106
+ The evaluator computes one canonical, ordered result no larger than the
107
+ host-declared row limit before it selects a page. A projection `query-limit` or
108
+ `result-bytes` truncation returns no page. The outward page reports its start,
109
+ end, configured and returned row counts, total rows, `hasMore`, `complete` or
110
+ `partial` status, and explicit empty truncation evidence. Its configured slice
111
+ must fit the host-declared page byte ceiling; the facade fails closed instead
112
+ of silently shortening the slice. Every returned page therefore has
113
+ `truncation.truncated: false`; `partial` means more exact pages exist, not that
114
+ the projection is incomplete. Proof-budget truncation remains visible on
115
+ the affected row as `proofsTruncated` and yields `unknown` premise authority,
116
+ as in V1.
117
+
118
+ A continuation is an authenticated bearer cursor, not knowledge authority. Its
119
+ canonical envelope contains an unsigned cursor identity, a public
120
+ `continuationSha256` digest of that identity, and a domain-separated
121
+ HMAC-SHA-256. The identity binds the next offset to the exact program, bindings,
122
+ complete projection result, page size, total row count, and composite memory
123
+ identity. The HMAC makes only host-issued offsets usable; recomputing the public
124
+ digest does not issue a cursor. The envelope is authenticated, not encrypted,
125
+ and the same token can be replayed for the same exact page.
126
+
127
+ By default the facade generates a private random continuation key, so its
128
+ cursors are scoped to that facade instance. A host that must reconstruct the
129
+ facade or route a cursor to another replica supplies the same 32 through 64 raw
130
+ key bytes through `continuationKey`; the factory clones those bytes. The host
131
+ keeps that key out of agent input and persisted results. Changing the key
132
+ invalidates outstanding cursors.
133
+
134
+ The request parser first establishes an exact shallow envelope, a bounded
135
+ primitive binding map, and bounded strings before canonical serialization.
136
+ After resolving the registered program and exact bindings, it authenticates a
137
+ continuation and checks its program, binding, page-size, range, and alignment
138
+ before reading the working store, invoking extractors, evaluating rules, or
139
+ mapping proofs. Every valid continued call then rereads the current working
140
+ head and rebuilds the projection. A head, source, result, or row-count change
141
+ fails with an integrity error before proof mapping rather than mixing pages
142
+ from two snapshots.
143
+
144
+ An outward result publishes `continuationSha256` beside the opaque token, or
145
+ `null` beside `null` on the final page. `resultSha256` commits that deterministic
146
+ digest instead of the key-dependent token, so the same exact result identity is
147
+ stable across signing keys. The actual token still counts toward the outward
148
+ page-byte ceiling. A V2 explanation capability retains only its exact outward
149
+ page and mapped physical proofs, and requires that page's result digest and
150
+ page-local row index.
151
+
152
+ ## Explanations and nominations
153
+
154
+ Query returns an opaque, random, short-lived explanation capability bound to
155
+ that exact deterministic result. Its expiry uses a non-regressing monotonic
156
+ clock; the wall-clock instant is display metadata. A capability may explain
157
+ multiple rows until expiry or eviction. Count, per-entry bytes, and aggregate
158
+ retained evidence are bounded. `explain` also requires the exact result digest
159
+ and row index. It maps every projection fact witness back to an authority ID,
160
+ binding digest, complete pinned head, lane, original record key and digest. A
161
+ wrong, expired, evicted, or result-mismatched capability fails closed.
162
+
163
+ `nominate` selects one host-registered route by opaque name, then exports and
164
+ re-verifies an exact dependency closure and exact requested root set from the
165
+ current working head. Its
166
+ output is only a content-addressed `prepared` proposal for that route's fixed
167
+ destination purpose. It does not sync the working operation chain, mutate the
168
+ canonical store, import a derived tuple, grant rights, record a review, or turn
169
+ a proposed assertion into reviewed knowledge. Destination-owned application
170
+ code must perform those steps under its own policy and compare-and-swap head.
171
+
172
+ ## Lifecycle and custody boundary
173
+
174
+ Oh deliberately does not choose a tenant, session, retention deadline,
175
+ physical database, credential, scheduler, or backup policy. The application
176
+ host owns those lifecycle controls and retains the separate working store host
177
+ object. Purge removes a working authority through that host-only
178
+ capability; tombstoning is not erasure because operation history retains prior
179
+ bytes. Database credentials or same-UID filesystem access remain outside this
180
+ API boundary.
181
+
182
+ The facade requests at most 8,192 records per lane, rejects a lane snapshot
183
+ over 32 MiB, rejects a remember request over 8 MiB, bounds extractor
184
+ invocations and emitted facts, limits the public result to 32 MiB, and retains
185
+ at most 64 MiB of explanation evidence. A trusted store still constructs the
186
+ snapshot before returning it, and a trusted synchronous fact extractor can
187
+ consume time or temporary memory before it returns. Provider response limits,
188
+ host storage quotas, callback review, isolation, deadlines, and cancellation
189
+ remain application responsibilities.
190
+
191
+ Suss is an optional differential evaluator behind the separate projection
192
+ compatibility subpath. The memory facade uses the package-owned bounded
193
+ reference evaluator. Cozo is neither evaluated nor loaded.
@@ -0,0 +1,92 @@
1
+ # Compatibility and migration V1
2
+
3
+ This document defines the supported migration path for one conforming Oh V1
4
+ space to another storage location or Oh installation. Source and target MUST
5
+ use contract `oh.ontology.v1` with contract digest
6
+ `e53ae573c2af417082be9f554d0f6f3e317f054daf745181f462608e3f622594` and
7
+ the same space ID.
8
+
9
+ V1 does not ship a cross-contract transformer. A different contract digest,
10
+ protocol identifier, or space ID fails closed before an operation is applied.
11
+
12
+ ## Preserved authority
13
+
14
+ The append-only operation chain is the migration unit. Every imported operation
15
+ MUST retain its canonical fields, record envelopes, logical keys, dependencies,
16
+ sequence, parent digest, record-set digest, graph-revision digest, and operation
17
+ digest. A migration MUST NOT rename identifiers, rewrite record values, replace
18
+ timestamps, recompute operations under a different contract, or reconstruct the
19
+ chain from current-row snapshots.
20
+
21
+ SQLite current-record and dependency tables are checked materializations of the
22
+ operation chain. Search documents, FTS5 rows, and the QMD semantic directory are
23
+ derived state and are not migration authority.
24
+
25
+ ## Offline migration
26
+
27
+ Use the shipped CLI to move a space:
28
+
29
+ 1. Stop or coordinate writers to keep the source head stable during export.
30
+ 2. Run `oh contract` and confirm its printed contract ID and digest match the
31
+ required values above. Then run `oh verify --db <source> --space <space>`
32
+ against the source database and space.
33
+ 3. Initialize an empty target with the same space ID.
34
+ 4. Export operations in ascending sequence with
35
+ `oh sync export --after <sequence> --limit <count>`. The limit MUST be from
36
+ 1 through 1,000. Begin after sequence `0` and continue from the last exported
37
+ sequence until the bundle is empty.
38
+ 5. Transfer each complete JSON bundle without changing its parsed content.
39
+ 6. Import the bundles in order with `oh sync import --file <path>`. Import
40
+ verifies the protocol, contract digest, bundle digest, space ID, operation
41
+ digests, contiguous sequence, parent head, and reproduced graph head.
42
+ 7. Run `oh verify` against the target.
43
+ 8. Compare the source and target `head` objects returned by `oh verify`. The
44
+ `generation`, `sequence`, `operationSha256`, `graphRevisionSha256`, and
45
+ `recordsSha256` values MUST match exactly before the target becomes
46
+ authoritative.
47
+
48
+ Re-importing an operation already present with the same digest and canonical
49
+ content is idempotent. An operation that does not extend the target head is a
50
+ conflict. Equal sequence numbers with different operation digests are also a
51
+ conflict. Oh does not merge divergent histories automatically.
52
+
53
+ ## Connected migration
54
+
55
+ `synchronizeOhStoreV1` provides the same fast-forward rule through an
56
+ `OhOperationSyncTransportV1`. The transport handshake compares the complete V1
57
+ contract manifest before exchanging operations. Settlement succeeds only when
58
+ both heads have the same sequence and operation digest. Applications own
59
+ transport credentials, availability, retries, backups, and any explicit merge
60
+ policy.
61
+
62
+ ## Search state
63
+
64
+ Keyword search remains available from the SQLite store after operation import.
65
+ Semantic state MAY be rebuilt with the exact profile in
66
+ [`embedding-profile.json`](embedding-profile.json). A semantic result is current
67
+ only after it rejoins a record with the same record digest. Copying a semantic
68
+ directory does not establish migration parity.
69
+
70
+ ## Rollback
71
+
72
+ Keep the verified source database read-only until the target head has matched
73
+ and the application has accepted the cutover. If the target fails verification
74
+ or serving checks, restore routing to that unchanged source. Do not make
75
+ rollback depend on reversing a content or identifier rewrite.
76
+
77
+ SQLite schema migrations are separate from space transfer. The store records
78
+ each applied migration name and SQL digest in `oh_migrations` and refuses to
79
+ open when an applied version has different migration bytes.
80
+
81
+ SQLite schema version 2 appends `0002_store_realms` without changing the
82
+ released `0001_oh_core` SQL. Existing spaces remain unbound after upgrade. A
83
+ host may bind one through the promise-based store authority; once persisted,
84
+ the exact realm and profile bytes cannot be replaced. A purged working space
85
+ cannot be used as a migration source or recreated under the same identifier.
86
+
87
+ The direct libSQL authority has its own `oh_authority_` schema digest. It emits
88
+ the same V1 record and operation bytes, but it is not a destination for the
89
+ offline CLI import procedure above. Applications moving authority between
90
+ adapters MUST prove an exact complete operation chain and matching head through
91
+ a separately reviewed migration workflow. A dependency-closure capsule is a
92
+ selective content export for adoption, not proof of full authority migration.
@@ -0,0 +1,55 @@
1
+ {
2
+ "contractId": "oh.ontology.v1",
3
+ "idPatterns": {
4
+ "assertion": "^kast_[a-z0-9]{24}$",
5
+ "entity": "^kent_[a-z0-9]{24}$",
6
+ "evidence": "^kevd_[a-z0-9]{24}$",
7
+ "inquiry": "^kinq_[a-z0-9]{24}$"
8
+ },
9
+ "kernelConcepts": [
10
+ {
11
+ "code": "entity",
12
+ "description": "A stable identity anchor for something that can be referred to.",
13
+ "label": "Entity"
14
+ },
15
+ {
16
+ "code": "statement",
17
+ "description": "An immutable proposition with a subject, predicate, object, and qualifiers.",
18
+ "label": "Statement"
19
+ },
20
+ {
21
+ "code": "assertion",
22
+ "description": "An attributable stance toward a statement.",
23
+ "label": "Assertion"
24
+ },
25
+ {
26
+ "code": "evidence",
27
+ "description": "A typed account of how an observation bears on an assertion.",
28
+ "label": "Evidence"
29
+ },
30
+ {
31
+ "code": "context",
32
+ "description": "The scenario and dimensions in which knowledge applies.",
33
+ "label": "Context"
34
+ },
35
+ {
36
+ "code": "inquiry",
37
+ "description": "A question and its durable investigation trail.",
38
+ "label": "Inquiry"
39
+ },
40
+ {
41
+ "code": "projection",
42
+ "description": "A reproducible view derived from exact knowledge.",
43
+ "label": "Projection"
44
+ }
45
+ ],
46
+ "limits": {
47
+ "dimensions": 64,
48
+ "listValues": 256,
49
+ "qualifiers": 128,
50
+ "statementBytes": 262144,
51
+ "textBytes": 65536
52
+ },
53
+ "ontologyVersion": "1.0.0",
54
+ "v": 1
55
+ }
@@ -0,0 +1,80 @@
1
+ # Ontology V1
2
+
3
+ Ontology V1 is identified by `oh.ontology.v1` and version `1.0.0`. Its contract
4
+ manifest digest is
5
+ `e53ae573c2af417082be9f554d0f6f3e317f054daf745181f462608e3f622594`.
6
+
7
+ ## Kernel concepts
8
+
9
+ | Concept | Meaning |
10
+ | --- | --- |
11
+ | Entity | A stable identity anchor for something that can be referred to. |
12
+ | Statement | An immutable proposition with a subject, predicate, object, and qualifiers. |
13
+ | Assertion | An attributable stance toward a statement. |
14
+ | Evidence | A typed account of how an observation bears on an assertion. |
15
+ | Context | The scenario and dimensions in which knowledge applies. |
16
+ | Inquiry | A question and its durable investigation trail. |
17
+ | Projection | A reproducible view derived from exact knowledge. |
18
+
19
+ The kernel separates a proposition from a person's stance toward it, evidence
20
+ from the assertion it bears on, and authored knowledge from a derived view.
21
+ Product vocabularies can refine these concepts without changing the graph
22
+ envelope.
23
+
24
+ ## Identities
25
+
26
+ V1 retains four opaque identity grammars:
27
+
28
+ | Identity | Pattern |
29
+ | --- | --- |
30
+ | Entity | `kent_[a-z0-9]{24}` |
31
+ | Assertion | `kast_[a-z0-9]{24}` |
32
+ | Evidence | `kevd_[a-z0-9]{24}` |
33
+ | Inquiry | `kinq_[a-z0-9]{24}` |
34
+
35
+ These identifiers are opaque. A consumer MUST NOT infer time, authorship, or
36
+ ordering from their suffixes.
37
+
38
+ Schema references contain the exact `namespace`, `code`, positive `revision`,
39
+ `schemaSha256`, and `v: 1`. Namespaces and codes use lowercase safe-code
40
+ segments separated by `.`, `_`, `:`, `/`, or `-`.
41
+
42
+ ## Values
43
+
44
+ A `KnowledgeValueV1` is one of:
45
+
46
+ - an entity reference;
47
+ - NFC text with a lowercase BCP 47-style language tag;
48
+ - a bounded string or boolean;
49
+ - a canonical integer or decimal represented as a string;
50
+ - a canonical absolute URI without credentials and without the `data`, `file`,
51
+ or `javascript` scheme;
52
+ - a list that preserves order;
53
+ - a set in strict canonical order with no duplicates; or
54
+ - an extension bound to a schema, canonicalizer digest, canonical value, media
55
+ type, and value digest.
56
+
57
+ Lists and sets contain at most 256 values and nest at most eight levels.
58
+ General text is at most 65,536 UTF-8 bytes.
59
+
60
+ ## Contexts, statements, and inquiries
61
+
62
+ A context contains at most 64 canonically ordered, unique predicate-value
63
+ dimensions and one scenario: `actual`, `counterfactual`, `hypothetical`, or
64
+ `planned`. `contextSha256` binds the complete context payload.
65
+
66
+ A statement binds an entity subject, schema predicate, typed object, and at
67
+ most 128 canonically ordered, unique qualifiers. Its canonical payload is at
68
+ most 262,144 UTF-8 bytes. `statementSha256` binds that payload.
69
+
70
+ An inquiry binds its opaque ID, author entity, question, answer form, language,
71
+ privacy, status, optional context digest, creation instant, and ordered parent
72
+ inquiry IDs. The creation instant uses exact UTC millisecond form such as
73
+ `2026-08-27T12:00:00.000Z`.
74
+
75
+ ## Errors
76
+
77
+ Ontology parsers return a field and one stable issue class:
78
+ `dependency-missing`, `digest-mismatch`, `invalid-input`, `limit-exceeded`, or
79
+ `noncanonical-input`. A result identifies a contract failure, not whether the
80
+ underlying research claim is true.
@@ -0,0 +1,138 @@
1
+ {
2
+ "$defs": {
3
+ "change": {
4
+ "oneOf": [
5
+ {
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "kind": {
9
+ "const": "put"
10
+ },
11
+ "record": {
12
+ "$ref": "./record.schema.json"
13
+ },
14
+ "v": {
15
+ "const": 1
16
+ }
17
+ },
18
+ "required": [
19
+ "kind",
20
+ "record",
21
+ "v"
22
+ ],
23
+ "type": "object"
24
+ },
25
+ {
26
+ "additionalProperties": false,
27
+ "properties": {
28
+ "key": {
29
+ "$ref": "#/$defs/recordKey"
30
+ },
31
+ "kind": {
32
+ "const": "tombstone"
33
+ },
34
+ "priorSha256": {
35
+ "$ref": "#/$defs/sha256"
36
+ },
37
+ "v": {
38
+ "const": 1
39
+ }
40
+ },
41
+ "required": [
42
+ "key",
43
+ "kind",
44
+ "priorSha256",
45
+ "v"
46
+ ],
47
+ "type": "object"
48
+ }
49
+ ]
50
+ },
51
+ "recordKey": {
52
+ "maxLength": 512,
53
+ "pattern": "^[a-z][a-z0-9]*(?:[._:/-][a-z0-9]+)*$",
54
+ "type": "string"
55
+ },
56
+ "safeCode": {
57
+ "maxLength": 128,
58
+ "pattern": "^[a-z][a-z0-9]*(?:[._:/-][a-z0-9]+)*$",
59
+ "type": "string"
60
+ },
61
+ "sha256": {
62
+ "pattern": "^[a-f0-9]{64}$",
63
+ "type": "string"
64
+ }
65
+ },
66
+ "$id": "https://oh.computer/spec/v1/operation.schema.json",
67
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
68
+ "$comment": "Runtime conformance additionally requires canonical ordered unique changes, a contiguous parent chain, exact graph and record-set digests, the 64 MiB byte bound, and a recomputed operationSha256.",
69
+ "additionalProperties": false,
70
+ "properties": {
71
+ "actorId": {
72
+ "$ref": "#/$defs/safeCode"
73
+ },
74
+ "changes": {
75
+ "items": {
76
+ "$ref": "#/$defs/change"
77
+ },
78
+ "maxItems": 8192,
79
+ "minItems": 1,
80
+ "type": "array"
81
+ },
82
+ "contractId": {
83
+ "const": "oh.ontology.v1"
84
+ },
85
+ "graphRevisionSha256": {
86
+ "$ref": "#/$defs/sha256"
87
+ },
88
+ "instant": {
89
+ "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\.[0-9]{3}Z$",
90
+ "type": "string"
91
+ },
92
+ "operationId": {
93
+ "$ref": "#/$defs/safeCode"
94
+ },
95
+ "operationSha256": {
96
+ "$ref": "#/$defs/sha256"
97
+ },
98
+ "parentOperationSha256": {
99
+ "anyOf": [
100
+ {
101
+ "type": "null"
102
+ },
103
+ {
104
+ "$ref": "#/$defs/sha256"
105
+ }
106
+ ]
107
+ },
108
+ "recordsSha256": {
109
+ "$ref": "#/$defs/sha256"
110
+ },
111
+ "sequence": {
112
+ "minimum": 1,
113
+ "type": "integer"
114
+ },
115
+ "spaceId": {
116
+ "$ref": "#/$defs/safeCode"
117
+ },
118
+ "v": {
119
+ "const": 1
120
+ }
121
+ },
122
+ "required": [
123
+ "actorId",
124
+ "changes",
125
+ "contractId",
126
+ "graphRevisionSha256",
127
+ "instant",
128
+ "operationId",
129
+ "operationSha256",
130
+ "parentOperationSha256",
131
+ "recordsSha256",
132
+ "sequence",
133
+ "spaceId",
134
+ "v"
135
+ ],
136
+ "title": "Oh operation V1",
137
+ "type": "object"
138
+ }