nomicore
A self-describing, governed data core for AI agents—schemas, authority, validation, and semantic context travel with the data.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 18, 2026
- Updated
- Sep 3, 2026
Introduction
Nomicore
English | 中文
The database built for agents.
面向 Agent 的数据库
Nomicore is a self-describing Namespace runtime built on Yjs. Each Namespace stores its VFSL schema alongside its data in the SCHEMA envelope. A host project uses the same schema.vfsl to generate TypeScript path projections, then performs controlled reads and writes through Registry leases. Hub/Peer replication maintains complete replicas across instances and independent Persistence roots.
Capabilities
- VFSL v1: parsing, evaluation, schema envelopes, logical ROOT validation, and path/carrier projections.
- TypeScript code generation: generates a
VfslPathMapaugmentation from the host-ownedschema.vfsl, providing typed mutation paths and values. - Namespace Runtime: synchronous reads, VFSL-validated writes, a strict FIFO write sequencer, and SCHEMA replacement.
- Namespace Registry: namespace creation/opening, leases, idle retention, lifecycle management, and ordered shutdown.
- Persistence: Memory and File adapters, dirty tracking and flush scheduling, recovery, archival, and replica reset. A File root is exclusively owned by one active process.
- Instance identity: an immutable
instanceId + roleCordis service. - WebSocket replication: role-specific Hub/Peer Cordis plugins with authentication, authorization, bootstrap/reconcile, backpressure, liveness, GOAWAY drain, and controlled recovery.
- Standalone server: the
@nomicore/yjs-serverCLI plus embeddable Node Hub-listen and Peer-dial adapters.
See CONTEXT.md for authoritative terminology, docs/adr/ for architecture decisions, and docs/protocols/instance-replication-v1.md for the wire contract.
Core usage rules
- The host project owns its
schema.vfsl, generated types, business code, configuration, tests, and deployment. Nomicore is a dependency; it does not take ownership of the host domain. - Namespace writes must use the generated
VfslPathMapprojection and a projection-aware typecheck. Route writes through a host-owned typed adapter overNamespaceLease.mutateData(). Runtime SCHEMA validation does not replace compile-time path/value checking. - Business mutations should be minimal, mergeable, and semantic. Do not read and replace an entire ROOT or parent object when updating one leaf.
- A File Persistence
rootDiris private to one process; it is not a shared database directory. Cross-process changes must use the owner application's API or Hub/Peer replication between independent roots. Never open the same root concurrently or edit snapshots directly. - Only a Hub may replace SCHEMA through an existing namespace lease. After replacement, regenerate the type projection and coordinate Peer reset/re-bootstrap or restart as documented.
Related guides:
- VFSL code generation and type-safe access in external projects
- Hosting Nomicore in a third-party Cordis application
- Standalone Hub/Peer deployment and operations
- Local source linking
Packages and repository layout
packages/
├── vfsl-protocol/ # path-access protocol consumed by generated types
├── vfsl/ # VFSL parser, evaluator, and validator
├── vfsl-codegen/ # TypeScript projection generator
├── doc-runtime/ # Yjs materialization, reads, and validated mutations
├── namespace-runtime/ # Namespace capabilities and write sequencer
├── clock/ # Cordis wall-clock service
├── instance/ # instanceId + role service
├── persistence/ # Memory/File persistence
├── namespace-registry/ # Registry, leases, and replication sessions
├── replication-protocol/ # instance replication v1 codec
├── ws-replication/ # Hub/Peer controllers and Cordis plugins
└── dsh-persistence/ # DSH development/probe profile
apps/yjs-server/ # standalone Hub/Peer composition and Node WS adapters
domains/ # repository examples and test domains
docs/ # ADRs, protocols, VFSL, and integration guides
artifacts/local-packages/ # generated local integration tarballs and manifest
Install from npm
All @nomicore/* packages are publicly available on npm. Independent consumers should prefer registry packages so the package manager resolves released versions and transitive dependencies:
pnpm add @nomicore/namespace-registry @nomicore/persistence
# To embed Hub/Peer replication:
pnpm add @nomicore/instance @nomicore/clock @nomicore/ws-replication @nomicore/yjs-server
# To generate typed projections:
pnpm add -D @nomicore/vfsl-codegen @nomicore/vfsl-protocol
Do not clone the Nomicore checkout, link src, or maintain a complete local tarball closure for ordinary consumption. Commit the selected npm versions and lockfile for reproducible production deployments. Source linking and local tarballs are only for Nomicore development, testing unreleased changes, or release preparation.
Build local tarballs
Build a local tarball set only when integrating unreleased repository changes or preparing an npm release.
1. Prepare the checkout
git switch main
git pull --ff-only origin main
pnpm install --frozen-lockfile
Node.js 20+ and the pnpm version declared by the repository are required.
2. Build the complete package set
pnpm run pack:local
The command:
- clears
artifacts/local-packages/; - builds each publishable package's
distin dependency order; - packs each package into a deterministic tarball;
- writes
artifacts/local-packages/manifest.json.
Default output:
artifacts/local-packages/
├── manifest.json
├── nomicore-vfsl-protocol-<version>.tgz
├── nomicore-vfsl-<version>.tgz
├── nomicore-vfsl-codegen-<version>.tgz
├── nomicore-doc-runtime-<version>.tgz
├── nomicore-clock-<version>.tgz
├── nomicore-instance-<version>.tgz
├── nomicore-persistence-<version>.tgz
├── nomicore-dsh-persistence-<version>.tgz
├── nomicore-namespace-runtime-<version>.tgz
├── nomicore-namespace-registry-<version>.tgz
├── nomicore-replication-protocol-<version>.tgz
├── nomicore-ws-replication-<version>.tgz
└── nomicore-yjs-server-<version>.tgz
To write to another directory:
pnpm run pack:local -- /absolute/path/to/output
manifest.json is the authoritative package-name-to-versioned-filename mapping. Do not hard-code the versions shown in examples. Generated *.tgz files are local/CI build artifacts and are ignored by Git; run pnpm pack:local after cloning instead of expecting archives in the repository. The tracked manifest declares the current package set and filename baseline and is rewritten during each build.
If package contents change, bump the corresponding package version before release. Never publish different contents under the same version.
3. Test an unreleased build in an independent project
Use file: dependencies only to test unreleased repository changes. Point the relevant @nomicore/* dependency closure to tarballs from the same manifest; do not mix registry and local builds accidentally.
Example package.json (use the filenames from the generated manifest):
{
"dependencies": {
"@nomicore/instance": "file:../nomicore/artifacts/local-packages/nomicore-instance-0.1.0.tgz",
"@nomicore/clock": "file:../nomicore/artifacts/local-packages/nomicore-clock-0.1.0.tgz",
"@nomicore/persistence": "file:../nomicore/artifacts/local-packages/nomicore-persistence-0.2.2.tgz",
"@nomicore/namespace-registry": "file:../nomicore/artifacts/local-packages/nomicore-namespace-registry-0.1.6.tgz",
"@nomicore/replication-protocol": "file:../nomicore/artifacts/local-packages/nomicore-replication-protocol-0.1.0.tgz",
"@nomicore/ws-replication": "file:../nomicore/artifacts/local-packages/nomicore-ws-replication-0.1.3.tgz",
"@nomicore/yjs-server": "file:../nomicore/artifacts/local-packages/nomicore-yjs-server-0.1.1.tgz"
}
}
The actual closure may also include vfsl-protocol, vfsl, doc-runtime, and namespace-runtime; use the package manager's report and manifest.json. Re-run the consumer's package-manager install after rebuilding tarballs so its lockfile captures the new files and integrity values.
4. Verify tarball consumption
A consumer should import packed dist output, not run production integration through the nomicore-source condition, source paths, or checkout-internal subpaths. At minimum, run:
pnpm install
pnpm typecheck
pnpm test
For typed Namespace writers, also run the host project's generation checks:
pnpm nomicore:generate
pnpm nomicore:generate:check
pnpm exec tsc -p <projection-aware-tsconfig> --listFilesOnly
The --listFilesOnly output must contain the exact projection file used by the business package.
npm release preparation and publication
All @nomicore/* packages use the MIT license and are configured as public npm scoped packages. scripts/package-catalog.mjs is the single source of truth for package ordering across build, verification, and publication.
Build and verify
pnpm install --frozen-lockfile
pnpm typecheck
pnpm test
pnpm pack:local
pnpm publish:verify
pnpm publish:reproducible
For each tarball, publish:verify checks:
- package
nameandversionmatch the manifest filename; - the package is public, non-private, MIT-licensed, and targets the public npm registry;
- dependencies contain no
workspace:orfile:protocols; - all packed
exportsandbintargets exist; npm publish --dry-run --json --ignore-scriptssucceeds for versions not yet published.
By default, publish:verify queries npm: an already-published version must have the same integrity as the local tarball, while an unpublished version must pass npm's dry run. Ordinary source PR CI sets NOMICORE_VERIFY_REGISTRY_INTEGRITY=0 and checks tarball structure only; registry integrity, version-bump enforcement, and npm publish dry runs remain release gates.
publish:reproducible independently builds two tarball sets from the same source and requires identical SHA-256 values for every package. The Node 20/24 CI matrix validates both package structure and reproducibility.
Safe dry run
pnpm publish:packages
This mode verifies again and executes npm publish --dry-run for every package in dependency order without creating a release.
Publish
A real publication requires:
- the current branch is
main; - the Git working tree is clean;
npm whoamiidentifies an account authorized to publish under thenomicoreorganization;- every package/version selected for publication is not already present on npm;
- every changed package has been version-bumped before rebuilding the manifest and tarballs.
Run:
pnpm publish:packages -- --publish
For npm provenance:
pnpm publish:packages -- --publish --provenance
The script publishes in dependency order and stops at the first failure. After publishing, install the top-level packages from npm in a fresh temporary project and run typecheck/runtime smoke tests to prove registry consumption does not depend on checkout sources.
Third-party Cordis hosting
Embedded hosts start public plugin factories in this dependency order:
Instance
→ Clock
→ Host-owned Timer
→ Memory/File Persistence
→ Namespace Registry
→ role-specific Hub/Peer replication plugin
→ namespace lease / replication readiness
→ domain service
Node hosts can import these adapters from @nomicore/yjs-server:
createNodeHubListenAdapter()createNodePeerDial()
See the Cordis hosting guide for readiness, Timer ownership, File roots, Peer reconnect, and teardown requirements.
Standalone Hub/Peer
@nomicore/yjs-server provides the nomicore-yjs-server CLI. Install it from npm and run:
pnpm exec nomicore-yjs-server --config /path/to/config.json
# or
NOMICORE_CONFIG=/path/to/config.json pnpm exec nomicore-yjs-server
See the Hub/Peer deployment guide for configuration, the NDJSON management interface, TLS, root locking, Hub restart, Peer recovery, and the reset runbook.
Development and verification
pnpm install --frozen-lockfile
pnpm typecheck
pnpm test
pnpm run pack:local
Common tools:
pnpm schema:check /absolute/path/to/schema.vfsl
pnpm generate --domains /absolute/path/to/host
CI runs on Node 20 and Node 24 via .github/workflows/ci.yml.