Releases: orneryd/NornicDB
v1.1.0 - Trendsetter
[v1.1.0] - Trendsetter - 2026-05-12
NornicDB v1.1.0 Release Notes
⚠️ ⚠️ ⚠️ READ BEFORE UPGRADING — STORAGE FORMAT CHANGES⚠️ ⚠️ ⚠️ This release ships breaking storage changes that require a one-time
in-place migration on first start. Once your data files are upgraded,
older versions of NornicDB will not be able to read them.🦀 Back up your data directory before upgrading. 🦀
Run the database with the
--upgrade-storageflag (or, in the macOS
installer, tick the upgrade checkbox on the first-run wizard, or in the
tray settings panel restart with the flag enabled). This is a rolling
upgrade — when it completes, the engine compacts the on-disk layout to
the new format and resumes normal operation.After this release, no further major storage overhauls are planned. 🤟
Release tag: v1.1.0
Range covered: v1.0.45..v1.1.0
Combined repository delta: 644 files changed, +170,459 / −9,816 lines across 91 non-merge commits.
This document is a single rolled-up changelog for everything shipped in v1.1.0
across both the v1.1.0-preview (2026-05-12) and v1.1.0-rc (2026-05-14) and v1.1.0 prime (2026-05-15)
milestones. Each section merges the entries from both tags so operators
upgrading directly from v1.0.x see the complete feature set.
Changes from RC:
-
Knowledge-policy
ON ACCESSrecording scope:- moved
ON ACCESSrecording out of storage visibility checks to trigger only for entities actually materialized into query results. - routed recording through storage wrappers to preserve namespaced IDs correctly.
- extended e2e coverage with positive and inverse test cases including accumulator contents before flush.
- moved
-
MVCC commit ordering at sequence saturation:
- hardened MVCC commit ordering when the global commit sequence reaches
MaxUint64. - The reason for the monotonic counter is that we can actually record transactions so fast that slower processors can have negative nanos drift causing random conflicts with serial ingesiton. @1 million commits/sec it would exhaust in 584.5 million years. @1 billion/sec - 584,500 years.
- keep sequence pinned and fall back to strictly increasing high-water timestamps rather than wrapping or failing in said years.
- updated snapshot conflict detection to use timestamp ordering only for the saturated equal-sequence case.
- added focused regression tests for the saturation fallback.
- hardened MVCC commit ordering when the global commit sequence reaches
Added
Knowledge-policy administration via Cypher
CREATE,ALTER,DROP, andSHOWsupport for knowledge-policy
management — decay profiles and promotion policies are administered
directly through Cypher DDL.- Built-in
CALL nornicdb.knowledgepolicy.*procedures for inspecting
policy state, profiles, resolution, and deindexing status. - Browser-side management UI now drives the Cypher-backed surface instead
of a separate admin API.
Knowledge-policy runtime and lifecycle scoring
- New shared-profile resolver, access-metadata indexing,
scoring-before-visibility, and suppression/deindex infrastructure. - Cypher functions for policy-aware scoring and diagnostics:
decayScore,decay, andpolicy. - Inverted Ebbinghaus-style decay curves — set a negative
halfLifeSecondsto flip any decay function family in place. Combined
with theLAST_ACCESSEDanchor, this implements Roynard-style
consolidation where idle time strengthens the score and access resets
it (seedocs/user-guides/decay-profiles.md).
Hybrid-search property pre-filter
POST /nornicdb/searchnow accepts an optionalfiltersfield that
restricts the candidate set by property values before top-K
vector/BM25 selection, preserving recall on sparse filtered sets.- Filter semantics: OR within a key
({"collection": ["user_a", "user_b"]}), AND across keys
({"collection": ["user_a"], "type": ["text"]}); scalar and array
property values both supported. - Applied in
rrfHybridSearch,vectorSearchOnly, and
fullTextSearchOnlypaths. - Primary use case: multi-tenant RAG where each node carries a
collectionarray identifying which users may access it.
End-to-end observability stack
- OpenTelemetry tracing across HTTP, Cypher planning and execution, Bolt
sessions, storage operations, embeddings, and search flows. - Helm chart support for observability deployment, including
ServiceMonitor,PodMonitor, startup/readiness/liveness probes, and
default network-policy wiring. - Curated Grafana dashboard, Prometheus alert rules, and an
auto-generated metrics reference covering the current exported metric
catalog. - pprof hooks for goroutine and mutex profiling.
Storage internals and observability
- Internal numeric IDs and a freelist-based key reclamation path to
reduce storage overhead while keeping keys monotonic and reusable. - Per-namespace property-key dictionary as part of the storage-v2 path.
- Migration progress and statistics logging during in-place upgrades.
Changed
Knowledge-policy operator surface
- Knowledge-policy administration moved off the dedicated HTTP API and
onto the new Cypher DDL + procedure model. - Admin UI, runtime behavior, and diagnostics aligned around the new
suppression-anchor and decay-profile model.
Storage serialization
- Removed Gob as an active serializer while preserving forward migration
support for older data written with Gob. - Storage-v2 hot path emits the tokenized property-key codec
exclusively; the v1 codec is read only by the in-place migration.
Write-heavy query execution
- Bulk-insert and canonical write paths expanded and tuned so more
high-volume ingestion shapes avoid unnecessary reads and stay on the
optimized execution path. - Refreshed bulk-insert cookbook and related operator guidance.
UI
- Browser management pages updated to use newer
uiGridcapabilities
for database and retention administration views.
Bundled runtimes
- Upgraded the bundled
llama.cppintegration tob9106.
Fixed
Cypher correctness
NOT INparsing — predicate now correctly negates theINmembership
check.- Knowledge-policy
ON ACCESSarithmetic coercion — runtime type
coercion now matches Cypher DDL expectations (no silent truncation of
floats by integer-typed parameters).
Transaction conflict handling
- Adjusted timing in conflict-sensitive paths to reduce avoidable write
conflicts. - Snapshot-isolation conflict detection now uses commit-sequence
comparison instead of full timestamp comparison, eliminating false
positives on hosts with non-monotonic wall clocks (CI flake fix). - Unique-merge conflict handling fixed so retryable conflict errors are
surfaced and scoped correctly for Bolt clients.
Storage migration and recovery
- Storage migration now creates all expected indexes during the in-place
upgrade (label, outgoing, incoming, edge-type), eliminating the
"edges disappeared after migration" issue. - MVCC schema metadata recovery fixed.
- Edge-between deindexing behavior fixed.
- Schema lock leak scenarios resolved.
- Tightened uniqueness-vs-constraint-contract handling in the affected
storage and Cypher paths.
Hybrid search filters
- Empty filter-list handling fixed so requests with empty filter lists
no longer discard all results.
Knowledge-policy correctness
- Decay diagnostics, targeted suppression invalidation, score-argument
handling, and reveal-path correctness fixed. - Embed and reveal worker concurrency hardened for the new knowledge
lifecycle features under load.
Lifecycle and high-watermark timing
- Lifecycle and high-watermark nanosecond timing bugs affecting
fast-write scenarios fixed.
Observability safety
- Trace redaction and baggage filtering fixed so credentials and other
sensitive values are not emitted into spans. - Nil-pointer and span-property edge cases in the observability pipeline
fixed.
Cross-platform build and packaging
- Windows and macOS build and packaging regressions affecting release CI
and local packaging flows fixed.
Compatibility
MVCC is now opt-in
- The default retained-version count is now
0, which disables MVCC
history unless explicitly enabled in configuration. Operators who
rely on as-of reads or audit trails must opt back in by setting
NORNICDB_MVCC_RETENTION_MAX_VERSIONS(or the equivalent config
field).
Storage format
- Data written by v1.1.0 is not readable by v1.0.x. Plan the upgrade
accordingly. The migration is one-way; rollback requires restoring
from your pre-upgrade backup.
Documentation
- Added and refreshed:
- Metrics reference generated from the current observability catalog.
- Helm, dashboard, and alerting guidance for the new observability
stack. - Knowledge-policy and decay diagnostics documentation aligned to the
Cypher-backed administration model. - Memory-decay and decay-profile documentation for the new inverted
decay behavior, including thescoreFloorvsvisibilityThreshold
disambiguation and lifecycle examples. - User guidance around promotion policy and Ebbinghaus/Roynard
bootstrap behavior. - Bulk-insert cookbook material for the current optimized write paths.
Upgrade Checklist
- Take a complete backup of your data directory. No exceptions —
the migration is in-place and not reversible without a restore. - Stop the running NornicDB instance cleanly so the WAL flushes.
- Start v1.1.0 with
--upgrade-storage(CLI), the macOS installer
checkbox, or the equivalent tray-settings flag. - Watch the migrati...
v1.0.45 - Go
[v1.0.45] - Go - 2026-05-08
Added
- Broader hot-path coverage for
UNWIND MATCH SETupdates:- added a batched
UNWIND+MATCH+SEThot path so more update-heavy Cypher write workloads can stay on the optimized execution path.
- added a batched
Changed
-
Browser query-results grid behavior:
- updated the web UI to
@ornery/ui-grid-*1.0.5, bringing the latest resize and scroll tracking behavior from the new grid runtime. - query-results selection now relies on the grid's per-column opt-out behavior for the synthetic Select column, so hidden sort and group controls follow the legacy ui-grid behavior instead of rendering as disabled header buttons.
- updated the web UI to
-
Cypher write-path routing:
- tightened
MATCH ... SEThot-path routing so optimized update execution only applies when uniqueness guarantees are present, reducing incorrect fast-path routing for ambiguous match shapes.
- tightened
-
Maintenance and dependency refreshes:
- refreshed UI grid dependencies from the
1.0.4line to1.0.5and regenerated the UI lockfile to match the published package graph. - updated package metadata and peer-dependency wiring in the UI package so installs resolve cleanly against the latest grid release.
- folded in mainline merge-conflict cleanup that affected the release range.
- refreshed UI grid dependencies from the
Fixed
-
Embedding worker lifecycle stability:
- fixed overlapping embed-worker reset and close flows by serializing worker lifecycle transitions, preventing wait-group reuse panics during concurrent embedding workloads.
-
Grid column opt-out chrome:
- fixed the query-results Select column so column-level sorting and grouping opt-outs now hide header controls using the grid's native per-column behavior instead of relying on CSS workarounds.
Technical Details
- Range covered:
v1.0.44..HEAD - Commits in range: 9 (non-merge)
- Repository delta: 15 files changed, +1,322 / -582 lines
- Primary focus areas: query-results grid upgrades,
UNWIND MATCH SEThot-path expansion and safety, embedding-worker lifecycle stability, and targeted UI package maintenance.
v1.0.44 - Lithium
[v1.0.44] Lithium - 2026-05-02
Added
-
Convenience defaults for vLLM-backed local generation:
- added vLLM-friendly defaults in the Heimdall/OpenAI-compatible generation path so local and self-hosted inference setups require less manual configuration.
-
Relationship-head recovery fallback for storage indexes:
- added an edge-between head-index fallback path so relationship lookups can recover more reliably when derived index state needs repair or reconstruction.
-
Named relationship-set support in batched merge flows:
- added support for named relationship sets in
UNWINDmerge batches, expanding the structured relationship-merge shapes that can stay on the optimized execution path.
- added support for named relationship sets in
Changed
-
Relationship merge and probe execution paths:
- optimized relationship probe planning and batched SQL relationship writes so more merge-heavy Cypher workloads avoid redundant work.
- shared node-lookup cache locking across executor and transaction clones to reduce duplicated lookup coordination during concurrent execution.
-
Transient error classification and retry signaling:
- refactored transient conflict handling into the shared
pkg/errorssurface and mapped Bolt transaction conflicts onto explicit transient error semantics. - improved server-side failure handling so retryable conflict conditions are surfaced more consistently to clients.
- refactored transient conflict handling into the shared
-
Storage relationship-index maintenance:
- hardened edge-between index repair, exact relationship lookups, and streamed edge index rebuild behavior to keep relationship indexes aligned with stored graph state.
-
Documentation and dependency maintenance:
- refreshed the README, retention-policy guide, and hot-path query cookbook to match the current relationship hot-path behavior and operator guidance.
- updated Go module dependencies and UI package dependencies as part of the release range.
Fixed
-
Relationship merge property-set correctness:
- fixed relationship merge property updates so property sets are applied correctly across merge execution paths.
-
Relationship hot-path edge cases:
- fixed edge-case handling in relationship hot paths, including exact edge lookup behavior and fallback coverage for edge-between index state.
-
Bolt transient failure behavior:
- fixed Bolt failure handling so conflict-driven transaction failures are decoded and classified more robustly for clients.
Tests
- Added and expanded coverage for:
- relationship merge property handling and named relationship-set merge batches
- relationship hot-path routing, SQL relationship writes, and probe optimization behavior
- Bolt transient error mapping and failure-chunk decoding
- storage edge-between index repair, streamed rebuild behavior, and exact relationship lookup regressions
- shared-state isolation in affected regression tests
Documentation
- Added and refreshed:
- retention policy operator guidance
- README release-facing behavior notes
- hot-path cookbook coverage for the current relationship query optimizations
Technical Details
- Range covered:
v1.0.43..HEAD - Commits in range: 23 (non-merge)
- Repository delta: 40 files changed, +2,494 / -255 lines
- Primary focus areas: relationship merge correctness, relationship hot-path and edge-index reliability, transient Bolt conflict handling, convenience inference defaults, and targeted documentation/dependency refreshes.
v1.0.43 - Clockwork
[v1.0.43] Clockwork - 2026-04-24
Special thanks to @linuxdynasty for submitting a bunch of fixes and optimizations!
Added
-
Runtime retention and privacy control plane:
- added runtime retention sweep management in the database layer, including sweep budgeting, excluded-label handling, record collection, and immediate sweep triggering.
- added admin retention endpoints for policies, legal holds, erasure requests, manual sweeps, and retention status.
- added GDPR integration hooks so privacy and retention workflows can share the same server-side control surface.
-
Retention administration UI:
- added a dedicated Retention Admin page in the web UI with policy editing, legal hold management, erasure request processing, defaults loading, and sweep controls.
- wired new client API types and routes so operators can manage retention behavior from the browser instead of only through raw admin calls.
-
Constraint and planner regression coverage:
- added extensive deterministic tests for constraint contract parsing, schema validation, Bolt database-manager behavior, transaction wrapper reuse,
UNWINDmerge batches, and fabric helper types. - added regression coverage around database-scoped rollback handling and deterministic multidatabase enforcement behavior.
- added extensive deterministic tests for constraint contract parsing, schema validation, Bolt database-manager behavior, transaction wrapper reuse,
-
Knowledge-layer documentation and research material:
- added a full knowledge-layer persistence implementation plan, expanded design material, Kalman-focused planning docs, and a new research-paper draft on persistence semantics. (v1.1.0)
Changed
-
Retention configuration and operator surface:
- expanded runtime config, example YAML, and macOS/app UI surfaces for retention and memory-management controls.
- made chunk overlap configurable in the macOS app and web UI chunking flow.
-
Cypher MERGE and
UNWIND MATCHrouting:- routed more
UNWIND+MATCH/map-merge shapes through the hot path and tightened optional-match fallback behavior. - started using unique-constraint and unique-index information more aggressively for merge lookup and validation paths.
- routed more
-
Constraint contract parsing and validation internals:
- replaced older regex-heavy constraint-contract parsing with allocation-free keyword scanning helpers.
- normalized unique-constraint cache keys and extended contract matching to cover broader label combinations and namespace cases.
-
Documentation and release content:
- refreshed README, operations docs, compliance docs, user-guide indexes, and the hot-path cookbook to match the current runtime behavior.
- removed or folded obsolete planning material into the newer knowledge-layer and compliance documentation set.
-
Dependency maintenance:
- refreshed Go module dependencies and updated UI package dependencies as part of the release range.
Fixed
-
Database-scoped Bolt rollback correctness:
- fixed Bolt explicit transaction rollback so rollback is honored against the correct selected database instead of leaking across database scope boundaries.
- hardened transaction wrapper reuse paths and related rollback regressions in Bolt/Cypher integration tests.
-
Constraint validation correctness and safety:
- fixed unique lookup and validation paths to guard non-comparable values and avoid incorrect equality handling during unique checks.
- corrected constraint-validation plumbing so unique indexes and schema checks stay aligned across storage and Cypher surfaces.
-
Local LLM generation stability:
- fixed CGO generation-path issues in the local llama integration, including causal-attention setup and health checks for non-unified KV caches.
-
Deterministic multidatabase enforcement tests:
- fixed rate-limit and enforcement test behavior to avoid timing-driven flakes and keep multidatabase coverage deterministic.
Tests
- Added and expanded coverage for:
- retention manager behavior, retention admin handlers, and privacy/erasure workflows
- Bolt database-manager integration, database-scoped rollback, and transaction-wrapper reuse
UNWIND/MATCH/MERGEhot-path routing and fallback behavior- constraint contract parsing, validation, schema interactions, and unique lookup edge cases
- fabric helper coverage, plan-cache behavior, and multidatabase enforcement determinism
Documentation
- Added and refreshed:
- GDPR compliance guidance and retention-policy operator documentation
- knowledge-layer persistence plan and implementation details
- Kalman behavioral signal planning notes
- persistence-semantics research paper draft, evaluation plan, bibliography, and related-work notes
Technical Details
- Range covered:
v1.0.42-hotfix..HEAD - Commits in range: 47 (non-merge)
- Repository delta: 64 files changed, +11,730 / -1,528 lines
- Primary focus areas: retention/GDPR operator workflows, Bolt rollback correctness, unique-constraint driven planner and validation improvements, deterministic regression coverage, and major knowledge-layer documentation expansion.
v1.0.42 - Anthem Pt. 2
[v1.0.42-hotfix] Anthem Pt. 2 - 2026-04-17
Added
-
Explicit Bolt host binding support:
- added a dedicated Bolt host field so the Bolt listener can bind to the resolved server address instead of always falling back to the wildcard socket.
-
Bind-address regression coverage:
- added CLI/config/environment precedence tests for server bind resolution.
- added Bolt listener tests to verify loopback binding and secure default host behavior.
Changed
-
Bind-address resolution precedence:
- centralized bind-address resolution for
servestartup so CLI flags, loaded config, and explicit protocol-specific environment variables are resolved consistently before HTTP and Bolt are started. - aligned startup endpoint display output with the resolved address, while still presenting
localhostfor wildcard binds in user-facing logs.
- centralized bind-address resolution for
-
Dependency maintenance:
- updated
github.com/hybridgroup/yzmatov1.12.0. - refreshed related Go module entries pulled in by the dependency update.
- updated UI dev dependencies:
postcssto8.5.10andtypescriptto6.0.3.
- updated
Fixed
- Bolt listener exposure:
- fixed the Bolt server so configured bind addresses now apply to the actual listener instead of only affecting user-facing startup messages.
- restored secure loopback binding as the default when no explicit override is provided.
Tests
- Added and expanded coverage for:
- CLI
--addressprecedence over config and environment sources - config-file and explicit environment bind-address overrides
- Bolt listener binding to the configured host instead of wildcard interfaces
- CLI
Technical Details
- Commit covered:
adce4f9a9fc7b6aada07c0bfa2d737cd7a6efaca - Commits in release: 1
- Repository delta: 8 files changed, +194 / -26 lines
- Primary focus areas: Bolt bind-address correctness, secure default listener behavior, regression coverage, and targeted Go/UI dependency maintenance.
v1.0.42 - Anthem
[v1.0.42] Anthem - 2026-04-16
The answer to life the universe and everything...
Anthem allows you to utilize the underlying model inside NornicDB with Continue VSCode Plugin or any other OpenAI-compatible chat interface.
Added
-
Heimdall tool coverage and documentation:
- exposed local chat tool routing more consistently so the OpenAI compatible endpoint can surface the user's tools from an agent into injected actions in chat flows.
- added and refreshed Heimdall, knowledge-layer, and compliance documentation, including new guides for the Heimdall AI assistant and knowledge-layer persistence planning.
-
Regression coverage for transactional and constraint edge cases:
- added regression coverage for constraint handling in Bolt/Cypher paths.
- added targeted tests for async flush race conditions and complex
UNWIND/MERGEfallback behavior.
Changed
-
Heimdall local chat behavior:
- hardened action parsing, tool forwarding, and local chat prompt behavior so action envelopes are handled more predictably.
- simplified the watcher hello/search tool flow and aligned injected action naming with the current plugin surface.
-
Cypher hot paths and fallback routing:
- generalized hot-path execution to support broader n-ary and generic query shapes.
- refined
UNWIND+MERGEfallback routing so complex query shapes are handed off to the full executor more consistently. - preserved transaction-visible lookups in fallback execution paths to keep behavior aligned with in-transaction state.
-
Documentation and release content:
- folded older planning material into the current docs set and refreshed migration, AI-agent, and deployment-facing documentation.
Fixed
-
MERGE cache and transaction correctness:
- fixed stale
MERGEcache invalidation after implicit transaction aborts. - fixed async flush timing so MVCC heads do not advance while a transaction still depends on its visible state.
- fixed stale
-
Installer and model download reliability:
- updated installer/download locations and added validation so failed model downloads are not accepted as valid artifacts.
- improved macOS model download handling to verify downloaded files before treating them as usable GGUF models.
-
Heimdall local chat stability:
- fixed local chat template replay and unknown tool-call forwarding behavior.
- hardened Heimdall test races and related local chat execution edge cases.
Tests
- Added and expanded coverage for:
- async engine flush/count race handling
UNWIND/MERGEfallback and optional lookup regression paths- constraint regressions across Bolt and Cypher execution
- Heimdall local chat tool execution and race-sensitive paths
Technical Details
- Range covered:
v1.0.41..HEAD - Commits in range: 19 (non-merge)
- Repository delta: 48 files changed, +5,437 / -3,007 lines
- Primary focus areas: Cypher fallback correctness, transaction visibility and async flush safety, Heimdall local chat/tool handling, installer download validation, and documentation consolidation.
v1.0.41 - Blue Orchid
v1.0.41 Blue Orchid
Blue Orchid brings us a simple graph explorer, fast-path enhancements, and other vairous fixes for the canonical graph ledger setup.
I'm also playing around with a side-project that I'm using to try and test out the temporal functions and graph explorer by reconstructing the code state of a given git repository based on commit hash. Git-to-Graph
Added
-
Graph explorer UI:
- added a new graph explorer tab with neighborhood visualization and node-details integration.
- wired the browser page, node details panel, and client API helpers to support the new exploration flow.
-
MERGE and string-literal infrastructure:
- added shared string-literal decoding helpers so Cypher literal handling is consistent across execution paths.
- expanded merge-chain and relationship-shape support for the fallback and hot-path planner routes.
Changed
-
UNWIND and MERGE hot paths:
- generalized the staged compound
UNWINDmutation path and tightened the merge-chain hot path so parameter handling and optional lookups behave consistently. - memoized the merge-chain path where the executor can safely reuse the structured shape detection.
- generalized the staged compound
-
Cypher executor plumbing:
- updated executor, pattern parsing, property evaluation, and clause handling to align the new hot-path routing logic.
- refreshed the query-shape tests and regression coverage around compound
UNWIND, merge chains, and literal decoding.
-
Release and dependency maintenance:
- updated README/version metadata and release workflows for the new build.
- refreshed dependency pins across Go, UI, llama.cpp, Docker, and build scripts.
- updated the hot-path performance cookbook to document the new query-shape coverage.
Fixed
-
Fallback MERGE binding preservation:
- fixed fallback MERGE chain handling so bindings are preserved correctly when the structured hot path is not selected.
- restored parameter handling in the generalized
UNWINDmerge-chain route.
-
Linker and packaging stability:
- fixed the native linker path used by the CUDA build flow.
- cleaned up version bump artifacts so the packaged build reports
1.0.41consistently.
Tests
- Added and expanded coverage for:
- compound
UNWINDmutation staging and merge-chain hot-path routing - fallback MERGE chain bindings and optional lookup behavior
- string-literal decoding and property evaluation helpers
- graph explorer browser integration and node-details interactions
- executor trace coverage and query-shape regression cases
- compound
Technical Details
- Range covered:
v1.0.40..HEAD - Commits in range: 10 (non-merge)
- Repository delta: 50 files changed, +3,163 / -502 lines
- Primary focus areas: Cypher merge/UNWIND hot-path generalization, literal decoding cleanup, graph explorer UI delivery, dependency refreshes, and packaging/build fixes.
v1.0.40 - Kiyote
v1.0.40 Kiyote
Everyone, thank you all! We crossed 500 stars in 3 months! Thank you all for coming along with me on my journey 🫶
Kiyote is all about optimization, reliability and hardening along the hot path. We got rid of the old regexes that were sitting around and replaced them with keyword scanning, which is much more efficient. (see below)
Parser Validation Benchmark: Nornic vs ANTLR
Isolated parser-validation benchmark on Apple M2 Max (darwin/arm64) using:
go test ./pkg/cypher -run '^$' -bench BenchmarkParserValidationIsolation -benchmem -count=1
Speedup is ANTLR ns/op ÷ Nornic ns/op.
| Query Shape | Nornic ns/op | ANTLR ns/op | Speedup | Nornic allocs/op | ANTLR allocs/op |
|---|---|---|---|---|---|
| simple_match | 43.76 | 5288 | 120.8x | 0 | 53 |
| match_with_label | 60.13 | 5962 | 99.2x | 0 | 58 |
| match_with_properties | 90.20 | 9508 | 105.4x | 0 | 86 |
| match_with_variable | 60.86 | 5996 | 98.5x | 0 | 58 |
| match_where_equals | 99.67 | 10836 | 108.7x | 0 | 97 |
| match_where_gt | 93.72 | 10854 | 115.8x | 0 | 98 |
| match_where_and | 135.2 | 15066 | 111.4x | 0 | 132 |
| match_where_or | 133.9 | 15279 | 114.1x | 0 | 134 |
| match_where_is_null | 108.4 | 9849 | 90.9x | 0 | 87 |
| match_where_is_not_null | 111.5 | 10071 | 90.3x | 0 | 89 |
| match_where_in | 114.0 | 16668 | 146.2x | 0 | 149 |
| match_where_starts_with | 114.7 | 10887 | 94.9x | 0 | 95 |
| match_where_contains | 112.2 | 10556 | 94.1x | 0 | 93 |
| match_relationship | 74.59 | 11230 | 150.6x | 0 | 105 |
| match_typed_relationship | 117.2 | 11489 | 98.0x | 0 | 102 |
| match_variable_length | 77.51 | 10151 | 131.0x | 0 | 92 |
| match_reverse_relationship | 68.75 | 9454 | 137.5x | 0 | 87 |
| create_node | 78.46 | 6573 | 83.8x | 0 | 62 |
| create_with_return | 95.12 | 9352 | 98.3x | 0 | 85 |
| merge_node | 78.76 | 6443 | 81.8x | 0 | 61 |
| set_property | 103.5 | 11033 | 106.6x | 0 | 98 |
| delete_node | 92.19 | 9433 | 102.3x | 0 | 85 |
| detach_delete | 104.0 | 9723 | 93.5x | 0 | 87 |
| return_alias | 92.86 | 8702 | 93.7x | 0 | 68 |
| return_distinct | 89.76 | 7045 | 78.5x | 0 | 64 |
| return_limit | 77.19 | 9179 | 118.9x | 0 | 79 |
| return_skip | 72.97 | 8894 | 121.9x | 0 | 79 |
| return_order_by | 94.72 | 9714 | 102.6x | 0 | 85 |
| return_order_desc | 100.7 | 10023 | 99.5x | 0 | 87 |
| with_simple | 73.97 | 9274 | 125.4x | 0 | 81 |
| with_where | 106.5 | 14110 | 132.5x | 0 | 121 |
| count_all | 79.43 | 6716 | 84.6x | 0 | 61 |
| count_nodes | 79.90 | 8664 | 108.4x | 0 | 78 |
| sum | 84.34 | 9439 | 111.9x | 0 | 83 |
| avg | 84.08 | 9322 | 110.9x | 0 | 83 |
| unwind_list | 76.37 | 13242 | 173.4x | 0 | 123 |
| optional_match | 128.4 | 13588 | 105.8x | 0 | 112 |
| call_procedure | 54.80 | 2785 | 50.8x | 0 | 30 |
Headline Numbers
- Nornic was faster on every isolated parser-validation shape measured.
- Speedups ranged from
50.8xto173.4x. - Nornic stayed at
0 allocs/opacross the full suite. - ANTLR ranged from
30to149 allocs/op.
Code-wide, the advantage comes from four things:
Nornic uses specialized string scanners instead of a full grammar pipeline. In pkg/cypher/executor.go, validateSyntaxNornic is mostly bounded checks over raw bytes: valid starting clause, balanced delimiters, and lightweight structural validation. That keeps the hot path in straight-line code with predictable branching.
Nornic avoids lexer, token stream, parse tree, and grammar machinery entirely on its fast path. ANTLR validation in pkg/cypher/antlr/parse.go still has to run a lexer, build a token stream, drive the parser automaton, and potentially retry from SLL to LL. Even pooled, that is fundamentally more work.
Nornic is heavily optimized around query-shape helpers and direct scans. Files like pkg/cypher/string_patterns.go, pkg/cypher/query_patterns.go, pkg/cypher/traversal.go, and pkg/cypher/compound_query_shape_matcher.go are written to recognize exactly the query structures the engine cares about, without paying for general-purpose parse-tree construction.
Nornic stays allocation-free on the isolated validation path, while ANTLR still allocates heavily. That is the visible benchmark result, but it is really a symptom of the design: Nornic validates directly against the input string; ANTLR builds intermediate parser state objects because it is solving a more general parsing problem.
TLDR; Nornic is faster because it is a purpose-built, zero-allocation, scanner-driven validator/executor front end, while ANTLR is a general grammar engine with lexer/token/parser overhead and fallback complexity. The speedup is mostly architectural, not just micro-optimization.
[v1.0.40] "Kiyote" - 2026-04-11
Added
-
Structured Cypher hot-path matchers:
- replaced several regex-based fast-path routers with scanner/helper-based matchers for compound queries,
UNWINDroutes, traversal shapes, shortest-path handling, and related query-shape detection. - added explicit hot-path trace coverage so the executor can report when the new structured matchers are used.
- replaced several regex-based fast-path routers with scanner/helper-based matchers for compound queries,
-
Parser comparison reporting:
- added an integrated Nornic-vs-ANTLR comparison harness that prints per-query timing ratios and an overall summary.
- stabilized the comparison output so users and maintainers can trust the speedup numbers instead of single-run noise.
Changed
-
Traversal and match planning:
- improved traversal planning for top-k seeded lookups so multi-key
ORDER BYshapes can still use the indexed path when possible. - compiled common binding-row
WHEREpredicates and made traversal execution honor the active temporal viewport consistently. - refined MERGE routing for composite-key patterns and hardened batch deduplication so key collisions are handled predictably.
- improved traversal planning for top-k seeded lookups so multi-key
-
Cypher execution cleanup:
- migrated hot-path query-shape parsing away from regex capture arrays and onto shared helpers.
- removed obsolete hot-path regex definitions after the structured matcher cutover.
- refreshed parser-mode and query-pattern plumbing so the same user-facing queries route more consistently across executor paths.
-
Documentation and release hygiene:
- refreshed README and deployment notes to reflect the current product direction.
- updated performance notes for hybrid Bolt queries.
- refreshed dependencies as part of the release cycle.
Fixed
-
Shortest-path parsing regression:
- fixed a panic in single-
MATCHshortest-path queries by correcting the clause boundary scan used to recover the precedingMATCHclause. - added regression coverage for the exact Bolt fallback query shape that exposed the issue.
- fixed a panic in single-
-
Query-shape stability:
- restored deterministic ordering and route selection for the query families that were being optimized in the hot path.
- tightened parser and traversal tests around the new helper-based implementations.
Tests
- Added and expanded coverage for:
- structured compound-query matcher behavior and reject reasons
- hot-path trace assertions for compound query routing and traversal seeding
- shortest-path parsing, execution, and regression handling
UNWINDcollect/distinct and batch merge helper paths- parser comparison output and performance reporting
Technical Details
- Range covered:
v1.0.39..HEAD - Commits in range: 13 (non-merge)
- Primary focus areas: Cypher hot-path matcher migration, traversal and merge routing, parser comparison tooling, shortest-path correctness, and release documentation updates.
v1.0.39 - Punkrocker
v1.0.39 - Punkrocker
Punkrocker is the latest release of NornicDB, focused on stronger graph data contracts, more predictable transaction behavior, better bulk-write stability, and faster traversal execution for real-world query shapes.
This release adds a new way to define grouped schema rules, expands relationship policy enforcement, improves parser compatibility, and tightens correctness in explicit transactions and ordered traversal queries.
Highlights
Block-style constraint contracts
You can now define multiple related rules together in a single constraint contract using REQUIRE { ... }.
This makes it easier to express real data rules in one place instead of scattering them across separate constraint definitions.
CREATE CONSTRAINT person_contract
FOR (n:Person)
REQUIRE {
n.id IS UNIQUE
n.name IS NOT NULL
n.status IN ['active', 'inactive']
(n.tenant, n.externalId) IS NODE KEY
COUNT { (n)-[:PRIMARY_EMPLOYER]->(:Company) } <= 1
}Relationship contracts work too:
CREATE CONSTRAINT works_at_contract
FOR ()-[r:WORKS_AT]-()
REQUIRE {
r.id IS UNIQUE
r.startedAt IS NOT NULL
startNode(r) <> endNode(r)
startNode(r).tenant = endNode(r).tenant
r.hoursPerWeek > 0
}You can inspect these grouped contracts separately with:
SHOW CONSTRAINT CONTRACTSRelationship cardinality constraints
Punkrocker adds directional relationship count limits, making it easier to enforce edge-level policy directly in the schema.
CREATE CONSTRAINT max_employers
FOR ()-[r:WORKS_AT]->()
REQUIRE MAX COUNT 3This is useful for graph rules like:
- limiting how many active outbound edges of a type a node can have
- enforcing single-primary or bounded-assignment patterns
- keeping relationship structure clean without application-side checks
Better parser compatibility
This release broadens Cypher compatibility around newer REQUIRE forms and improves support for WITH EMBEDDING and related query shapes.
That means more valid user queries work consistently across parser modes, including richer constraint syntax and embedding-enabled write flows.
Example:
CREATE (n:Doc {id:'d1', content:'hello world'})
WITH EMBEDDING
RETURN count(n) AS createdExplicit transaction correctness
Punkrocker improves explicit transaction behavior so validation happens against the final committed state, not against temporary intermediate states inside a transaction.
This matters for multi-step writes where a later statement makes the data valid before commit.
Example transaction flow:
BEGIN
CREATE (a:Person {id:'p1'})
CREATE (b:Company {id:'c1'})
CREATE (a)-[:WORKS_AT {id:'w1', hoursPerWeek: 0}]->(b)
MATCH ()-[r:WORKS_AT {id:'w1'}]->() SET r.hoursPerWeek = 40
COMMITIn Punkrocker, this kind of flow is validated correctly at commit time based on the final state.
More stable bulk writes
Large UNWIND and batch update pipelines are more robust in this release.
Punkrocker reduces write amplification when a row creates a node and then updates it again in the same transaction, helping avoid oversized transaction failures in heavy write workloads.
Example:
UNWIND $rows AS row
CREATE (n:Doc {id: row.id})
SET n = row
RETURN count(n)Faster ordered traversal queries
This release adds a generic relationship ORDER BY ... LIMIT planner that can seed traversal from the filtered end-node side using index-backed top-k lookups.
In practice, that improves latency for ordered traversal queries without relying on hardcoded, application-specific rewrites.
Example:
MATCH (o:OriginalText)-[:TRANSLATES_TO]->(t:TranslatedText)
WHERE t.language = 'fr'
RETURN o, t, t.createdAt
ORDER BY t.createdAt DESC
LIMIT 10More predictable ordering for graph query results
Punkrocker fixes ordering behavior for relationship-heavy query results, including:
- ordering by aliased expressions
- ordering by returned node properties
- cases where labels or relationship types such as
:Orderor:ORDERSpreviously interfered withORDER BYdetection
Formal Patch notes:
Added
- Block-style constraint contracts (
REQUIRE { ... }):- added grouped schema contracts so multiple rules can be declared together on a node or relationship target.
- block entries can mix primitive constraints already supported by the engine with runtime boolean validations.
- added
SHOW CONSTRAINT CONTRACTSto inspect stored contracts separately from the compiled primitive constraints they generate.
Example - node contract:
CREATE CONSTRAINT person_contract
FOR (n:Person)
REQUIRE {
n.id IS UNIQUE
n.name IS NOT NULL
n.status IN ['active', 'inactive']
(n.tenant, n.externalId) IS NODE KEY
COUNT { (n)-[:PRIMARY_EMPLOYER]->(:Company) } <= 1
}Example - relationship contract:
CREATE CONSTRAINT works_at_contract
FOR ()-[r:WORKS_AT]-()
REQUIRE {
r.id IS UNIQUE
r.startedAt IS NOT NULL
startNode(r) <> endNode(r)
startNode(r).tenant = endNode(r).tenant
r.hoursPerWeek > 0
}- Relationship cardinality and endpoint policy constraints (NornicDB extensions):
- added directional relationship cardinality limits using
REQUIRE MAX COUNT <n>. - added endpoint policy constraints so allowed start-label/end-label combinations can be enforced for a relationship type.
- added directional relationship cardinality limits using
Example - directional cardinality:
CREATE CONSTRAINT max_employers
FOR ()-[r:WORKS_AT]->()
REQUIRE MAX COUNT 3Changed
-
Cypher parser compatibility and DDL coverage:
- expanded ANTLR parser support for Neo4j 5-style
REQUIREforms, parenthesized property chains in key constraints, trailingOPTIONS, andWITH EMBEDDINGsyntax. - aligned parser-mode behavior so the same user-facing query shapes work consistently in both parser paths.
- expanded ANTLR parser support for Neo4j 5-style
-
Traversal planning and query execution:
- added a generic relationship
ORDER BY ... LIMITplanner that can seed traversal from the filtered end-node side using index top-k lookups. - added dedicated hot-path tracing for the new traversal planner and broadened routing/coverage for the translation-query family and adjacent query shapes.
- added a generic relationship
-
Release and dependency maintenance:
- refreshed Go, UI, and workflow dependencies.
- updated release/readme/docs content to reflect the current feature set and release flow.
Fixed
-
Explicit transaction final-state semantics:
- fixed explicit transaction handling so relationship constraints are validated against the final committed state rather than intermediate statement state.
- fixed transaction read-your-own-write behavior for relationship reads and relationship property updates in explicit transactions.
-
Large batch write amplification:
- fixed
UNWIND/bulk write paths that could fail with oversized transactions when a node was created and then updated again in the same transaction. - create-then-update mutations now collapse into a single pending create operation where possible.
- fixed
-
Relationship query ordering and stability:
- fixed
ORDER BYhandling for relationship query results when ordering by aliased return expressions or node properties. - fixed MATCH-clause
ORDER BYextraction so labels and relationship types such as:Orderand:ORDERSno longer interfere with sorting. - restored deterministic ordering for Northwind-style relationship aggregation fast paths.
- fixed
Tests
- Added and expanded regression coverage for:
- block-style constraint contracts and
SHOW CONSTRAINT CONTRACTS - relationship cardinality and endpoint policy constraints
- explicit transaction relationship final-state validation
- batch
UNWINDcreate/update collapse behavior - exact translation query-family parsing, routing, e2e behavior, and traversal hot-path assertions
- relationship aggregation ordering and
ORDER BYclause parsing aroundOrder/ORDERStokens
- block-style constraint contracts and
Technical Details
- Range covered:
v1.0.38..HEAD - Commits in range: 19 (non-merge)
- Repository delta: 85 files changed, +7,997 / -2,854 lines
- Primary focus areas: schema contracts and relationship policy constraints, parser compatibility, explicit transaction correctness, bulk-write stability, and generic relationship traversal/query hot paths.
v1.0.38 - Phantom
v1.0.38 - Phantom
EDIT: This was previously called "dimes." because I was just really releasing "my own stuff," I had started releasing versions with music I was currently listening to when I hit the button to release that version. However, this is starting to see real traction potentially, especially in corporate and academic settings, so going forward all songs will be more suitable for a corporate setting. Thanks for your support!
Phantom brings full Neo4j relationship constraint parity — uniqueness, existence, property type, and relationship key constraints now work on relationships using FOR ()-[r:TYPE]-() syntax, with automatic owned backing indexes, creation-time validation against existing data, and enforcement across every write path including transactions and bulk operations.
Phantom also introduces two NornicDB-exclusive constraint extensions: temporal no-overlap constraints on relationships that prevent overlapping time intervals grouped by a composite key, and domain/enum constraints that restrict any node or relationship property to a declared set of allowed values.
On the operational side, Phantom adds CMEK/HSM-backed at-rest encryption, fixes embedding property namespace pollution so the embedding property name is no longer reserved, stabilizes ORDER BY on returned node properties, aligns CREATE CONSTRAINT duplicate-name semantics with Neo4j by requiring IF NOT EXISTS for idempotent creation, and ships macOS installer service lifecycle fixes.
[v1.0.38] - 2026-04-02
Added
- Neo4j relationship constraint parity:
- all constraint families now work on both nodes and relationships: uniqueness, existence (IS NOT NULL), property type (IS :: TYPE), and key constraints (IS RELATIONSHIP KEY).
- relationship constraints use the
FOR ()-[r:TYPE]-()target pattern, matching Neo4j 5.x syntax. - uniqueness and key constraints on relationships automatically create owned backing indexes that are dropped when the constraint is dropped.
Example — relationship uniqueness:
CREATE CONSTRAINT transfer_ref_unique IF NOT EXISTS
FOR ()-[r:TRANSFERRED]-()
REQUIRE r.reference_id IS UNIQUEExample — relationship existence:
CREATE CONSTRAINT transferred_amount_exists IF NOT EXISTS
FOR ()-[r:TRANSFERRED]-()
REQUIRE r.amount IS NOT NULLExample — relationship property type:
CREATE CONSTRAINT transferred_amount_type IF NOT EXISTS
FOR ()-[r:TRANSFERRED]-()
REQUIRE r.amount IS :: FLOATExample — relationship key (composite uniqueness + existence):
CREATE CONSTRAINT works_at_key IF NOT EXISTS
FOR ()-[r:WORKS_AT]-()
REQUIRE (r.employee_id, r.department) IS RELATIONSHIP KEY- Temporal no-overlap constraints on relationships (NornicDB extension):
- extends the existing node temporal no-overlap constraint to relationships.
- supports a composite endpoint-pair form where the last two properties are always the time range and any preceding properties form the grouping key.
Example — 3-property form (single grouping key):
CREATE CONSTRAINT employment_temporal IF NOT EXISTS
FOR ()-[r:WORKS_AT]-()
REQUIRE (r.employee_id, r.valid_from, r.valid_to) IS TEMPORAL NO OVERLAPExample — 4-property form (composite grouping key):
CREATE CONSTRAINT assignment_temporal IF NOT EXISTS
FOR ()-[r:ASSIGNED_TO]-()
REQUIRE (r.employee_id, r.project_id, r.valid_from, r.valid_to) IS TEMPORAL NO OVERLAP- Domain/enum constraints (NornicDB extension):
- new constraint type that restricts a property to a fixed set of allowed values.
- works on both nodes and relationships.
- domain constraints with different allowed-value sets on the same schema are treated as conflicting.
Example — node domain:
CREATE CONSTRAINT person_status_domain IF NOT EXISTS
FOR (n:Person)
REQUIRE n.status IN ['active', 'inactive', 'suspended']Example — relationship domain:
CREATE CONSTRAINT works_at_role_domain IF NOT EXISTS
FOR ()-[r:WORKS_AT]-()
REQUIRE r.role IN ['engineer', 'manager', 'director']-
CMEK/HSM-backed at-rest encryption:
- added customer-managed encryption key (CMEK) and HSM-backed at-rest encryption for the database engine.
-
macOS installer service lifecycle:
- added macOS packager workflow with automatic release upload.
- separated macOS packager from Docker CD pipeline.
Changed
-
IF NOT EXISTSsemantics forCREATE CONSTRAINT:- exact-duplicate
CREATE CONSTRAINTnow returns an error unlessIF NOT EXISTSis specified, matching Neo4j behavior. Previously, duplicates were silently idempotent.
- exact-duplicate
-
SHOW INDEXESandSHOW CONSTRAINTSrelationship awareness:SHOW INDEXESnow reportsentityType(NODE or RELATIONSHIP) andowningConstraintfor backing indexes created by relationship uniqueness/key constraints.SHOW CONSTRAINTSnow reportsentityTypeas RELATIONSHIP for relationship-scoped constraints.
-
Branding and documentation:
- abstracted Mimir-specific references to NornicDB-focused language across docs, source comments, test files, and configuration.
- updated system-design documentation with WITH EMBEDDING support and correct embedding defaults (8192 chunk size, bge-m3 model).
- updated user-facing documentation for all new constraint types with syntax examples.
Fixed
-
Embedding property namespace pollution:
- removed special-case routing that intercepted the
embeddingproperty name during SET/GET operations. Theembeddingproperty is now treated as a regular user property. Users can name their embedding fields anything and create vector indexes for them.
- removed special-case routing that intercepted the
-
ORDER BY on returned node properties:
- stabilized ORDER BY when sorting on properties of returned nodes (e.g.,
ORDER BY t.createdAtwhen onlytis returned). - fixed row-sorting to resolve
var.propagainst map-backed node values the same way expression evaluation does.
- stabilized ORDER BY when sorting on properties of returned nodes (e.g.,
-
Constraint enforcement namespace filtering:
- fixed empty-namespace prefix filtering that caused unnamespaced edge IDs to be skipped during constraint enforcement scans.
- fixed cross-namespace leak in transaction-level temporal constraint enforcement where pending edges from other namespaces could cause false violations.
-
Owned backing index metadata:
- fixed
SHOW INDEXESto carryentityTypeandowningConstraintthrough relationship-scoped backing indexes instead of hardcoding NODE and nil.
- fixed
-
macOS installer service lifecycle:
- fixed start/stop/restart controls to behave correctly for the macOS service.
-
Graph API hardening:
- hardened graph MVCC/diff handlers, aligned graph endpoint contracts, and improved validation and error mapping for the graph API.
Security
- Updated dependencies to resolve vulnerability scan findings.
- Updated example code to pass security scanning.
Tests
- Added and expanded regression coverage for:
- all relationship constraint families (uniqueness, existence, property type, key) with DDL, creation-time validation, and write-path enforcement tests
- relationship temporal no-overlap constraints (3-property and 4-property forms)
- domain/enum constraints on nodes and relationships with conflict detection
IF NOT EXISTSidempotency semantics for all constraint types- embedding property namespace pollution removal
- ORDER BY stability on returned node properties
- CMEK/HSM encryption compliance
- expanded unit test coverage across uncovered packages
Technical Details
- Range covered:
v1.0.37..HEAD - Commits in range: 30 (non-merge)
- Repository delta: 180 files changed, +15,077 / -2,619 lines
- Primary focus areas: Neo4j relationship constraint parity, NornicDB constraint extensions (temporal no-overlap, domain/enum), CMEK encryption, embedding property namespace cleanup, ORDER BY stability, and macOS packaging.